Problem: Ivan plays some computer game. There are n quests in the game. Each quest can be upgraded once, this increases the reward for its completion. Each quest has 3 parameters a_{i}, b_{i}, p_{i}: reward for completing quest before upgrade, reward for completing quest after upgrade (a_{i} < b_{i}) and probability of successful completing the quest.

Each second Ivan can try to complete one quest and he will succeed with probability p_{i}. In case of success Ivan will get the reward and opportunity to upgrade any one quest (not necessary the one he just completed). In case of failure he gets nothing. Quests do not vanish after completing.

Ivan has t seconds. He wants to maximize expected value of his total gain after t seconds. Help him to calculate this value.

Input

First line contains 2 integers n ( 1 ≤ n ≤ 10^{5}) and t ( 1 ≤ t ≤ 10^{10}) — number of quests and total time.

Following n lines contain description of quests. Each description is 3 numbers a_{i} b_{i} p_{i} (1 ≤ a_{i} < b_{i} ≤ 10^{8}, 0 < p_{i} < 1) — reward for completing quest before upgrade, reward for completing quest after upgrade and probability of successful completing of quest. a_{i} and b_{i} are integers. All probabilities are given with at most 9 decimal places.

Output

Print the expected value.

Your answer will be accepted if absolute or relative error does not exceed 10^{-6}. Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if (|a-b|)/(max⁡(b,    1)) ≤ 10^{-6}.

Examples

Input

3 2
3 1000 0.5
1 2 0.48
3 20 0.3


Output

252.2500000000000


Input

2 2
1 1000 0.1
2 3 0.2


Output

20.7200000000000

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : ", ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T>
ostream &operator<<(ostream &o, tuple<T...> const &t) {
  o << "(";
  _ot<0>(o, t);
  o << ")";
  return o;
}
template <class T, class U>
ostream &operator<<(ostream &o, pair<T, U> const &p) {
  o << "(" << p.first << ", " << p.second << ")";
  return o;
}
template <class T>
ostream &operator<<(ostream &o, const stack<T> &a) {
  o << "{";
  for (auto tmp = a; tmp.size(); tmp.pop())
    o << (a.size() == tmp.size() ? "" : ", ") << tmp.top();
  o << "}";
  return o;
}
template <class T,
          class = typename iterator_traits<typename T::iterator>::value_type,
          class = typename enable_if<!is_same<T, string>::value>::type>
ostream &operator<<(ostream &o, const T &a) {
  for (auto ite = a.begin(); ite != a.end(); ++ite)
    o << (ite == a.begin() ? "" : " ") << *ite;
  return o;
}
const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];
template <class T = long long, class Comp = less<T> >
struct DynamicCHT {
  static T INF;
  static Comp comp;

 private:
  struct Line {
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const {
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom;
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    CP(const Line &p1, const Line &p2) : p(p2) {
      if (p1.a == INF || p1.a == -INF)
        numer = -INF, denom = 1;
      else if (p2.a == INF || p2.a == -INF)
        numer = INF, denom = 1;
      else {
        numer = p1.b - p2.b, denom = p2.a - p1.a;
        if (denom < 0) numer = -numer, denom = -denom;
      }
    }
    bool operator<(const CP &rhs) const {
      if (numer == INF || rhs.numer == -INF) return 0;
      if (numer == -INF || rhs.numer == INF) return 1;
      return numer * rhs.denom < rhs.numer * denom;
    }
  };
  set<Line> lines;
  set<CP> cps;

