#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define MN 100001
using namespace std;
int n,ne[MN],fi[MN],p;
double X[MN],Y[MN],f[MN],A[MN],B[MN],R[MN],q[MN];
inline double fk(int a,int b){
if (!a) return 2e9;if (!b) return -2e9;
if (X[a]==X[b]) return 2e9*(Y[a]<=Y[b]?1:-1);
return (Y[a]-Y[b])/(X[a]-X[b]);
}
struct tree{
int l,r,k,w,f,s;
tree(){
f=l=r=0;
}
};
inline double max(double a,double b){return a>b?a:b;}
struct splay_tree{
int size,root;
tree t[100001];
splay_tree(){
size=0;root=0;
}
inline void ler(int &p){
int k=t[p].r;
t[k].f=t[p].f;
t[p].f=k;
t[t[k].l].f=p;
t[p].r=t[k].l;
t[k].l=p;
t[k].s=t[p].s;
t[p].s=t[t[p].l].s+t[t[p].r].s+t[p].w;
p=k;
}
inline void rir(int &p){
int k=t[p].l;
t[k].f=t[p].f;
t[p].f=k;
t[t[k].r].f=p;
t[p].l=t[k].r;
t[k].r=p;
t[k].s=t[p].s;
t[p].s=t[t[p].l].s+t[t[p].r].s+t[p].w;
p=k;
}
inline void ph(int &x,bool bo){if (bo) rir(x);else ler(x);}
inline bool gc(int x){return t[t[x].f].l==x;}
inline void rot(int p){
if (t[p].f==root) ph(root,gc(p));else
if (gc(t[p].f)) ph(t[t[t[p].f].f].l,gc(p));else ph(t[t[t[p].f].f].r,gc(p));
}
inline void splay(int p,int f){
while(t[p].f!=f){
if (t[t[p].f].f==f) rot(p);else
if (gc(t[p].f)==gc(p)) rot(t[p].f),rot(p);else rot(p),rot(p);
}
}
inline void insert(int &p,int k,int f){
if (!p){
p=++size;
t[p].k=k;
t[p].w=1;
t[p].f=f;
t[p].s=1;
splay(p,0);
return;
}
t[p].s++;
if (X[t[p].k]>X[k]) insert(t[p].l,k,p);else insert(t[p].r,k,p);
}
inline int qui(int p,int k){
if (!p) return -1;
if (X[t[p].k]>X[k]) return qui(t[p].l,k);else{
int u=qui(t[p].r,k);
if (u==-1) splay(p,0),u=p;return u;
}
}
inline int ask(int p,double k){
if (!p) return -1;
if (fk(p,ne[p])==k) return p;else
if (fk(p,ne[p])>k) return ask(t[p].r,k);else
if (t[p].l==0) return p;else{
int u=ask(t[p].l,k);
if (u==-1){splay(p,0);return p;}else return u;
}
}
};
splay_tree t;
inline void in(int x){
int s=t.qui(t.root,x),p=ne[s];
if (s&&X[s]==X[x]) if (Y[s]>=Y[x]){t.size++;return;}else s=fi[s];
if (fk(s,x)<fk(x,p)){t.size++;return;}
if (s==-1){
p=ne[0];
while ((fk(x,p)<fk(p,ne[p]))&&p) p=ne[p];
t.splay(p,0);t.t[p].l=0;
ne[x]=p;
ne[0]=x;
fi[x]=0;
fi[ne[x]]=x;
t.insert(t.root,x,0);
return;
}
while (fk(fi[s],s)<fk(s,x)&&s) s=fi[s];
while ((fk(x,p)<fk(p,ne[p]))&&p) p=ne[p];
if ((!s)&&(!p)) t.root=0;else
if ((!s)&&p) t.splay(p,0),t.t[p].l=0;else
if (s&&(!p)) t.splay(s,0),t.t[s].r=0;else
t.splay(s,0),t.splay(p,s),t.t[p].l=0;
ne[s]=x;fi[x]=s;
ne[x]=p;fi[p]=x;
t.insert(t.root,x,0);
}
inline int que(double k){
return t.ask(t.root,k);
}
int main(){
scanf("%d%lf",&n,&f[1]);
for (int i=1;i<=n;i++) scanf("%lf%lf%lf",&A[i],&B[i],&R[i]),q[i]=-A[i]/B[i];
X[1]=f[1]/(R[1]*A[1]+B[1])*R[1];
Y[1]=f[1]/(R[1]*A[1]+B[1]);
in(1);
for (int i=2;i<=n;i++){
p=que(q[i]);
f[i]=max(X[p]*A[i]+Y[p]*B[i],f[i-1]);
X[i]=f[i]/(A[i]*R[i]+B[i])*R[i];
Y[i]=f[i]/(R[i]*A[i]+B[i]);
in(i);
}
printf("%.3lf\n",f[n]);
return 0;
}