#include <bits/stdc++.h>   using namespace std;   using ll = long long;   using ld = long double;   using ii = pair<ll, ll>;   using vi = vector<ll>;   using vb = vector<bool>;   using vvi = vector<vi>;   using vii = vector<ii>;   using vvii = vector<vii>;   constexpr int INF = 2000000000;   constexpr ll LLINF = 9000000000000000000;   struct ConvexHullSet {     struct Line {       ld a, b;       mutable ld x;       bool type;       bool operator<(const Line &rhs) const {         return type || rhs.type ? x < rhs.x : a < rhs.a;       }       ld intersect(const Line &rhs) const {         return ld(b - rhs.b) / ld(rhs.a - a);       }     };     set<Line> lines;     static constexpr ld MAX = std::numeric_limits<ld>::max();     ld query(ld x) {       auto it = lines.lower_bound(Line{0.0, 0.0, x, true});       return (it != lines.end() ? it->a * x + it->b : -1e300);     }     void adjust(set<Line>::iterator it) {       if (it != lines.end())         it->x = next(it) != lines.end() ? it->intersect(*next(it)) : MAX;       if (it != lines.begin())         prev(it)->x = it != lines.end() ? it->intersect(*prev(it)) : MAX;     }     void insert(ld a, ld b) {       Line ln = Line{a, b, 0.0, false};       auto it1 = lines.lower_bound(ln);       if (it1 != lines.end() && it1->a == a) {         if (it1->b >= b) return;         it1 = lines.erase(it1);         adjust(it1);       }       ln.x = it1 != lines.end() ? ln.intersect(*it1) : MAX;       while (it1 != lines.end() && ln.x >= it1->x) {         it1 = lines.erase(it1);         ln.x = it1 != lines.end() ? it1->intersect(ln) : MAX;         adjust(it1);       }       while (it1 != lines.begin()) {         --it1;         ld nx = it1->intersect(ln);         if (nx >= it1->x) return;         if (it1 != lines.begin() && prev(it1)->x >= nx) {           it1 = lines.erase(it1);           adjust(it1);         } else           break;       }       it1 = lines.insert(ln).first;       adjust(it1);     }   };   constexpr int L = 0, R = 1000000;   vector<ld> solve(vii &pairs, int s) {     vector<ld> d(R - L + 1, 1e300);     sort(pairs.begin(), pairs.end());     ConvexHullSet chs;     for (int i = 0, p = L; p <= R; ++p) {       while (i < (int)pairs.size() && pairs[i].first == p) {         int x = pairs[i].first, v = pairs[i].second;         ld a = 1.0 / ld(s - v) - ld(v) / (ld(s - v) * ld(s + v));         ld b = -ld(x) / ld(s - v) + ld(x) / ld(s + v) +                ld(v) * ld(x) / (ld(s - v) * ld(s + v));         chs.insert(-a, -b);         ++i;       }       d[p] = -chs.query(p);     }     return d;   }   int main() {     ios::sync_with_stdio(false);     cin.tie(NULL);     int n, s;     cin >> n >> s;     vi x(n, 0), v(n, 0), t(n, 0);     ld lr = 1e300, rr = 1e300;     int minl = R + 1, maxr = L - 1;     for (int i = 0; i < n; ++i) {       cin >> x[i] >> v[i] >> t[i];       if (t[i] == 1) {         lr = min(lr, ld(x[i]) / ld(v[i]));         if (x[i] < minl) minl = x[i];       } else {         rr = min(rr, ld(R - x[i]) / ld(v[i]));         if (x[i] > maxr) maxr = x[i];       }     }     cerr <<  lr =   << lr <<  , rr =   << rr << endl;     vector<ld> lp, rp;     {       vii pairs[2];       for (int i = 0; i < n; ++i) pairs[t[i] - 1].push_back({x[i], v[i]});       for (ii &pr : pairs[1]) pr.first = R - pr.first;       lp = solve(pairs[0], s);       rp = solve(pairs[1], s);       reverse(rp.begin(), rp.end());     }     ld ans = max(lr, rr);     for (int p = L; p <= R; ++p)       ans = min(ans, max(min(lr, lp[p]), min(rr, rp[p])));     printf( %.10lf n , double(ans));     return 0;   }