← Home
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func readInt(reader *bufio.Reader) int {
	var n int
	var c byte
	var err error
	for {
		c, err = reader.ReadByte()
		if err != nil {
			return n
		}
		if c >= '0' && c <= '9' {
			break
		}
	}
	for {
		n = n*10 + int(c-'0')
		c, err = reader.ReadByte()
		if err != nil || c < '0' || c > '9' {
			break
		}
	}
	return n
}

type Line struct {
	m, c float64
}

func (l Line) eval(x int) float64 {
	return l.m*float64(x) + l.c
}

type LCTNode struct {
	line  Line
	left  int
	right int
}

var lct []LCTNode

func addNode() int {
	lct = append(lct, LCTNode{line: Line{0, 1e18}, left: -1, right: -1})
	return len(lct) - 1
}

func insert(node int, l, r int, newLine Line) {
	mid := l + (r-l)/2
	betterLeft := newLine.eval(l) < lct[node].line.eval(l)
	betterMid := newLine.eval(mid) < lct[node].line.eval(mid)

	if betterMid {
		lct[node].line, newLine = newLine, lct[node].line
	}

	if l == r {
		return
	}

	if betterLeft != betterMid {
		if lct[node].left == -1 {
			lct[node].left = addNode()
		}
		insert(lct[node].left, l, mid, newLine)
	} else {
		if lct[node].right == -1 {
			lct[node].right = addNode()
		}
		insert(lct[node].right, mid+1, r, newLine)
	}
}

func query(node int, l, r int, x int) float64 {
	if node == -1 {
		return 1e18
	}
	res := lct[node].line.eval(x)
	if l == r {
		return res
	}
	mid := l + (r-l)/2
	if x <= mid {
		leftRes := query(lct[node].left, l, mid, x)
		if leftRes < res {
			res = leftRes
		}
	} else {
		rightRes := query(lct[node].right, mid+1, r, x)
		if rightRes < res {
			res = rightRes
		}
	}
	return res
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	n := readInt(reader)
	sInt := readInt(reader)
	s := float64(sInt)

	const X = 1000000

	CL := 1e18
	CR := 1e18

	leftByX := make([][]int, X+1)
	rightByX := make([][]int, X+1)

	mL := make([]float64, n)
	cL := make([]float64, n)
	mR := make([]float64, n)
	cR := make([]float64, n)

	for i := 0; i < n; i++ {
		x := readInt(reader)
		vInt := readInt(reader)
		dir := readInt(reader)
		v := float64(vInt)

		if dir == 1 {
			t := float64(x) / v
			if t < CL {
				CL = t
			}
			mL[i] = s / (s*s - v*v)
			cL[i] = -v * float64(x) / (s*s - v*v)
			leftByX[x] = append(leftByX[x], i)
		} else {
			t := float64(X-x) / v
			if t < CR {
				CR = t
			}
			mR[i] = -s / (s*s - v*v)
			cR[i] = (s*float64(X) - v*float64(X-x)) / (s*s - v*v)
			rightByX[x] = append(rightByX[x], i)
		}
	}

	lct = make([]LCTNode, 0, 2000000)
	rootL := addNode()

	fL := make([]float64, X+1)
	for Y := 0; Y <= X; Y++ {
		for _, i := range leftByX[Y] {
			insert(rootL, 0, X, Line{mL[i], cL[i]})
		}
		q := query(rootL, 0, X, Y)
		fL[Y] = math.Min(CL, q)
	}

	lct = lct[:0]
	rootR := addNode()

	fR := make([]float64, X+1)
	for Y := X; Y >= 0; Y-- {
		for _, i := range rightByX[Y] {
			insert(rootR, 0, X, Line{mR[i], cR[i]})
		}
		q := query(rootR, 0, X, Y)
		fR[Y] = math.Min(CR, q)
	}

	ans := 1e18
	for Y := 0; Y <= X; Y++ {
		maxT := math.Max(fL[Y], fR[Y])
		if maxT < ans {
			ans = maxT
		}
	}

	fmt.Printf("%.7f\n", ans)
}