 public:
  DynamicCHT() {
    lines.insert({Line(INF, 0), Line(-INF, 0)});
    cps.insert(CP(Line(INF, 0), Line(-INF, 0)));
  }
  void add(const T &a, const T &b) {
    const Line p(a, b);
    typename set<Line>::iterator pos = lines.insert(p).first;
    if (check(*prev(pos), p, *next(pos))) {
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      typename set<Line>::iterator it = prev(pos);
      while (it != lines.begin() && check(*prev(it), *it, p)) --it;
      eraseRange(it, prev(pos));
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      typename set<Line>::iterator it = next(pos);
      while (next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      eraseRange(++pos, it);
      lines.erase(pos, it);
      pos = lines.find(p);
    }
    cps.insert(CP(*prev(pos), *pos));
    cps.insert(CP(*pos, *next(pos)));
  }
  T query(const T &x) const {
    const Line &p = (--cps.lower_bound(CP(x)))->p;
    return p.a * x + p.b;
  }
  tuple<T, T> get(const T &x) const {
    const Line &p = (--cps.lower_bound(CP(x)))->p;
    return make_tuple(p.a, p.b);
  }
  friend ostream &operator<<(ostream &os, const DynamicCHT &a) {
    os << "\n";
    os << "lines : " << a.lines.size() << "\n";
    for (auto &p : a.lines)
      os << "(" << p.a << ", " << p.b << ")"
         << "\n";
    os << "cross points : " << a.cps.size() << "\n";
    for (auto &p : a.cps)
      os << "(x = " << p.numer << "/" << p.denom << "; " << p.p.a << ", "
         << p.p.b << ")"
         << "\n";
    return os;
  }

 private:
  void eraseRange(typename set<Line>::iterator a,
                  typename set<Line>::iterator b) {
    for (typename set<Line>::iterator it = a; it != b; ++it)
      cps.erase(CP(*it, *next(it)));
  }
  bool check(const Line &p1, const Line &p2, const Line &p3) {
    if (p1.a == p2.a) return 1;
    if (p1.a == INF || p1.a == -INF || p3.a == INF || p3.a == -INF) return 0;
    return (p2.a - p1.a) * (p3.b - p2.b) + (1e-19) >=
           (p2.b - p1.b) * (p3.a - p2.a);
  }
};
template <class T, class Comp>
T DynamicCHT<T, Comp>::INF = numeric_limits<T>::has_infinity
                                 ? numeric_limits<T>::infinity()
                                 : numeric_limits<T>::max();
template <class T, class Comp>
Comp DynamicCHT<T, Comp>::comp = Comp();
template <class T>
vector<vector<T> > mult(vector<vector<T> > a, vector<vector<T> > b) {
  assert(a[0].size() == b.size());
  vector<vector<T> > res(a.size(), vector<T>(b[0].size(), 0));
  for (size_t i = 0; i < a.size(); i++) {
    for (size_t j = 0; j < b[0].size(); j++) {
      for (size_t k = 0; k < b.size(); k++) {
        res[i][j] += a[i][k] * b[k][j];
      }
    }
  }
  return res;
}
template <class T>
vector<vector<T> > makeE(int n) {
  vector<vector<T> > r(n, vector<T>(n, 0));
  for (int i = 0; i < n; i++) r[i][i] = T(1);
  return r;
}
template <class T>
vector<vector<T> > pow(vector<vector<T> > a, ll k) {
  assert(a.size() == a[0].size());
  vector<vector<T> > r = makeE<T>(a.size());
  while (k) {
    if (k & 1) r = mult(r, a);
    a = mult(a, a);
    k >>= 1;
  }
  return r;
}
using Vec = vector<D>;
using Mat = vector<Vec>;
int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  cin >> n >> t;
  D m = 0;
  DynamicCHT<D, greater<D> > cht;
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> b[i] >> p[i];
    m = max(m, b[i] * p[i]);
    cht.add(p[i], p[i] * a[i]);
  }
  (42);
  cout << fixed << setprecision(12);
  ll le = 1;
  Mat v{{cht.query(0)}, {1}, {1}};
  while (le != t) {
    D xle = m * le - v[0][0];
    auto g = cht.get(xle);
    (42);
    (42);
    ll f = t - le;
    ll h = 1;
    vector<Mat> mats;
    Mat A(3, Vec(3));
    A[0][0] = 1 - get<0>(g);
    A[0][1] = get<0>(g) * m;
    A[0][2] = get<1>(g);
    A[1][1] = A[1][2] = A[2][2] = 1;
    mats.push_back(A);
    while ((1ll << h) - 1 < f) {
      A = mult(A, A);
      mats.push_back(A);
      h++;
    }
    ll now = 0;
    for (int k = h - 1; k >= 0; k--) {
      ll j = 1ll << k;
      if (now + j > f) continue;
      auto tv = mult(mats[k], v);
      auto tdp = tv[0][0];
      ll tt = le + now + j;
      D x = m * tt - tdp;
      (42);
      (42);
      (42);
      if (g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if (now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    (42);
    le += now;
  }
  cout << v[0][0] << endl;
  return 0;
}