#include <bits/stdc++.h>
#define rt "\n"
#define sp " "
#define test(n) cout << "test" << n << endl;
#define fixsp(n) fixed << setprecision(n)
#define defsp(n) defaultfloat << setprecision(n)
#define kyopro ios::sync_with_stdio(false);cin.tie(NULL)
#define MOD 1000000007
#define iikae auto&
#define vector3D(K, N, M, DP) vector<vector<vector<ll>>> DP(K, vector<vector<ll>>(N, vector<ll>(M)));
#define vector4D(K, N, M, O, DP) vector<vector<vector<vector<ll>>>> DP(K, vector<vector<vector<ll>>>(N, vector<vector<ll>>(M, vector<ll>(O))));
#define zenbu(a) a.begin(), a.end()
#define rzenbu(a) a.rbegin(), a.rend()
#define rep(i, s, N) for(ll i{s}; i < N; i++)
#define rem(i, N, s) for(ll i{N}; i > s; i--)
using namespace std;using ll = long long;using ld = long double;using P = pair<ll,ll>;
template<typename T> T gcd(T a, T b){return b != 0 ? gcd(b, a % b) : a;}
template<typename T> struct UnionFind{vector<T> par;UnionFind(T n) : par(n, -1){}void init(T n){par.assign(n, -1);}T root(T x){if (par[x] < 0) return x;else return par[x] = root(par[x]);}bool issame(T x, T y){return root(x) == root(y);}bool merge(T x, T y){x = root(x); y = root(y);if(x == y) return false;if(par[x] > par[y]) swap(x, y);par[x] += par[y];par[y] = x;return true;}int size(int x) {return -par[root(x)];}};
template<typename T> ll combpm(T N_, T C_) {const int NUM_=400001;static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1];if (fact[0]==0) {inv[1]=fact[0]=factr[0]=1;for (int i=2;i<=NUM_;++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%MOD, factr[i]=factr[i-1]*inv[i]%MOD;}if(C_<0 || C_>N_) return 0;return factr[C_]*fact[N_]%MOD*factr[N_-C_]%MOD;}
struct phash{inline size_t operator()(const pair<ll,ll> & p) const{const auto h1 = hash<ll>()(p.first);const auto h2 = hash<ll>()(p.second);return h1 ^ (h2 << 1);}};
/* ここからコード開始 */

int main(){
  kyopro;
  ll N, X;
  cin >> N >> X;
  vector<ll> b(N), l(N), u(N);
  rep(i, 0, N){
    cin >> b[i] >> l[i] >> u[i];
  }
  vector<P> bli(N);
  ll sum{};
  rep(i, 0, N){
    bli[i].first = b[i]*l[i] + (X-b[i])*u[i];
    bli[i].second = i;
    sum -= b[i]*l[i];
  }
  sort(rzenbu(bli));
  ll hours{};
  vector<ll> remain;
  vector<ll> resub;
  ll sumlast;
  rep(i, 0, N){
    if(sum > 0) resub.push_back(bli[i].second);
    else{
      sum += bli[i].first;
      hours += X;
      remain.push_back(bli[i].second);
      sumlast = bli[i].first;
    }
  }
  resub.push_back(remain[remain.size()-1]);
  rep(i, 0, N){
    if(sum - (X-b[i])*u[i] < 0){
      ll d = sum / u[i];
    }
    else{
      ll d = (X-b[i]) + (sum - (X-b[i])*u[i]) / l[i];
    }
  }
  ll alpha{};
  for(auto&& i : remain){
    if(sum - (X-b[i])*u[i] < 0){
      ll d = sum / u[i];
      alpha = max(d, alpha);
      // cout << d << rt;
    }
    else{
      ll d = (X-b[i]) + (sum - (X-b[i])*u[i]) / l[i];
      alpha = max(d, alpha);
      // cout << d << rt;
    }
  }
  sum -= sumlast;
    for(auto&& i : resub){
    if(sum + b[i]*l[i] >= 0){
      ll d = (-sum + l[i] - 1) / l[i];
      alpha = max(X-d, alpha);
      // cout << X-d << rt;
    }
    else{
      ll d = b[i] + (-sum - b[i]*l[i] + u[i] - 1) / u[i];
      alpha = max(X-d, alpha);
      // cout << X-d << rt;
    }
  }
  cout << hours - alpha << rt;
}

Measured memory_bytes: 5496