#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;
}
