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)
}