#include<cstdio>
#include<algorithm>
#define MAXN 101000

int n,s[MAXN],t;

long long T,rsec[MAXN];

struct data {double a,b,p;} d[MAXN];

double ans,MaxBP,rres[MAXN];

double Mul(long double a,long long b)
{
	double c(1);
	for(;b;b>>=1,a*=a)
		if(b&1)
			c*=a;
	return c;
}

bool cmp(data a,data b){return a.p*a.a>b.p*b.a;}

double f(data x,long long t,long long rsec,double rres)
{
	double temp=Mul(1.0-x.p,t);
	return MaxBP*t+(x.a-MaxBP/x.p)*(1.0-temp)+MaxBP*rsec*(1.0-temp)+temp*rres;
}

long long GetMinT(data x,data y,long long rsec,long long rres) // Get Minimum t that f(x,t)>=f(y,t)
{
	long long L=0,R=T,M;
	//printf("%lf %lf %lf %lf %lf %lf\n",x.a,x.b,x.p,y.a,y.b,y.p);
	//printf("%lf %lf\n",f(x,1,rsec+R,f(y,R,rsec,rres)),f(y,R+1,rsec,rres));
	if(f(x,1,rsec+R,f(y,R,rsec,rres))<=f(y,R+1,rsec,rres))
		return R+rsec+1;
	for(;L+1<R;)
	{
		M=(L+R+1)/2;
		if(f(x,1,rsec+M,f(y,M,rsec,rres))>f(y,M+1,rsec,rres))
			R=M;
		else
			L=M;
	}
	return R+rsec;
}

int main()
{
	long long rest;
	//freopen("d.in","rb",stdin);
	scanf("%d%I64d",&n,&T);
	MaxBP=-1e10;
	for(int i=0;i<n;i++)
	{
		scanf("%lf%lf%lf",&d[i].a,&d[i].b,&d[i].p);
		if(d[i].b*d[i].p>MaxBP)
			MaxBP=d[i].b*d[i].p;
	}
	std::sort(d,d+n,cmp);
	t=0;
	for(int i=0;i<n;i++)
	{
		if(t>0&&GetMinT(d[i],d[s[t-1]],rsec[t-1],rres[t-1])>=T)
			continue;
		for(;t>0&&f(d[i],1,rsec[t-1],rres[t-1])>f(d[s[t-1]],1,rsec[t-1],rres[t-1]);t--);
		s[t]=i;
		if(t>0)
		{
			rsec[t]=GetMinT(d[i],d[s[t-1]],rsec[t-1],rres[t-1]);
			rres[t]=f(d[s[t-1]],rsec[t]-rsec[t-1],rsec[t-1],rres[t-1]);
		}
		else
		{
			rsec[t]=0;
			rres[t]=0;
		}
		t++;
//	for(int ii=0;ii<t;ii++)
//		printf("%lf %lf %lf %I64d %lf\n",d[s[ii]].a,d[s[ii]].b,d[s[ii]].p,rsec[ii],rres[ii]);
//		printf("\n");
	}
	//printf("%lf\n",T-rsec[t-1]);
	ans=f(d[s[t-1]],T-rsec[t-1],rsec[t-1],rres[t-1]);
//	printf("%lf\n",MaxBP);
/*	for(int i=0;i<t;i++)
		printf("%lf %lf %lf\n",d[s[i]].a,d[s[i]].b,d[s[i]].p);
	for(int i=0;i<t-1;i++)
		printf("%I64d\n",GetMinT(d[s[i+1]],d[s[i]]));
*/
//	for(int i=0;i<t;i++)
//		printf("%lf %lf %lf %I64d %lf\n",d[s[i]].a,d[s[i]].b,d[s[i]].p,rsec[i],rres[i]);
	printf("%lf\n",ans);
	return 0;
}

#include <bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;
const int N = 1e5 + 6;
int a[N], b[N];
ld p[N];
struct point
{
	ld x, y;
	bool operator < (const point &a)const
	{
		if(y != a.y) return y > a.y;
		return x > a.x;
	}
}nd[N];
ld k(point a, point b)
{
	return (b.y - a.y) / (b.x - a.x);
}
point st[N];
int top;
ld ksm(ld a, ll k)
{
	if(k == 0) return 1;
	ld ns = ksm(a, k >> 1);
	ns = ns * ns;
	if(k & 1) ns = ns * a;
	return ns;
}
ld cal1(ld p, ld ms, ld k)
{
	ld ans = k * (1 - ksm(p, ms + 1)) / (1 - p);
	return ans;
}
ld cal2(ld p, ld ms, ld k)
{
	ld ans = k * (cal1(p, ms, 1) - ms * ksm(p, ms + 1) - 1) / (1 - p);
	return ans;
}
ld mv(ll fr, ll ed, ld k, ld b, ld p, ld frs)
{
	if(fr == ed) return frs;
	ld n1 = ksm(p, ed - fr) * frs;
	ld n2 = cal1(p, ed - 1 - fr, k * (ed - 1) + b) + cal2(p, ed - 1 - fr, -k);
	return n1 + n2;
}
int main()
{
	ld s = 0;
	int n;
	ll t;
	scanf("%d%lld", &n, &t);
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d%Lf", &a[i], &b[i], &p[i]);
		s = max(s, b[i] * p[i]);
		nd[i].x = p[i], nd[i].y = a[i] * p[i];
	}
	sort(nd + 1, nd + n + 1);
	for(int i = 1; i <= n; i++)
	{
		if(nd[i].y == st[top - 1].y) continue;
		if(i && nd[i].x < st[top - 1].x) continue;
		while(top >= 2 && k(st[top - 1], nd[i]) >= k(st[top - 2], st[top - 1])) top--;
		st[top++] = nd[i];
	}
	ll nt = 0;
	ld lans = 0;
	for(int i = 0; i < top; i++)
	{
		if(nt == t) break;
		ld nk = st[i].x * s, nb = st[i].y, np = (1 - st[i].x);
		ll l = nt, r = t;
		if(i == top - 1)
			l = t;
		while(l < r)
		{
			ll mid = (l + r) >> 1;
			ld nans = mv(nt, mid, nk, nb, np, lans);
			if(-k(st[i], st[i + 1]) <= mid * s - nans)
				r = mid;
			else l = mid + 1;
		}
		lans = mv(nt, l, nk, nb, np, lans);
		nt = l;
	}
	printf("%.12Lf\n", lans);//
	return 0;
}

#include<bits/stdc++.h>
#include<iomanip>
#define N 100005
#define ll long long
#define db double
int n;
db a[N], b[N], p[N], S;
ll T;
struct point
{
	db x, y;
	friend bool operator <(point t1, point t2) { return t1.y > t2.y; }
}A[N];
struct Matrix
{
	db s[3][3];
	void init ()
	{
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++) s[i][j] = 0;
	}
	friend Matrix operator *(Matrix a, Matrix b)
	{
		Matrix c;
		for(int i=0;i<3;i++)
			for (int j = 0; j < 3; j++)
			{
				c.s[i][j] = 0;
				for (int k = 0; k < 3; k++) c.s[i][j] += a.s[i][k] * b.s[k][j];
			}
		return c;
	}
}bas[N], f[40], mat;
struct node
{
	int id; ll lst; Matrix p;
};
std::vector<node> sta;
int main ()
{
	std::ios::sync_with_stdio (0);
	std::cin >> n >> T;
	for (int i = 1; i <= n; i++)
	{
		std::cin >> a[i] >> b[i] >> p[i];
		S = std::max (S, b[i] * p[i]);
		A[i] = { p[i],a[i] * p[i] };
	}
	std::sort (A + 1, A + 1 + n);
	for (int i = 1; i <= n; i++)
	{
		bas[i].s[1][1] = bas[i].s[2][2] = 1, bas[i].s[0][0] = 1 - A[i].x;
		bas[i].s[0][1] = A[i].x, bas[i].s[0][2] = A[i].y, bas[i].s[1][2] = S;
	}
	mat.s[2][0] = 1;
	sta.push_back ({ 1,T,mat });
	for (int i = 2; i <= n; i++)
	{
		for (; (bas[i] * sta.back ().p).s[0][0] > (bas[sta.back ().id] * sta.back ().p).s[0][0]; sta.pop_back ());
		if (!sta.back ().lst) continue;
		node x = sta.back ();
		f[0] = bas[x.id];
		for (int j = 1; j <= 35; j++) f[j] = f[j - 1] * f[j - 1];
		for (int j = 35; ~j; j--)
			if (x.lst - (1ll << j) >= 1)
				if ((bas[i] * f[j] * x.p).s[0][0] <= (bas[x.id] * f[j] * x.p).s[0][0])
					x.p = f[j] * x.p, x.lst -= 1ll << j;
		x.p = f[0] * x.p, x.lst--;
		if (x.lst) x.id = i;
		sta.push_back (x);
	}
	Matrix ans = sta.back ().p, x = bas[sta.back ().id];
	for (ll res = sta.back ().lst; res; res >>= 1, x = x * x)
		if (res & 1) ans = x * ans;
	std::cout << std::fixed << std::setprecision (12) << ans.s[0][0] << "\n";
}

#include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
#define mp make_pair

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;

const int N = (int)1e5 + 123, inf = 1e9, LOG = 35;
const ll INF = 1e18;
struct Matrix{
	vector< vector< double > > val;
	int n, m;
	Metrix(){
		val.clear();
	}
	Matrix(int _n, int _m){
		n = _n;
		m = _m;
		val.resize(n, vector< double > (m, 0));
	}
	Matrix operator *(Matrix b){
		int nn = n, mm = b.m;
		if(m != b.n){
			cerr << "matrix mult";
			assert(0);
		}
		Matrix res(nn, mm);
		for(int i = 0; i < nn; i++)
			for(int j = 0; j < mm; j++)
				for(int q = 0; q < m; q++)
					res.val[i][j] += val[i][q]* b.val[q][j];
		return res;
	}
};
struct line{
	double k, b;
	bool operator < (line a){
		return k < a.k || (k == a.k && b  < a.b);
	}
	double cross(line a){
		return -(b - a.b) / (k - a.k);
	}
};
struct convex_hull{
	vector< line > v;
	vector< double > vc;
	void add(line l){
		while(!v.empty() && v.back().k == l.k)
			v.pop_back();
		while(v.size() > 2){
			line a = v[v.size() - 2];
			line b = v[v.size() - 1];
			if(l.cross(a) > l.cross(b))
				v.pop_back();
			else
				break;
		}
		v.pb(l);
	}
	void calc(){
		vc.clear();
		for(int i = 0; i + 1 < v.size(); i++)
			vc.pb(v[i].cross(v[i + 1]));
		vc.pb(1e18);
	}
	double get_val(double x){
		int id = lower_bound(vc.begin(), vc.end(), x) - vc.begin();
		return v[id].k * x + v[id].b;
	}
    double get_id(double x){
		int id = lower_bound(vc.begin(), vc.end(), x) - vc.begin();
		return id;
	}
};
vector< line > vline;
convex_hull C;
int n;
ll T, t;
double M, ans, dp;
int main(){
	scanf("%d%lld", &n, &T);
	for(int i = 0; i < n; i++){
		int a, b;
		double p;
		scanf("%d%d%lf", &a, &b, &p);
		M = max(M, b * p);
		vline.pb({p, p * a});
	}
	sort(vline.begin(), vline.end());
	for(auto it : vline)
		C.add(it);
	C.calc();
	/*
	for(ll t = 0; t < T; t++){
		cerr << t << ":" << C.get_id(t * M - dp) << endl;
		dp = dp + C.get_val(t * M - dp);
	}
	cerr << dp << endl;
	*/
	t = 0;
	n = C.v.size();
	dp = 0;
	for(int i = 0; i < n; i++){
		if(C.get_id(t * M - dp) != i)
			continue;
		vector< Matrix > kp(LOG, Matrix(3, 3));
		kp[0].val[0][0] = (1 - C.v[i].k);
		kp[0].val[0][1] = C.v[i].k * M;
		kp[0].val[0][2] = C.v[i].b;
		kp[0].val[1][1] = kp[0].val[1][2] = kp[0].val[2][2] = 1;
		for(int i = 1; i < LOG; i++)
			kp[i] = kp[i - 1] * kp[i - 1];

		Matrix mt(3, 1);
		mt.val[0][0] = dp;
		mt.val[1][0] = t;
		mt.val[2][0] = 1;

		for(int j = LOG - 1; j >= 0; j--){
			Matrix nxtmt = kp[j] * mt;
			double nxtdp = nxtmt.val[0][0];
			ll nxtt = t + (1ll<<j);
			if(C.get_id(nxtt * M - nxtdp) != min(i, n - 1) || nxtt >= T)
				continue;
			/*
			cerr << j << " " << t << endl;
			cerr << nxtmt.val[0][0] << endl;
			cerr << nxtmt.val[1][0] << endl;
			cerr << nxtmt.val[2][0] << endl;
			*/
			mt = nxtmt;
			dp = nxtdp;
			t = nxtt;
		}
		dp = dp + C.get_val(t * M - dp);
		t++;
		if(t == T)
			break;
	}
	ans = dp;
	printf("%.10f", ans);
	return 0;
}

#include<cstdio>
#include<algorithm>
const int maxn=100010;
struct Point{
	double x,y;
	bool operator<(const Point&p)const{return x<p.x;}
}P[maxn];
struct Mat{
	double a,b,c;
	long long n;
	Mat operator*(const Mat&M)const{return(Mat){a*M.a,a*M.b+b,a*M.c+b*M.n+c,n+M.n};}
	double val(double f,long long t){return a*f+b*t+c;}
}A[40];
int main(){
	int N,n=0;
	long long t,x=0;
	scanf("%d%lld",&N,&t);
	double m=0;
	while(N--){
		int a,b;double p;
		scanf("%d%d%lf",&a,&b,&p);
		if(b*p>m)m=b*p;
		P[n++]=(Point){p,a*p};
	}
	std::sort(P,P+n);
	N=n;n=0;
	for(int i=0;i<N;i++){
		bool fl=1;
		if(n&&P[i].x<P[n-1].x+1e-10)P[i].y>P[n-1].y?--n:fl=0;
		if(!fl)continue;
		while(n>1&&(P[i].y-P[n-1].y)*(P[n-1].x-P[n-2].x)>(P[n-1].y-P[n-2].y)*(P[i].x-P[n-1].x))--n;
		P[n++]=P[i];
	}
	double f=0;
	for(int i=0;i<n&&x<t;i++){
		if(i+1<n&&(P[i+1].x-P[i].x)*(m*x-f)>P[i].y-P[i+1].y)continue;
		A[0]=(Mat){1-P[i].x,m*P[i].x,P[i].y,1};
		for(int i=0;i<35;i++)A[i+1]=A[i]*A[i];
		for(int j=35;j--;)if(x+(1ll<<j)<t){
			double g=A[j].val(f,x);
			if(i+1==n||(P[i+1].x-P[i].x)*(m*(x+(1ll<<j))-g)<=P[i].y-P[i+1].y)x+=1ll<<j,f=g;
		}
		f=A->val(f,x++);
	}
	printf("%lf\n",f);
}

//By Don4ick
//#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;

#define forn(i, n) for (int i = 1; i <= n; i++)
#define pb push_back
#define all(x) x.begin(), x.end()
#define y1 qewr1234

const double PI = acos(-1.0);
const int DIR = 4;
const int X[] = {1, 0, -1, 0};
const int Y[] = {0, 1, 0, -1};

const double INF = 1e18;
const int N = (int)1e5 + 228;
const int LOG = 45;
const double eps = 1e-9;

using namespace std;

struct Matrix
{
	double a[3][3] = {};

	Matrix () {};

	Matrix (double m[9])
	{
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				a[i][j] = m[i * 3 + j];
	};

	Matrix operator * (Matrix a)
	{
		Matrix res;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				for (int k = 0; k < 3; k++)
					res.a[i][j] += a.a[i][k] * a.a[k][j];
		return res;
	}
} f[LOG];

int n, a[N], b[N], ord[N];
ll t;
double p[N];

double cross(pair < double, double > x, pair < double, double > y)
{
	return (y.second - x.second) / (x.first - y.first);
}

bool cmp(int x, int y)
{
	return p[x] < p[y] || (p[x] == p[y] && p[x] * a[x] < p[y] * a[y]);
}

int main()
{
	//ios_base::sync_with_stdio(false);
	//cin.tie();
	//cout.tie();

	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	//~read
	scanf("%d%lld", &n, &t);
	forn(i, n)
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
	//~build_CHT
	forn(i, n)
		ord[i] = i;
	sort(ord + 1, ord + n + 1, &cmp);
	vector < pair < double, double > > hull;
	vector < int > id;
	forn(i, n)
	{
		while((int)hull.size() >= 2)
		{
			double x1 = cross(hull[(int)hull.size() - 2], hull.back());
			double x2 = cross(hull[(int)hull.size() - 2], {p[ord[i]], p[ord[i]] * a[ord[i]]});
			if (x1 < x2)
				break;
			id.pop_back();
			hull.pop_back();
		}
		id.pb(ord[i]);
		hull.pb({p[ord[i]], p[ord[i]] * a[ord[i]]});
	}
	//~precalc_M
	double M = 0.0;
	forn(i, n)
		M = max(M, (double)p[i] * b[i]);
	//~solve
	ll curT = 0;
	double Dp = 0.0;
	for	 (int i = 0; i < (int)hull.size() && curT < t; i++)
	{
		double x = INF;
		if (i < (int)hull.size() - 1)
			x = cross(hull[i], hull[i + 1]);
		if (M * curT - Dp > x)
			continue;
		double m[] = {1.0 - p[id[i]], p[id[i]] * M, p[id[i]] * a[id[i]], 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0};
		f[0] = Matrix(m);
		for (int j = 1; j < LOG; j++)
			f[j] = f[j - 1] * f[j - 1];
		for (int j = LOG - 1; j >= 0; j--)
		{
			if ((1ll << j) + curT >= t)
				continue;
			double newDp = f[j].a[0][0] * Dp + f[j].a[0][1] * curT + f[j].a[0][2];
			double newX = M * (curT + (1ll << j)) - newDp;
			if (newX > x)
				continue;
			curT += (1ll << j);
			Dp = newDp;
		}
		Dp = (M * curT - Dp) * hull[i].first + hull[i].second + Dp;
		curT++;
	}
	printf("%.10f", Dp);

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
//#define int ll
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< vvi > vvvi;
typedef vector<short> vs;
typedef vector<vs> vvs;
typedef vector<vvs> vvvs;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef vector<ld> vld;
typedef vector<vld> vvld;
typedef vector<vvld> vvvld;
typedef vector<string> vst;
typedef vector<vst> vvst;
typedef pair<ld, ld> pld;
typedef complex<double> base;

#define mmin(a, b) a = min(a, (b))
#define mmax(a, b) a = max(a, (b))
#define mp(a,b) make_pair(a,b)
#define modsum(a, b) ((a) + (b) >= M ? (a) + (b) - M : (a) + (b))
#define modsubtract(a, b) ((a) - (b) < 0 ? (a) - (b) + M : (a) - (b))
#define modmultiply(a, b) (((a) * (b)) % M)
#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define sqr(x) ((x) * (x))
#define fori(i, n) for(int i = 0; i < int(n); ++i)
#define cint const int &
#define SZ(a) ((int)(a.size()))
#define watch(x) cout << (#x) << " = " << x << endl;

const double PI = 2 * acos(0.0);

const string DIGITS = "0123456789";
const string ALPH = "abcdefghijklmnopqrstuvwxyz";

template<class T>
ostream & operator << (ostream &out, vector<T> &a) {
    out << "(";
    for (auto x : a) out << x << " ";
    return out << ")";
}

template<class T>
ostream & operator << (ostream &out, pair<T, T> &a) {
    out << "(";
    cout << a.first << ", " << a.second;
    return out << ")";
}

void smain();

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

#ifdef MAX_HOME
    freopen("input.txt", "r", stdin);
#endif

    cout << setprecision(12) << fixed;

    smain();
}

const int N = 1e5 + 9;
int n;
ll T;
ll a[N], b[N];
ld p[N];
const  ld oo = 1e15;

struct line {
    ld a, b, l, r;
};

ostream & operator << (ostream &out, line &a) {
    out << "(";
    cout << a.a << " " << a.b << " " << a.l << " " << a.r;
    return out << ")";
}

line stck[N];
int sz = 0;

const ld EPS = 1e-10;

ld intersect(line f, line s) {
    assert(abs(f.a - s.a) >= EPS);
    return (s.b - f.b) / (f.a - s.a);
}

int find_line(ld x) {
    int l = 0, r = sz;
    while (r - l > 1) {
        int m = r + l >> 1;
        if (stck[m].l <= x) l = m;
        else r = m;
    }
    return l;
}

ld v;

vvld operator *(const vvld &a, const vvld &b) {
    int n = a.size();
    vvld ret(n, vld(n, 0));
    fori (i, n) fori (j, n) fori (k, n) ret[i][j] += a[i][k] * b[k][j];
    return ret;
}

vld operator *(const vld &b, const vvld &a) {
    int n = b.size();
    vld ret(n, 0);
    fori (j, n) fori (i, n) ret[j] += b[i] * a[i][j];
    return ret;
}

vvld bin_pow(vvld &a, ll n) {
    vvld ret(a.size(), vld(a.size(), 0));
    fori (i, SZ(a)) ret[i][i] = 1;
    while (n) {
        if (n & 1) ret = ret * a;
        a = a * a;
        n >>= 1;
    }
    return ret;
}

void upd(ld &dp, ll &t, int ind, ll steps) {
    vld vec = {dp, t, 1};
    ld a = stck[ind].a, b = stck[ind].b;
    vvld mat = {{-a + 1, 0, 0},
                {a * v, 1, 0},
                {b, 1, 1}};
    mat = bin_pow(mat, steps);
    vec = vec * mat;
    t = vec[1], dp = vec[0];
}

ld get_x(ld dp, ll t, int ind, ll steps) {
   upd(dp, t, ind, steps);
   return v * t - dp;
}

const int LOG = 40;

void smain() {

    cin >> n >> T;
    v = 0;
    vector<pair<ld, ld>> lines;
    fori (i, n) {
        cin >> a[i] >> b[i] >> p[i];
        mmax(v, p[i] * b[i]);
        lines.push_back({p[i], p[i] * a[i]});
    }
    sort(ALL(lines));

    for (auto x : lines) {
        line cur = {x.first, x.second, -oo, oo};
        while (sz > 1) {
            if (abs(stck[sz - 1].a - cur.a) < EPS) {
              if (stck[sz - 1].b >= cur.b) break;
              sz--;
            } else if (intersect(stck[sz - 2], stck[sz - 1]) >= intersect(stck[sz - 2], cur)) sz--;
            else break;
        }
        if (sz && abs(stck[sz - 1].a - cur.a) < EPS) continue;
        if (sz > 0) stck[sz - 1].r = cur.l = intersect(stck[sz - 1], cur);
        stck[sz++] = cur;
    }

    ll t = 0;
    ld dp = 0;

    while (t < T) {
        ld x = v * t - dp;
        int ind = find_line(x);

        ld a = stck[ind].a, b = stck[ind].b;
        vvld mat = {{-a + 1, 0, 0},
                    {a * v, 1, 0},
                    {b, 1, 1}};
        vvvld mats(LOG);
        mats[0] = mat;
        for (int i = 1; i < LOG; ++i) mats[i] = mats[i - 1] * mats[i - 1];

        for (int i = LOG - 1; i >= 0; --i) {
            vld vec = {dp, t, 1};
            vec = vec * mats[i];

            ld temp_dp = vec[0];
            ll temp_t = vec[1];
            if (temp_t < T && temp_t * v - temp_dp <= stck[ind].r) {
                t = temp_t;
                dp = temp_dp;
            }
        }
        vld vec = {dp, t, 1};
        vec = vec * mat;
        dp = vec[0], t = vec[1];
    }
    cout << dp;
}

#include <bits/stdc++.h>
using namespace std;

#define N 100100

typedef long double ld;
typedef long long ll;

struct CHT {
    struct line {
        ld a, b;
        line() {a = b = 0;}
        line(ld _a, ld _b) : a(_a), b(_b) {}
        bool operator < (const line &l) const {
            if (a != l.a) return a < l.a;
            return b < l.b;
        }
        ld eval(ld x) {return 1ll * a * x + b;}
    };
    vector <line> hull;
    void init() {
        hull.clear();
    }
    void add_line(ld a, ld b) {
        if (!hull.empty() && hull.back().a == a) {
            if (hull.back().b < b) hull.pop_back();
            else return;
        }
        line L(a, b), M, P;
        int sz = hull.size();
        while (sz > 1) {
            M = hull.back(); P = hull[sz - 2];
            if (1.0l * (M.a - P.a) * (L.b - M.b) >= 1.0l * (P.b - M.b) * (M.a - L.a)) hull.pop_back(), sz --;
            else break;
        }
        hull.push_back(L);
        return;
    }
    void build(vector <line> Line) {
        init();
        sort(Line.begin(), Line.end());
        for (auto L : Line) add_line(L.a, L.b);
    }
} cht;

int n, a[N], b[N];
ld p[N];
ll t;

struct Mat {
    ld a[3][3];
    Mat() {
        memset(a, 0, sizeof a);
    }
    Mat operator * (Mat M) {
        Mat rlt;
        for (int i = 0; i < 3; i ++)
            for (int j = 0; j < 3; j ++)
                for (int k = 0; k < 3; k ++) rlt.a[i][j] += a[i][k] * M.a[k][j];
        return rlt;
    }
    ld calc(ld x, ld y, ld z) {
        return a[0][0] * x + a[0][1] * y + a[0][2] * z;
    }
    void print() {
        puts("Matrix : Start");
        for (int i = 0; i < 3; i ++, puts(""))
            for (int j = 0; j < 3; j ++) cout << a[i][j] << ' ';
        puts("Matrix : End");
    }
} pw[100];

ld dp[N];
ll x[N];

int main() {
    scanf("%d %I64d", &n, &t); pw[0].a[0][0] = pw[0].a[1][1] = pw[0].a[2][2] = 1;
    for (int i = 1; i <= n; i ++) {double d; scanf("%d %d %lf", &a[i], &b[i], &d); p[i] = d;}
    ld M = 0; vector <CHT::line> Line;
    for (int i = 1; i <= n; i ++) M = max(M, p[i] * b[i]), Line.emplace_back(p[i], p[i] * a[i]);
    cht.build(Line);
    int sz = cht.hull.size();
    for (int k = 0; k < sz; k ++) {
        Mat mat;
        mat.a[0][0] = 1 - cht.hull[k].a, mat.a[0][1] = cht.hull[k].a * M, mat.a[0][2] = cht.hull[k].b;
        mat.a[1][1] = mat.a[1][2] = mat.a[2][2] = 1;
        for (int i = 1; i < 40; i ++) pw[i] = pw[i - 1] * pw[i - 1] * mat;
        x[k + 1] = x[k], dp[k + 1] = dp[k];
        for (int i = 39; i >= 0; i --) {
            ll p = x[k + 1] + (1ll << i) - 1;
            if (p + 1 > t) continue;
            ld tp = pw[i].calc(dp[k + 1], x[k + 1], 1);
            ld X = p * M - tp;
            if (k == sz - 1 || cht.hull[k].eval(X) > cht.hull[k + 1].eval(X)) {
                x[k + 1] = p + 1; dp[k + 1] = tp + cht.hull[k].eval(X);
            }
        }
    }
    cout << setprecision(10) << fixed << dp[sz] << endl;
    return 0;
}

#include <bits/stdc++.h>

typedef long long int int64;
typedef double ld;
struct quest {
    ld prob;
    ld w;
    ld prod;
    ld get(ld x) {
        return prob * x + prod;
    }
} q[100003];
int64 t;
int n;
double maxw;
bool cmp1(const quest &a, const quest &b) {
    return a.prob < b.prob || (a.prob == b.prob && a.w < b.w);
}
bool cmp(ld k1, ld b1, ld k2, ld b2, ld k3, ld b3) {
    return (k2 - k1) * (b3 - b1) - (k3 - k1) * (b2 - b1) < 0;
}
struct matrix {
    double val[3][3];
    matrix operator *(const matrix &y) const {
        matrix ans;
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                ld v = 0;
                for (int k = 0; k < 3; ++k)
                    v += val[i][k] * y.val[k][j];
                ans.val[i][j] = v;
            }
        }
        return ans;
    }
    ld getdp(ld dpn, ld n) const {
        return val[0][0] * dpn + val[1][0] * n + val[2][0];
    }
};
matrix e;
matrix getm(const quest &q) {
    matrix ans;
    /*
    ans.val[0][1] = ans.val[0][2] = ans.val[1][2] = 0;
    ans.val[1][1] = ans.val[2][2] = ans.val[2][1] = 1;
    ans.val[0][0] = 1 - q.prob;
    ans.val[1][0] = q.prob * maxw;
    ans.val[2][0] = q.prob * q.w;
    */
    ans.val[0][0] = 1 - q.prob; ans.val[1][0] = q.prob * maxw; ans.val[2][0] = q.prod;
    ans.val[0][1] = 0; ans.val[1][1] = 1; ans.val[2][1] = 1;
    ans.val[0][2] = 0; ans.val[1][2] = 0; ans.val[2][2] = 1;
    return ans;
}
int main() {
    memset(&e, 0, sizeof(e));
    for (int i = 0; i < 3; ++i) e.val[i][i] = 1;
    scanf("%d%I64d", &n, &t);
    for (int i = 0; i < n; ++i) {
        ld a, b, p;
        scanf("%lf%lf%lf", &a, &b, &p);
        if (b * p > maxw)
            maxw = b * p;
        q[i].prob = p; q[i].w = a; q[i].prod = p * a;
    }
    std::sort(q, q + n, cmp1);
    int j = 1;
    for (int i = 1; i < n; ++i) {
        while (j >= 2 && !cmp(q[j - 2].prob, q[j - 2].prod, q[j - 1].prob, q[j - 1].prod, q[i].prob, q[i].prod)) --j;
        while (j >= 1 && q[j - 1].prob >= q[i].prob) --j;
        q[j++] = q[i];
    }
    int64 curt = 0;
    ld curdp = 0;
    for (int i = 0; i < j; ++i) {
        matrix temp[34];
        matrix temp2[34];
        temp[0] = e;
        for (int k = 1; k <= 33; ++k) {
            if ((curt + (1LL << k)) > t) break;
            temp[k] = temp[k - 1] * temp[k - 1] * getm(q[i]);
        }
        for (int k = 33; k >= 0; --k) {
            int64 next = curt + (1LL << k) - 1;
            if (next + 1 > t) continue;
            ld nexdp = temp[k].getdp(curdp, curt);
            ld x = next * maxw - nexdp;
            if (i == j - 1 || q[i].get(x) > q[i + 1].get(x)) {
                //curdp = temp[k].getdp(curdp, curt);
                curdp = nexdp + q[i].get(x);
                curt = next + 1;
            }
        }
    }
    printf("%f\n", curdp);
}
//hello

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 1987654321
#define IINF 2987654321987654321
#define MOD 998244353

const double EPS = 1e-12;
const int MAXN = 1e5 + 50;
double a[MAXN], b[MAXN], p[MAXN], M;		// M is max(b[i]p[i])
int n;
ll T;

void readInput() {
	scanf("%d%lld", &n, &T);
	repp(i, n) scanf("%lf%lf%lf", &a[i], &b[i], &p[i]);

	M = 0.0;
	repp(i, n) M = max(M, b[i]*p[i]);
	//printf("M: %f\n", M);
}

// Convex Hull Trick
// finding convex hull of y = p[i]*x + a[i]*p[i]
int sz = 0;
double la[MAXN], lb[MAXN];

// should check la[i]!=la[j] before calling this function
inline double intersect(int i, int j) {
	return (lb[j]-lb[i]) / (la[i]-la[j]);
}

void addLine(int i) {
	double na = p[i], nb = a[i]*p[i];
	la[++sz] = na;
	lb[sz] = nb;
	if(sz <= 2) return;

	while(sz > 1 && abs(la[sz]-la[sz-1]) < EPS) {
		lb[sz-1] = max(lb[sz-1], lb[sz]);
		sz--;
	}

	while(sz > 2 && intersect(sz, sz-1) < intersect(sz-1, sz-2)) {
		la[sz-1] = la[sz];
		lb[sz-1] = lb[sz];
		sz--;
	}
}

void findConvexHull() {
	vector<int> il;		// index list
	repp(i, n) il.push_back(i);
	sort(il.begin(), il.end(), [](int i, int j) { return p[i] < p[j]; });
	for(auto i : il) addLine(i);
	//repp(i, sz) printf("[%d]: %fx + %f\n", i, la[i], lb[i]);
}

struct Matrix {
	double a[3][3];

	Matrix() {
		rep(i, 3) rep(j, 3) a[i][j] = 0.0;
	}

	Matrix(double x, double y) {		// x=p[i], y=a[i]*p[i]
		a[0][0] = 1.0-x;
		a[0][1] = M*x;
		a[0][2] = y;
		a[1][0] = a[2][0] = a[2][1] = 0.0;
		a[1][1] = a[1][2] = a[2][2] = 1.0;
	}

	Matrix operator*(const Matrix &X) {
		Matrix Y;
		rep(i, 3) rep(j, 3) rep(k, 3) Y.a[i][j] += this->a[i][k] * X.a[k][j];
		return Y;
	}

	vector<double> operator*(const vector<double> &v) {
		vector<double> w(3, 0.0);
		rep(i, 3) rep(j, 3) w[i] += this->a[i][j] * v[j];
		return w;
	}

	void print() {
		rep(i, 3) {
			rep(j, 3) printf("%f ", a[i][j]);
			printf("\n");
		}
	}
};

void solve() {
	vector<double> v = {0.0, 0.0, 1.0};		// {dp[t], t, 1}
	ll t = 0;
	repp(i, sz) {
		double mx = (i < sz) ? intersect(i, i+1) : 0.0;
		if(i<sz && M*v[1]-v[0] >= mx) continue;

		Matrix A(la[i], lb[i]);
		Matrix P = A;
		vector<Matrix> Alist;
		for(ll k = 0; (1LL<<k) <= (T-t); k++) {
			Alist.push_back(P);
			P = P*P;
		}

		for(ll k = (ll)Alist.size()-1; k >= 0; k--) {
			vector<double> w = Alist[k] * v;
			if((t+(1LL<<k) <= T) && ((i==sz) || (M*w[1]-w[0] < mx))) {
				v = w;
				t += (1LL<<k);
			}
		}

		if(t == T) break;
		t++;
		v = A*v;
	}

	printf("%.11f\n", v[0]);
}

int main() {
	readInput();
	findConvexHull();
	solve();
}

#define NDEBUG
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const double PI = 4 * atan(1);

#define MAXN 100013
#define MAXLG 34
#define EPS 1e-10
int N;
struct quest {
	int a, b;
	double p;
} Q[MAXN];
double K;
LL T;

typedef pair<double, double> line;
typedef vector<double> mat;

mat succ[MAXLG];

double intersect(const line& a, const line& b) {
	assert(abs(b.first - a.first) > EPS);
	return (a.second - b.second) / (b.first - a.first);
}

mat mul(mat a, mat b) { // 2x2
	return {
		a[0] * b[0] + a[1] * b[2], a[0] * b[1] + a[1] * b[3],
		a[2] * b[0] + a[3] * b[2], a[2] * b[1] + a[3] * b[3]
	};
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	// freopen("input.txt", "r", stdin);

	cin >> N >> T;
	for (int i = 0; i < N; i++) {
		cin >> Q[i].a >> Q[i].b >> Q[i].p;
		K = max(K, Q[i].b * Q[i].p);
	}

	sort(Q, Q + N, [](const quest& a, const quest& b) {
		return abs(a.p - b.p) > EPS ? a.p < b.p : a.a > b.a;
	});

	vector<line> cht;
	vector<double> xs;
	cht.emplace_back(Q[0].p, Q[0].p * Q[0].a);
	for (int i = 1; i < N; i++) {
		if (abs(Q[i].p - Q[i - 1].p) < EPS)
			continue;
		line cur = { Q[i].p, Q[i].p * Q[i].a };
		while (cht.size() >= 2 && intersect(cht.back(), cur)
				< intersect(cht.back(), cht[cht.size() - 2])) {
			cht.pop_back();
			xs.pop_back();
		}
		xs.push_back(intersect(cht.back(), cur));
		cht.push_back(cur);
	}
	xs.push_back(numeric_limits<double>::infinity());

	LL cur = 0; double val = 0;
	for (int i = 0; i < cht.size(); i++) {
		if (val > xs[i])
			continue;
		succ[0] = { 1 - cht[i].first, K - cht[i].second, 0, 1 };
		for (int j = 0; j < MAXLG - 1; j++)
			succ[j + 1] = mul(succ[j], succ[j]);

		for (int j = MAXLG - 1; j >= 0; j--) {
			if (cur + (1LL<<j) <= T) {
				double v2 = succ[j][0] * val + succ[j][1];
				if (v2 < xs[i]) {
					cur += (1LL<<j);
					val = v2;
				}
			}
		}

		if (cur == T)
			break;
		++cur, val = succ[0][0] * val + succ[0][1];
		assert(val > xs[i]);
	}

	assert(cur == T);
	cout << fixed << setprecision(10) << T * K - val << endl;
	return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
#define maxn 100005
#define ll long long
#define ld double
using namespace std;
int a[maxn], b[maxn];
ld p[maxn];
struct point
{
	ld x, y;
	bool operator < (const point &a)const
	{
		if(y != a.y) return y > a.y;
		return x > a.x;
	}
}nd[maxn];
ld k(point a, point b)
{
	return (b.y - a.y) / (b.x - a.x);
}
point stack[maxn];
int top;
ld ksm(ld a, ll k)
{
	if(k == 0) return 1;
	ld ns = ksm(a, k >> 1);
	ns = ns * ns;
	if(k & 1) ns = ns * a;
	return ns;
}
ld cal1(ld p, ld ms, ld k)
{
	// k0
	ld ans = k * (1 - ksm(p, ms + 1)) / (1 - p);
//	cout<<p<<" "<<ms<<" "<<k<<" "<<ans<<endl;
	return ans;
}
ld cal2(ld p, ld ms, ld k)
{
	//kx
	ld ans = k * (cal1(p, ms, 1) - ms * ksm(p, ms + 1) - 1) / (1 - p);
//	cout<<p<<" "<<ms<<" "<<k<<" "<<ans<<endl;
	return ans;
}
ld mv(ll fr, ll ed, ld k, ld b, ld p, ld frs)
{
	//cout<<"MV"<<fr<<" "<<ed<<" "<<k<<" "<<b<<" "<<p<<" "<<frs<<endl;
	if(fr == ed) return frs;
	ld n1 = ksm(p, ed - fr) * frs;
	ld n2 = cal1(p, ed - 1 - fr, k * (ed - 1) + b) + cal2(p, ed - 1 - fr, -k);
//	cout<<n2<<endl;
	return n1 + n2;
}
int main()
{
	ld s = 0;
	int n;
	ll t;
	scanf("%d%lld", &n, &t);
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
		s = max(s, b[i] * p[i]);
		nd[i].x = p[i], nd[i].y = a[i] * p[i];
	}
	sort(nd + 1, nd + n + 1);
	for(int i = 1; i <= n; i++)
	{
		if(nd[i].y == stack[top - 1].y) continue;
		if(i && nd[i].x < stack[top - 1].x) continue;
		while(top >= 2 && k(stack[top - 1], nd[i]) >= k(stack[top - 2], stack[top - 1])) top--;
		stack[top++] = nd[i];
	}
//	cout<<top<<endl;
	ll nt = 0;
	ld lans = 0;
	for(int i = 0; i < top; i++)
	{
		if(nt == t) break;
		ld nk = stack[i].x * s, nb = stack[i].y, np = (1 - stack[i].x);
//		cout<<nk<<" "<<nb<<" "<<np<<" "<<s<<endl;
		ll l = nt, r = t;
		if(i == top - 1)
			l = t;
		while(l < r)
		{
			ll mid = (l + r) >> 1;
			ld nans = mv(nt, mid, nk, nb, np, lans);
			if(-k(stack[i], stack[i + 1]) <= mid * s - nans)
				r = mid;
			else l = mid + 1;
		}
		lans = mv(nt, l, nk, nb, np, lans);
		nt = l;
	}
//	cout<<lans<<endl;
	printf("%.10lf\n", lans);
	return 0;
}

#include <iostream>
#include <vector>
#include <utility>
#include <iomanip>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
const ll INF = 1e12;
const ld EPS = (ld)1 / INF;

const int N = 1e5;
ld ps[N];
ld vs[N];
ld best;

// x_t+k, with quest pv
ld advance(ld xt, ll k, int i) {
	pair<ld, ld> pv = {1 - ps[i], best - vs[i]};

	for (ll j = 1; j <= k; j <<= 1) {
		if (k & j) {
			xt = xt * pv.first + pv.second;
		}
		pv.second *= (1 + pv.first);
		pv.first *= pv.first;
	}

	return xt;
}

// Find min k such that x_t+k >= l or k == high_k, while we're picking option i until that happens
ll bins(ld xt, ld bound, ll high_k, int i) {
	ll low_k = 0;
	while(low_k != high_k) {
		ll mid = (low_k + high_k) >> 1;
		if (advance(xt, mid, i) >= bound) high_k = mid;
		else low_k = mid + 1;
	}
	return low_k;
}

// Collision point of two lines
ld collPoint(int a, int b) {
	// x = (vs[b]-vs[a]) / (ps[a]-ps[b])
	ld dp = ps[a] - ps[b];
	ld dv = vs[b] - vs[a];
	return dv / dp;
}

vector<int> hull; // Indexes in ps, vs
void addLine(int c) {
	if ((! hull.empty()) && (abs(ps[c] - ps[hull.back()]) < EPS)) {
		if (vs[hull.back()] > vs[c]) return;
		else hull.pop_back();
	}
	while(hull.size() >= 2) {
		int n = hull.size();
		int a = hull[n-2];
		int b = hull[n-1];

		if (collPoint(b, c) <= collPoint(a, b)) hull.pop_back();
		else break;
	}
	hull.push_back(c);
}

int main() {
	/*
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	*/

	// When we manage to upgrade a quest, upgrade the one that after upgrade gives the greatest expected return, and do that for the rest of the time.
	// At time t+1, quest i has expected return:
	// p_i (a_i + t * best) + (1 - pi) DP[t]

	// So we have:
	// DP[t+1] = max_i(p_i (a_i + t * best) + (1 - pi) DP[t])
	// 		= DP[t] + max_i(p_i (t * best - DP[t]) + p_i a_i)
	// 		= DP[t] + max_i(p_i x_t + v_i) (after setting x, a_i = a_i p_i)

	// x_t = t * best - DP[t] is increasing
	// 		why?
	// 		x_(t+1) - x_t = best - (DP[t+1] - DP[t]) = (DP[t] + best) - DP[t+1] >= 0
	//		Since getting to do the optimal quest cannot harm you

	// How does x_t change when i is constant? We'll just have to find the spot when x_t makes us want to switch to the next line
	//		x_t+1 = (t+1) * best - DP[t+1]
	// 			= x_t + (best + DP[t] - DP[t+1])
	// 			= x_t + (best + DP[t] - (DP[t] + pi x_t + v_i))
	// 			= x_t + best - pi x_t - v_i
	// 			= x_t (1 - pi) + best - v_i

	// We can calculate how the situation changes in k steps with matrix power:
	// 		[p 1]^k [x] = [y]
	// 		[0 1]   [v]   [v]
	// where:
	// 	p = 1 - pi
	// 	x = x_t
	// 	y = x_t+k
	// 	v = best - vi
	// 	res = [x_t+k v]

	// Once we know x_T, we have
	// 	ans = DP[T] = t*best - x_T
	// And we get our answer from that

	int n; ll t;
	cin >> n >> t;

	// Best is defined in global scope
	vector<pair<ld, int>> ord(n);
	for (int i = 0; i < n; ++i) {
		int a, b;
		cin >> a >> b >> ps[i];
		best = max(best, ps[i] * b);
		vs[i] = a * ps[i];

		ord[i] = {ps[i], i};
	}

	sort(ord.begin(), ord.end());
	for (int i = 0; i < n; ++i) addLine(ord[i].second);

	vector<ld> x_bounds(hull.size());
	x_bounds[0] = 0;
	for (int i = 1; i < hull.size(); ++i) {
		x_bounds[i] = collPoint(hull[i-1], hull[i]);
	}

	/*
	for (int i = 0; i < n; ++i) cout << ps[i] << ' ' << vs[i] << '\n';
	for (auto i : hull) cout << i << ' '; cout << '\n';
	for (int i = 0; i < hull.size(); ++i) cout << x_bounds[i] << ' '; cout << '\n';
	*/

	ll ct = 0;
	ld xt = 0; // x_0 = 0
	int j = 0; // ind in hull
	while((j+1 < hull.size()) && (x_bounds[j+1] <= xt)) {
		++j;
	}

	// Take hull[j] until next x_bounds
	while(ct < t) {
		ll k;
		if (j+1 < hull.size()) {
			k = bins(xt, x_bounds[j+1], t - ct, hull[j]);
		} else {
			k = t - ct;
		}
		// cout << ct << ' ' << xt << ' ' << j << ": " << k << '\n';

		xt = advance(xt, k, hull[j]);
		ct += k;
		++j;
	}

	ld ans = best * t - xt;
	cout << fixed << setprecision(10) << ans << '\n';
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// CHT<T, x-increasing?, Comp>()
// - maximize : let Comp = greater<T>
// .add(a, b) : f(x) = ax + b
// - minimize : (a) desc
// - maximize : (a) asc
/// --- Convex Hull Trick Library {{{ ///

#include <vector>
#include <functional>
#include <cassert>
#include <utility>

template < class T = long long, bool xIncreasing = false,
           class Comp = less< T > >
struct CHT {
  static T EPS;
  static Comp comp;

private:
  using Line = pair< T, T >;

public:
  vector< Line > lines;
  // is l2 unnecessary ?
  bool check(Line l1, Line l2, Line l3) {
    if(l2.first == l3.first) return 1;
    // cp(l2, l3).x <= cp(l2, l1).x
    return (l2.first - l1.first) * (l3.second - l2.second) + EPS >=
           (l3.first - l2.first) * (l2.second - l1.second);
  }
  T f(int i, const T &x) { return lines[i].first * x + lines[i].second; }
  void add(const T &a, const T &b) {
    assert("add monotonic" && (lines.empty() || !comp(lines.back().first, a)));
    if(lines.size() && lines.back().first == a && !comp(b, lines.back().second))
      return;
    while((int) lines.size() >= 2 &&
          check(lines[lines.size() - 2], lines.back(), Line(a, b)))
      lines.pop_back();
    lines.emplace_back(a, b);
  }
  T query(const T &x) {
    Line p = get(x);
    return p.first * x + p.second;
  }
  pair< T, T > get(const T &x) {
    assert(lines.size());
    if(xIncreasing) {
      static size_t head = 0;
      if(head >= lines.size()) head = lines.size() - 1;
      while(head + 1 < lines.size() && comp(f(head + 1, x), f(head, x))) head++;
      return lines[head];
    } else {
      int ok = lines.size() - 1, ng = -1;
      while(ok - ng > 1) {
        int mid = (ok + ng) >> 1;
        if(comp(f(mid, x), f(mid + 1, x)))
          ok = mid;
        else
          ng = mid;
      }
      return lines[ok];
    }
  }
};

template < class T, bool xIncreasing, class Comp >
T CHT< T, xIncreasing, Comp >::EPS = 1e-19;

template < class T, bool xIncreasing, class Comp >
Comp CHT< T, xIncreasing, Comp >::comp;

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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;
  CHT< D, 0, greater< D > > cht;

  vector< pair< D, D > > ls;
  for(int i = 0; i < n; i++) {
    cin >> a[i] >> b[i] >> p[i];
    m = max(m, b[i] * p[i]);
    ls.emplace_back(p[i], p[i] * a[i]);
  }
  sort(begin(ls), end(ls));
  for(auto &l : ls) cht.add(l.first, l.second);
  // dump(cht);
  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);
    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;
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

#include<bits/stdc++.h>

const int N = 100010;
const int BIT = 42;
const double INF = 1e100;
const double eps = 1e-12; typedef long long ll;
typedef std::pair <double, double> pdd;

inline int sig(double x){return (x > eps) - (x < -eps);}

struct L{
    double k, b, p;

    L(double k = 0, double b = 0, double p = 0):k(k), b(b), p(p){}

    bool operator < (const L &l)const{
        return k < l.k;
    }

    double gety(double x){
        return k * x + b;
    }
};

struct matrix{
    static const int N = 3;
    int n, m;
    double a[N][N];

    matrix():n(0),m(0){memset(a, 0, sizeof(a));}
    matrix(int n, int m):n(n),m(m){memset(a, 0, sizeof(a));}

    double *operator [](const int &sit){return a[sit];}

    matrix operator *(const matrix &mat)const{
        matrix ret(n, mat.m);
        for (int k = 0; k < m; ++ k){
            for (int i = 0; i < n; ++ i){
                for (int j = 0; j < mat.m; ++ j){
                    ret[i][j] += a[i][k] * mat.a[k][j];
                }
            }
        }
        return ret;
    }

    matrix power(ll exp)const{
        matrix ret(n, n), tmp = *this;
        for (int i = 0; i < n; ++ i){
            ret[i][i] = 1;
        }
        for ( ; exp > 0; exp >>= 1){
            if (exp & 1){
                ret = ret * tmp;
            }
            tmp = tmp * tmp;
        }
        return ret;
    }
};

int a[N], b[N];
double p[N];
matrix trans[BIT];

int main(){
    int n;
    ll t;
    scanf("%d%lld", &n, &t);
    double max = 0;
    for (int i = 0; i < n; ++ i){
        scanf("%d%d%lf", &a[i], &b[i], &p[i]);
        max = std::max(max, b[i] * p[i]);
    }
    std::vector <pdd> vec;
    std::vector <L> stack;
    for (int i = 0; i < n; ++ i){
        vec.push_back({p[i], p[i] * a[i]});
    }
    std::sort(vec.begin(), vec.end());
    for (auto u : vec){
        while (!stack.empty()){
            L last = stack.back();
            if (!sig(last.k - u.first)){
                stack.pop_back();
                continue;
            }
            double x = (u.second - last.b) / (last.k - u.first);
            if (sig(x - last.p) <= 0){
                stack.pop_back();
                continue;
            }
            stack.push_back(L(u.first, u.second, x));
            break;
        }
        if (stack.empty()){
            stack.push_back(L(u.first, u.second, -INF));
        }
    }
    matrix now(3, 1);
    now[0][0] = 1;
    for (int i = 0, sz = stack.size(); i < sz; ++ i){
        if (i < sz - 1 && sig(now[1][0] * max - now[2][0] - stack[i + 1].p) >= 0) continue;
        L l = stack[i];
        trans[0] = matrix(3, 3);
        trans[0][0][0] = trans[0][1][0] = trans[0][1][1] = 1;
        trans[0][2][0] = l.b;
        trans[0][2][1] = l.k * max;
        trans[0][2][2] = 1 - l.k;
        for (int j = 1; j < BIT; ++ j){
            trans[j] = trans[j - 1] * trans[j - 1];
        }
        matrix tmp(3, 3);
        for (int j = 0; j < 3; ++ j){
            tmp[j][j] = 1;
        }
        for (int j = BIT - 1; j >= 0; -- j){
            matrix mat = tmp * trans[j];
            matrix nowmat = mat * now;
            if ((ll) std::round(nowmat[1][0]) <= t && (i == sz - 1 || sig(nowmat[1][0] * max - nowmat[2][0] - stack[i + 1].p) < 0)){
                tmp = mat;
            }
        }
        now = tmp * now;
        if ((ll) std::round(now[1][0]) == t){
            break;
        }
        now = trans[0] * now;
    }
    printf("%.12f\n", now[2][0]);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define LD long double

const LD INF = 1e20;
vector< pair<LD, LD> > vec;

struct Line{
    LD m,c;
    Line (LD x, LD y) {m = x; c = y;}
    LD Get(LD x) {return m * x + c;}
    bool operator < (const Line &other) const {return m < other.m;}
};

bool Bad(Line &P, Line &C, Line &N){
    return (P.c - C.c) * 1.0L * (N.m - P.m) > (P.c - N.c) * 1.0L * (C.m - P.m);
}

namespace ConvexHull{
    vector<Line>hull;

    void Add(LD m, LD c){
        if(hull.size() > 0 && hull.back().m == m) {
            if(hull.back().c > c) hull.pop_back();
            else return;
        }

        hull.push_back(Line(m, c));
        int sz = hull.size();
        while(sz > 2 && Bad(hull[sz-3], hull[sz-2], hull[sz-1])){
            swap(hull[sz-2],hull[sz-1]); hull.pop_back(); sz--;
        }
    }
};
using namespace ConvexHull;

const int MAX = 3;
struct Matrix{
    int row, col;
    LD m[MAX][MAX];
    Matrix() {memset(m,0,sizeof(m));}
    void Set(int r,int c) {row = r; col = c;}
    Matrix(int r,int c) {memset(m,0,sizeof(m)); Set(r,c);}
};

Matrix Multiply(Matrix A,Matrix B){
    Matrix ans(A.row,B.col);
    for(int i=0;i<A.row;i++){
        for(int j=0;j<B.col;j++){
            ans.m[i][j] = 0;
            for(int k=0;k<A.col;k++){
                ans.m[i][j] += (A.m[i][k] * B.m[k][j]);
            }
        }
    }
    return ans;
}

const int LOG = 35;
Matrix pwr[LOG];
void preProcess(int idx, LD M){
    pwr[0].Set(3, 3);
    pwr[0].m[0][0] = 1;   pwr[0].m[0][1] = -hull[idx].m;   pwr[0].m[0][2] = -hull[idx].c;
    pwr[0].m[1][0] = 0;   pwr[0].m[1][1] = 1+hull[idx].m;  pwr[0].m[1][2] = M+hull[idx].c;
    pwr[0].m[2][0] = 0;   pwr[0].m[2][1] = 0;              pwr[0].m[2][2] = 1;

    for(int i=1; i<LOG; i++) pwr[i] = Multiply(pwr[i-1], pwr[i-1]);
}

pair<ll, LD> jump(ll cur, int id, LD x, LD ans, ll t){
    // Standing
    for(int j = LOG-1; j >= 0; j--){
        if(cur + (1LL << j) > t) continue;

        LD nx = pwr[j].m[1][1] * x + pwr[j].m[1][2];
        if(id == hull.size()-1 || hull[id].c - hull[id+1].c <= (hull[id+1].m - hull[id].m) * nx){
            cur += (1LL << j);
            ans = pwr[j].m[0][0] * ans + pwr[j].m[0][1] * x + pwr[j].m[0][2];
            x = nx;
        }
    }
    return {cur, ans};
}

int main(){
    int n; ll t;
    scanf("%d %lld",&n, &t);

    LD M = 0;
    int a, b; double p;
    for(int i=1; i<=n; i++){
        scanf("%d %d %lf",&a, &b, &p);
        vec.push_back({p, a});
        M = max(M, b * 1.0L * p);
    }
    sort(vec.begin(), vec.end());
    for(auto v : vec) Add(-v.first, -v.first * v.second);

    int id = 0;
    LD ans = 0;
    int sz = hull.size();

    for(ll i=1; i<=t; i++){
        // Covered upto i-1, jump from i-1 to i
        LD x = (i - 1) * M - ans;
        while(id + 1 < sz && hull[id].c - hull[id+1].c > (hull[id+1].m - hull[id].m) * x) id++;
        ans -= hull[id].Get(x);

        preProcess(id, M);

        // Covered upto i, jump from i to ret.first
        x = i * M - ans;
        auto ret = jump(i, id, x, ans, t);
        i = ret.first;
        ans = ret.second;
    }

    double out = ans;
    printf("%.12f", out);
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define LD long double

const LD INF = 1e20;
vector< pair<LD, LD> > vec;

struct Line{
    LD m,c;
    Line (LD x, LD y) {m = x; c = y;}
    LD Get(LD x) {return m * x + c;}
    bool operator < (const Line &other) const {return m < other.m;}
};

bool Bad(Line &P, Line &C, Line &N){
    return (P.c - C.c) * 1.0L * (N.m - P.m) > (P.c - N.c) * 1.0L * (C.m - P.m);
}

namespace ConvexHull{
    vector<Line>hull;

    void Add(LD m, LD c){
        if(hull.size() > 0 && hull.back().m == m) {
            if(hull.back().c > c) hull.pop_back();
            else return;
        }

        hull.push_back(Line(m, c));
        int sz = hull.size();
        while(sz > 2 && Bad(hull[sz-3], hull[sz-2], hull[sz-1])){
            swap(hull[sz-2],hull[sz-1]); hull.pop_back(); sz--;
        }
    }
};
using namespace ConvexHull;

const int MAX = 3;
struct Matrix{
    int row, col;
    LD m[MAX][MAX];
    Matrix() {memset(m,0,sizeof(m));}
    void Set(int r,int c) {row = r; col = c;}
    Matrix(int r,int c) {memset(m,0,sizeof(m)); Set(r,c);}
};

Matrix Multiply(Matrix A,Matrix B){
    Matrix ans(A.row,B.col);
    for(int i=0;i<A.row;i++){
        for(int j=0;j<B.col;j++){
            ans.m[i][j] = 0;
            for(int k=0;k<A.col;k++){
                ans.m[i][j] += (A.m[i][k] * B.m[k][j]);
            }
        }
    }
    return ans;
}

const int LOG = 35;
Matrix pwr[LOG];
void preProcess(int idx, LD M){
    pwr[0].Set(3, 3);
    pwr[0].m[0][0] = 1;   pwr[0].m[0][1] = -hull[idx].m;   pwr[0].m[0][2] = -hull[idx].c;
    pwr[0].m[1][0] = 0;   pwr[0].m[1][1] = 1+hull[idx].m;  pwr[0].m[1][2] = M+hull[idx].c;
    pwr[0].m[2][0] = 0;   pwr[0].m[2][1] = 0;              pwr[0].m[2][2] = 1;

    for(int i=1; i<LOG; i++) pwr[i] = Multiply(pwr[i-1], pwr[i-1]);
}

pair<ll, LD> jump(ll cur, int id, LD x, LD ans, ll t){
    // Covered upto i, now calculate maximum time cur <= t which lies on Line[id]
    for(int j = LOG-1; j >= 0; j--){
        if(cur + (1LL << j) > t) continue;

        LD nx = pwr[j].m[1][1] * x + pwr[j].m[1][2];
        if(id == hull.size()-1 || hull[id].c - hull[id+1].c <= (hull[id+1].m - hull[id].m) * nx){
            cur += (1LL << j);
            ans = pwr[j].m[0][0] * ans + pwr[j].m[0][1] * x + pwr[j].m[0][2];
            x = nx;
        }
    }
    return {cur, ans};
}

int main(){
    int n; ll t;
    scanf("%d %lld",&n, &t);

    LD M = 0;
    int a, b; double p;
    for(int i=1; i<=n; i++){
        scanf("%d %d %lf",&a, &b, &p);
        vec.push_back({p, a});
        M = max(M, b * 1.0L * p);
    }
    sort(vec.begin(), vec.end());
    for(auto v : vec) Add(-v.first, -v.first * v.second);

    int id = 0;
    LD ans = 0;
    int sz = hull.size();

    for(ll i=1; i<=t; i++){
        // Covered upto i-1, jump from i-1 to i
        LD x = (i - 1) * M - ans;
        while(id + 1 < sz && hull[id].c - hull[id+1].c > (hull[id+1].m - hull[id].m) * x) id++;
        ans -= hull[id].Get(x);

        preProcess(id, M);

        // Covered upto i, jump from i to ret.first
        x = i * M - ans;
        auto ret = jump(i, id, x, ans, t);
        i = ret.first;
        ans = ret.second;
    }

    double out = ans;
    printf("%.12f", out);
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const long double eps=0;//1e-15;
int n,a[N],b[N],j,tp,pp;
ll T,i;
long double p[N],w;
struct P{long double x,y;long double getv(long double v){return y-x*v;}}c[N],st[N];
P operator-(P a,P b){return (P){a.x-b.x,a.y-b.y};}
long double cross(P a,P b){return a.x*b.y-b.x*a.y;}
void mv(long double x){for(;pp<tp && st[pp].getv(x)<st[pp+1].getv(x)+eps;++pp);}
long double v1[3],v2[3];
struct mat{
	long double a[3][3];
	void trs(){memset(v2,0,sizeof v2);for(int i=0;i<3;++i)for(int j=0;j<3;++j)v2[j]+=v1[i]*a[i][j];}
}mi[35];
mat operator*(mat a,mat b){
	static mat ret;memset(ret.a,0,sizeof ret.a);
	for(int i=0;i<3;++i)for(int j=0;j<3;++j)for(int k=0;k<3;++k)ret.a[i][k]+=a.a[i][j]*b.a[j][k];
	return ret;
}
int main(){
	scanf("%d%lld",&n,&T);
	for(i=1;i<=n;++i){
		double pp;scanf("%d%d%lf",a+i,b+i,&pp);p[i]=pp;
		w=max(w,b[i]*p[i]);
	}
	for(i=1;i<=n;++i)c[i]=(P){p[i],p[i]*(a[i]+T*w)};
	sort(c+1,c+n+1,[&](P a,P b){return a.x<b.x;});
	for(i=1;i<=n;++i){
		for(;tp>1 && cross(c[i]-st[tp-1],st[tp]-st[tp-1])<=eps;--tp);
		st[++tp]=c[i];
	}
	pp=1;
	long double f=0;
	for(i=T;;){
		mv(f+i*w);
		memset(mi[0].a,0,sizeof mi[0].a);
		mi[0].a[2][0]=st[pp].y;mi[0].a[2][1]=-1;mi[0].a[2][2]=1;
		mi[0].a[1][1]=1;mi[0].a[1][0]=-st[pp].x*w;
		mi[0].a[0][0]=1-st[pp].x;
		v1[0]=f;v1[1]=i;v1[2]=1;
		for(j=1;j<35;++j)mi[j]=mi[j-1]*mi[j-1];
		for(j=34;j>=0;--j){
			mi[j].trs();
			if(v2[1]>0 && (pp==tp || st[pp].getv(v2[0]+v2[1]*w)>st[pp+1].getv(v2[0]+v2[1]*w)+eps))memcpy(v1,v2,sizeof v1);
		}
		mi[0].trs();memcpy(v1,v2,sizeof v1);
		f=v2[0];i=v2[1];if(i==0)break;++pp;
	}
	printf("%.8f\n",double(f));
	return 0;
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

struct quest {
    double p, value;

    bool operator<(const quest &other) const {
        return make_pair(p, value) > make_pair(other.p, other.value);
    }
};

int N;
long long T;
double best_quest;
vector<quest> quests;
vector<long long> move_on;
vector<double> exp_value;
vector<pair<long long, int>> stack;

double compute_value(int index, long long time) {
    assert(time >= 0);

    if (time == 0)
        return 0;

    if (time < move_on[index]) {
        int position = upper_bound(stack.begin(), stack.end(), make_pair(time, N)) - stack.begin() - 1;
        assert(position >= 0);
        index = stack[position].second;
    }

    assert(index < N);
    long long n = time - move_on[index];
    double p = quests[index].p;
    double r = 1.0 - p;
    double pow_rn = pow(r, n);
    double geom_sum = (1.0 - pow_rn) / p;

    double answer = pow_rn * exp_value[index];
    answer += quests[index].value * geom_sum;
    answer += p * best_quest * (move_on[index] * geom_sum + (n - geom_sum) / p);
    return answer;
}

int main() {
    scanf("%d %lld", &N, &T);
    quests.resize(N);
    best_quest = 0;

    for (quest &q : quests) {
        int a, b;
        scanf("%d %d %lf", &a, &b, &q.p);
        q.value = a * q.p;
        best_quest = max(best_quest, b * q.p);
    }

    sort(quests.begin(), quests.end());
    vector<quest> useful;
    double value_max = -1;

    for (quest &q : quests)
        if (q.value > value_max) {
            value_max = q.value;
            useful.push_back(q);
        }

    quests = useful;
    N = quests.size();
    move_on.resize(N);
    exp_value.resize(N);
    move_on[N - 1] = 0;
    exp_value[N - 1] = 0;
    stack.emplace_back(move_on[N - 1], N - 1);

    for (int i = N - 2; i >= 0; i--) {
        long long low = 0, high = T;

        while (low < high) {
            long long mid = (low + high) / 2;
            move_on[i] = mid;
            exp_value[i] = compute_value(i + 1, mid);

            if (compute_value(i, mid + 1) < compute_value(i + 1, mid + 1))
                low = mid + 1;
            else
                high = mid;
        }

        move_on[i] = low;
        exp_value[i] = compute_value(i + 1, low);

        while (!stack.empty() && move_on[i] <= stack.back().first)
            stack.pop_back();

        stack.emplace_back(move_on[i], i);
    }

    printf("%.12lg\n", compute_value(0, T));
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

struct quest {
    long long A, B;
    long double P;
    long double value;

    bool operator<(const quest &other) const {
        return P > other.P;
    }
};

int N;
long long T;
long double best_quest;
vector<quest> quests;
vector<long long> move_on;
vector<long double> exp_value;
vector<pair<long long, int>> stack;

long double compute_value(int index, long long time) {
    assert(time >= 0);

    if (time == 0)
        return 0;

    if (time < move_on[index]) {
        int position = upper_bound(stack.begin(), stack.end(), make_pair(time, N)) - stack.begin() - 1;
        assert(position >= 0);
        index = stack[position].second;

        // TODO: make this faster
        // while (index < N && time < move_on[index])
        //     index++;
    }

    assert(index < N);
    // cerr << "index: " << index << endl;

    long long n = time - move_on[index];
    // cerr << "n: " << n << endl;

    long double p = quests[index].P;
    long double r = 1 - p;
    // cerr << "p and r: " << p << ' ' << r << endl;

    long double geom_sum = (1 - pow(r, n)) / (1 - r);
    // cerr << "geom_sum: " << geom_sum << endl;

    long double answer = pow(1 - p, n) * exp_value[index];
    answer += p * quests[index].A * geom_sum;
    // cerr << "a: " << answer << endl;

    answer += p * best_quest * move_on[index] * geom_sum;
    answer += p * best_quest * (n - geom_sum) / (1 - r);
    return answer;
}

int main() {
    scanf("%d %lld", &N, &T);
    quests.resize(N);
    best_quest = 0;

    for (quest &q : quests) {
        double p;
        scanf("%lld %lld %lf", &q.A, &q.B, &p);
        q.P = p;
        q.value = q.A * q.P;
        best_quest = max(best_quest, q.B * q.P);
    }

    // cerr << "best: " << best_quest << endl;

    sort(quests.begin(), quests.end());
    vector<quest> useful;
    long double value_max = -1;

    for (quest &q : quests)
        if (q.value > value_max) {
            value_max = q.value;
            useful.push_back(q);
            // cerr << "useful: " << q.A << ' ' << q.B << ' ' << q.P << endl;
        }

    quests = useful;
    N = quests.size();
    move_on.assign(N, 0);
    exp_value.assign(N, 0);
    move_on[N - 1] = 0;
    exp_value[N - 1] = 0;
    stack.emplace_back(0, N - 1);

    for (int i = N - 2; i >= 0; i--) {
        long long low = 0, high = T;

        while (low < high) {
            long long mid = (low + high) / 2;
            move_on[i] = mid;
            exp_value[i] = compute_value(i + 1, mid);

            if (compute_value(i, mid + 1) < compute_value(i + 1, mid + 1))
                low = mid + 1;
            else
                high = mid;
        }

        move_on[i] = low;
        exp_value[i] = compute_value(i + 1, low);
        pair<long long, int> p = {move_on[i], i};

        while (!stack.empty() && p.first <= stack.back().first)
            stack.pop_back();

        stack.push_back(p);
    }

    printf("%.12lf\n", (double) compute_value(0, T));
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

struct quest {
    double p, value;

    bool operator<(const quest &other) const {
        return make_pair(p, value) > make_pair(other.p, other.value);
    }
};

int N;
long long T;
double best_quest;
vector<quest> quests;
vector<long long> move_on;
vector<double> exp_value;
vector<pair<long long, int>> stack;

double compute_value(int index, long long time) {
    assert(time >= 0);

    if (time == 0)
        return 0;

    if (time < move_on[index]) {
        int position = upper_bound(stack.begin(), stack.end(), make_pair(time, N)) - stack.begin() - 1;
        assert(position >= 0);
        index = stack[position].second;
    }

    assert(0 <= index && index < N);
    long long n = time - move_on[index];
    double p = quests[index].p;
    long double pow_rn = pow(1.0L - p, n);
    long double geom_sum = (1.0L - pow_rn) / p;

    double answer = pow_rn * exp_value[index];
    answer += quests[index].value * geom_sum;
    answer += p * best_quest * (move_on[index] * geom_sum + (n - geom_sum) / p);
    return answer;
}

int main() {
    scanf("%d %lld", &N, &T);
    quests.resize(N);
    best_quest = 0;

    for (quest &q : quests) {
        int a, b;
        scanf("%d %d %lf", &a, &b, &q.p);
        q.value = a * q.p;
        best_quest = max(best_quest, b * q.p);
    }

    sort(quests.begin(), quests.end());
    vector<quest> useful;
    double value_max = -1;

    for (quest &q : quests)
        if (q.value > value_max) {
            value_max = q.value;
            useful.push_back(q);
        }

    quests = useful;
    N = quests.size();
    move_on.resize(N);
    exp_value.resize(N);
    move_on[N - 1] = 0;
    exp_value[N - 1] = 0;
    stack.emplace_back(move_on[N - 1], N - 1);

    for (int i = N - 2; i >= 0; i--) {
        long long low = 0, high = T;

        while (low < high) {
            long long mid = (low + high) / 2;
            move_on[i] = mid;
            exp_value[i] = compute_value(i + 1, mid);

            if (compute_value(i, mid + 1) < compute_value(i + 1, mid + 1))
                low = mid + 1;
            else
                high = mid;
        }

        move_on[i] = low;
        exp_value[i] = compute_value(i + 1, low);

        while (!stack.empty() && move_on[i] <= stack.back().first)
            stack.pop_back();

        stack.emplace_back(move_on[i], i);
    }

    printf("%.12lg\n", compute_value(0, T));
}

#include<bits/stdc++.h>
using namespace std;
typedef long double ldb;
struct pdd{
	ldb first,second;
	int id;
	pdd(){}
	pdd(ldb first,ldb second,int id):
		first(first),second(second),id(id){}
};
int n,a[100100],tp,b[100100];
ldb mx,pi[101000];
pdd sta[101000],g[101000];
long long T;
ldb cal1(ldb p,ldb T){
	return (pow(p,T)-1)/(p-1);
}
ldb cal2(ldb p,ldb T){
	return (cal1(p,T)-(T-1)*pow(p,T)-1)/(1-p);
}
int chk(pdd a,pdd b,pdd c){
	ldb a1=(b.second-a.second)/(a.first-b.first);
	ldb a2=(c.second-b.second)/(b.first-c.first);
	return a1>=a2;
}
int cmp(pdd a,pdd b){
	if(fabs(a.first-b.first)<=1e-10)return a.second>b.second;
	return a.first<b.first;
}
ldb trans(int x,ldb ans,long long pos,long long nxt){
	if(nxt==pos)return ans;
	long long X=nxt-pos;
	ldb ai=a[sta[x].id],bi=b[sta[x].id],P=pi[sta[x].id],Q=1-P;
	ldb val=pow(Q,X)*ans+ai*P*cal1(Q,X);
	val+=mx*P*nxt*cal1(Q,X);
	val-=mx*P*cal2(Q,X);
	return val;
}
int main(){
	scanf("%d%lld",&n,&T);
	mx=0;
	for(int i=1;i<=n;++i){
		scanf("%d%d%Lf",&a[i],&b[i],&pi[i]);
		mx=max(mx,b[i]*pi[i]);
		g[i]=pdd(pi[i],pi[i]*a[i],i);
	}
	sort(g+1,g+n+1,cmp);
	for(int i=1;i<=n;++i){
		if(tp&&fabs(sta[tp].first-g[i].first)<=1e-10)continue;
		while(tp>=2&&chk(sta[tp-1],sta[tp],g[i]))tp--;
		sta[++tp]=g[i];
	}
//	printf("[%d]",tp);
	ldb ans=0;
	for(int i=1;i<=n;++i)ans=max(ans,pi[i]*a[i]);
	long long pos=0,x=1;
	while(pos<T){
		if(x==tp){
		//	printf("{%d}",sta[tp].id);
			ans=trans(tp,ans,pos,T-1);
			break;
		} else {
			long long l=pos+1,r=T-1,nxt=pos;
			ldb X=(sta[x].second-sta[x+1].second)/(sta[x+1].first-sta[x].first);
			while(l<=r){
				long long mid=l+r>>1;
				ldb d=-trans(x,ans,pos,mid-1)+mx*mid;
				if(d<=X)nxt=mid,l=mid+1;
				else r=mid-1;
			}
//			printf("[%lld]",nxt);
			ans=trans(x,ans,pos,nxt);
			pos=nxt;
			x++;
		}
	}
	printf("%.15Lf",ans);
}

#include <bits/stdc++.h>

using namespace std;
#define sz(a) (int)(a).size()
#define rep(i, a, b) for (int i = (a), _b = (b); i < _b; ++i)
#define frep(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define debug(a) cerr << #a << ": " << (a) << '\n';
#define debug_arr(a) { cerr << #a << " "; rep(i, 0, sz(a)) cout << a[i] << " \n"[i+1== sz(a)]; }
#define debug_two(a, b) cerr << #a << ": " << (a) << ", " << #b << ": " << (b) << '\n';

typedef long long ll;

const int INF = 1e9 + 7;
const ll LL_INF  = 1ll * INF * INF;
const int MAX_N = 100000 + 7;

template <typename T>
inline void addmod(T& a, const ll& b, const int& MOD = INF) {
  a = (a + b) % MOD; if (a < 0) a += MOD;
}

typedef long double T;
const T oo = (T) 1e18;
struct LineHull {
  struct Line {
    T a, b;
    Line(T a, T b) : a(a), b(b) {}
  };
  long double intersect(Line ln1, Line ln2) {
    return (long double) (ln2.b - ln1.b) / (ln1.a - ln2.a);
  }
  int bad(Line ln1, Line ln2, Line ln3) {
    return (long double) (ln1.a - ln2.a) * (ln2.b - ln3.b) >= (long double) (ln2.a - ln3.a) * (ln1.b - ln2.b);
    //return intersect(ln1, ln2) >= intersect(ln2, ln3);
    //return (long double) (ln1.a - ln2.a) * (ln2.b - ln3.b) <= (long double) (ln2.a - ln3.a) * (ln1.b - ln2.b); //for adding in ascending order
    //return intersect(ln1, ln2) <= intersect(ln2, ln3); //for adding in ascending order
  }
  vector<Line> hull;
  vector<long double> pos;
  LineHull() {
    pos.push_back(-oo);
    pos.push_back(+oo);
  }
  void add(T a, T b) {
    Line ln(a, b);
    pos.pop_back();
    while (hull.size() >= 2 && bad(hull[hull.size() - 2], hull[hull.size() - 1], ln)) {
      hull.pop_back();
      pos.pop_back();
    }
    hull.push_back(ln);
    if (hull.size() >= 2) pos.push_back(intersect(hull[hull.size() - 2], hull[hull.size() - 1]));
    //if (hull.size() >= 2) pos.push_back(-intersect(hull[hull.size() - 2], hull[hull.size() - 1])); //for adding in ascending order
    pos.push_back(+oo);
  }
  pair<T, int> query(T x) {
    if (!hull.size()) return { +oo, -1 } ;
    int k = lower_bound(pos.begin(), pos.end(), x) - pos.begin() - 1;
    //int k = lower_bound(pos.begin(), pos.end(), -x) - pos.begin() - 1; //for adding in ascending order
//    assert(k )
    return { hull[k].a * x + hull[k].b, k };
  }
} lh;

int n; long long max_t;
int a[MAX_N], b[MAX_N];
double p[MAX_N];

vector<pair<double, int>> line;

double read_p() {
  string s; cin >> s;
  double res = s[0] - '0';
  double k = 10;
  for (int i = 2; i < sz(s); ++i) {
    res = res + (s[i] - '0') / k;
    k *= 10;
  }
  return res;
}

long double calc(double f, double a, double best, long long len, long long base = 0) {
  return ((a + best * (len + base)) * (1 - pow(1 - f, len))) + best * (len * pow(1 - f, len) + pow(1 - f, len) / f - 1 / f);
}

void solve() {
  cin >> n >> max_t;
  double best = 0;
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i]; p[i] = read_p();
    best = max(best, b[i] * p[i]);
    line.push_back({ p[i], a[i] });
  }
  sort(line.begin(), line.end());
  for (auto x : line) {
    lh.add(x.first, x.first * x.second);
  }

  long double res = 0;
  for (long long i = max_t; i > 0;) {
    auto tmp = lh.query(best * (max_t - i) - res);
    int k = tmp.second;
    double f = lh.hull[k].a;
    double a = lh.hull[k].b / f;
    long long lo = 1, hi = i, found = i;
    while (lo <= hi) {
      long long mid = (lo + hi) >> 1;
      long long len = i - mid + 1;
      long double prev = pow(1 - f, len - 1) * res + calc(f, a, best, len - 1, max_t - i);
      auto ans = lh.query(best * (max_t - mid) - prev);
      if (ans.second == k) {
        found = mid;
        hi = mid - 1;
      } else {
        lo = mid + 1;
      }
    }
    long long len = i - found + 1;
//    debug_two(k, len);
    res = pow(1 - f, len) * res + calc(f, a, best, len, max_t - i);
    i = found - 1;
  }

  cout << fixed << setprecision(6) << res << '\n';
}

int main() {
  ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef _LOCAL_
  freopen("in.txt", "r", stdin);
#endif
  const bool multiple_test = false;
  int test = 1;
  if (multiple_test)
    cin >> test;

  for(int i = 0; i < test; ++i) {
    //printf("Case #%d: ", i + 1);
    solve();
  }
#ifdef _LOCAL_
  cerr << "\n" << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
#endif
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#include <iomanip>
#include <array>
#include <cstdio>
#define int long long
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define pii pair<long long, long long>
#define endl "\n"
#define all(a) (a).begin(), (a).end()
#pragma GCC optimize ("O3")
#define PI 3.14159265
#define pdd pair<double, double>
#define rect pair<pii, pii>
#define ld long double

using namespace std;

const int N = 1e5 + 14;
const int inf = (int)1e18 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const vector<vector<ld>> im = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

vector<vector<ld>> mul(const vector<vector<ld>> &m1, const vector<vector<ld>> &m2)
{
	int n = m1.size();
	int m = m2[0].size();

	vector<vector<ld>> rmat(n, vector<ld>(m));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
		{
			ld val = 0;

			for (int z = 0; z < m2.size(); ++z)
				val += m1[i][z] * m2[z][j];

			rmat[i][j] = val;
		}

	return move(rmat);
}

vector<vector<vector<ld>>> bpc;

vector<vector<ld>> bpow(const vector<vector<ld>> &m, int b)
{
	if (b == 0)
		return im;

	auto t = move(bpow(m, b >> 1));

	bpc.push_back(t);

	if (b & 1)
		return move(mul(move(mul(t, t)), m));

	return move(mul(t, t));
}

struct Line {
	ld k, m;
	mutable ld p;

	bool operator<(const Line &o) const
	{
		return k < o.k;
	}

	bool operator<(const ld &x) const
	{
		return p < x;
	}
};

struct LineContainer : multiset<Line, less<>>
{
	const ld inf = 1e18;

	ld div(const ld &a, const ld &b)
	{
		return a / b;
	}

	bool isect(iterator x, iterator y)
	{
		if (y == end()) { x->p = inf;  return false; }

		if (x->k == y->k)
			x->p = x->m > y->m ? inf : -inf;
		else
			x->p = div(x->m - y->m, y->k - x->k);

		return x->p >= y->p;
	}

	void add(ld k, ld m)
	{
		auto z = insert({ k, m, 0 }), y = z++, x = y;

		while (isect(y, z)) z = erase(z);

		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));

		while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y));
	}

	iterator query(ld x)
	{
		assert(!empty());
		return lower_bound(x);
	}
};

int n, t;
array<ld, 3> a[N];
LineContainer lc;
ld mx = 0;

ld calcdp(ld sdp, int curi, int cnt, const Line &ln)
{
	ld p = ln.k;

	vector<vector<ld>> m = { {((ld)1.0 - p), ln.m, p * mx}, {0, 1, 0}, {0, 1, 1} };

	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	bpc.clear();
	v = move(mul(move(bpow(m, cnt)), v));

	return v[0][0];
}

void initpows(const Line &ln)
{
	ld p = ln.k;

	vector<vector<ld>> m = { {((ld)1.0 - p), ln.m, p * mx}, {0, 1, 0}, {0, 1, 1} };

	bpc.clear();

	for (int i = 0; i < 36; ++i)
	{
		bpc.push_back(m);
		m = move(mul(m, m));
	}
}

ld calcdp(ld sdp, ll curi, const vector<vector<ld>> &m)
{
	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	v = move(mul(m, v));

	return v[0][0];
}

ld calcnxt(const LineContainer::iterator &ln, ld pdp, ld pi)
{
	if (ln == lc.end())
		return -1e18;

	ld dp = ln->m + pi * mx * ln->k + pdp - ln->k * pdp;

	return dp;
}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cout.precision(10);

	scanf("%lld %lld", &n, &t);

	for (int i = 0; i < n; ++i)
	{
		int32_t tmp1, tmp2;

		scanf("%d %d", &tmp1, &tmp2);

		a[i][0] = tmp1;
		a[i][1] = tmp2;
		double ftmp;
		scanf("%lf", &ftmp);
		a[i][2] = ftmp;

		lc.add(a[i][2], a[i][0] * a[i][2]);
		mx = max(mx, a[i][1] * a[i][2]);
	}

	ld dp = 0;
	int elapsed = 0;

	while (elapsed < t)
	{
		auto curit = lc.query((ld)elapsed * mx - dp);
		auto nxtit = curit;
		++nxtit;

		auto curl = *curit;

		initpows(curl);

		for (int i = 35; i >= 0; --i)
		{
			if (elapsed + (1ll << i) > t)
				continue;

			ld nxtdp = calcdp(dp, elapsed, bpc[i]);

			if (calcnxt(curit, nxtdp, elapsed + (1ll << i)) >= calcnxt(nxtit, nxtdp, elapsed + (1ll << i)))
			{
				elapsed += (1ll << i);
				dp = nxtdp;
			}
		}

		if (elapsed < t)
		{
			dp = calcnxt(curit, dp, elapsed);
			++elapsed;
		}
	}

	double ans = dp;

	printf("%.12f\n", ans);
}

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define x(u) (g[u].p)
#define y(u) (g[u].p * g[u].a)
using namespace std;

typedef long long LL;

const double eps = 1e-14;

const int N = 100005, L = 34;

LL T;

int n, q[N], hh = 1, tt = 0;

double B;

struct Game{
	int a, b;
	double p;
	bool operator < (const Game &y) const {
		if (fabs(y.p - p) < eps) return a * p > y.a * y.p;
		return p < y.p;
	}
} g[N];

double inline K(int a, int b) {
	return (y(b) - y(a)) / (x(b) - x(a));
}

struct Matrix{
	int n, m;
	double w[3][3];
	Matrix operator * (const Matrix b) const {
		Matrix c; c.n = n, c.m = b.m;
		memset(c.w, 0, sizeof c.w);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < b.m; j++)
				for (int k = 0; k < m; k++)
					c.w[i][j] += w[i][k] * b.w[k][j];
		return c;
	}
} res, A[L];

Matrix inline build(int j) {
	Matrix c; memset(c.w, 0, sizeof c.w);
	c.n = 3, c.m = 3;
	c.w[0][0] = 1 - g[j].p, c.w[1][0] = g[j].p * B, c.w[2][0] = g[j].p * g[j].a;
	c.w[1][1] = c.w[2][1] = c.w[2][2] = 1;
	return c;
}

double inline get(double S, int j) {
	return g[j].p * (g[j].a - S);
}

int main() {
	scanf("%d%lld", &n, &T);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d%lf", &g[i].a, &g[i].b, &g[i].p);
		B = max(B, g[i].b * g[i].p);
	}
	sort(g + 1, g + 1 + n);
	for (int i = 1; i <= n; i++) {
	    if (i > 1 && fabs(g[i].p - g[i - 1].p) < eps) continue;
	    while (hh < tt && K(q[tt - 1], q[tt]) <= K(q[tt], i)) tt--;
		q[++tt] = i;
	}
	res.n = 1, res.m = 3, res.w[0][2] = 1;
	LL x = 0; double k = 0;
	while (x != T) {
		while (hh < tt && get(k, q[hh]) < get(k, q[hh + 1])) hh++;
		A[0] = build(q[hh]);
		for (int i = 1; i < L; i++) A[i] = A[i - 1] * A[i - 1];
		for (int i = L - 1; ~i; i--) {
			if (x + (1ll << i) < T) {
				Matrix C = res * A[i];
				double nK = C.w[0][0] - B * C.w[0][1];
				if (hh == tt || get(nK, q[hh]) > get(nK, q[hh + 1]))
					res = C, x += 1ll << i;
			}
		}
		res = res * A[0], k = res.w[0][0] - B * res.w[0][1], ++x;
	}
	printf("%.16f\n", res.w[0][0]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef long double louble;

template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}
template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}

const char lf = '\n';

const int _ = 100007;
const double eps = 1e-10;

inline int dcmp(double x){if(-eps<x && x<eps)return 0;return x>0?1:-1;}

struct lines
{
	double k,b;
	lines(double k_=0,double b_=0){k=k_,b=b_;}
	double f(double x){return k*x+b;}

	friend bool operator < (lines a,lines b)
	{
		if(dcmp(a.k-b.k)==0)return a.b<b.b;
		return a.k>b.k;
	}
}ps[_];

double llcrash(lines a,lines b)
{
	return (a.b-b.b)/(b.k-a.k);
}

double fuck(double nowf,double mx,lines dlt,lint tim)
{
	double los=1+dlt.k,per=dlt.b+mx,slos=pow(los,tim);
	return nowf*slos+per*(1-slos)/(1-los);
}

int n;lint tim;
lines stk[_];double loc[_];int top=0;

int main()
{
	ios::sync_with_stdio(0),cin.tie(nullptr),cout.tie(nullptr);

	cin>>n>>tim;

	double mx=0;
	for(int i=1;i<=n;i++){int a,b;double p;cin>>a>>b>>p,mx=max(mx,b*p),ps[i]=lines(-p,-a*p);}
	sort(ps+1,ps+n+1);

	top=0;
	for(int i=1;i<=n;i++)
	{
		if(dcmp(ps[i].k-ps[i-1].k)==0)continue;
		while(top>0 && ps[i].f(loc[top])<stk[top].f(loc[top]))top--;
		stk[++top]=ps[i],loc[top]=llcrash(stk[top],stk[top-1]);
	}

	loc[top+1]=1e99;
	lint now=0;double nowf=0;
	for(int i=1;i<=top;i++)
	{
		lint l=0,r=tim-now;
		while(r>l)
		{
			lint mid=(l+r)>>1;
			if(fuck(nowf,mx,stk[i],mid)>loc[i+1])r=mid;
			else l=mid+1;
		}
		now+=r,nowf=fuck(nowf,mx,stk[i],r);
		if(now>=tim)break;
	}

	cout<<setprecision(11)<<fixed<<mx*now-nowf<<lf;

	return 0;
}

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<long double, long double> P;
const LL INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
const LL mod = 998244353;
const long double Exp = 1e-12;
const bool debug = false;

struct M{
    long double v[3][3];
    int n;
    void init(long double p){
        n = 3;
        v[0][0] = 1 - p;
        v[1][0] = p;
        v[1][1] = v[2][1] = v[2][2] = 1;
    }
    M operator * (M &it) const{
        M ret;
        ret.n = n;
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                ret.v[i][j] = 0.0;
                for(int k = 0; k < n; ++k){
                    ret.v[i][j] += v[i][k] * it.v[k][j];
                }
            }
        }
        return ret;
    }
}tp[40];
P node[N];
int line[N], en;
bool cmp(int k, int j, int i){
    if(node[i].fi - node[j].fi < Exp)   return true;
    return (node[j].fi - node[k].fi) * (node[j].se - node[i].se) < (node[i].fi - node[j].fi) * (node[k].se - node[j].se);
}
bool cmp2(int i, int j, long double x){
    return x * (node[i].fi - node[j].fi) > node[j].se - node[i].se;
}
int main()
{
    int n;
    LL t;
    scanf("%d%lld", &n, &t);
    long double mx = 0, ans = 0;
    for(int i = 1; i <= n; ++i){
        int a, b;
        double p;
        scanf("%d%d%lf", &a, &b, &p);
        node[i] = {p, p * a};
        mx = max(mx, (long double)p * b);
    }
    sort(node + 1, node + n + 1);
    en = 0;
    for(int i = 1; i <= n; ++i){
        ans = max(ans, t * node[i].se);
        while(en >= 2 && cmp(line[en - 1], line[en], i))    en--;
        while(en && node[i].fi - node[line[en]].fi < Exp)    en--;
        line[++en] = i;
    }
    long double now = 0;
    LL now_t = 0;
    for(int i = 1, id, iid; i < en; ++i){
        id = line[i], iid = line[i + 1];
        if(debug){
            cout << i << " : " << node[id].fi << " " << node[id].se << endl;
            cout << now << " " << now_t << endl;
            cout << (node[id].se - node[iid].se) / (node[iid].fi - node[id].fi) << endl;
        }
        tp[0].init(node[id].fi);
        for(int j = 1; j < 40; ++j) tp[j] = tp[j - 1] * tp[j - 1];
        for(int j = 35; j >= 0; --j){
            if(now_t + (1ll << j) > t) continue;
            LL to_t = now_t + (1ll << j);
            long double to = tp[j].v[0][0] * now + tp[j].v[1][0] * (node[id].se / node[id].fi + now_t * mx) + tp[j].v[2][0] * mx;
            if(!cmp2(iid, id, to_t * mx - to)) now = to, now_t = to_t;
        }
        if(!cmp2(iid, id, now_t * mx - now) && now_t < t)now = tp[0].v[0][0] * now + tp[0].v[1][0] * (node[id].se / node[id].fi + now_t * mx), now_t++;
        if(debug){
            cout << now << " " << now_t << endl;
        }
    }
    en = line[en];
    if(debug){
        cout << now_t << endl;
        cout << en << " : " << node[en].fi << " " << node[en].se << endl;
    }
    tp[0].init(node[en].fi);
    for(int j = 1; j < 40; ++j) tp[j] = tp[j - 1] * tp[j - 1];
    for(int j = 35; j >= 0; --j){
        if(now_t + (1ll << j) > t)  continue;
        now = tp[j].v[0][0] * now + tp[j].v[1][0] * (node[en].se / node[en].fi + now_t * mx) + tp[j].v[2][0] * mx;
        now_t += (1ll << j);
    }
    ans = max(ans, now);
    printf("%.12Lf\n", ans);
    return 0;
}
/*
*/

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<long double, long double> P;
const LL INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
const LL mod = 998244353;
const long double Exp = 1e-12;
const bool debug = false;

struct M{
    long double v[3][3];
    int n;
    void init(long double p){
        n = 3;
        v[0][0] = 1 - p;
        v[1][0] = p;
        v[1][1] = v[2][1] = v[2][2] = 1;
    }
    M operator * (M &it) const{
        M ret;
        ret.n = n;
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                ret.v[i][j] = 0.0;
                for(int k = 0; k < n; ++k){
                    ret.v[i][j] += v[i][k] * it.v[k][j];
                }
            }
        }
        return ret;
    }
}tp[40];
P node[N];
int line[N], en;
bool cmp(int k, int j, int i){
    return (node[j].fi - node[k].fi) * (node[j].se - node[i].se) < (node[i].fi - node[j].fi) * (node[k].se - node[j].se);
}
bool cmp2(int i, int j, long double x){
    return x * (node[i].fi - node[j].fi) > node[j].se - node[i].se;
}
int main()
{
    int n;
    LL t;
    scanf("%d%lld", &n, &t);
    long double mx = 0, ans = 0;
    for(int i = 1; i <= n; ++i){
        int a, b;   double p;
        scanf("%d%d%lf", &a, &b, &p);
        node[i] = {p, p * a};
        mx = max(mx, (long double)p * b);
    }
    sort(node + 1, node + n + 1);
    en = 0;
    for(int i = 1; i <= n; ++i){
        ans = max(ans, t * node[i].se);
        while(en && node[i].fi - node[line[en]].fi < Exp)    en--;
        while(en >= 2 && cmp(line[en - 1], line[en], i))    en--;
        line[++en] = i;
    }
    long double now = 0;
    LL now_t = 0;
    for(int i = 1, id, iid; i < en; ++i){
        id = line[i], iid = line[i + 1];
        tp[0].init(node[id].fi);
        for(int j = 1; j < 40; ++j) tp[j] = tp[j - 1] * tp[j - 1];
        for(int j = 35; j >= 0; --j){
            if(now_t + (1ll << j) > t) continue;
            LL to_t = now_t + (1ll << j);
            long double to = tp[j].v[0][0] * now + tp[j].v[1][0] * (node[id].se / node[id].fi + now_t * mx) + tp[j].v[2][0] * mx;
            if(!cmp2(iid, id, to_t * mx - to)) now = to, now_t = to_t;
        }
        if(!cmp2(iid, id, now_t * mx - now) && now_t < t)now = tp[0].v[0][0] * now + tp[0].v[1][0] * (node[id].se / node[id].fi + now_t * mx), now_t++;
    }
    en = line[en];
    tp[0].init(node[en].fi);
    for(int j = 1; j < 40; ++j) tp[j] = tp[j - 1] * tp[j - 1];
    for(int j = 35; j >= 0; --j){
        if(now_t + (1ll << j) > t)  continue;
        now = tp[j].v[0][0] * now + tp[j].v[1][0] * (node[en].se / node[en].fi + now_t * mx) + tp[j].v[2][0] * mx;
        now_t += (1ll << j);
    }
    ans = max(ans, now);
    printf("%.12Lf\n", ans);
    return 0;
}
/*
*/

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

typedef vector<vector<double>> MATR;
MATR IDENT() {
	MATR A(3, vector<double>(3));
	for (int i = 0; i < 3; i++) A[i][i] = 1;
	return A;
}
MATR mul(MATR A, MATR B) {
	MATR C(A.size(), vector<double>(B[0].size()));
	for (size_t i = 0; i < C.size(); i++) {
		for (size_t j = 0; j < C[i].size(); j++) {
			for (size_t k = 0; k < A[0].size(); k++) {
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
	return C;
}
MATR exp(MATR A, ll k)
{
	MATR res = IDENT();
	while (k) {
		if (k % 2 == 1) {
			res = mul(res, A);
		}
		A = mul(A, A);
		k /= 2;
	}
	return res;
}

const int MX = 100005;
const double EPS = 1e-20;

struct Line {
	double k, b;
	double a, p;
	double L, R;
} lines[MX];

bool operator< (Line a, Line b) {
	if (abs(a.k - b.k) < EPS) {
		return a.b > b.b;
	}
	return a.k < b.k;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	ll T;
	cin >> n >> T;

	double M = 0;

	for (int i = 0; i < n; i++) {
		double a, b, p;
		cin >> a >> b >> p;
		M = max(M, b * p);

		lines[i].k = p;
		lines[i].b = p * a;
		lines[i].a = a;
		lines[i].p = p;
	}

	sort(lines, lines + n);

	int sz = 0;
	for (int i = 0; i < n; i++) {
		if (i == 0) {
			lines[i].L = -2000000000000000000000.0;
			lines[i].R = 20000000000000000000000.0;
			sz++;
			continue;
		}

		if (abs(lines[i].k - lines[sz - 1].k) < EPS) continue;

		double X;
		while (true) {
			X = (lines[i].b - lines[sz - 1].b) / (lines[sz - 1].k - lines[i].k);
			if (X <= lines[sz - 1].L) sz--;
			else break;
		}
		lines[sz - 1].R = X;
		lines[sz] = lines[i];
		lines[sz].L = X;
		lines[sz].R = 2000000000000000000.0;
		sz++;
	}

	for (int i = 0; i < sz; i++) {
		//cout << setprecision(3) << fixed << "y = " << lines[i].k << "*x + " << lines[i].b <<": " << lines[i].L << " " << lines[i].R << endl;
	}

	MATR cur_state(3, vector<double>(1));
	cur_state[2][0] = 1;

	ll t = 0;
	for (int i = 0; i < sz; i++) {
		if (cur_state[1][0] * M - cur_state[0][0] >= lines[i].R || t >= T) continue;

		MATR X[45];
		X[0] = {{1 - lines[i].p, lines[i].p * M, lines[i].p * lines[i].a},
			    {0,              1,              1                      },
			    {0,              0,              1                      }};
		for (int j = 0; j < 44; j++) {
			X[j + 1] = mul(X[j], X[j]);
		}

		for (ll j = 44; j >= 0; j--) {
			if (t + (1LL << j) >= T) continue;
			MATR new_state = mul(X[j], cur_state);
			if (new_state[1][0] * M - new_state[0][0] < lines[i].R) {
				cur_state = new_state;
				t += (1LL << j);
			}
		}
		cur_state = mul(X[0], cur_state);
		t++;
	}

	cout << setprecision(15) << fixed << cur_state[0][0];
}

#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

bool cmp(cat a, cat b, cat c, cat d) {
	// true if a*b > c*d
	cat ah = a>>30, al = a&((1<<30)-1);
	cat bh = b>>30, bl = b&((1<<30)-1);
	cat ch = c>>30, cl = c&((1<<30)-1);
	cat dh = d>>30, dl = d&((1<<30)-1);
	// a*b = (ah*bh)<<60 + (ah*bl+al*bh)<<30 + al*bl
	cat dif = ah*bh-ch*dh;
	if(dif >= (1LL<<31)) return true;
	if(dif <= -(1LL<<31)) return false;
	dif = dif * (1<<30) + ah*bl+al*bh-ch*dl-cl*dh;
	if(dif >= (1LL<<30)) return true;
	if(dif <= -(1LL<<30)) return false;
	dif = dif * (1<<30) + al*bl-cl*dl;
	return (dif > 0);
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N;
	cat T;
	cin >> N >> T;
	cat M = 0;
	vector< pair<cat, cat> > V(N);
	for(int i = 0; i < N; i++) {
		int a, b;
		double p;
		cin >> a >> b >> p;
		int p_i = p*1e9+.01;
		V[i] = {p_i, 1LL*a*p_i};
		M = max(M, 1LL*b*p_i);
	}
	sort(begin(V), end(V));

	// hull
	int a = N-1;
	for(int i = N-1, mx = -1; i >= 0; i--) if(V[i].ss > mx) {
		mx = V[i].ss;
		V[a] = V[i];
		a--;
	}
	for(int i = a+1; i < N; i++) V[i-a-1] = V[i];
	V.resize(N-1-a);
	N -= a+1;
	a = (N == 1) ? 0 : 1;
	for(int i = 2; i < N; i++) {
		while(a > 0) {
			if(cmp(V[a].ss-V[i].ss, V[a].ff-V[a-1].ff, V[a-1].ss-V[a].ss, V[i].ff-V[a].ff)) break;
			a--;
		}
		V[a+1] = V[i];
		a++;
	}
	V.resize(a+1);
	N = a+1;

	double E = 0;
	a = 0;
	for(cat k = 0; k < T; k++) {
		cat n = T-k;
		double c = 1. * (M - V[a].ss) / V[a].ff;
		double d = 1.*k*M/1e9 - E;
		double p = 1. - V[a].ff/1e9;
		if(a < N-1) {
			double crit = 1.*(V[a].ss-V[a+1].ss) / (V[a+1].ff-V[a].ff);
			if(c-d <= 0) return 1;
			if(d > crit) n = 0;
			if(c-crit > 0 && d <= crit) {
				n = floor((log(c-d)-log(c-crit)) / (-log(p)));
				n = max(n, 0LL);
				n = min(n, T-k);
			}
		}
		k += n;
		E = 1.*k*M/1e9 - d * pow(p, n) - c * (1 - pow(p, n));
		if(k == T) break;
		double E_new = (V[a].ff / 1e9) * (k * (M / 1e9) - E) + (E + V[a].ss / 1e9);
		int a_new = a;
		for(int i = a+1; i < N; i++) {
			double val = (V[i].ff / 1e9) * (k * (M / 1e9) - E) + (E + V[i].ss / 1e9);
			if(val > E_new - soclose) {
				E_new = val;
				a_new = i;
			}
			else if(val < E_new - soclose)
				break;
		}
		E = E_new;
		a = a_new;
	}
	cout << E << "\n";
	return 0;
}

// look at my code
// my code is amazing

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>

using namespace std;

typedef long double ld;

#ifdef DEBUG
#define eprintf(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#else
#define eprintf(...) ;
#endif

#define sz(x) ((int) (x).size())
#define TASK "text"

const int inf = (int) 1.01e9;
const long long infll = (long long) 1.01e18;
const ld eps = 1e-12;
const ld pi = acos((ld) -1);

mt19937 mrand(random_device{} ());

int rnd(int x) {
  return mrand() % x;
}

void precalc() {
}

const int maxn = (int) 1e5 + 5;
int n;
long long t;
int a[maxn], b[maxn];
ld p[maxn];

int read() {
  if (scanf("%d%lld", &n, &t) < 2) {
    return false;
  }
  for (int i = 0; i < n; i++) {
    double pp;
    scanf("%d%d%lf", &a[i], &b[i], &pp);
    p[i] = pp;
  }
  return true;
}

struct Mat {
  static const int n = 3;
  ld a[n][n];

  Mat() {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        a[i][j] = 0;
      }
    }
  }

  void mul(ld v[n], ld res[n]) {
    for (int i = 0; i < n; i++) {
      res[i] = 0;
      for (int j = 0; j < n; j++) {
        res[i] += a[i][j] * v[j];
      }
    }
  }

  Mat operator * (const Mat &b) const {
    Mat res;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        res.a[i][j] = 0;
        for (int k = 0; k < n; k++) {
          res.a[i][j] += a[i][k] * b.a[k][j];
        }
      }
    }
    return res;
  }
};

ld best;

struct line {
  ld a, b;

  line() {}

  line(ld _a, ld _b): a(_a), b(_b) {}

  bool operator < (const line &l) const {
    return a < l.a - eps || (a < l.a + eps && b < l.b - eps);
  }

  ld eval(ld x) {
    return a * x + b;
  }
};

bool bad(const line &l0, const line &l1, const line &l2) {
  return (l0.b - l1.b) / (l1.a - l0.a) > (l1.b - l2.b) / (l2.a - l1.a) - eps;
}

vector<line> st;

void solve() {
  best = 0;
  for (int i = 0; i < n; i++) {
    best = max(best, b[i] * p[i]);
  }
  st.clear();
  for (int i = 0; i < n; i++) {
    st.push_back(line(p[i], p[i] * a[i]));
  }
  sort(st.begin(), st.end());
  {
    int k = 0;
    for (int i = 0; i < sz(st); i++) {
      while (k >= 1 && abs(st[k - 1].a - st[i].a) < eps) {
        k--;
      }
      while (k >= 2 && bad(st[k - 2], st[k - 1], st[i])) {
        k--;
      }
      st[k++] = st[i];
    }
    st.resize(k);
  }
  long long curt = 0;
  ld dp = 0;
  for (int i = 0; i < sz(st) && curt < t; i++) {
    ld x = best * curt - dp;
    if (i + 1 < sz(st) && st[i + 1].eval(x) > st[i].eval(x) - eps) {
      continue;
    }
    vector<Mat> as;
    as.push_back(Mat());
    as[0].a[0][0] = 1 - st[i].a;
    as[0].a[0][1] = st[i].a * best;
    as[0].a[0][2] = st[i].b;
    as[0].a[1][1] = 1;
    as[0].a[1][2] = 1;
    as[0].a[2][2] = 1;
    ld v0[3] = {dp, (ld) curt, (ld) 1};
    ld v[3];
    while (true) {
      if (curt + (1ll << (sz(as) - 1)) > t) {
        as.pop_back();
        break;
      }
      as.back().mul(v0, v);
      ld nx = best * v[1] - v[0];
      if (i + 1 < sz(st) && st[i + 1].eval(nx) > st[i].eval(nx) - eps) {
        as.pop_back();
        break;
      }
      Mat nxt = as.back() * as.back();
      as.push_back(nxt);
    }
    while (!as.empty()) {
      if (curt + (1ll << (sz(as) - 1)) > t) {
        as.pop_back();
        continue;
      }
      as.back().mul(v0, v);
      ld nx = best * v[1] - v[0];
      if (i + 1 < sz(st) && st[i + 1].eval(nx) > st[i].eval(nx) - eps) {
        as.pop_back();
        continue;
      }
      curt += (1ll << (sz(as) - 1));
      for (int j = 0; j < 3; j++) {
        v0[j] = v[j];
      }
      dp = v0[0];
      as.pop_back();
    }
    if (curt >= t) {
      break;
    }
    as.push_back(Mat());
    as[0].a[0][0] = 1 - st[i].a;
    as[0].a[0][1] = st[i].a * best;
    as[0].a[0][2] = st[i].b;
    as[0].a[1][1] = 1;
    as[0].a[1][2] = 1;
    as[0].a[2][2] = 1;
    as[0].mul(v0, v);
    curt++;
    dp = v[0];
  }
  printf("%.12f\n", (double) dp);
}

int main() {
  precalc();
#ifdef DEBUG
  assert(freopen(TASK ".in", "r", stdin));
  assert(freopen(TASK ".out", "w", stdout));
#endif
  while (read()) {
    solve();
#ifdef DEBUG
    eprintf("Time %.2f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
  }
  return 0;
}

#include <bits/stdc++.h>
#include <type_traits>
using namespace std;

using ll=int64_t;
#define int ll

#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(x) x.begin(),x.end()
auto& errStream=cerr;
#ifdef LOCAL
#define cerr (cerr<<"-- line "<<__LINE__<<" -- ")
#else
class CerrDummy{}cerrDummy;
template<class T>
CerrDummy& operator<<(CerrDummy&cd,const T&){
	return cd;
}
using charTDummy=char;
using traitsDummy=char_traits<charTDummy>;
CerrDummy& operator<<(CerrDummy&cd,basic_ostream<charTDummy,traitsDummy>&(basic_ostream<charTDummy,traitsDummy>&)){
	return cd;
}
#define cerr cerrDummy
#endif
#define REACH cerr<<"reached"<<endl
#define DMP(x) cerr<<#x<<":"<<x<<endl
#define ZERO(x) memset(x,0,sizeof(x))
#define ONE(x) memset(x,-1,sizeof(x))

using pi=pair<int,int>;
using vi=vector<int>;
using ld=long double;

template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
	os<<"{";
	REP(i,(int)v.size()){
		if(i)os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"(";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<")";
}

ll read(){
	ll i;
	scanf("%"  SCNd64,&i);
	return i;
}

double readDouble(){
	double d;
	scanf("%lf",&d);
	return d;
}

void printSpace(){
	printf(" ");
}

void printEoln(){
	printf("\n");
}

void print(ll x,int suc=1){
	printf("%" PRId64,x);
	if(suc==1)
		printEoln();
	if(suc==2)
		printSpace();
}

string readString(){
	static char buf[3341000];
	scanf("%s",buf);
	return string(buf);
}

char* readCharArray(){
	static char buf[3341000];
	static int bufUsed=0;
	char* ret=buf+bufUsed;
	scanf("%s",ret);
	bufUsed+=strlen(ret)+1;
	return ret;
}

template<class T,class U>
void chmax(T& a,U b){
	if(a<b)
		a=b;
}

template<class T,class U>
void chmin(T& a,U b){
	if(b<a)
		a=b;
}

template<class T>
T Sq(const T& t){
	return t*t;
}

#define CAPITAL
void Yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void No(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

constexpr ll Ten(int n){
	return n==0?1:Ten(n-1)*10;
}

template<class T>
vector<T> Uniqued(const vector<T>&vv){
	auto v(vv);
	sort(ALL(v));
	v.erase(unique(ALL(v)),v.end());
	return v;
}
template<class T>
void MakeUniqued(vector<T>&v){
	sort(ALL(v));
	v.erase(unique(ALL(v)),v.end());
}

template<class Num>
struct Vector{
	vector<Num> v;
	Vector(int s=0){
		v.resize(s,Num(0));
	}
	int size()const{
		return v.size();
	}
	Num& operator[](int i){
		return v[i];
	}
	Num const& operator[](int i)const{
		return v[i];
	}
	Vector& operator+=(const Vector&rhs){
		assert(size()==rhs.size());
		REP(i,size())
			v[i]+=rhs[i];
		return *this;
	}
	Vector& operator-=(const Vector&rhs){
		assert(size()==rhs.size());
		REP(i,size())
			v[i]-=rhs[i];
		return *this;
	}
	Vector& operator*=(const Num&x){
		REP(i,size())
			v[i]*=x;
		return *this;
	}
	Vector& operator/=(const Num&x){
		Num y=Num(1)/x;
		REP(i,size())
			v[i]*=y;
		return *this;
	}
	Vector operator+(const Vector&rhs)const{
		return Vector(*this)+=rhs;
	}
	Vector operator-(const Vector&rhs)const{
		return Vector(*this)-=rhs;
	}
	Vector operator*(const Num&x)const{
		return Vector(*this)*=x;
	}
	Vector operator/(const Num&x)const{
		return Vector(*this)/=x;
	}
};

template<class Num>
Num Dot(const Vector<Num>&a,const Vector<Num>&b){
	assert(a.size()==b.size());
	const int S=a.size();
	Num ans=0;
	REP(i,S)
		ans+=a[i]*b[i];
	return ans;
}

template<class Num>
struct Matrix{
	using V=Vector<Num>;
	vector<V> m;
	Matrix(int s=0,Num z=Num(0)){
		m.resize(s,V(s));
		REP(i,size())
			m[i][i]=z;
	}
	int size()const{
		return m.size();
	}
	Matrix operator*(const Matrix&rhs)const{
		assert(size()==rhs.size());
		Matrix res(size());
		REP(i,size())REP(j,size())REP(k,size())
			res[i][j]+=m[i][k]*rhs[k][j];
		return res;
	}
	V operator*(const V&rhs)const{
		assert(size()==rhs.size());
		V res(size());
		REP(i,size())
			res[i]=Dot(m[i],rhs);
		return res;
	}
	V& operator[](int i){
		return m[i];
	}
	V const& operator[](int i) const{
		return m[i];
	}
};

template<class Num>
ostream&operator<<(ostream&os,const Matrix<Num>&x){
	const int S=x.size();
	os<<"----------"<<endl;
	REP(i,S){
		REP(j,S){
			os<<x[i][j];
			if(j==S-1){
				os<<endl;
			}else{
				os<<" ";
			}
		}
	}
	return os<<"----------";
}

template<class Num>
Num Det(Matrix<Num> a){
	const int S=a.size();
	Num ans(1);
	REP(i,S){
		FOR(j,i+1,S)if(a[j][i]){
			ans=-ans;
			swap(a[j],a[i]);
			break;
		}
		if(!a[i][i])return 0;
		ans*=a[i][i];
		FOR(j,i+1,S)
			a[j]-=a[i]*(a[j][i]/a[i][i]);
	}
	return ans;
}

using M=Matrix<ld>;
using V=Vector<ld>;

signed main(){
	int n=read(),t=read();
	ld maxBP=0;
	vector<pair<ld,ld>> rq;
	REP(i,n){
		int a=read(),b=read();
		ld p=readDouble();
		chmax(maxBP,b*p);
		rq.EB(1-p,a*p);
	}
	MakeUniqued(rq);
	const ld eps=1e-15;
	vector<pair<ld,ld>> conv;
	ld last=0;
	REP(i,n){
		ld r=rq[i].first,q=rq[i].second;
		if(last+eps>=q)
			continue;
		last=q;
		while(conv.size()>=2){
			int s=conv.size();
			ld a=conv[s-1].first-conv[s-2].first;
			ld b=conv[s-1].second-conv[s-2].second;
			ld c=r-conv[s-1].first;
			ld d=q-conv[s-1].second;
			if(b*c>=d*a+eps)
				break;
			conv.pop_back();
		}
		conv.PB(rq[i]);
	}

	const int L=40;
	ld base=maxBP*t,g=0;
	while(t){
		ld r=conv.back().first,q=conv.back().second;
		M org(2);
		org[0][0]=r;
		org[0][1]=maxBP-q;
		org[1][1]=1;
		vector<M> ms{org};
		REP(_,L-1){
			M m=ms.back();
			ms.PB(m*m);
		}

		V cur(2);
		cur[0]=g;
		cur[1]=1;
		if(conv.size()==1){
			REP(i,L)if((t>>i)&1)
				cur=ms[i]*cur;
			g=cur[0];
			t=0;
			break;
		}else{
			int s=conv.size();
			auto UseHead=[&](const ld x){
				ld nxg[2];
				REP(k,2){
					nxg[k]=maxBP-conv[s-1-k].second+conv[s-1-k].first*x;
				}
				return nxg[0]+eps<=nxg[1];
			};
			if(!UseHead(g)){
				conv.pop_back();
				continue;
			}
			for(int i=L-1;i>=0;i--){
				int len=int(1)<<i;
				if(len<t){
					V nx=ms[i]*cur;
					if(UseHead(nx[0])){
						cur=nx;
						t-=len;
					}
				}
			}
			cur=ms[0]*cur;
			g=cur[0];
			t--;
			conv.pop_back();
		}
	}

	cout<<fixed<<setprecision(20)<<base-g<<endl;
}

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
#define db double

using namespace std;

const int N=1e5+10;
int n,m; db mx,ans; ll t,cnt;

const db eps=1e-12;
const int dcmp(db x){return fabs(x)<eps?0:x<-eps?-1:1;}

struct line{
	db k,b;
	line(db k=0,db b=0):k(k),b(b){}
	friend bool operator < (line x,line y){
		return dcmp(x.k-y.k)==0?dcmp(x.b-y.b)>0:dcmp(x.k-y.k)<0;
	}
}p[N],q[N];

struct mat{
	int n,m; db a[3][3];
	mat(int n=0,int m=0):n(n),m(m){memset(a,0,sizeof(a));}
	friend mat operator * (mat x,mat y){
		mat z(x.n,y.m);
		rep (i,0,z.n-1)
			rep (j,0,z.m-1)
				rep (k,0,x.m-1) z.a[i][j]+=x.a[i][k]*y.a[k][j];
		return z;
	}
}A,B,trs[35];

db inter_x(line x,line y){return (y.b-x.b)/(x.k-y.k);}

int main(){
	scanf("%d%lld",&n,&t);
	rep (i,1,n){
		int a,b; db c;
		scanf("%d%d%lf",&a,&b,&c);
		mx=max(mx,b*c),p[i]=line(c,a*c);
	}
	sort(p+1,p+1+n);
	rep (i,1,n) if (i==1||dcmp(p[i].k-p[i-1].k)!=0) q[++m]=p[i];
	n=0;
	rep (i,1,m){
		while (n>=2&&dcmp(inter_x(q[i],p[n])-inter_x(p[n],p[n-1]))<=0) n--;
		p[++n]=q[i];
	}
	cnt=0;
	A=mat(3,1); A.a[2][0]=1;
	for (int i=1;i<=n&&cnt<t;i++){
		db R=mx*cnt-A.a[0][0];
		while (i<n&&dcmp(inter_x(p[i],p[i+1])-R)<=0) i++;
		if (i<n) R=inter_x(p[i],p[i+1]);
		trs[0]=mat(3,3);
		trs[0].a[0][0]=1-p[i].k,trs[0].a[0][1]=p[i].k*mx,trs[0].a[0][2]=p[i].b;
		trs[0].a[1][1]=trs[0].a[1][2]=trs[0].a[2][2]=1;
		rep (j,1,33) trs[j]=trs[j-1]*trs[j-1];
		for (int j=33;~j;j--)
			if (cnt+(1ll<<j)<t){
				B=trs[j]*A;
				if (i==n||dcmp((cnt+(1ll<<j))*mx-B.a[0][0]-R)<=0) A=B,cnt+=1ll<<j;
			}
		cnt++,A=trs[0]*A;
	}
	printf("%.10lf\n",A.a[0][0]);
	return 0;
}
/*
f[t+1]=max{c[i]*(a[i]+t*mx)+(1-c[i])*f[t]}
f[t+1]=max{c[i]*a[i]+c[i]*(t*mx-f[t])}+f[t]
维护凸包， t*mx-f[t] 单调

*/

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)

const int N(1e5 + 10);
const double eps(1e-12);

int n, top; long long t; double M;
struct node { double a, b, p, e; } a[N], stk[N];
inline int operator < (const node &l, const node &r)
	{ return std::fabs(l.p - r.p) < eps ? l.e > r.e : l.p < r.p; }
inline int check(node i, node j, node k)
	{ return (j.p - i.p) * (k.e - j.e) > (j.e - i.e) * (k.p - j.p); }
struct Matrix
{
	double a[3][3];
	double *operator [] (const int &x) { return a[x]; }
	const double *operator [] (const int &x) const { return a[x]; }
} S, P, T[35];

Matrix operator * (const Matrix &a, const Matrix &b)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			for (int k = 0; k < 3; k++)
				c[i][k] += a[i][j] * b[j][k];
	return c;
}

Matrix Init(const node &x)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	c[0][0] = 1 - x.p, c[1][0] = M * x.p, c[2][0] = x.e;
	return c[1][1] = c[2][1] = c[2][2] = 1., c;
}

int main()
{
#ifndef ONLINE_JUDGE
	file(cpp);
#endif
	scanf("%d%lld", &n, &t);
	for (int i = 1; i <= n; i++)
		scanf("%lf%lf%lf", &a[i].a, &a[i].b, &a[i].p),
		a[i].e = a[i].a * a[i].p, M = std::max(M, a[i].b * a[i].p);
	std::sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++)
	{
		if (std::fabs(a[i].p - a[i - 1].p) < eps) continue;
		// if (top <= 1) { stk[++top] = a[i]; continue; }
		while (top > 0 && check(stk[top - 1], stk[top], a[i])) --top;
		stk[++top] = a[i];
	}
	int pos = 1; S[0][2] = 1;
	for (long long tim = 0; tim < t; ++tim)
	{
		double sum = S[0][0] - S[0][1] * M, _ = 0;
		while (pos < top && stk[pos + 1].e - stk[pos].e > sum * (stk[pos + 1].p - stk[pos].p)) ++pos;
		T[0] = Init(stk[pos]); for (int i = 1; i < 35; i++) T[i] = T[i - 1] * T[i - 1];
		for (int i = 34; ~i; i--) if (tim + (1ll << i) < t)
		{
			P = S * T[i], _ = P[0][1] * M - P[0][0];
			if (pos == top || stk[pos].p * _ + stk[pos].e > stk[pos + 1].p * _ + stk[pos + 1].e)
				S = P, tim += (1ll << i);
		}
		S = S * T[0];
	}
	printf("%.10lf\n", S[0][0]);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

const double eps = 1e-12;
const int N = 101000;

int fcmp(double x, double y) {
  return fabs(x - y) > eps ? (x < y ? 1 : -1) : 0;
}

struct Line {
  double p, x;
  bool operator < (const Line &rhs) const {
    return fcmp(p, rhs.p) ? fcmp(p, rhs.p) == -1 : fcmp(x, rhs.x) == -1;
  }
  double Val(double y) {
    return p * y + x;
  }
}a[N], st[N];

double Cross(Line a, Line b) {
  return (b.x - a.x) / (a.p - b.p);
}

double mx;

struct Matrix {
  double a[3][3];

  Matrix operator * (const Matrix &rhs) const {
    Matrix c;
    memset(c.a, 0, sizeof c.a);
    for(int k = 0; k < 3; k++)
      for(int i = 0; i < 3; i++)
	for(int j = 0; j < 3; j++)
	  c.a[i][j] += a[i][k] * rhs.a[k][j];
    return c;
  }

  void Init(const Line &rhs) {
    a[0][0] = 1 - rhs.p;
    a[0][1] = mx * rhs.p;
    a[0][2] = rhs.x;
    a[1][1] = a[2][2] = a[1][2] = 1;
  }
}Tran[40], F;

int n, top;
long long t;

int main(void) {
  scanf("%d%lld", &n, &t);
  mx = 0;
  for(int i = 1, b; i <= n; i++) {
    scanf("%lf%d%lf", &a[i].x, &b, &a[i].p);
    mx = max(mx, a[i].p * b);
    a[i].x *= a[i].p;
    //cerr << a[i].x << " " << a[i].p << endl;
  }
  sort(a + 1, a + n + 1);
  for(int i = 1; i <= n; i++) {
    if(i > 1 && !fcmp(a[i].p, a[i - 1].p)) continue;
    while(top > 1 && fcmp(Cross(a[i], st[top - 1]), Cross(st[top], st[top - 1])) == -1)
      top--;
    st[++top] = a[i];
  }

  //for(int i = 1; i <= top; i++)
  // cerr << st[i].x << " " << st[i].p << endl;

  F.a[2][0] = 1;
  double L;
  for(int i = top; i; i--) {
    if(i > 1) L = Cross(st[i], st[i - 1]);
    else L = 1e20;
    if(F.a[1][0] * mx - F.a[0][0] > L) continue;

    Tran[0].Init(st[i]);
    long long pw = 2;
    int lim = 1;
    for(; pw <= t - F.a[1][0]; lim++, pw *= 2)
      Tran[lim] = Tran[lim - 1] * Tran[lim - 1];

    lim--;
    for(int j = lim; ~j; j--) {
      Matrix tmp = Tran[j] * F;
      if(tmp.a[1][0] * mx - tmp.a[0][0] <= L && tmp.a[1][0] <= t)
	F = tmp;
    }
    if(F.a[1][0] < t && F.a[1][0] * mx - F.a[0][0] <= L)
      F = Tran[0] * F;
  }
  printf("%.10f\n", F.a[0][0]);
}

#include <bits/stdc++.h>

using namespace std;

#define fin stdin
#define fout stdout
//FILE *fin = fopen("x.in", "r"), *fout = fopen("x.out", "w");

typedef long long i64;

const int nmax = 1e5;
int a[nmax + 1], b[nmax + 1];
double p[nmax + 1];

struct fct {
    double a, b;

    fct () {}
    fct (double _a, double _b) {
        a = _a, b = _b;
    }

    bool operator < (const fct &shp) const {
        if (a != shp.a)
            return a < shp.a;
        return b > shp.b;
    }
};

vector<fct> f;
pair<fct, double> st[nmax + 1];

inline double intersect (fct A, fct B) {
    if (A.a == B.a)
        return INFINITY;
    return (B.b - A.b) / (A.a - B.a);
}

struct Matrice {
    double v[3][3];

    Matrice () {
        memset(v, 0, sizeof(v));
    }
    void init () {
        for (int i = 0; i < 3; ++ i)
            v[i][i] = 1;
    }

    Matrice operator * (const Matrice &shp) const {
        Matrice ans;
        for (int i = 0; i < 3; ++ i) {
            for (int k = 0; k < 3; ++ k) {
                for (int j = 0; j < 3; ++ j) {
                    ans.v[i][j] += v[i][k] * shp.v[k][j];
                }
            }
        }

        return ans;
    }

    Matrice operator ^ (i64 pw) const {
        Matrice ans, ba = *this;
        ans.init();

        while (pw > 0) {
            if (pw & 1)
                ans = ans * ba;
            ba = ba * ba;
            pw >>= 1;
        }
        return ans;
    }
} tr, lst;

double solve (i64 pas, i64 ant) {
    Matrice aux = lst * (tr ^ (pas - ant));
    return aux.v[0][0];
}

int main() {
    int n; i64 t;
    fscanf(fin, "%d%I64d", &n, &t);

    i64 t2;
    for (t2 = 1; (t2 << 1) <= t; t2 <<= 1) {
    }

    double cst = 0;
    for (int i = 1; i <= n; ++ i) {
        fscanf(fin, "%d%d%lf", &a[i], &b[i], &p[i]);
        cst = max(cst, b[i] * p[i]);
        f.push_back(fct(p[i], p[i] * a[i]));
    }

    sort(f.begin(), f.end());
    int top = 0;

    for (auto i : f) {
        while (top >= 2 && st[top].second >= intersect(st[top].first, i))
            -- top;

        if (top == 0)
            st[++ top] = {i, -INFINITY};
        else if (intersect(st[top].first, i) != INFINITY) {
            st[top + 1] = {i, intersect(st[top].first, i)};
            ++ top;
        }
    }
    st[top + 1].second = INFINITY;

    lst.v[0][2] = 1;
    i64 sol = 0;

    for (int i = 1; i <= top; ++ i) {
        tr.v[0][0] = 1 - st[i].first.a;
        tr.v[1][0] = cst * st[i].first.a;
        tr.v[2][0] = st[i].first.b;
        tr.v[0][1] = tr.v[0][2] = tr.v[1][2] = 0;
        tr.v[1][1] = tr.v[2][1] = tr.v[2][2] = 1;

        i64 aux = sol;
        for (i64 step = t2; step > 0; step >>= 1) {
            if (sol + step <= t && cst * (sol + step - 1) - solve(sol + step - 1, aux) <= st[i + 1].second) {
                sol += step;
            }
        }
        lst = lst * (tr ^ (sol - aux));
    }

    cout << setprecision(12) << fixed;
    cout << lst.v[0][0] << "\n";
    return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
    if(sz > 0 && _m == lm[sz-1] && _b <= lb[sz-1]) return;
    while(sz > 1){

		if((lb[sz-2] - lb[sz-1])*(_m - lm[sz-1]) >= (lb[sz-1] - _b)*(lm[sz-1] - lm[sz-2]))
            sz--;
        else break;
    }
    if(sz == 1 && lm[0] == _m && lb[0] <= _b) sz--;
    lm[sz] = _m, lb[sz] = _b;
    sz++;
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
}

long double save[34][3][3];

void prec(int id){
    save[0][0][0] = 1;
    save[0][0][1] = lm[id];
    save[0][0][2] = lb[id];
    save[0][1][0] = 0;
    save[0][1][1] = 1-lm[id];
    save[0][1][2] = mx-lb[id];
    save[0][2][0] = 0;
    save[0][2][1] = 0;
    save[0][2][2] = 1;

    for(int i = 1; i < 34; i++)
        matmul(save[i-1], save[i-1], save[i]);
}

long double push(ll &q, int id, long double x, long double ans){

    long double xx;
    for(int j = 33; j >= 0; j--){
        if(q + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(id == sz-1 || lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            q += (1LL << j);
            ans = save[j][0][0] * ans + save[j][0][1] * x + save[j][0][2];
            x = xx;
        }
    }

    return save[0][0][0]*ans + save[0][0][1]*x + save[0][0][2];
}
int sid[N];

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        sid[i] = i;
        mx = max(mx, b[i] * p[i]);
    }
    sort(sid, sid+n, [](int q, int w){
        return make_pair(p[q], a[q]*p[q]) < make_pair(p[w], a[w]*p[w]);
        if(p[q] == p[w]) return a[q] * p[q] < a[w] * p[w];
        return p[q] < p[w];
    });

    for(int i = 0; i < n; i++)
        insert_line(p[ sid[i] ], a[ sid[i] ] * p[ sid[i] ]);

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ans = push(q, id, x, ans);
    }

    printf("%.20lf\n", (double)ans);
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
#define pdd pair<double,double>
const int N=100005;
struct mat{
	double a[3][3];
	mat(){
		memset(a,0,sizeof(a));
	}
	mat operator *(const mat &b)const{
		mat ans;
		For(i,0,2) For(j,0,2) For(k,0,2)
			ans.a[i][j]+=a[i][k]*b.a[k][j];
		return ans;
	}
};
struct node{
	int id;
	ll las;
	mat pre;
};
mat tr[N],f[40],ord;
node q[N];
int n;
ll T;
double B;
pdd p[N];
int main(){
	scanf("%d%lld",&n,&T);
	For(i,1,n){
		double x,y,v;
		scanf("%lf%lf%lf",&x,&y,&v);
		B=max(B,y*v);
		p[i]=pdd(x*v,v);
	}
	sort(p+1,p+n+1);
	reverse(p+1,p+n+1);
	ord.a[2][0]=1;
	For(i,1,n){
		tr[i].a[2][2]=1;
		tr[i].a[1][1]=1;
		tr[i].a[1][2]=B;
		tr[i].a[0][0]=1-p[i].se;
		tr[i].a[0][1]=p[i].se;
		tr[i].a[0][2]=p[i].fi;
	}
	int t=0;
	q[++t]=(node){1,T,ord};
	For(i,2,n){
		for (;t&&(tr[i]*q[t].pre).a[0][0]>
		         (tr[q[t].id]*q[t].pre).a[0][0];--t);
		if (!q[t].las) continue;
		node tmp=q[t];
		f[0]=tr[tmp.id];
		For(j,1,35) f[j]=f[j-1]*f[j-1];
		Rep(j,35,0)
			if (tmp.las>(1ll<<j))
				if ((tr[i]*f[j]*tmp.pre).a[0][0]<=
					(tr[tmp.id]*f[j]*tmp.pre).a[0][0]){
						tmp.pre=f[j]*tmp.pre;
						tmp.las-=(1ll<<j);
					}
		tmp.pre=f[0]*tmp.pre; --tmp.las;
		if (tmp.las) tmp.id=i;
		q[++t]=tmp;
	}
	mat s=q[t].pre;
	mat x=tr[q[t].id];
	ll y=q[t].las;
	for (;y;y/=2,x=x*x)
		if (y&1) s=x*s;
	printf("%.10lf\n",s.a[0][0]);
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

const long double is_eval = 1e50;
struct Line{
	long double m, b;
	mutable function<const Line*()> succ;
	bool operator<(const Line& rhs) const{
		if(rhs.b != is_eval) return m < rhs.m;
		const Line* s = succ();
		if(!s) return 0;
		long double x = rhs.m;
		return b - s->b < (s->m - m) * x;
	}
};
struct Cht : public multiset<Line>{ // maintain max
	bool bad(iterator y){
		auto z = next(y);
		if(y == begin()){
			if(z == end()) return 0;
			return y->m == z->m && y->b <= z->b;
		}
		auto x = prev(y);
		if(z == end()) return y->m == x->m && y->b <= x->b;
		return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m);
	}
	void insert_line(long double m, long double b){
		auto y = insert({ m, b });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if(bad(y)){ erase(y); return; }
		while(next(y) != end() && bad(next(y))) erase(next(y));
		while(y != begin() && bad(prev(y))) erase(prev(y));
	}
	long double eval(long double x){
		auto l = *lower_bound((Line) { x, is_eval });
		return l.m * x + l.b;
	}
};

Cht ma, mb;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

long double f(ll q){
    if(q == 0) return 0;

    long double ans = 0;
    long double e = mx*(long double)(q-1), r = f(q-1);
    ans = ma.eval(e-r);
    ans += r;
    return ans;
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = tmp[i][j];
}

long double save[40][3][3];

void prec(int id){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        save[0][i][j] = mbase[i][j];

    for(int i = 1; i < 40; i++){
        for(int w = 0; w < 3; w++) for(int q = 0; q < 3; q++)
            save[i][w][q] = save[i-1][w][q];
        matmul(save[i], save[i-1], tmp);
    }
}

long double pass(long double ans, long double &x, int id, ll cnt){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double mans[3][3], tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = (i == j);
    while(cnt){
        // ans = lm[id] * x + lb[id] + ans;
        // x = x * (1 - lm[id]) + mx - lb[id];
        if(cnt & 1) matmul(mans, mbase, tmp);
        matmul(mbase, mbase, tmp);
        cnt /= 2;
    }

    ans = mans[0][0] * ans + mans[0][1] * x + mans[0][2];

    x = mans[1][1] * x + mans[1][2];
    return ans;
}

long double howlong(ll &q, int id, long double x, long double ans){

    long double xx;
    for(int j = 38; j >= 0; j--){
        if(q + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(id == sz-1 || lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            q += (1LL << j);
            ans = save[j][0][0] * ans + save[j][0][1] * x + save[j][0][2];
            x = xx;
        }
    }

    return save[0][0][0]*ans + save[0][0][1]*x + save[0][0][2];
}

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        ma.insert_line(p[i], a[i] * p[i]);
        mb.insert_line(p[i], b[i] * p[i]);
        mx = max(mx, b[i] * p[i]);
    }

    for(auto x : ma){
        lm[sz] = x.m, lb[sz] = x.b;
        sz++;
    }

    // f(q+1) - f(q) <= mx
    // f(q+1) <= mx + f(q)

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ans = howlong(q, id, x, ans);
        // ans = pass(ans, x, id, j - q + 1);
        // ans = eval(mx*(q-1) - ans) + ans;
        // ans = lm[id] * x + lb[id] + ans;
    }

    printf("%.20lf\n", (double)ans);
    // printf("%lf\n", f(t));

}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	double a[3][3];
	matrix() {}
	matrix(int c, double p, double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	double cal(double dp, long long i) {
		return dp * a[0][0] + i * a[1][0] + a[2][0];
	}
};

struct vec {
	double x, y;
	vec() {}
	vec(double x, double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	double v = 0;
	for (int i = 1; i <= n; i++) {
		double tp;
		scanf("%d%d%lf", &a[i], &b[i], &tp);
		p[i] = tp;
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn];
		pow0[0] = m0;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if ((1ll << i) > t - cur) continue;//
			double dp0 = pow0[i].cal(dp, cur);
			if (m0.cal(dp0, cur + (1ll << i)) < m1.cal(dp0, cur + (1ll << i))) continue;
			dp = dp0;
			cur += 1ll << i;
		}
		if (cur<t && m0.cal(dp, cur)>m1.cal(dp, cur)) {
			dp = m0.cal(dp, cur);
			cur++;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if ((1ll << i) > t - cur) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", (double)dp);
	return 0;
}

pair<double, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i]*p[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<double, int> >());
	int m = 2;
	ord[1] = tmp[1].second;
	ord[2] = tmp[2].second;
	for (int _ = 3; _ <= n; _++) {
		int i = tmp[_].second;
		while (m > 1 && vec(a[i]*p[i] - a[ord[m - 1]]*p[ord[m-1]], p[i] - p[ord[m - 1]])*vec(a[i]*p[i] - a[ord[m]]*p[ord[m]], p[i] - p[ord[m]]) < 0) m--;
		ord[++m] = i;
	}
	return m;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

const long double is_eval = 1e50;
struct Line{
	long double m, b;
	mutable function<const Line*()> succ;
	bool operator<(const Line& rhs) const{
		if(rhs.b != is_eval) return m < rhs.m;
		const Line* s = succ();
		if(!s) return 0;
		long double x = rhs.m;
		return b - s->b < (s->m - m) * x;
	}
};
struct Cht : public multiset<Line>{ // maintain max
	bool bad(iterator y){
		auto z = next(y);
		if(y == begin()){
			if(z == end()) return 0;
			return y->m == z->m && y->b <= z->b;
		}
		auto x = prev(y);
		if(z == end()) return y->m == x->m && y->b <= x->b;
		return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m);
	}
	void insert_line(long double m, long double b){
		auto y = insert({ m, b });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if(bad(y)){ erase(y); return; }
		while(next(y) != end() && bad(next(y))) erase(next(y));
		while(y != begin() && bad(prev(y))) erase(prev(y));
	}
	long double eval(long double x){
		auto l = *lower_bound((Line) { x, is_eval });
		return l.m * x + l.b;
	}
};

Cht ma, mb;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

long double f(ll q){
    if(q == 0) return 0;

    long double ans = 0;
    long double e = mx*(long double)(q-1), r = f(q-1);
    ans = ma.eval(e-r);
    ans += r;
    return ans;
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = tmp[i][j];
}

long double save[40][3][3];

void prec(int id){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        save[0][i][j] = mbase[i][j];

    for(int i = 1; i < 40; i++){
        for(int w = 0; w < 3; w++) for(int q = 0; q < 3; q++)
            save[i][w][q] = save[i-1][w][q];
        matmul(save[i], save[i-1], tmp);
    }
}

long double pass(long double ans, long double &x, int id, ll cnt){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double mans[3][3], tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = (i == j);
    while(cnt){
        // ans = lm[id] * x + lb[id] + ans;
        // x = x * (1 - lm[id]) + mx - lb[id];
        if(cnt & 1) matmul(mans, mbase, tmp);
        matmul(mbase, mbase, tmp);
        cnt /= 2;
    }

    ans = mans[0][0] * ans + mans[0][1] * x + mans[0][2];

    x = mans[1][1] * x + mans[1][2];
    return ans;
}

long double howlong(ll &q, int id, long double x, long double ans){

    long double xx;
    for(int j = 38; j > 0; j--){
        if(q + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(id == sz-1 || lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            q += (1LL << j);
            ans = save[j][0][0] * ans + save[j][0][1] * x + save[j][0][2];
            x = xx;
        }
    }

    ans = pass(ans, x, id, 1);

    return ans;
}

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        ma.insert_line(p[i], a[i] * p[i]);
        mb.insert_line(p[i], b[i] * p[i]);
        mx = max(mx, b[i] * p[i]);
    }

    for(auto x : ma){
        lm[sz] = x.m, lb[sz] = x.b;
        sz++;
    }

    // f(q+1) - f(q) <= mx
    // f(q+1) <= mx + f(q)

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ans = howlong(q, id, x, ans);
        // ans = pass(ans, x, id, j - q + 1);
        // ans = eval(mx*(q-1) - ans) + ans;
        // ans = lm[id] * x + lb[id] + ans;
    }

    printf("%.20lf\n", (double)ans);
    // printf("%lf\n", f(t));

}

#include <bits/stdc++.h>

#define __advance __attribute__((optimize("O3")))

using LL = long long;

const double EPS = 0;

__advance __inline int sgn(double x) { return x < -EPS ? -1 : x > EPS; }

const int MAXN = 1e5 + 5;

struct Matrix {
	double mat[3][3];
	int r, c;

	__advance __inline void reset(int _r = 0, int _c = 0) {
		r = _r; c = _c;
		for (register int i = 0; i < r; ++i)
		for (register int j = 0; j < c; ++j)
			mat[i][j] = 0;
	}

	Matrix(int _r = 0, int _c = 0) {
		reset(_r, _c);
	}

	__advance __inline Matrix multiply(const Matrix &oth) const {
		Matrix res(r, oth.c);
		for (register int i = 0; i < res.r; ++i)
		for (register int j = 0; j < res.c; ++j)
		for (register int k = 0; k < c; ++k)
			res.mat[i][j] += mat[i][k] * oth.mat[k][j];
		return res;
	}

	__advance __inline static Matrix Unit(int _x) {
		Matrix res(_x, _x);
		for (register int i = 0; i < _x; ++i)
			res.mat[i][i] = 1;
		return res;
	}
};

__advance __inline Matrix Pow(Matrix a, LL x) {
	Matrix res = Matrix::Unit(a.r);
	for (; x > 0; x >>= 1) {
		if (x % 2 == 1) res = res.multiply(a);
		a = a.multiply(a);
	}
	return res;
}

struct Line {
	double k, b;

	Line() = default;
	Line(double _k, double _b): k(_k), b(_b) {};

	__advance __inline bool operator < (const Line &oth) const {
		return sgn(k - oth.k) == 0 ? sgn(b - oth.b) < 0 : sgn(k - oth.k) < 0;
	}

	__advance __inline double intersect(const Line &oth) const {
		if (sgn(k - oth.k) == 0) return -1e20;
		return (b - oth.b) / (oth.k - k);
	}
};

int n; LL t;
int a[MAXN], b[MAXN];
double p[MAXN];

__advance int main() {
	double maxB = 0;

	scanf("%d%lld", &n, &t);
	for (register int i = 1; i <= n; ++i) {
		scanf("%d%d%lf", a + i, b + i, p + i);

		maxB = std::max(maxB, b[i] * p[i]);
	}

	std::vector<Line> lines;
	for (register int i = 1; i <= n; ++i) {
		lines.emplace_back(p[i], a[i] * p[i]);
	}

	std::sort(lines.begin(), lines.end());

	std::vector<Line> ch;
	std::vector<double> xs;

	for (register int i = 0; i < (int)lines.size(); ++i) {
		while (ch.size() >= 2 && sgn(lines[i].intersect(ch.back()) - xs.back()) < 0) {
			ch.pop_back(); xs.pop_back();
		}

		if (!ch.empty()) xs.push_back(lines[i].intersect(ch.back()));
		ch.push_back(lines[i]);
	}

	Matrix A(3, 3);
	A.mat[1][1] = A.mat[1][2] = A.mat[2][2] = 1;

	Matrix B(3, 1);
	B.mat[0][0] = 0;
	B.mat[1][0] = 0;
	B.mat[2][0] = 1;

	for (register int i = 0; B.mat[1][0] < t; ++i) {
		A.mat[0][0] = 1 - ch[i].k;
		A.mat[0][1] = ch[i].k * maxB;
		A.mat[0][2] = ch[i].b;

		if (i == (int)ch.size() - 1) {
			B = Pow(A, t - B.mat[1][0]).multiply(B);
			break;
		}

		LL nxt = t, l = B.mat[1][0], r = t - 1;

		while (l <= r) {
			LL mid = (l + r) >> 1;

			Matrix C = Pow(A, mid - B.mat[1][0]).multiply(B);
			if (sgn(maxB * C.mat[1][0] - C.mat[0][0] - xs[i]) > 0) nxt = mid, r = mid - 1;
			else l = mid + 1;
		}

		B = Pow(A, nxt - B.mat[1][0]).multiply(B);
	}

	printf("%.8f\n", B.mat[0][0]);

	return 0;
}

#include <bits/stdc++.h>

typedef long long int int64;
typedef double ld;
struct quest {
	ld prob;
	ld w;
	ld prod;
	ld get(ld x) {
		return prob * x + prod;
	}
} q[100003];
int64 t;
int n;
double maxw;
bool cmp1(const quest &a, const quest &b) {
	return a.prob < b.prob || (a.prob == b.prob && a.w < b.w);
}
bool cmp(ld k1,ld b1,ld k2,ld b2,ld k3,ld b3) {
	return (k2 - k1) * (b3 - b1) - (k3 - k1) * (b2 - b1) < 0;
}
struct matrix {
	double val[3][3];
	matrix operator *(const matrix &y) const {
		matrix ans;
		for(int i = 0;i < 3;++i) {
			for(int j = 0;j < 3;++j) {
				ld v = 0;
				for(int k = 0;k < 3;++k) {
					v += val[i][k] * y.val[k][j];
				}
				ans.val[i][j] = v;
			}
		}
		return ans;
	}
	ld getdp(ld dpn, ld n) const {
		return val[0][0] * dpn + val[1][0] * n + val[2][0];
	}
};
matrix e;
matrix getm(const quest &q) {
	matrix ans;
	/*
	ans.val[0][1] = ans.val[0][2] = ans.val[1][2] = 0;
	ans.val[1][1] = ans.val[2][2] = ans.val[2][1] = 1;
	ans.val[0][0] = 1 - q.prob;
	ans.val[1][0] = q.prob * maxw;
	ans.val[2][0] = q.prob * q.w;
	*/
	ans.val[0][0] = 1 - q.prob;ans.val[1][0] = q.prob * maxw;ans.val[2][0] = q.prod;
	ans.val[0][1] = 0;ans.val[1][1] = 1;ans.val[2][1] = 1;
	ans.val[0][2] = 0;ans.val[1][2] = 0;ans.val[2][2] = 1;
	return ans;
}
int main()
{
	memset(&e,0,sizeof(e));
	for(int i = 0;i < 3;++i) e.val[i][i] = 1;
	scanf("%d%I64d",&n,&t);
	for(int i = 0;i < n;++i) {
		ld a,b,p;
		scanf("%lf%lf%lf",&a,&b,&p);
		if(b * p > maxw)
			maxw = b * p;
		q[i].prob = p;q[i].w = a;q[i].prod = p * a;
	}
	std::sort(q,q+n,cmp1);
	int j = 1;
	for(int i = 1;i < n;++i) {
		while(j >= 2 && !cmp(q[j-2].prob,q[j-2].prod,q[j-1].prob,q[j-1].prod,q[i].prob,q[i].prod)) --j;
		while(j >= 1 && q[j-1].prob >= q[i].prob) --j;
		q[j++] = q[i];
	}
	int64 curt = 0;
	ld curdp = 0;
	for(int i = 0;i < j;++i) {
		matrix temp[34];
		matrix temp2[34];
		temp[0] = getm(q[i]);
		temp2[0] = e;
		for(int k = 1;k <= 33;++k) {
			if((curt + (1LL << k)) > t) break;
			temp[k] = temp[k-1] * temp[k-1];
			temp2[k] = temp[k-1] * temp2[k-1];
		}
		for(int k = 33;k >= 0;--k) {
			int64 next = curt + (1LL << k) - 1;
			if(next + 1 > t) continue;
			ld nexdp = temp2[k].getdp(curdp, curt);
			ld x = next * maxw - nexdp;
			if(i == j - 1 || q[i].get(x) > q[i+1].get(x)) {
				curdp = temp[k].getdp(curdp, curt);
				curt = next + 1;
			}
		}
	}
	printf("%f\n", curdp);
}

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
using namespace std;
const int inf=0x7fffffff;
const double eps=1e-10;
const double pi=acos(-1.0);
//char buf[1<<15],*S=buf,*T=buf;
//char getch(){return S==T&&(T=(S=buf)+fread(buf,1,1<<15,stdin),S==T)?0:*S++;}
inline long long read(){
	long long x=0,f=1;char ch;ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
	if(f)return x;else return -x;
}
const int N=1e5+10;
int a[N],b[N],n;
long long t;
double p[N],Maxs;
struct Point{
double x,y;
bool operator <(const Point &a)const{return (y!=a.y)?y>a.y:x>a.x;}
}P[N];
double slope(Point a,Point b){
	return (b.y-a.y)/(b.x-a.x);
}
double power(double a,long long b){
  double ans=1;
  for(;b;a=a*a,b>>=1)if(b&1)ans=ans*a;
  return ans;
}
Point Q[N];
int top;
double cal1(double p,double ms,double k)
{double ret=k*(1-power(p,ms+1))/(1-p);return ret;}
double cal2(double p,double ms,double k)
{double ret=k*(cal1(p,ms,1)-ms*power(p,ms+1)-1)/(1-p);return ret;}
double solve(long long S,long long T,double k,double b,double p,double ret){
	if(S==T)return ret;
	double n1=power(p,T-S)*ret;
	double n2=cal1(p,T-S-1,k*(T-1)+b)+cal2(p,T-S-1,-k);
	return n1+n2;
}
int main()
{
	n=(int)read();t=read();
	for(int i=1;i<=n;i++){
		a[i]=(int)read();b[i]=(int)read();
		scanf("%lf",&p[i]);
		Maxs=max(Maxs,1.0*b[i]*p[i]);
		P[i].x=p[i],P[i].y=a[i]*p[i];
	}
	sort(P+1,P+n+1);
	for(int i=1;i<=n;i++){
		if(P[i].y==Q[top-1].y)continue;
		if(i&&P[i].x<Q[top-1].x)continue;
		while(top>=2&&slope(Q[top-1],P[i])>=slope(Q[top-2],Q[top-1]))top--;
		Q[top++]=P[i];
	}
	long long nt=0;
	double ans=0;
	for(int i=0;i<top;i++){
		if(nt==t) break;
		double nk=Q[i].x*Maxs,nb=Q[i].y,np=(1-Q[i].x);
		long long l=nt,r=t;
		if(i==top-1)l=t;
		while(l<r){
			long long mid=(l+r)>>1;
			double nans=solve(nt,mid,nk,nb,np,ans);
			if(-slope(Q[i],Q[i+1])<=Maxs*mid-nans)r=mid;
			else l=mid+1;
		}
		ans=solve(nt,l,nk,nb,np,ans);
		nt=l;
	}
	printf("%.10lf\n",ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

const long double is_eval = 1e50;
struct Line{
	long double m, b;
	mutable function<const Line*()> succ;
	bool operator<(const Line& rhs) const{
		if(rhs.b != is_eval) return m < rhs.m;
		const Line* s = succ();
		if(!s) return 0;
		long double x = rhs.m;
		return b - s->b < (s->m - m) * x;
	}
};
struct Cht : public multiset<Line>{ // maintain max
	bool bad(iterator y){
		auto z = next(y);
		if(y == begin()){
			if(z == end()) return 0;
			return y->m == z->m && y->b <= z->b;
		}
		auto x = prev(y);
		if(z == end()) return y->m == x->m && y->b <= x->b;
		return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m);
	}
	void insert_line(long double m, long double b){
		auto y = insert({ m, b });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if(bad(y)){ erase(y); return; }
		while(next(y) != end() && bad(next(y))) erase(next(y));
		while(y != begin() && bad(prev(y))) erase(prev(y));
	}
	long double eval(long double x){
		auto l = *lower_bound((Line) { x, is_eval });
		return l.m * x + l.b;
	}
};

Cht ma, mb;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

long double f(ll q){
    if(q == 0) return 0;

    long double ans = 0;
    long double e = mx*(long double)(q-1), r = f(q-1);
    ans = ma.eval(e-r);
    ans += r;
    return ans;
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = tmp[i][j];
}

long double save[40][3][3];

void prec(int id){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        save[0][i][j] = mbase[i][j];

    for(int i = 1; i < 40; i++){
        for(int w = 0; w < 3; w++) for(int q = 0; q < 3; q++)
            save[i][w][q] = save[i-1][w][q];
        matmul(save[i], save[i-1], tmp);
    }
}

long double pass(long double ans, long double &x, int id, ll cnt){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double mans[3][3], tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = (i == j);
    while(cnt){
        // ans = lm[id] * x + lb[id] + ans;
        // x = x * (1 - lm[id]) + mx - lb[id];
        if(cnt & 1) matmul(mans, mbase, tmp);
        matmul(mbase, mbase, tmp);
        cnt /= 2;
    }

    ans = mans[0][0] * ans + mans[0][1] * x + mans[0][2];

    x = mans[1][1] * x + mans[1][2];
    return ans;
}

ll howlong(ll q, int id, long double x, long double ans){
    if(id == sz-1) return t;
    ll bans = q;

    long double xx, ww;
    for(int j = 38; j > 0; j--){
        if(bans + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        ww = x;
        pass(ans, ww, id, 1LL << j);
        assert(abs(xx - ww) < 1e-9);
        if(lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            bans += (1LL << j);
            x = xx;
        }
    }

    return bans;
}

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        ma.insert_line(p[i], a[i] * p[i]);
        mb.insert_line(p[i], b[i] * p[i]);
        mx = max(mx, b[i] * p[i]);
    }

    for(auto x : ma){
        lm[sz] = x.m, lb[sz] = x.b;
        sz++;
    }

    // f(q+1) - f(q) <= mx
    // f(q+1) <= mx + f(q)

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ll j = howlong(q, id, x, ans);
        ans = pass(ans, x, id, j - q + 1);
        q = j;
        // ans = eval(mx*(q-1) - ans) + ans;
        // ans = lm[id] * x + lb[id] + ans;
    }

    printf("%.20lf\n", (double)ans);
    // printf("%lf\n", f(t));

}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,cnt;
ll t;
long double mx;
struct line{long double k,b,r;}c[100005],d[100005];
struct mat
{
    long double s[3][3];
    mat(){memset(s,0,sizeof(s));}
    friend mat operator *(const mat &x,const mat &y)
    {
        mat res;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    res.s[i][j]+=x.s[i][k]*y.s[k][j];
        return res;
    }
}tr[35];
bool cmp(line x,line y){return fabs(x.k-y.k)<1e-12?x.b<y.b:x.k<y.k;}
int main()
{
    double x,y,z;
    scanf("%d%lld",&n,&t);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf%lf",&x,&y,&z),mx=max(mx,(long double)y*z),c[i].k=z,c[i].b=x*z;
    sort(c+1,c+n+1,cmp);
    for(int i=1;i<=n;i++)
        while(1)
        {
            if(!cnt){d[cnt=1]=c[i];break;}
            if(fabs(c[i].k-d[cnt].k)<1e-12&&c[i].b>d[cnt].b){cnt--;continue;}
            double tmp=(c[i].b-d[cnt].b)/(d[cnt].k-c[i].k);
            if(cnt>1&&tmp-c[cnt-1].r<-1e-12){cnt--;continue;}
            d[cnt].r=tmp;d[++cnt]=c[i];break;
        }
    d[cnt].r=1e22;
    ll now=0;
    mat res;res.s[0][0]=res.s[1][1]=res.s[2][2]=1;
    for(int i=1;i<=cnt;i++)
    {
        if(d[i].r<now*mx-res.s[0][2])continue;
        tr[0].s[0][0]=1.0-d[i].k,tr[0].s[0][1]=d[i].k*mx,tr[0].s[0][2]=d[i].b;
        tr[0].s[1][1]=tr[0].s[1][2]=tr[0].s[2][2]=1;
        for(int j=1;j<=34;j++)tr[j]=tr[j-1]*tr[j-1];
        for(ll j=34;j>=0;j--)
        {
            if(now+(1ll<<j)>=t)continue;
            mat tmp=tr[j]*res;
            if((now+(1ll<<j))*mx-tmp.s[0][2]<d[i].r)res=tmp,now+=(1ll<<j);
        }
        res=tr[0]*res,now++;
        if(now==t)break;
    }
    printf("%.12lf",((double)res.s[0][2]));
    return 0;
}

#include <bits/stdc++.h>
#define eps 1e-10
#define Maxn 200007
using namespace std;
int n;
long long T;
double M=0.0;
struct point
{
    double x,y;
    bool operator <(const point &p)
    const
    {
        return x<p.x;
    }
} que[Maxn];
struct matrix
{
    double a,b,c;
    long long r;
    matrix operator *(const matrix &p)
    const
    {
        return (matrix){1.0*a*p.a,1.0*a*p.b+b,1.0*a*p.c+1.0*b*p.r+c,r+p.r};
    }
} A[57];
int main()
{
    scanf("%d%lld",&n,&T);
    for (int i=1;i<=n;i++)
    {
        int a,b;
        double p;
        scanf("%d%d%lf",&a,&b,&p);
        M=max(M,1.0*b*p);
        que[i]=(point){p,1.0*a*p};
    }
    sort(que+1,que+n+1);
    int now=0;
    for (int i=1;i<=n;i++)
    {
        if (now>0&&que[i].x<que[now].x+eps&&que[i].y<=que[now].y) continue;
        if (now>0&&que[i].x<que[now].x+eps&&que[i].y>que[now].y) --now;
        while (now>1&&1.0*(que[i].y-que[now].y)*(que[now].x-que[now-1].x)>1.0*(que[now].y-que[now-1].y)*(que[i].x-que[now].x)) --now;
        que[++now]=que[i];
    }
    n=now;
    long long x=0;
    double ans=0.0;
    for (int i=1;i<=n&&x<T;i++)
    {
        if (i<n&&1.0*(que[i+1].x-que[i].x)*(1.0*M*x-ans)+que[i+1].y-que[i].y>0) continue;
        A[0]=(matrix){1.0-que[i].x,1.0*M*que[i].x,que[i].y,1};
        for (int j=1;j<=40;j++)
            A[j]=A[j-1]*A[j-1];
        for (int j=40;j>=0;j--)
            if (x+(1LL<<j)<T)
            {
                double tmp=1.0*A[j].a*ans+1.0*A[j].b*x+A[j].c;
                if (i==n||1.0*(que[i+1].x-que[i].x)*(1.0*M*(x+(1LL<<j))-tmp)+que[i+1].y-que[i].y<=0.0)
                {
                    x+=1LL<<j;
                    ans=tmp;
                }
            }
        ans=1.0*ans*A[0].a+1.0*x*A[0].b+A[0].c;
        ++x;
    }
    printf("%.9lf\n",ans);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double ld;
const int N=1e5+100;
const double eps=1e-12;

int n,a[N],b[N],rk[N],q[N],h,t;
double p[N],f[N],mx;
LL T;
#define y(x) (p[x]*a[x])
bool cmp(int u,int v) { return fabs(p[u]-p[v])>eps?(p[u]<p[v]):(y(u)<y(v)); }

ld slope(int u,int v) { return (y(u)-y(v))/(p[u]-p[v]); }
struct matrix {
	double arr[3][3];
	matrix() {memset(arr,0,sizeof(arr));}
	double* operator [](int x) { return arr[x]; }
	void build(int x) {
		memset(arr,0,sizeof(arr));
		arr[0][0]=-p[x]+1, arr[1][0]=mx*p[x], arr[2][0]=y(x);
		arr[1][1]=arr[2][1]=arr[2][2]=1;
	}
} F,tmp,bit[40];

matrix operator * (matrix A,matrix B) {
	matrix ret;
	for(int i=0;i<3;++i)
		for(int j=0;j<3;++j) {
			ret[i][j]=0;
			for(int k=0;k<3;++k)
				ret[i][j]+=A[i][k]*B[k][j];
		}
	return ret;
}

int main() {
	scanf("%d%lld",&n,&T);
	for(int i=1;i<=n;++i)
		scanf("%d%d%lf",&a[i],&b[i],&p[i]), rk[i]=i;
	for(int i=1;i<=n;++i)
		mx=max(mx,b[i]*p[i]);
	sort(rk+1,rk+n+1,cmp);
	h=1, t=0;
	for(int i=1;i<=n;++i) {
		int id=rk[i];
		if(i<n && fabs(p[id]-p[rk[i+1]])<eps ) continue;
		while(h<t && slope(q[t-1],q[t])<=slope(q[t],id)) --t;
		q[++t]=id;
	}
	LL cur=0;
	F[0][2]=1;
	while(233) {
		while(h<t && F[0][0]-mx*cur <= slope(q[h],q[h+1])) ++h;
		double K;
		if(h != t) K=slope(q[h],q[h+1]);
		bit[0].build(q[h]);
		for(int i=1;i<=35;++i) bit[i]=bit[i-1]*bit[i-1];
		for(int i=35;i>=0;--i) {
			if(cur+(1ll<<i) >= T) continue;
			tmp=F*bit[i];
			if(h == t || tmp[0][0]-mx*(cur+(1ll<<i)) > K)
				F=F*bit[i], cur+=(1ll<<i);
		}
		++cur, F=F*bit[0], ++h;
	//	cout<<h<<" "<<t<<" "<<F[0][0]<<endl;
		if(cur == T) break;
	}
	printf("%.12lf",F[0][0]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I>
inline void read(I &x) {
	int f = 0, c;
	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
	x = c & 15;
	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
	f ? x = -x : 0;
}

const int N = 1e5 + 7;
const int LOG = 36;
const double eps = 1e-13;

int n, nl;
ll t;
double M;
int a[N], b[N], q[N];
double p[N];

inline int dcmp(const double &x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1); }
struct Line {
	double k, b;
	inline bool operator < (const Line &a) const { return dcmp(k - a.k) < 0 || (dcmp(k - a.k) == 0 && b < a.b); }
//	inline bool operator < (const Line &a) const { return b > a.b; }
} l[N];

inline double crs(const Line &l1, const Line &l2) { return (l2.b - l1.b) / (l1.k - l2.k); }

struct Matrix {
	double a[3][3];
	inline Matrix() { memset(a, 0, sizeof(a)); }
	inline Matrix(const double &x) {
		memset(a, 0, sizeof(a));
		a[0][0] = a[1][1] = a[2][2] = x;
	}

	inline void print() {
		for (int i = 0; i < 3; ++i) {
			for (int j = 0; j < 3; ++j)
				dbg("%.13lf ", a[i][j]);
			puts("");
		}
	}

	inline Matrix operator * (const Matrix &b) {
		Matrix c;
		c.a[0][0] = a[0][0] * b.a[0][0] + a[0][1] * b.a[1][0] + a[0][2] * b.a[2][0];
		c.a[0][1] = a[0][0] * b.a[0][1] + a[0][1] * b.a[1][1] + a[0][2] * b.a[2][1];
		c.a[0][2] = a[0][0] * b.a[0][2] + a[0][1] * b.a[1][2] + a[0][2] * b.a[2][2];
		c.a[1][0] = a[1][0] * b.a[0][0] + a[1][1] * b.a[1][0] + a[1][2] * b.a[2][0];
		c.a[1][1] = a[1][0] * b.a[0][1] + a[1][1] * b.a[1][1] + a[1][2] * b.a[2][1];
		c.a[1][2] = a[1][0] * b.a[0][2] + a[1][1] * b.a[1][2] + a[1][2] * b.a[2][2];
		c.a[2][0] = a[2][0] * b.a[0][0] + a[2][1] * b.a[1][0] + a[2][2] * b.a[2][0];
		c.a[2][1] = a[2][0] * b.a[0][1] + a[2][1] * b.a[1][1] + a[2][2] * b.a[2][1];
		c.a[2][2] = a[2][0] * b.a[0][2] + a[2][1] * b.a[1][2] + a[2][2] * b.a[2][2];
		return c;
	}
} f[LOG];

inline void ycl() {
	for (int i = 1; i <= n; ++i) smax(M, p[i] * b[i]), l[i] = (Line){ p[i], p[i] * a[i] };
	sort(l + 1, l + n + 1);
	for (int i = 1; i <= n; ++i) if (dcmp(l[i].k - l[nl].k)) l[++nl] = l[i]; else l[nl] = l[i];
	n = nl, nl = 1;
	q[1] = 1;
	for (int i = 2; i <= n; ++i) {
//		if (dcmp(crs(l[q[nl]], l[i])) <= 0) continue;
		while (nl > 1 && dcmp(crs(l[q[nl - 1]], l[i]) - crs(l[q[nl - 1]], l[q[nl]])) <= 0) --nl;
		q[++nl] = i;
	}
	for (int i = 1; i <= nl; ++i) l[i] = l[q[i]];//, dbg("Line : %.13lf %.13lf\n", l[i].k, l[i].b);
	n = nl;
//	for (int i = 1; i <= n; ++i) dbg("Line : %.13lf %.13lf\n", l[i].k, l[i].b);
//	dbg("%.13lf %.13lf\n", crs(l[1], l[4]), crs(l[1], l[3]));
}

inline void work() {
	ycl();

	double dp = 0;
	ll tt = 0;
	for (int i = 1; i <= n && tt < t; ++i) {
		double stp;
		if (i < n) stp = crs(l[i], l[i + 1]);
		else stp = 1e20;

		if (tt < t && dcmp(tt * M - dp - stp) >= 0) continue;

		Matrix A, B;
		A.a[0][0] = dp, A.a[1][0] = tt, A.a[2][0] = 1;
		B.a[0][0] = 1 - l[i].k, B.a[0][1] = l[i].k * M, B.a[0][2] = l[i].b;
		B.a[1][1] = 1, B.a[1][2] = 1;
		B.a[2][2] = 1;
		f[0] = B;
		for (int i = 1; i < LOG; ++i) f[i] = f[i - 1] * f[i - 1];

		for (int i = LOG - 1; ~i; --i) if (tt + (1ll << i) < t) {
			Matrix C = f[i] * A;
//			if (i == 1) C.print();
			if (dcmp(C.a[1][0] * M - C.a[0][0] - stp) < 0) A = C, tt += 1ll << i;
		}
		A = f[0] * A, ++tt;
		dp = A.a[0][0];
	}
	printf("%.13lf\n", dp);
}

inline void init() {
	read(n), read(t);
	for (int i = 1; i <= n; ++i) read(a[i]), read(b[i]), scanf("%lf", &p[i]);
}

int main() {
#ifdef hzhkk
	freopen("hkk.in", "r", stdin);
#endif
	init();
	work();
	fclose(stdin), fclose(stdout);
	return 0;
}

#include <bits/stdc++.h>

#define For(i, j, k) for (int i = j; i <= k; i++)

using namespace std;

typedef long long LL;

const int N = 1e5 + 10;
const double eps = 1e-10;

int n, c;
LL T;

struct Line {
	double k, b;

	bool operator < (const Line& B) const {
		if (fabs(k - B.k) > eps) return k > B.k;
		else return b < B.b;
	}
}L[N], st[N];

double pos[N], mx;

double calc(double x, Line v, LL m) {
	double b = v.b + mx;
	double a = 1 + v.k, val = pow(a, m);
	return x * val + (1 - val) / (1 - a) * b;
}

int main() {

	cin >> n >> T;
	For(i, 1, n) {
		int a, b;
		double p;
		scanf("%d%d%lf", &a, &b, &p);
		mx = max(mx, b * p);
		L[i] = (Line){-p, -p * a};
	}
	sort(L + 1, L + n + 1);

	For(i, 1, n) {
		if (fabs(L[i].k - L[i - 1].k) <= eps) continue;
		while (c && pos[c] * L[i].k + L[i].b < pos[c] * st[c].k + st[c].b) --c;
		st[++c] = L[i], pos[c] = c == 1 ? 0 : (st[c].b - st[c - 1].b) / (st[c - 1].k - st[c].k);
	}
	pos[c + 1] = 1e100;

	LL x = 0;
	double dp = 0;
	For(i, 1, c) {
		LL l = 0, r = T - x;
		while (l < r) {
			LL mid = (l + r) / 2;
			if (calc(dp, st[i], mid) > pos[i + 1]) r = mid;
			else l = mid + 1;
		}
		x += l;
		dp = calc(dp, st[i], l);
		if (x == T) break;
	}
	printf("%.10lf\n", T * mx - dp);

	return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int a[100000];
double p[100000],X = 0;
struct line { double m,b; };
bool comp(line a,line b) {
    if (a.m == b.m) return a.b < b.b;
    else return a.m < b.m;
}
int bad(line a,line b,line c) {
    return (a.b-b.b)*(c.m-b.m) >= (b.b-c.b)*(b.m-a.m);
}
vector<line> lines,hull;
double apply(line l,double p,LLI t) {
    return (1-pow(1-l.m,t))/l.m*(X-l.b)+pow(1-l.m,t)*p;
}
int main() {
    int i;
    int n,b;
    LLI t;
    scanf("%d %I64d",&n,&t);
    for (i = 0; i < n; i++) scanf("%d %d %lf",&a[i],&b,&p[i]),X = max(X,p[i]*b);

    for (i = 0; i < n; i++) lines.pb((line){p[i],p[i]*a[i]});
    sort(lines.begin(),lines.end(),comp);
    for (i = 0; i < n; i++) {
        while (!hull.empty() && (hull.back().m == lines[i].m)) hull.pop_back();
        while ((hull.size() >= 2) && bad(hull[hull.size()-2],hull.back(),lines[i])) hull.pop_back();
        hull.pb(lines[i]);
    }
    LLI c = 0;
    double p = 0;
    i = 0;
    while (c < t) {
        LLI l = c,r = t;
        while (l < r) {
            LLI m = (l+r) / 2;
            double pp = apply(hull[i],p,m-c);
            if (i == hull.size()-1) l = m+1;
            else if (hull[i].m*pp+hull[i].b < hull[i+1].m*pp+hull[i+1].b) r = m;
            else l = m+1;
        }
        p = apply(hull[i],p,l-c),c = l,i++;
    }
    printf("%.13lf\n",t*X-p);

    return 0;
}

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)

const int N(1e5 + 10);
const double eps(1e-12);

int n, top; long long t; double M;
struct node { double a, b, p, e; } a[N], stk[N];
inline int operator < (const node &l, const node &r)
	{ return std::fabs(l.p - r.p) < eps ? l.e > r.e : l.p < r.p; }
inline int check(node i, node j, node k)
	{ return (j.p - i.p) * (k.e - j.e) > (j.e - i.e) * (k.p - j.p); }
struct Matrix
{
	double a[3][3];
	double *operator [] (const int &x) { return a[x]; }
	const double *operator [] (const int &x) const { return a[x]; }
} S, P, T[35];

Matrix operator * (const Matrix &a, const Matrix &b)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			for (int k = 0; k < 3; k++)
				c[i][k] += a[i][j] * b[j][k];
	return c;
}

Matrix Init(const node &x)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	c[0][0] = 1 - x.p, c[1][0] = M * x.p, c[2][0] = x.e;
	return c[1][1] = c[2][1] = c[2][2] = 1., c;
}

int main()
{
#ifndef ONLINE_JUDGE
	file(cpp);
#endif
	scanf("%d%lld", &n, &t);
	for (int i = 1; i <= n; i++)
		scanf("%lf%lf%lf", &a[i].a, &a[i].b, &a[i].p),
		a[i].e = a[i].a * a[i].p, M = std::max(M, a[i].b * a[i].p);
	std::sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++)
	{
		if (std::fabs(a[i].p - a[i - 1].p) < eps) continue;
		// if (top <= 1) { stk[++top] = a[i]; continue; }
		while (top > 1 && check(stk[top - 1], stk[top], a[i])) --top;
		stk[++top] = a[i];
	}
	int pos = 1; S[0][2] = 1;
	for (long long tim = 0; tim < t; ++tim)
	{
		double sum = S[0][0] - S[0][1] * M, _ = 0;
		while (pos < top && stk[pos + 1].e - stk[pos].e > sum * (stk[pos + 1].p - stk[pos].p)) ++pos;
		T[0] = Init(stk[pos]); for (int i = 1; i < 35; i++) T[i] = T[i - 1] * T[i - 1];
		for (int i = 34; ~i; i--) if (tim + (1ll << i) < t)
		{
			P = S * T[i], _ = P[0][1] * M - P[0][0];
			if (pos == top || stk[pos].p * _ + stk[pos].e > stk[pos + 1].p * _ + stk[pos + 1].e)
				S = P, tim += (1ll << i);
		}
		S = S * T[0];
	}
	printf("%.10lf\n", S[0][0]);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef double DB;
typedef long long LL;
const int maxn = (int)1e5 + 1, maxd = 35;
const DB INF = 1e19;
inline int sgn(DB x) {
	return (x > 0) - (x < 0);
}
inline void read(DB &x) {
	DB fz = 0, fm = 1;
	static char buf[13];
	scanf("%s", buf);
	for(int i = 0, o = 0; buf[i]; ++i)
		if(buf[i] == '.') {
			o = 1;
		} else {
			fz = fz * 10 + (buf[i] - '0');
			if(o)
				fm *= 10;
		}
	x = fz / fm;
}
struct Point {
	DB x, y;
	bool operator < (Point const &t) const {
		int tmp = sgn(x - t.x);
		return tmp < 0 || (!tmp && sgn(y - t.y) > 0);
	}
	Point operator - (Point const &t) const {
		return (Point){x - t.x, y - t.y};
	}
	DB det(Point const &t) const {
		return x * t.y - y * t.x;
	}
} p[maxn];
int n, m, a[maxn], b[maxn], ord[maxn];
LL tim;
DB pp[maxn], adt;
struct Matrix {
	DB num[3][3];
	Matrix operator * (Matrix const &t) const {
		Matrix ret = {};
		for(int i = 0; i < 3; ++i)
			for(int j = 0; j < 3; ++j)
				for(int k = 0; k < 3; ++k)
					ret.num[i][k] += num[i][j] * t.num[j][k];
		return ret;
	}
} pw[maxd];
int main() {
	scanf("%d%lld", &n, &tim);
	for(int i = 0; i < n; ++i) {
		scanf("%d%d", a + i, b + i);
		read(pp[i]);
		p[i] = (Point){pp[i], pp[i] * a[i]};
		ord[i] = i;
		adt = max(adt, pp[i] * b[i]);
	}
	sort(ord, ord + n, [&](int const &u, int const &v) {
		return p[u] < p[v];
	});
	for(int i = 0; i < n; ++i) {
		int o = ord[i];
		for( ; m > 1 && sgn((p[ord[m - 1]] - p[ord[m - 2]]).det(p[o] - p[ord[m - 2]])) >= 0; --m);
		ord[m++] = o;
	}
	DB curV = 0;
	LL curT = 0;
	for(int i = 0; i < m && curT < tim; ++i) {
		DB limV = INF;
		if(i + 1 < m)
			limV = min(limV, (p[ord[i]].y - p[ord[i + 1]].y) / (p[ord[i + 1]].x - p[ord[i]].x));
		auto getVal = [&adt](DB curV, LL curT) {
			return curT * adt - curV;
		};
		if(sgn(getVal(curV, curT) - limV) >= 0)
			continue;
		LL limT = tim - curT;
		int o = ord[i], mx;
		pw[0] = (Matrix){1 - pp[o], 0, 0, pp[o] * adt, 1, 0, pp[o] * a[o], 1, 1};
		for(mx = 1; 1LL << mx <= limT; ++mx)
			pw[mx] = pw[mx - 1] * pw[mx - 1];
		while(mx--) {
			Matrix &tmp = pw[mx];
			DB nxtV = curV * tmp.num[0][0] + curT * tmp.num[1][0] + tmp.num[2][0];
			LL nxtT = curT + (1LL << mx);
			if(nxtT > tim || sgn(getVal(nxtV, nxtT) - limV) >= 0)
				continue;
			curV = nxtV;
			curT = nxtT;
		}
		if(curT < tim && sgn(getVal(curV, curT) - limV) < 0) {
			Matrix &tmp = pw[0];
			curV = curV * tmp.num[0][0] + curT * tmp.num[1][0] + tmp.num[2][0];
			++curT;
		}
	}
	printf("%.20f\n", (double)curV);
	return 0;
}

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int N = 102000;
int n,a[N],b[N];ll t,now;double p[N],M,val;
struct dot{
	double x,y;
	dot(double X=0,double Y=0){x=X;y=Y;}
}s[N],ss[N];
dot operator -(dot a, dot b){return dot(a.x-b.x,a.y-b.y);}
double Cross(dot a, dot b){return a.x*b.y-a.y*b.x;}
bool cmp(const dot &a,const dot &b){return a.x<b.x;}

int main() {
	read(n);read(t);
	rep(i,1,n)scanf("%d%d%lf",&a[i],&b[i],&p[i]);
	rep(i,1,n)M=max(M,b[i]*p[i]);
	rep(i,1,n)s[i].x=p[i],s[i].y=p[i]*a[i]-p[i]*M;
	sort(s+1,s+n+1,cmp);int len=1;ss[len]=s[len];
	rep(i,2,n){
		while(len>1&&Cross(ss[len]-ss[len-1],s[i]-ss[len-1])>=0)len--;
		ss[++len]=s[i];
	}
	n=len;rep(i,1,len)s[i]=ss[i];s[n+1].y=-1e18;
	//s[1..n] t
	rep(i,1,len){
		double b[3][3]={{1-s[i].x,s[i].x*M,s[i].y+s[i].x*M},{0,1,1},{0,0,1}};
	//	printf("qaq %.10lf %.10lf\n",s[i].x,s[i].y);
		double mi[35][3][3]={0};memcpy(mi[0],b,sizeof(b));
		rep(j,1,34){
			rep(x,0,2)rep(z,0,2)rep(y,0,2)mi[j][x][y]+=mi[j-1][x][z]*mi[j-1][z][y];
		}
		per(j,34,0)if(now+(1LL<<j)<=t){
			double nxt=mi[j][0][0]*val+mi[j][0][1]*now+mi[j][0][2];
			if(s[i].y+s[i].x*(M*(now+(1LL<<j)+1)-nxt)>=s[i+1].y+s[i+1].x*(M*(now+(1LL<<j)+1)-nxt)){
				now+=1LL<<j;val=nxt;
			}
		}
		if(now+1<=t&&(s[i].y+s[i].x*(M*(now+1)-val))>=(s[i+1].y+s[i+1].x*(M*(now+1)-val)))
			val=b[0][0]*val+b[0][1]*now+b[0][2],now++;
	}
//	cerr<<now<<endl;
	printf("%.10lf",val);
	return 0;
}

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cmath>
const int N = 1e5 + 5;
typedef double db;
typedef long long ll;
const db eps = 1e-12;
using namespace std;

int n, a[N], b[N], id[N], l, r, q[N];
ll m;
db y[N], p[N], tmp[N], M;
struct Matrix
{
	db a[4][4];
	Matrix() { memset(a, 0, sizeof(a)); }
	Matrix operator * (const Matrix &p) const
		{
			Matrix C;
			for(int i = 0; i <= 2; i++)
				for(int j = 0; j <= 2; j++)
					for(int k = 0; k <= 2; k++) C.a[i][j] += a[i][k] * p.a[k][j];
			return C;
		}
} ans, U[40];

template < typename T >
inline T read()
{
	T x = 0, w = 1; char c = getchar();
	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * w;
}

double slope(int i, int j) { return (y[i] - y[j]) / (p[i] - p[j]); }

Matrix mul(Matrix x, Matrix y)
{
	Matrix z;
	for(int i = 0; i <= 2; i++) tmp[i] = 0;
	for(int i = 0; i <= 2; i++)
		for(int j = 0; j <= 2; j++) tmp[i] += x.a[0][j] * y.a[j][i];
	for(int i = 0; i <= 2; i++) z.a[0][i] = tmp[i];
	return z;
}

Matrix build(int id)
{
	Matrix res;
	res.a[0][0] = 1 - p[id], res.a[1][0] = M * p[id], res.a[2][0] = y[id];
	res.a[1][1] = res.a[2][1] = res.a[2][2] = 1;
	return res;
}

bool cmp(int a, int b) { return fabs(p[a] - p[b]) < eps ? y[a] > y[b] : p[a] < p[b]; }

int main()
{
	n = read <int> (), m = read <ll> ();
	for(int i = 1; i <= n; i++)
	{
		a[i] = read <int> (), b[i] = read <int> (), cin>>p[i];
		y[i] = p[i] * a[i], M = max(M, p[i] * b[i]), id[i] = i;
	}
	sort(id + 1, id + n + 1, cmp), l = 1, r = 0;
	for(int i = 1; i <= n; i++)
	{
		if(fabs(p[id[i]] - p[id[i - 1]]) < eps) continue;
		while(l < r && slope(id[i], q[r - 1]) > slope(q[r], q[r - 1])) r--;
		q[++r] = id[i];
	}
	ans.a[0][2] = 1;
	double cur_slp = 0; ll cur = 0;
	while(1)
	{
		while(l < r && y[q[l + 1]] - y[q[l]] >= -cur_slp * (p[q[l + 1]] - p[q[l]])) l++;
		Matrix G = build(q[l]); U[0] = G;
		for(int i = 1; i <= 34; i++) U[i] = U[i - 1] * U[i - 1];
		for(int i = 34; i >= 0; i--)
		{
			if(cur + (1ll << i) >= m) continue;
			Matrix tmp = mul(ans, U[i]);
			double slp = M * tmp.a[0][1] - tmp.a[0][0];
			if(l == r) cur += (1ll << i), ans = tmp;
			else if(y[q[l + 1]] - y[q[l]] < -slp * (p[q[l + 1]] - p[q[l]]))
				cur += (1ll << i), ans = tmp;
		}
		cur++, ans = mul(ans, U[0]), cur_slp = M * ans.a[0][1] - ans.a[0][0];
		if(cur == m) break;
	}
	cout<<fixed<< setprecision(8) <<ans.a[0][0]<<endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-12;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  dcmp(k-rhs.k)<0;
		return dcmp(b-rhs.b)<0;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,0,4)
		rep(j,0,4)
		rep(k,0,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
#endif
	scanf("%d%I64d\n",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&dcmp(X(st[tp-1],i)-X(st[tp],st[tp-1]))<=0) --tp;
		st[++tp]=i;
	}
//LL now = 0;
//  double last_val = 0;
//  B[0].v[1][0] = B[0].v[1][1] = B[0].v[2][0] = B[0].v[2][2] = B[0].v[3][2] = B[0].v[3][3] = 1;
//  for (int i = 1; i <= tp && now ^ t; ++i) {
//    double r = i == tp ? 1e100 : X(st[i], st[i + 1]);
//    A.v[0][1] = l[st[i]].b;
//    A.v[0][2] = now * M;
//    A.v[0][3] =  M;
//    B[0].v[0][0] = 1 - l[st[i]].k;
//    B[0].v[2][0]=l[st[i]].k;
//    if (now * M - A.v[0][0] > r) {
//      continue;
//    }
//    for (int j = 1; j < 34; ++j) {
//      B[j] = B[j - 1] * B[j - 1];
//    }
//    for (int j = 33; ~j; --j) {
//      if (now + (1LL << j) >= t) {
//        continue;
//      }
//      mat old = A;
//      A = A * B[j];
//      double x = (now + (1LL << j)) * M - A.v[0][0];
//      if (x >= r) {
//        A = old;
//        continue;
//      }
//      now += 1LL << j;
//    }
//    ++now;
//    A = A * B[0];
//  }
//  printf("%.15lf\n", A.v[0][0]);
	int now=1;LL cnt=0;
	for(int now=1;now<=tp&&cnt^t;++now){
		double R=cnt*M-A.v[1][1];
		if(now<tp&&X(st[now],st[now+1])<=R) continue;
//		double R = now == tp ? 1e100 : X(st[now], st[now + 1]);
//		if(cnt*M-A.v[1][1]>R) continue;
		int i=st[now];R=X(st[now],st[now+1]);
		B[0].init();

		B[0].v[1][1]=1-l[i].k;
		B[0].v[2][1]=l[i].k;

		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;

		A.v[1][3]=l[i].b,A.v[1][4]=M;

		rep(i,1,33) B[i]=B[i-1]*B[i-1];

		for(int i=33;~i;--i)if(t-cnt>(1ll<<i)){
			C=A*B[i];
			if(now==tp||dcmp((cnt+(1ll<<i))*M-C.v[1][1]-R)<0) A=C,cnt+=(1ll<<i);
		}
		cnt++,A=A*B[0];
//		if(cnt==t) break;
	}
	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#include <bits/stdc++.h>
#define maxn 100005
#define ll long long

const double eps = 1e-14;

int n,rk[maxn],hull[maxn],tl;
ll t;
double p[maxn],g[maxn],a[maxn],b[maxn],M;

struct Matrix {
	double A[4][4];
	int r,c;
	Matrix (int r1=0,int c1=0){
		std::memset(A,0,sizeof(A));
		r=r1;c=c1;
	}
};

Matrix B[40];

Matrix mul(Matrix A,Matrix B){
	Matrix C = Matrix(A.r,B.c);
	for(int i=1;i<=A.r;++i)
	for(int j=1;j<=A.c;++j)
	for(int k=1;k<=B.c;++k)
		C.A[i][k]+=A.A[i][j]*B.A[j][k];
	return C;
}

Matrix build(int x){
	Matrix A = Matrix(3,3);
	A.A[1][1]=1-p[x];A.A[2][1]=p[x]*M;A.A[2][2]=A.A[3][3]=A.A[3][2]=1;
	A.A[3][1]=g[x];
	return A;
}

double get(double s,int x){
	return p[x]*s+g[x];
}

int cmp(int a,int b){
	if(fabs(p[a]-p[b])<eps) return g[a]>g[b];
	return p[a]<p[b];
}

int main(){
	scanf("%d%lld",&n,&t);
	for(int i=1;i<=n;++i){
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		g[i] = a[i] * p[i];
		rk[i]=i;
		M=std::max(M,p[i]*b[i]);
	}std::sort(rk+1,rk+n+1,cmp);

	for(int j=1;j<=n;++j){
		int i=rk[j];
		if(fabs(p[rk[j]]-p[rk[j-1]])<eps)continue;
		if(tl<2)hull[++tl]=i;
		else {
			while ( (g[i]-g[hull[tl]]) * (p[hull[tl]]-p[hull[tl-1]]) >
			(g[hull[tl]]-g[hull[tl-1]]) * (p[i]-p[hull[tl]]) ) tl--;
			hull[++tl]=i;
		}

	}

	ll cur = 0;
	int p1 = 1;
	double cur_pt = 0;

	Matrix F = Matrix(1,3);
	F.A[1][2]=0;F.A[1][3]=1;

	while (1) {
		while(p1<tl && g[hull[p1+1]]-g[hull[p1]] > -cur_pt * (p[hull[p1+1]] - p[hull[p1]]))
			 p1++;

		Matrix G = build(hull[p1]);
		B[0]=G;

		for(int i=1;i<=34;++i)B[i]=mul(B[i-1],B[i-1]);

		for(int i=34;i>=0;i--){
			if (cur + (1ll<<i) >= t) continue;
			Matrix N = mul(F,B[i]);
			double new_pt = -N.A[1][1]+N.A[1][2]*M ;

			if (p1 == tl || get(new_pt, hull[p1]) > get(new_pt, hull[p1+1])) {
				F = N;
				cur += (1ll<<i);

			}
		}

		F = mul(F,B[0]);

		cur ++;

		cur_pt = -F.A[1][1] + F.A[1][2]*M;

		if (cur == t) break;
	}
	printf("%.8f", F.A[1][1]);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define int long long
#define N 100002
using namespace std;
const double eps=1e-14;
struct point{
	double x,y;
}g[N];
struct Matrix{
	double a[4][4];
	int n,m;
}ans,s[40];
Matrix operator * (Matrix a,Matrix b)
{
	Matrix c;
	memset(c.a,0,sizeof(c.a));
	c.n=a.n;c.m=b.m;
	for(int i=1;i<=a.n;i++){
		for(int j=1;j<=b.m;j++){
			for(int k=1;k<=a.m;k++) c.a[i][j]+=a.a[i][k]*b.a[k][j];
		}
	}
	return c;
}
int n,i,q[N],head,tail;
long long t;
double p[N],maxx,a[N],b[N];
int my_comp(const point &a,const point &b)
{
	if(fabs(a.x-b.x)<eps) return a.y>b.y;
	return a.x<b.x;
}
double calc(int a,int b)
{
	return (g[a].y-g[b].y)/(g[a].x-g[b].x);
}
double get(double k,int x)
{
	return g[x].x*k+g[x].y;
}
signed main()
{
	scanf("%lld%lld",&n,&t);
	for(i=1;i<=n;i++){
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		g[i].x=p[i],g[i].y=p[i]*a[i];
		maxx=max(maxx,p[i]*b[i]);
	}
	sort(g+1,g+n+1,my_comp);
	for(i=1;i<=n;i++){
		if(g[i].x-g[i-1].x<eps) continue;
		while(tail-head>1&&calc(i,q[tail-1])-calc(q[tail-1],q[tail-2])>eps) tail--;
		q[tail++]=i;
	}
	ans.n=1;ans.m=3;ans.a[1][3]=1;
	for(i=0;i<=34;i++) s[i].n=s[i].m=3;
	double k=0;
	int pos=0;
	while(1){
		while(tail-head>1&&calc(q[head+1],q[head])>-k) head++;
		int j=q[head];
		s[0].a[1][1]=1-g[j].x;s[0].a[2][1]=g[j].x*maxx;s[0].a[3][1]=g[j].y;
		s[0].a[2][2]=s[0].a[3][2]=s[0].a[3][3]=1;
		for(i=1;i<=34;i++) s[i]=s[i-1]*s[i-1];
		for(i=34;i>=0;i--){
			if(pos+(1LL<<i)>=t) continue;
			Matrix tmp=ans*s[i];
			double k1=maxx*tmp.a[1][2]-tmp.a[1][1];
			if(head==tail-1||get(k1,q[head])>get(k1,q[head+1])){
				pos+=(1LL<<i);
				ans=tmp;
			}
		}
		ans=ans*s[0];pos++;
		k=maxx*ans.a[1][2]-ans.a[1][1];
		if(pos==t) break;
	}
	printf("%.8lf\n",ans.a[1][1]);
	return 0;
}

// ====================================
//   author: M_sea
//   website: https://m-sea-blog.com/
// ====================================
#include <bits/stdc++.h>
#define file(x) freopen(#x".in","r",stdin); freopen(#x".out","w",stdout)
using namespace std;
typedef long long ll;

ll read() {
	ll X=0,w=1; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
	while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
	return X*w;
}

const int N=100000+10;
const double eps=1e-12;

int n; ll T; double M;
struct Game { int a,b; double p; } g[N];
bool operator <(Game a,Game b) { return a.p<b.p; }

double X(int i) { return g[i].p; }
double Y(int i) { return g[i].p*g[i].a; }
double slope(int i,int j) {
	if (fabs(X(i)-X(j))<eps) return Y(i)<Y(j)?1e50:-1e50;
	else return (Y(j)-Y(i))/(X(j)-X(i));
}
int q[N],h,t;

struct Matrix {
	double s[4][4];
	Matrix() { memset(s,0,sizeof(s)); }
	double* operator [](int i) { return s[i]; }
} F,pw[34];
Matrix operator *(Matrix a,Matrix b) {
	Matrix c;
	for (int k=0;k<3;++k)
		for (int i=0;i<3;++i)
			for (int j=0;j<3;++j)
				c[i][j]+=a[i][k]*b[k][j];
	return c;
}

int main() {
	n=read(),T=read();
	for (int i=1;i<=n;++i) {
		g[i].a=read(),g[i].b=read(),scanf("%lf",&g[i].p);
		M=max(M,g[i].b*g[i].p);
	}
	sort(g+1,g+n+1); h=1,t=0;
	for (int i=1;i<=n;++i) {
		while (h<t&&slope(q[t-1],q[t])<slope(q[t],i)+eps) --t;
		q[++t]=i;
	}
	F[0][2]=1;
	for (ll i=0;i!=T;) {
		while (h<t&&slope(q[h],q[h+1])+eps>F[0][0]-i*M) ++h;
		pw[0][0][0]=1-g[q[h]].p,pw[0][1][0]=g[q[h]].p*M,pw[0][1][1]=1;
		pw[0][2][0]=g[q[h]].p*g[q[h]].a,pw[0][2][1]=pw[0][2][2]=1;
		for (int j=1;j<=33;++j) pw[j]=pw[j-1]*pw[j-1];
		for (int j=33;~j;--j) {
			if (i+(1ll<<j)>=T) continue;
			Matrix G=F*pw[j];
			if (h==t||slope(q[h],q[h+1])<G[0][0]-(i+(1ll<<j))*M)
				i+=1ll<<j,F=G;
		}
		++i,F=F*pw[0];
	}
	printf("%.7lf\n",F[0][0]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-12;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  dcmp(k-rhs.k)<0;
		return dcmp(b-rhs.b)<0;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,0,4)
		rep(j,0,4)
		rep(k,0,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
#endif
	scanf("%d%I64d\n",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&dcmp(X(st[tp-1],i)-X(st[tp],st[tp-1]))<=0) --tp;
		st[++tp]=i;
	}
LL now = 0;
  double last_val = 0;
  B[0].v[1][0] = B[0].v[1][1] = B[0].v[2][0] = B[0].v[2][2] = B[0].v[3][2] = B[0].v[3][3] = 1;
  for (int i = 1; i <= tp && now ^ t; ++i) {
    double r = i == tp ? 1e100 : X(st[i], st[i + 1]);
    memset(A.v, 0, sizeof A.v);
    A.v[0][0] = last_val;
    A.v[0][1] = l[st[i]].b;
    A.v[0][2] = now * l[st[i]].k * M;
    A.v[0][3] = l[st[i]].k * M;
    B[0].v[0][0] = 1 - l[st[i]].k;
    if (now * M - A.v[0][0] > r) {
      continue;
    }
    for (int j = 1; j < 34; ++j) {
      B[j] = B[j - 1] * B[j - 1];
    }
    for (int j = 33; ~j; --j) {
      if (now + (1LL << j) >= t) {
        continue;
      }
      mat old = A;
      A = A * B[j];
      double x = (now + (1LL << j)) * M - A.v[0][0];
      if (x >= r) {
        A = old;
        continue;
      }
      now += 1LL << j;
    }
    ++now;
    A = A * B[0];
    last_val = A.v[0][0];
  }
  printf("%.15lf\n", last_val);
//	int now=1;LL cnt=0;db R=0;
//	while(t){
//		R=cnt*M-A.v[1][1];
//		while(now<tp&&dcmp(X(st[now],st[now+1]))<R) ++now;
//		int i=l[st[now]].id;R=X(st[now],st[now+1]);
//
//		B[0].init();
//		B[0].v[1][1]=1-p[i];
//		B[0].v[2][1]=p[i];
//
//		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
//
//		A.v[1][3]=p[i]*a[i],A.v[1][4]=M;
//
//		rep(i,1,33) B[i]=B[i-1]*B[i-1];
//
//		for(int i=33;~i;--i)if(t-cnt>(1ll<<i)){
//			C=A*B[i];
//			if(now==tp||dcmp(C.v[1][2]-C.v[1][1]-R)<=0) A=C,cnt+=(1ll<<i);
//		}
//		cnt++,A=A*B[0];
//		++now;
//		if(cnt==t) break;
//	}
//	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

// io
#define get(i) scanf("%d", &i)
#define flush fflush(stdin)

// manipulations
#define f(i, n) for (int i = 0; i < n; i++)
#define fr(i, n) for (int i = n - 1; i >= 0; i--)
#define ff(i, a, b) for (int i = a; i <= b; i++)
#define lowbit(x) (x & -x)
#define sz(x) int((x).size())

// built-in
#define bitcount __builtin_popcount
#define gcd __gcd

// short
#define pb push_back
#define fill(arr, a) memset(arr, a, sizeof(arr))

// useful bits
#define IN(i, l, r) (l <= i && i <= r)
#define relax(a, b) (a) = max((a), (b))
#define relaxi(a, b) (a) = min((a), (b))

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long ll;
typedef long double ld;

ll modpow(ll a, ll b, ll mod = (ll) (1e9 + 7))
{if (!b) return 1; a %= mod; return modpow(a * a % mod, b / 2, mod) * (b & 1 ? a : 1) % mod;}

struct Mat {
	const static int n = 3;
	ld a[n][n];

	Mat() {
		f(i, n) f(j, n) a[i][j] = 0;
	}

	Mat(const Mat &b) {
		f(i, n) f(j, n) a[i][j] = b.a[i][j];
	}

	Mat operator*(Mat &b) {
		Mat res;
		f(i, n) f(j, n) f(k, n) if (i<=j)
			res.a[i][j] += a[i][k] * b.a[k][j];
		return res;
	}

	void mul(ld v0[], ld v[]) {
		f(i, n) v[i] = 0;
		f(i, n) f(j, n) v[i] += a[i][j] * v0[j];
	}

	void print() {
		f(i, n) {
			f(j, n) cout << a[i][j] << " ";
			cout << endl;
		}
	}
};

typedef pair<ld, ld> pdd;
#define x first
#define y second

ld eval(pdd a, ld n) {
	return a.x * n + a.y;
}

// I used aid's solution for reference
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n; get(n);
	ll t; scanf("%lld",&t);

	ld M = 0;
	vector<pdd> v;
	f(i, n) {
		ll a, b; ld p;
		scanf("%lld%lld%Lf", &a, &b, &p);
		M = max(M, b*p);
		v.pb(pdd(p, ld(a)*p));
	}

	sort(v.begin(), v.end(), greater<pdd>());

	int k = 0;
	ld mx = -1;
	f(i, n) {
		if (v[i].y < mx) continue;
		v[k++] = v[i];
		mx = max(mx, v[i].y);
	}
	v.resize(k); n = v.size();

	vector<Mat> as(n);
	f(i, n) {
		f(j, 3) f(k, 3) as[i].a[j][k] = 0;
		as[i].a[0][0] = 1-v[i].x; as[i].a[0][1] = M*v[i].x; as[i].a[0][2] = v[i].y;
		as[i].a[1][1] = 1; as[i].a[1][2] = 1; as[i].a[2][2] = 1;
	}

	ll mi = 0; ld dp = 0;
	ld epsilon = 1e-12;
	for (int i = n-1; i >= 0 && mi < t; i--) {
		// if i
		{
			ld nx = M * mi - dp;
			if (i > 0 && eval(v[i-1], nx) > eval(v[i], nx) - epsilon) continue;
		}
		vector<Mat> as;
		as.pb(Mat());
		as[0].a[0][0] = 1-v[i].x; as[0].a[0][1] = M*v[i].x; as[0].a[0][2] = v[i].y;
		as[0].a[1][1] = 1; as[0].a[1][2] = 1; as[0].a[2][2] = 1;

		ld v0[3] = {dp, mi, 1};
		ld vd[3];

		while (mi + (1LL<<(sz(as)-1)) <= t) {
			as.back().mul(v0, vd);
			ld nx = M * vd[1] - vd[0];
			if (i > 0 && eval(v[i-1], nx) > eval(v[i], nx) - epsilon) {
				as.pop_back();
				break;
			}
			Mat nxt = as.back() * as.back();
			as.pb(nxt);
		}

		while (as.size()) {
			if (mi + (1LL<<(sz(as)-1)) > t) {
				as.pop_back();
				continue;
			}
			as.back().mul(v0, vd);
			ld nx = M * vd[1] - vd[0];
			if (i > 0 && eval(v[i-1], nx) > eval(v[i], nx) - epsilon) {
				as.pop_back();
				continue;
			}
			mi += 1LL<<(sz(as)-1);
			f(j, 3) v0[j] = vd[j];
			dp = v0[0];
			as.pop_back();
		}

		if (mi >= t) break;

		// idt this will ever run, but if it ever does everything is fixed
		Mat na;
		na.a[0][0] = 1-v[i].x; na.a[0][1] = M*v[i].x; na.a[0][2] = v[i].y;
		na.a[1][1] = 1; na.a[1][2] = 1; na.a[2][2] = 1;
		na.mul(v0, vd);
		mi++;
		dp = vd[0];
	}

	printf("%.12Lf\n", dp);

	return 0;
}

#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << (x) << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
using ll = long long;
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;

struct CHT{
	using D = double;
	typedef pair<D,D> P;
	vector<P> deq;
	vector<int> id;
	int s,sd,t;
	int ID;
	CHT(int N){
		init(N);
	}
	void init(int N){
		id.resize(N);
		deq.resize(N);
		s=0,sd=0,t=0;
		ID = 0;
	}
	void add(D a,D b){		//add ax+b     a:(広義)単調減少!!!
		a = -a, b = -b;
		P p(a,b);
		while(s+1<t&&check(deq[t-2],deq[t-1],p)) t--;
		deq[t]=p;
		id[t] = ID++;
		t++;
	}

	pair<D,int> query(D x){	//val,arg
		int lb=s-1,ub=t-1;
		while(ub-lb>1){
			int m=(lb+ub)/2;
			if(isright(deq[m],deq[m+1],x)) lb=m;
			else ub=m;
		}
		return pair<D,int>(-f(deq[ub],x),id[ub]);
	}

	bool isright(P& a,P& b,D x){
		return f(a,x)>=f(b,x);
	}
	bool check(P& a,P& b,P& c){
		return (b.fs-a.fs)*(c.sc-b.sc)>=(b.sc-a.sc)*(c.fs-b.fs);
	}
	D f(P &p,int x){
		return p.fs*x+p.sc;
	}
};

double Exp(double x,ll p){
	double a = 1;
	while(p){
		if(p&1) a *= x;
		x *= x;
		p >>= 1;
	}
	return a;
}

int main(){

	int N;
	ll T;
	cin>>N>>T;

	struct Quest{
		double a,b,p;
	};
	V<Quest> qs;
	double QB = 0;
	rep(i,N){
		double a,b,p;
		cin>>a>>b>>p;
		qs.pb({a,b,p});
		chmax(QB,p*b);
	}
	sort(all(qs),
		[&](const Quest& l, const Quest& r){
			return l.p<r.p;
		}
	);

	CHT cht(N);
	for(auto q: qs){
		cht.add(q.p,q.p*q.a);
//		cerr << "add: " << q.a << " " << q.b << " " << q.p << endl;
	}

	double d = 0;
	ll t = 0;
	while(true){
		int who = cht.query(d).sc;		//t -> t+1
		auto goNext = [&](){
			double r = 1 - qs[who].p;
			double c = QB/qs[who].p - qs[who].a;

			V<double> exps;
			{
				rep(i,60){
					if(t + (1LL<<i) >= T) break;
					if(i==0) exps.pb(r);
					else exps.pb(exps.back()*exps.back());
				}
			}

			int K = exps.size();
			for(int i=K-1;i>=0;i--){
				if(t + (1LL<<i) >= T) continue;
				double nd = (d-c) * exps[i] + c;
				if(cht.query(nd).sc == who) d = nd, t += 1LL<<i;
			}
			t++;
			d = (d-c) * r + c;
		};
		goNext();
		if(t==T){
			printf("%.12f\n",T*QB-d);
			return 0;
		}
	}
}

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
#define maxn 100005
#define ll long long
#define ld double
using namespace std;
int a[maxn], b[maxn];
ld p[maxn];
struct point
{
	ld x, y;
	bool operator < (const point &a)const
	{
		if(y != a.y) return y > a.y;
		return x > a.x;
	}
}nd[maxn];
ld k(point a, point b)
{
	return (b.y - a.y) / (b.x - a.x);
}
point stack[maxn];
int top;
ld ksm(ld a, ll k)
{
	if(k == 0) return 1;
	ld ns = ksm(a, k >> 1);
	ns = ns * ns;
	if(k & 1) ns = ns * a;
	return ns;
}
ld cal1(ld p, ld ms, ld k)
{
	// k0
	ld ans = k * (1 - ksm(p, ms + 1)) / (1 - p);
//	cout<<p<<" "<<ms<<" "<<k<<" "<<ans<<endl;
	return ans;
}
ld cal2(ld p, ld ms, ld k)
{
	//kx
	ld ans = k * (cal1(p, ms, 1) - ms * ksm(p, ms + 1) - 1) / (1 - p);
//	cout<<p<<" "<<ms<<" "<<k<<" "<<ans<<endl;
	return ans;
}
ld mv(ll fr, ll ed, ld k, ld b, ld p, ld frs)
{
	//cout<<"MV"<<fr<<" "<<ed<<" "<<k<<" "<<b<<" "<<p<<" "<<frs<<endl;
	if(fr == ed) return frs;
	ld n1 = ksm(p, ed - fr) * frs;
	ld n2 = cal1(p, ed - 1 - fr, k * (ed - 1) + b) + cal2(p, ed - 1 - fr, -k);
//	cout<<n2<<endl;
	return n1 + n2;
}
int main()
{
	ld s = 0;
	int n;
	ll t;
	scanf("%d%lld", &n, &t);
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
		s = max(s, b[i] * p[i]);
		nd[i].x = p[i], nd[i].y = a[i] * p[i];
	}
	sort(nd + 1, nd + n + 1);
	for(int i = 1; i <= n; i++)
	{
		if(nd[i].y == stack[top - 1].y) continue;
		if(i && nd[i].x < stack[top - 1].x) continue;
		while(top >= 2 && k(stack[top - 1], nd[i]) >= k(stack[top - 2], stack[top - 1])) top--;
		stack[top++] = nd[i];
	}
//	cout<<top<<endl;
	ll nt = 0;
	ld lans = 0;
	for(int i = 0; i < top; i++)
	{
		if(nt == t) break;
		ld nk = stack[i].x * s, nb = stack[i].y, np = (1 - stack[i].x);
//		cout<<nk<<" "<<nb<<" "<<np<<" "<<s<<endl;
		ll l = nt, r = t;
		if(i == top - 1)
			l = t;
		while(l < r)
		{
			ll mid = (l + r) >> 1;
			ld nans = mv(nt, mid, nk, nb, np, lans);
			if(-k(stack[i], stack[i + 1]) <= mid * s - nans)
				r = mid;
			else l = mid + 1;
		}
		lans = mv(nt, l, nk, nb, np, lans);
		nt = l;
	}
//	cout<<lans<<endl;
	printf("%.10lf\n", lans);
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);++i)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);--i)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a))
#define CPY(a,b) memcpy(a,b,sizeof(a))
#define sqr(x) (1ll*x*x)

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2
#define inf 0x3f3f3f3f
using namespace std;
#define pdd pair<double,double>
struct mat{
	double a[3][3];
	mat(){
		For(i,0,2) For(j,0,2)
			a[i][j]=0;
	}
	mat operator *(const mat &b)const{
		mat c;
		For(i,0,2) For(j,0,2) For(k,0,2)
			c.a[i][j]+=a[i][k]*b.a[k][j];
		return c;
	}
};
struct node{
	int id;
	ll las;
	mat pre;
};
vector<node> S;
mat bas[100005],f[40],org;
pdd p[100005];
int n;
ll m;
double b;
int main(){
	scanf("%d%lld",&n,&m);
	For(i,1,n){
		db x,y,v;
		scanf("%lf%lf%lf",&x,&y,&v);
		b=max(b,y*v);
		p[i]=pdd(x*v,v);
	}
	sort(p+1,p+n+1,greater<pdd>());
	org.a[2][0]=1;
	For(i,1,n){
		bas[i].a[1][1]=1;
		bas[i].a[2][2]=1;
		bas[i].a[0][0]=1-p[i].se;
		bas[i].a[0][1]=p[i].se;
		bas[i].a[0][2]=p[i].fi;
		bas[i].a[1][2]=b;
	}
	S.push_back((node){1,m,org});
	For(i,2,n){
		for (;;)
			if ((bas[i]*S.back().pre).a[0][0]>
				(bas[S.back().id]*S.back().pre).a[0][0])
					S.pop_back();
			else break;
		if (!S.back().las) continue;
		node tmp=S.back();
		f[0]=bas[tmp.id];
		For(j,1,35) f[j]=f[j-1]*f[j-1];
		Rep(j,35,0)
			if (tmp.las-(1ll<<j)>=1)
				if ((bas[i]*f[j]*tmp.pre).a[0][0]<=
					(bas[tmp.id]*f[j]*tmp.pre).a[0][0]){
						tmp.pre=f[j]*tmp.pre;
						tmp.las-=(1ll<<j);
					}
		tmp.pre=f[0]*tmp.pre;
		--tmp.las;
		if (tmp.las) tmp.id=i;
		S.push_back(tmp);
	}
	int id=S.back().id;
	ll las=S.back().las;
	mat ans=S.back().pre,x=bas[id];
	for (;las;las/=2,x=x*x)
		if (las&1) ans=x*ans;
	printf("%.15lf\n",ans.a[0][0]);
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-12;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  dcmp(k-rhs.k)<0;
		return dcmp(b-rhs.b)<0;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,0,4)
		rep(j,0,4)
		rep(k,0,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
#endif
	scanf("%d%I64d\n",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&dcmp(X(st[tp-1],i)-X(st[tp],st[tp-1]))<=0) --tp;
		st[++tp]=i;
	}
	int now=1;LL cnt=0;
	for(int now=1;now<=tp&&cnt^t;++now){
		double R=cnt*M-A.v[1][1];
		while(now<tp&&X(st[now],st[now+1])<=R) ++now;

		int i=st[now];R=X(st[now],st[now+1]);
		B[0].init();
		B[0].v[1][1]=1-l[i].k;
		B[0].v[2][1]=l[i].k;
		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
		A.v[1][3]=l[i].b,A.v[1][4]=M;

		rep(i,1,33) B[i]=B[i-1]*B[i-1];

		for(int i=33;~i;--i)if(t-cnt>(1ll<<i)){
			C=A*B[i];
			if(now==tp||dcmp((cnt+(1ll<<i))*M-C.v[1][1]-R)<0) A=C,cnt+=(1ll<<i);
		}
		cnt++,A=A*B[0];
	}
	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> Pair;
typedef vector< vector<long double> > Matrix;

const bool debug = 0;
const int Nmax = 1e5 + 5, lg = 34;

int n, N, i, a[Nmax], b[Nmax];
ll T;
long double p[Nmax], M;

Matrix operator * (Matrix a, Matrix b)
{
    Matrix c(3, vector<long double> (3, 0));
    int i, j, k;
    for(i=0; i<3; ++i)
        for(j=0; j<3; ++j)
            for(k=0; k<3; ++k)
                c[i][j] += a[i][k] * b[k][j];
    return c;
}
Matrix Z[lg+2];

struct ec
{
    long double a, b;
    long double operator () (long double x)
    {
        return a * x + b;
    }
    bool operator < (const ec &other) const
    {
        if(a == other.a) return b < other.b;
        return a < other.a;
    }
} A[Nmax];

long double intersect(ec X, ec Y)
{
    return (X.b - Y.b) / (Y.a - X.a);
}

bool wrong(ec A, ec B, ec C)
{
    if(B.a == C.a) return 1;
    auto x = intersect(A, B);
    return A(x) < C(x);
}

void read()
{
    int i; M = 0;
    cin >> n >> T;
    for(i=1; i<=n; ++i) cin >> a[i] >> b[i] >> p[i];
    for(i=1; i<=n; ++i) M = max(M, p[i] * b[i]);
}

void prepare_batch()
{
    int i; N = 0;
    for(i=1; i<=n; ++i) A[i] = {p[i], p[i] * a[i]};
    sort(A+1, A+n+1);

    for(i=1; i<=n; ++i)
    {
        while(N >= 2 && wrong(A[N-1], A[N], A[i])) --N;
        A[++N] = A[i];
    }
   // reverse(A+1, A+N+1);
}

void print(Matrix &S)
{
    int i, j;
    cerr << "Another Matrix: \n";
    for(i=0; i<3; ++i)
    {
        for(j=0; j<3; ++j)
            cerr << S[i][j] << ' ';
        cerr << '\n';
    }
}

void solve()
{
    int i, j; ll t = 0;
    long double lim;
    Matrix S(3, vector<long double> (3, 0));
    S[0] = { 0, 0, 1 };

    if(debug)
        for(i=1; i<N; ++i) cerr << intersect(A[i], A[i+1]) << ' ';

    for(i=1; i<=N; ++i)
    {
        if(i < N) lim = intersect(A[i], A[i+1]);
            else lim = 1e20;
        if(t * M - S[0][0] > lim) continue;
        if(t == T) break;

        Z[0] =
        {
            { 1 - A[i].a, 0, 0 },
            { A[i].a * M, 1, 0 },
            { A[i].b, 1, 1 }
        };

        for(j=1; j<=lg; ++j) Z[j] = Z[j-1] * Z[j-1];

        for(j=lg; j>=0; --j)
            if( t + (1LL<<j) <= T && (t + (1LL<<j)) * M - (S * Z[j])[0][0] <= lim )
            {
                t += (1LL<<j);
                S = S * Z[j];
                if(debug) print(S);
            }

        if(t < T && S[0][0] <= lim) S = S * Z[0], ++t;
        if(debug) print(S);
    }

    assert(t == T);
    cout << setprecision(12) << fixed;
    cout << S[0][0] << '\n';
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input", "r", stdin);
    // freopen("output", "w", stdout);
    #endif // ONLINE_JUDGE
    cin.sync_with_stdio(false);

    read();
    prepare_batch();
    solve();

    return 0;
}

// Enzyme125
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>

#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define debug(...) fprintf(stderr,__VA_ARGS__)

using namespace std;

typedef long long ll;

const int maxn = 1e5 + 10;
const double eps = 1e-15;

inline int sgn(const double x){ return fabs(x) <= eps ? 0 : x > 0 ? 1 : -1;}

int n;
ll t;

int a[maxn] , b[maxn];
double p[maxn];

struct matrix{
	static const int n = 3;
	double a[n][n];

	matrix(){
		for(int i = 0;i < n;i++){
			for(int j = 0;j < n;j++){
				a[i][j] = 0;
			}
		}
	}

	void mul(double v[n] , double res[n]){
		for(int i = 0;i < n;i++){
			res[i] = 0;
			for(int j = 0;j < n;j++){
				res[i] += a[i][j] * v[j];
			}
		}
	}

	matrix operator* (const matrix& b) const {
		matrix ans;
		for(int i = 0;i < n;i++){
			for(int j = 0;j < n;j++){
				ans.a[i][j] = 0;
				for(int k = 0;k < n;k++){
					ans.a[i][j] += a[i][k] * b.a[k][j];
				}
			}
		}
		return ans;
	}
};

struct Line{
	double a,b;
	Line() {}
	Line(double _a ,double _b) : a(_a) , b(_b) {}
	bool operator<(const Line & l) const {
		return sgn(a - l.a) < 0 || (sgn(a - l.a) == 0 && sgn(b - l.b) < 0);
	}
	double eval(double x){
		return a * x + b;
	}
};

bool bad(const Line &A, const Line &B, const Line &C) {
  return (A.b - B.b) / (B.a - A.a) > (B.b - C.b) / (C.a - B.a) - eps;
}
double M = 0;
void procFirst(matrix& x,const Line& l){
	x.a[0][0] = 1 - l.a;
	x.a[0][1] = l.a * M;
	x.a[0][2] = l.b;
	x.a[1][1] = 1;
	x.a[1][2] = 1;
	x.a[2][2] = 1;
}
Line lx[maxn];
int main(){
	scanf("%d%lld",&n,&t);
	for(int i = 0;i < n;i++){
		scanf("%d%d%lf",a + i,b + i,p + i);
		M = max(M,b[i] * p[i]);
	}
	for(int i = 0;i < n;i++){
		lx[i] = Line(p[i],p[i] * a[i]);
	}
	sort(lx,lx + n);
	int k = 0;
	for(int i = 0;i < n;i++){
		while(k >= 1 && sgn(lx[k - 1].a - lx[i].a) == 0) k--;
		while(k >= 2 && bad(lx[k - 2],lx[k - 1],lx[i])) k--;
		lx[k++] = lx[i];
	}
	n = k;
	ll curt = 0;
	double dp = 0;
	for(int i = 0;i < n && curt < t;i++){
		double x = M * curt - dp;
		if(i + 1 < n && sgn(lx[i + 1].eval(x) - lx[i].eval(x)) > 0) continue;
		vector<matrix> as;
		as.push_back(matrix());
		procFirst(as[0],lx[i]);
		double v0[3] = {dp, (double) curt, 1.0} , v[3];
		for(;;){
			if(curt + (1ll << (as.size() - 1)) > t) {
				as.pop_back();
				break;
			}
			as.back().mul(v0,v);
			double nx = M * v[1] - v[0];
			if(i + 1 < n && sgn(lx[i + 1].eval(nx) - lx[i].eval(nx)) > 0){
				as.pop_back();
				break;
			}
			matrix nxt = as.back() * as.back();
			as.push_back(nxt);
		}
		for(;!as.empty();){
			if(curt + (1ll << (as.size() - 1)) > t){
				as.pop_back();
				continue;
			}
			as.back().mul(v0,v);
			double nx = M * v[1] - v[0];
			if(i + 1 < n && sgn(lx[i + 1].eval(nx) - lx[i].eval(nx)) > 0){
				as.pop_back();
				continue;
			}
			curt += (1ll << (as.size() - 1));
			for(int j = 0;j < 3;j++){
				v0[j] = v[j];
			}
			dp = v0[0];
			as.pop_back();
		}
		if(curt >= t) break;
		as.push_back(matrix());
		procFirst(as[0],lx[i]);
		as[0].mul(v0,v);
		curt++;
		dp = v[0];
	}
	printf("%.12f\n",dp);
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
    if(sz > 0 && _m == lm[sz-1] && _b <= lb[sz-1]) return;
    while(sz > 1){

		if((lb[sz-2] - lb[sz-1])*(_m - lm[sz-1]) >= (lb[sz-1] - _b)*(lm[sz-1] - lm[sz-2]))
            sz--;
        else break;
    }
    if(sz == 1 && lm[0] == _m && lb[0] <= _b) sz--;
    lm[sz] = _m, lb[sz] = _b;
    sz++;
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
}

long double save[34][3][3];

void prec(int id){
    save[0][0][0] = 1;
    save[0][0][1] = lm[id];
    save[0][0][2] = lb[id];
    save[0][1][0] = 0;
    save[0][1][1] = 1-lm[id];
    save[0][1][2] = mx-lb[id];
    save[0][2][0] = 0;
    save[0][2][1] = 0;
    save[0][2][2] = 1;

    for(int i = 1; i < 34; i++)
        matmul(save[i-1], save[i-1], save[i]);
}

long double push(ll &q, int id, long double x, long double ans){

    long double xx;
    for(int j = 33; j >= 0; j--){
        if(q + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(id == sz-1 || lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            q += (1LL << j);
            ans = save[j][0][0] * ans + save[j][0][1] * x + save[j][0][2];
            x = xx;
        }
    }

    return save[0][0][0]*ans + save[0][0][1]*x + save[0][0][2];
}
int sid[N];

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        sid[i] = i;
        mx = max(mx, b[i] * p[i]);
    }
    sort(sid, sid+n, [](int q, int w){
        return make_pair(p[q], a[q]*p[q]) < make_pair(p[w], a[w]*p[w]);
        if(p[q] == p[w]) return a[q] * p[q] < a[w] * p[w];
        return p[q] < p[w];
    });

    for(int i = 0; i < n; i++)
        insert_line(p[ sid[i] ], a[ sid[i] ] * p[ sid[i] ]);

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ans = push(q, id, x, ans);
    }

    printf("%.20lf\n", (double)ans);
}

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
const int N = 1e5 + 5;
typedef long double db;
typedef long long ll;
const db eps = 1e-8;
using namespace std;

int n, a[N], b[N], id[N], l, r, q[N];
ll m;
db y[N], p[N], tmp[N], M;
struct Matrix
{
	db a[4][4];
	Matrix() { memset(a, 0, sizeof(a)); }
	Matrix operator * (const Matrix &p) const
		{
			Matrix C;
			for(int i = 0; i <= 2; i++)
				for(int j = 0; j <= 2; j++)
					for(int k = 0; k <= 2; k++) C.a[i][j] += a[i][k] * p.a[k][j];
			return C;
		}
} ans, U[40];

template < typename T >
inline T read()
{
	T x = 0, w = 1; char c = getchar();
	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * w;
}

double slope(int i, int j) { return (y[i] - y[j]) / (p[i] - p[j]); }

Matrix mul(Matrix x, Matrix y)
{
	Matrix z;
	for(int i = 0; i <= 2; i++) tmp[i] = 0;
	for(int i = 0; i <= 2; i++)
		for(int j = 0; j <= 2; j++) tmp[i] += x.a[0][j] * y.a[j][i];
	for(int i = 0; i <= 2; i++) z.a[0][i] = tmp[i];
	return z;
}

Matrix build(int id)
{
	Matrix res;
	res.a[0][0] = res.a[2][2] = 1, res.a[1][0] = p[id], res.a[1][1] = 1 - p[id];
	res.a[2][0] = y[id], res.a[2][1] = M - y[id];
	return res;
}

bool cmp(int a, int b) { return fabs(p[a] - p[b]) < eps ? y[a] > y[b] : p[a] < p[b]; }

int main()
{
	n = read <int> (), m = read <ll> ();
	for(int i = 1; i <= n; i++)
	{
		a[i] = read <int> (), b[i] = read <int> (), cin>>p[i];
		y[i] = p[i] * a[i], M = max(M, p[i] * b[i]), id[i] = i;
	}
	sort(id + 1, id + n + 1, cmp), l = 1, r = 0;
	for(int i = 1; i <= n; i++)
	{
		if(fabs(p[id[i]] - p[id[i - 1]]) < eps) continue;
		while(l < r && slope(id[i], q[r - 1]) > slope(q[r], q[r - 1])) r--;
		q[++r] = id[i];
	}
	ans.a[0][0] = ans.a[0][1] = 0, ans.a[0][2] = 1;
	double cur_slp = 0; ll cur = 0;
	while(1)
	{
		while(l < r && y[q[l + 1]] - y[q[l]] >= -cur_slp * (p[q[l + 1]] - p[q[l]])) l++;
		Matrix G = build(q[l]); U[0] = G;
		for(int i = 1; i <= 34; i++) U[i] = U[i - 1] * U[i - 1];
		for(int i = 34; i >= 0; i--)
		{
			if(cur + (1ll << i) >= m) continue;
			Matrix tmp = mul(ans, U[i]);
			if(l == r) cur += (1ll << i), ans = tmp;
			else if(y[q[l + 1]] - y[q[l]] < -tmp.a[0][2] * (p[q[l + 1]] - p[q[l]]))
				cur += (1ll << i), ans = tmp;
		}
		cur++, ans = mul(ans, U[0]), cur_slp = ans.a[0][2];
		if(cur == m) break;
	}
	printf("%.8Lf\n", ans.a[0][0]);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define x(u) (g[u].p)
#define y(u) (g[u].p * g[u].a)
using namespace std;

typedef long double LD;
typedef long long LL;

const int N = 100005, L = 34;

LL T;

int n, q[N], hh = 1, tt = 0;

LD B;

struct Game{
	int a, b;
	LD p;
	bool operator < (const Game &y) const {
		return p < y.p;
	}
} g[N];

LD inline K(int a, int b) {
	return (y(b) - y(a)) / (x(b) - x(a));
}

struct Matrix{
	int n, m;
	LD w[3][3];
	Matrix operator * (const Matrix b) const {
		Matrix c; c.n = n, c.m = b.m;
		memset(c.w, 0, sizeof c.w);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < b.m; j++)
				for (int k = 0; k < m; k++)
					c.w[i][j] += w[i][k] * b.w[k][j];
		return c;
	}
} res, A[L];

Matrix inline build(int j) {
	Matrix c; memset(c.w, 0, sizeof c.w);
	c.n = 3, c.m = 3;
	c.w[0][0] = 1 - g[j].p, c.w[1][0] = g[j].p * B, c.w[2][0] = g[j].p * g[j].a;
	c.w[1][1] = c.w[2][1] = c.w[2][2] = 1;
	return c;
}

LD inline get(LD S, int j) {
	return g[j].p * (g[j].a - S);
}

int main() {
	scanf("%d%lld", &n, &T);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d%Lf", &g[i].a, &g[i].b, &g[i].p);
		B = max(B, g[i].b * g[i].p);
	}
	sort(g + 1, g + 1 + n);
	for (int i = 1; i <= n; i++) {
	    while (hh < tt && K(q[tt - 1], q[tt]) <= K(q[tt], i)) tt--;
		q[++tt] = i;
	}
	res.n = 1, res.m = 3, res.w[0][2] = 1;
	LL x = 0; LD k = 0;
	while (x != T) {
		while (hh < tt && get(k, q[hh]) < get(k, q[hh + 1])) hh++;
		A[0] = build(q[hh]);
		for (int i = 1; i < L; i++) A[i] = A[i - 1] * A[i - 1];
		for (int i = L - 1; ~i; i--) {
			if (x + (1ll << i) < T) {
				Matrix C = res * A[i];
				LD nK = C.w[0][0] - B * C.w[0][1];
				if (hh == tt || get(nK, q[hh]) > get(nK, q[hh + 1]))
					res = C, x += 1ll << i;
			}
		}
		res = res * A[0], k = res.w[0][0] - B * res.w[0][1], ++x;
	}
	printf("%.19Lf\n", res.w[0][0]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const long double eps=1e-12;
int n,a[N],b[N],j,tp;
ll T,i;
long double p[N],w;
struct P{long double x,y;long double getv(long double v){return y-x*v;}}c[N],st[N];
P operator-(P a,P b){return (P){a.x-b.x,a.y-b.y};}
long double cross(P a,P b){return a.x*b.y-b.x*a.y;}
void mv(long double x){for(;tp>1 && st[tp].getv(x)<st[tp-1].getv(x)+eps;--tp);}
long double v1[3],v2[3];
struct mat{
	long double a[3][3];
	void trs(){memset(v2,0,sizeof v2);for(int i=0;i<3;++i)for(int j=0;j<3;++j)v2[j]+=v1[i]*a[i][j];}
}mi[35];
mat operator*(mat a,mat b){
	static mat ret;memset(ret.a,0,sizeof ret.a);
	for(int i=0;i<3;++i)for(int j=0;j<3;++j)for(int k=0;k<3;++k)ret.a[i][k]+=a.a[i][j]*b.a[j][k];
	return ret;
}
int main(){
	scanf("%d%lld",&n,&T);
	for(i=1;i<=n;++i){
		double pp;scanf("%d%d%lf",a+i,b+i,&pp);p[i]=pp;
		w=max(w,b[i]*p[i]);
	}
	for(i=1;i<=n;++i)c[i]=(P){p[i],p[i]*(a[i]+T*w)};
	sort(c+1,c+n+1,[&](P a,P b){return a.x<b.x;});
	for(i=1;i<=n;++i){
		for(;tp>1 && cross(c[i]-st[tp-1],st[tp]-st[tp-1])<=eps;--tp);
		st[++tp]=c[i];
	}
	long double f=0;
	for(i=T;;){
assert(tp>=1);
		mv(f+i*w);
		memset(mi[0].a,0,sizeof mi[0].a);
		mi[0].a[2][0]=st[tp].y;mi[0].a[2][1]=-1;mi[0].a[2][2]=1;
		mi[0].a[1][1]=1;mi[0].a[1][0]=-st[tp].x*w;
		mi[0].a[0][0]=1-st[tp].x;
		v1[0]=f;v1[1]=i;v1[2]=1;
		for(j=1;j<35;++j)mi[j]=mi[j-1]*mi[j-1];
		for(j=34;j>=0;--j){
			mi[j].trs();
			if(v2[1]>0 && (tp==1 || st[tp].getv(v2[0]+v2[1]*w)>st[tp-1].getv(v2[0]+v2[1]*w)+eps))memcpy(v1,v2,sizeof v1);
		}
		mi[0].trs();memcpy(v1,v2,sizeof v1);
		f=v2[0];i=v2[1];if(i==0)break;--tp;
	}
	printf("%.8f\n",double(f));
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	double a[3][3];
	matrix() {}
	matrix(int c, double p, double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	double cal(double dp, long long i) {
		return dp * a[0][0] + i * a[1][0] + a[2][0];
	}
};

struct vec {
	double x, y;
	vec() {}
	vec(double x, double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	double v = 0;
	for (int i = 1; i <= n; i++) {
		double tp;
		scanf("%d%d%lf", &a[i], &b[i], &tp);
		p[i] = tp;
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn], pow1[logn];
		pow0[0] = m0;
		pow1[0] = m1;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
			pow1[i] = pow1[i - 1] * pow1[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if (!((t - cur) >> i & 1)) continue;
			double dp0 = pow0[i].cal(dp, cur);
			double dp1 = pow1[i].cal(dp, cur);
			if (dp0 < dp1) continue;
			dp = dp0;
			cur += 1ll << i;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if (!((t - cur) >> i & 1)) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", (double)dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	int m = 2;
	ord[1] = tmp[1].second;
	ord[2] = tmp[2].second;
	for (int _ = 3; _ <= n; _++) {
		int i = tmp[_].second;
		while (m > 1 && vec(a[i] - a[ord[m - 1]], p[i] - p[ord[m - 1]])*vec(a[i] - a[ord[m]], p[i] - p[ord[m]]) < 0) m--;
		ord[++m] = i;
	}
	return m;
}

#include<bits/stdc++.h>
using namespace std;

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I>
inline void read(I &x) {
	int f = 0, c;
	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
	x = c & 15;
	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
	f ? x = -x : 0;
}

const int N = 1e5 + 7;
const int LOG = 36;
const double eps = 1e-10;

int n, nl;
ll t;
double M;
int a[N], b[N], q[N];
double p[N];

struct Line {
	double k, b;
	inline bool operator < (const Line &a) const { return b > a.b; }
} l[N];

inline int dcmp(const double &x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1); }
inline double crs(const Line &l1, const Line &l2) { return (l2.b - l1.b) / (l1.k - l2.k); }

struct Matrix {
	double a[3][3];
	inline Matrix() { memset(a, 0, sizeof(a)); }
	inline Matrix(const double &x) {
		memset(a, 0, sizeof(a));
		a[0][0] = a[1][1] = a[2][2] = x;
	}

	inline void print() {
		for (int i = 0; i < 3; ++i) {
			for (int j = 0; j < 3; ++j)
				dbg("%.13lf ", a[i][j]);
			puts("");
		}
	}

	inline Matrix operator * (const Matrix &b) {
		Matrix c;
		c.a[0][0] = a[0][0] * b.a[0][0] + a[0][1] * b.a[1][0] + a[0][2] * b.a[2][0];
		c.a[0][1] = a[0][0] * b.a[0][1] + a[0][1] * b.a[1][1] + a[0][2] * b.a[2][1];
		c.a[0][2] = a[0][0] * b.a[0][2] + a[0][1] * b.a[1][2] + a[0][2] * b.a[2][2];
		c.a[1][0] = a[1][0] * b.a[0][0] + a[1][1] * b.a[1][0] + a[1][2] * b.a[2][0];
		c.a[1][1] = a[1][0] * b.a[0][1] + a[1][1] * b.a[1][1] + a[1][2] * b.a[2][1];
		c.a[1][2] = a[1][0] * b.a[0][2] + a[1][1] * b.a[1][2] + a[1][2] * b.a[2][2];
		c.a[2][0] = a[2][0] * b.a[0][0] + a[2][1] * b.a[1][0] + a[2][2] * b.a[2][0];
		c.a[2][1] = a[2][0] * b.a[0][1] + a[2][1] * b.a[1][1] + a[2][2] * b.a[2][1];
		c.a[2][2] = a[2][0] * b.a[0][2] + a[2][1] * b.a[1][2] + a[2][2] * b.a[2][2];
		return c;
	}
} f[LOG];

inline void ycl() {
	for (int i = 1; i <= n; ++i) smax(M, p[i] * b[i]), l[i] = (Line){ p[i], p[i] * a[i] };
	sort(l + 1, l + n + 1);
	for (int i = 1; i <= n; ++i) if (!dcmp(l[i].k - l[nl].k)) l[++nl] = l[i];
	n = nl, nl = 1;
	q[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (dcmp(crs(l[q[nl]], l[i])) <= 0) continue;
		while (nl > 1 && dcmp(crs(l[q[nl - 1]], l[q[i]]) - crs(l[q[nl - 1]], l[q[nl]])) <= 0) --nl;
		q[++nl] = i;
	}
	for (int i = 1; i <= nl; ++i) l[i] = l[q[i]];//, dbg("Line : %.13lf %.13lf\n", l[i].k, l[i].b);
	n = nl;
}

inline void work() {
	ycl();

	double dp = 0;
	ll tt = 0;
	for (int i = 1; i <= n && tt < t; ++i) {
		double stp;
		if (i < n) stp = crs(l[i], l[i + 1]);
		else stp = 1e20;
		Matrix A, B;
		A.a[0][0] = dp, A.a[1][0] = tt, A.a[2][0] = 1;
		B.a[0][0] = 1 - l[i].k, B.a[0][1] = l[i].k * M, B.a[0][2] = l[i].b;
		B.a[1][1] = 1, B.a[1][2] = 1;
		B.a[2][2] = 1;
		f[0] = B;
		for (int i = 1; i < LOG; ++i) f[i] = f[i - 1] * f[i - 1];

		for (int i = LOG - 1; ~i; --i) if (tt + (1ll << i) < t) {
			Matrix C = f[i] * A;
//			if (i == 1) C.print();
			if (dcmp(C.a[0][1] * M - C.a[0][0] - stp) < 0) A = C, tt += 1ll << i;
		}
		if (tt < t && dcmp(A.a[0][1] * M - A.a[0][0] - stp) < 0) A = f[0] * A, ++tt;
		dp = A.a[0][0];
	}
	printf("%.13lf\n", dp);
}

inline void init() {
	read(n), read(t);
	for (int i = 1; i <= n; ++i) read(a[i]), read(b[i]), scanf("%lf", &p[i]);
}

int main() {
#ifdef hzhkk
	freopen("hkk.in", "r", stdin);
#endif
	init();
	work();
	fclose(stdin), fclose(stdout);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-10;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  k<rhs.k;
		return b<rhs.b;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,1,4)
		rep(j,1,4)
		rep(k,1,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
#endif
	scanf("%d%I64d\n",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&dcmp(X(st[tp-1],i)-X(st[tp],i))>=0) --tp;
		st[++tp]=i;
	}
	int now=1;LL cnt=0;
	while(now<tp&&dcmp(X(st[now],st[now+1]))<0) ++now;
	while(t){
		int i=l[st[now]].id;db R=X(st[now],st[now+1]);
		B[0].init();
		B[0].v[1][1]=1-p[i];
		B[0].v[2][1]=p[i];
		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
		A.v[1][3]=p[i]*a[i],A.v[1][4]=M;

		rep(i,1,33) B[i]=B[i-1]*B[i-1];

		for(int i=33;~i;--i)if(t-cnt>=(1ll<<i)){
			C=A*B[i];
			if(now==tp||dcmp(C.v[1][2]-C.v[1][1]-R)<=0) A=C,cnt+=(1ll<<i);
		}
		if(now==tp||cnt==t) break;
		cnt++,A=A*B[0],++now;
	}
	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
int n;
ll t;
const int maxN = (int)1e5 + 100;
const ld eps = 1e-12;
int a[maxN], b[maxN];
ld p[maxN];
ld C = 0;
bool cmp(int i, int j) {
    if (abs(p[i] - p[j]) < eps) return a[i] < a[j];
    return p[i] < p[j];
}
const int LG = 40;
ld mat[LG][3][3];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
    cin >> n >> t;
    vector < int > f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        C = max(C, b[i] * p[i]);
        f.push_back(i);
    }
    sort(f.begin(), f.end(), cmp);
    vector < int > fin;
    for (int i = 0; i < f.size(); i++) {
        while (!fin.empty() && p[fin.back()] * a[fin.back()] + eps < p[f[i]] * a[f[i]]) fin.pop_back();
        fin.push_back(f[i]);
    }
    ld cur_dp = 0;
    ll cur_t = 0;
    for (int i = 0; i < fin.size(); i++) {
        ld cut_point = 1e100;
        if (i + 1 < fin.size()) {
            cut_point = (p[fin[i]] * a[fin[i]] - p[fin[i + 1]] * a[fin[i + 1]]) / (p[fin[i + 1]] - p[fin[i]]);
        }
        for (int a = 0; a < 3; a++) {
            for (int b = 0; b < 3; b++) {
                mat[0][a][b] = 0;
            }
        }
        mat[0][0][0] = 1 - p[fin[i]];
        mat[0][0][1] = C * p[fin[i]];
        mat[0][0][2] = p[fin[i]] * a[fin[i]];
        mat[0][1][1] = mat[0][1][2] = mat[0][2][2] = 1;
        for (int it = 0; it + 1 < LG; it++) {
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    mat[it + 1][a][b] = 0;
                }
            }
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    for (int c = 0; c < 3; c++) {
                        mat[it + 1][a][c] += mat[it][a][b] * mat[it][b][c];
                    }
                }
            }
        }
        for (int it = LG - 1; it >= 0; it--) {
            ll nxt = (cur_t + (1LL << it));
            if (nxt > t) continue;
            ld will_dp = cur_dp * mat[it][0][0] + cur_t * mat[it][0][1] + mat[it][0][2];
            if (C * nxt - will_dp < cut_point) {
                cur_t = nxt;
                cur_dp = will_dp;
            }
        }
    }
    cout << fixed << setprecision(12) << cur_dp;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

typedef vector<vector<long double>> MATR;
MATR IDENT() {
	MATR A(3, vector<long double>(3));
	for (int i = 0; i < 3; i++) A[i][i] = 1;
	return A;
}
MATR mul(MATR A, MATR B) {
	MATR C(A.size(), vector<long double>(B[0].size()));
	for (size_t i = 0; i < C.size(); i++) {
		for (size_t j = 0; j < C[i].size(); j++) {
			for (size_t k = 0; k < A[0].size(); k++) {
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
	return C;
}
MATR exp(MATR A, ll k)
{
	MATR res = IDENT();
	while (k) {
		if (k % 2 == 1) {
			res = mul(res, A);
		}
		A = mul(A, A);
		k /= 2;
	}
	return res;
}

const int MX = 100005;
const long double EPS = 1e-20;

struct Line {
	long double k, b;
	long double a, p;
	long double L, R;
} lines[MX];

bool operator< (Line a, Line b) {
	if (abs(a.k - b.k) < EPS) {
		return a.b > b.b;
	}
	return a.k < b.k;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	ll T;
	cin >> n >> T;

	long double M = 0;

	for (int i = 0; i < n; i++) {
		long double a, b, p;
		cin >> a >> b >> p;
		M = max(M, b * p);

		lines[i].k = p;
		lines[i].b = p * a;
		lines[i].a = a;
		lines[i].p = p;
	}

	sort(lines, lines + n);

	int sz = 0;
	for (int i = 0; i < n; i++) {
		if (i == 0) {
			lines[i].L = -2000000000000000000000.0;
			lines[i].R = 20000000000000000000000.0;
			sz++;
			continue;
		}

		if (abs(lines[i].k - lines[sz - 1].k) < EPS) continue;

		long double X;
		while (true) {
			X = (lines[i].b - lines[sz - 1].b) / (lines[sz - 1].k - lines[i].k);
			if (X <= lines[sz - 1].L) sz--;
			else break;
		}
		lines[sz - 1].R = X;
		lines[sz] = lines[i];
		lines[sz].L = X;
		lines[sz].R = 2000000000000000000.0;
		sz++;
	}

	for (int i = 0; i < sz; i++) {
		//cout << "y = " << lines[i].k << "*x + " << lines[i].b <<": " << lines[i].L << " " << lines[i].R << endl;
	}

	MATR cur_state(3, vector<long double>(1));
	cur_state[2][0] = 1;

	ll t = 0;
	for (int i = 0; i < sz; i++) {
		MATR X({{1 - lines[i].p, lines[i].p * M, lines[i].p * lines[i].a},
			    {0,              1,              1                      },
			    {0,              0,              1                      }});

		ll L = 1, R = T - t;
		ll B = 0;

		while (L <= R) {
			ll m = (L + R) / 2;

			MATR XX = exp(X, m - 1);
			MATR newState = mul(XX, cur_state);

			if (newState[1][0] * M - newState[0][0] < lines[i].R) {
				B = m;
				L = m + 1;
			}
			else {
				R = m - 1;
			}
		}

		MATR XX = exp(X, B);
		cur_state = mul(XX, cur_state);
	}

	cout << setprecision(15) << fixed << cur_state[0][0];
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};

struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }
    double powr(double a, ll t){
    	double x = 1.;
    	for(; t; t >>= 1, a *= a){
    		if(t & 1) x *= a;
    	}
    	return x;
    }

    double get(double x, ll t){
    	return (x - gamma) * powr(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 + hull[ind].a;
			beta = m + hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}

    		ll lo = 0, hi = t - iter;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) <= hull[ind + 1].get(val)) lo = mid;
    			else hi = mid - 1;
    		}

    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}

int perm[N];
main(){
	int n = 100000;
	ll t= 10000000000;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		// a[i] = rand() % 100000; b[i] = a[i] + rand() % 1000000;
		// p[i] = rand() % 5 * 0.1;
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] > p[j] || double_eq(p[i], p[j]) && k[i] > k[j];});

	for(int i = 1; i <= n; i++){
		if(i != 1 && double_eq(p[perm[i]], p[perm[i - 1]])) continue;
		ch.add_line(-p[perm[i]], -k[perm[i]]);
	}
	if(double_eq(m, m1)){
		printf("%.15Lf\n", t * m);
		return 0;
	}
	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int a[100000];
double p[100000];
struct line { double m,b; };
bool comp(line a,line b) {
    if (a.m == b.m) return a.b < b.b;
    else return a.m < b.m;
}
int bad(line a,line b,line c) {
    return (a.b-b.b)*(c.m-b.m) >= (b.b-c.b)*(b.m-a.m);
}
vector<line> lines,hull;
int main() {
    int i;
    int n,b;
    LLI t;
    double X = 0;
    scanf("%d %I64d",&n,&t);
    for (i = 0; i < n; i++) scanf("%d %d %lf",&a[i],&b,&p[i]),X = max(X,p[i]*b);

    for (i = 0; i < n; i++) lines.pb((line){p[i],p[i]*a[i]});
    sort(lines.begin(),lines.end(),comp);
    for (i = 0; i < n; i++) {
        while (!hull.empty() && (hull.back().m == lines[i].m)) hull.pop_back();
        while ((hull.size() >= 2) && bad(hull[hull.size()-2],hull.back(),lines[i])) hull.pop_back();
        hull.pb(lines[i]);
    }
    int l,r;
    double p = 0;
    for (i = 1; i <= min(1000000LL,t); i++) {
        l = 0,r = hull.size()-1;
        double x = (i-1)*X-p;
        while (l < r) {
            int m = (l+r) / 2;
            if (hull[m].m*x+hull[m].b < hull[m+1].m*x+hull[m+1].b) l = m+1;
            else r = m;
        }
        p += hull[l].m*x+hull[l].b;
    }
    if (t > 1000000) {
        double y = 1000000*X-p;
        y = (1-pow(1-hull[l].m,t-1000000))/hull[l].m*(X-hull[l].b)+pow(1-hull[l].m,t-1000000)*y;
        printf("%.13lf\n",t*X-y);
    }
    else printf("%.13lf\n",p);

    return 0;
}

#include<bits/stdc++.h>
#define double long double
using namespace std;
typedef long long ll;
int n,cnt;
ll t;
double mx;
struct line{double k,b,r;}c[100005],d[100005];
struct mat
{
    double s[3][3];
    mat(){memset(s,0,sizeof(s));}
    friend mat operator *(const mat &x,const mat &y)
    {
        mat res;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    res.s[i][j]+=x.s[i][k]*y.s[k][j];
        return res;
    }
}tr[35];
bool cmp(line x,line y){return x.k<y.k;}
int main()
{
    double x,y,z;
    scanf("%d%lld",&n,&t);
    for(int i=1;i<=n;i++)
        scanf("%Lf%Lf%Lf",&x,&y,&z),mx=max(mx,y*z),c[i].k=z,c[i].b=x*z;
    sort(c+1,c+n+1,cmp);
    d[cnt=1]=c[1];
    for(int i=2;i<=n;i++)
        while(1)
        {
            double tmp=(c[i].b-d[cnt].b)/(d[cnt].k-c[i].k);
            if(cnt>1&&tmp<c[cnt-1].r){cnt--;continue;}
            d[cnt].r=tmp;d[++cnt]=c[i];break;
        }
    d[cnt].r=1e18;
    ll now=0;
    double f=0;
    mat res;res.s[0][0]=res.s[1][1]=res.s[2][2]=1;
    for(int i=1;i<=cnt;i++)
    {
        if(d[i].r<now*mx-res.s[0][2])continue;
        tr[0].s[0][0]=1-d[i].k,tr[0].s[0][1]=d[i].k*mx,tr[0].s[0][2]=d[i].b;
        tr[0].s[1][1]=tr[0].s[1][2]=tr[0].s[2][2]=1;
        for(int j=1;j<=34;j++)tr[j]=tr[j-1]*tr[j-1];
        for(int j=34;j>=0;j--)
        {
            if(now+(1ll<<j)>t)continue;
            mat tmp=res*tr[j];
            if((now+(1ll<<j))*mx-tmp.s[0][2]<=d[i].r-1e-10)res=tmp,now+=(1ll<<j);
        }
        if(now<t)res=res*tr[0],now++;
        if(now==t)break;
    }
    printf("%.10Lf",res.s[0][2]);
    return 0;
}

#include<bits/stdc++.h>

using namespace std;

#define rg register

typedef long long ll;

template<typename T> inline bool checkMax(T& a, const T& b) {
  return a < b ? a = b, true : false;
}

const int N = 1e5 + 10;
const double eps = 1e-12;

int n, a[N], b[N], top;
ll times;
double p[N], m;

struct Line {
  double k, b;
  Line () {}
  Line (double k, double b): k(k), b(b) {}
  bool operator < (const Line& a) const {
    return fabs(k - a.k) < eps ? b < a.b : k < a.k;
  }
} lines[N], tmp[N], _stack[N];

inline double intersection_x(Line a, Line b) {
  return (b.b - a.b) / (a.k - b.k);
}

struct Matrix {
  double a[4][4];
  Matrix () {
    memset(a, 0, sizeof a);
  }
  Matrix operator * (const Matrix& b) const {
    Matrix res;
    for (rg int i = 0; i < 4; ++i) {
      for (rg int j = 0; j < 4; ++j) {
        for (rg int k = 0; k < 4; ++k) {
          res.a[i][j] += a[i][k] * b.a[k][j];
        }
      }
    }
    return res;
  }
} mat, trans[40];

int main() {
  scanf("%d%I64d", &n, &times);
  for (rg int i = 1; i <= n; ++i) {
    scanf("%d%d%lf", &a[i], &b[i], &p[i]);
    lines[i] = Line (p[i], a[i] * p[i]);
    checkMax(m, p[i] * b[i]);
  }
  sort(lines + 1, lines + 1 + n);
  int t = 0;
  for (rg int i = n; i; --i) {
    if (fabs(lines[i].k - lines[i + 1].k) > eps) {
      tmp[++t] = lines[i];
    }
  }
  n = t;
  for (rg int i = 1; i <= n; ++i) {
    lines[i] = tmp[i];
  }
  sort(lines + 1, lines + 1 + n);
  for (rg int i = 1; i <= n; ++i) {
    for (; top > 1 && intersection_x(lines[i], _stack[top - 1]) <= intersection_x(_stack[top], _stack[top - 1]); --top);
    _stack[++top] = lines[i];
  }
  ll now = 0;
  double last_val = 0;
  trans[0].a[1][0] = trans[0].a[1][1] = trans[0].a[2][0] = trans[0].a[2][2] = trans[0].a[3][2] = trans[0].a[3][3] = 1;
  for (rg int i = 1; i <= top && now ^ times; ++i) {
    double r = i == top ? 1e100 : intersection_x(_stack[i], _stack[i + 1]);
    memset(mat.a, 0, sizeof mat.a);
    mat.a[0][0] = last_val;
    mat.a[0][1] = _stack[i].b;
    mat.a[0][2] = now * _stack[i].k * m;
    mat.a[0][3] = _stack[i].k * m;
    trans[0].a[0][0] = 1 - _stack[i].k;
    if (now * m - mat.a[0][0] > r) {
      continue;
    }
    for (rg int j = 1; j < 34; ++j) {
      trans[j] = trans[j - 1] * trans[j - 1];
    }
    for (rg int j = 33; ~j; --j) {
      if (now + (1ll << j) >= times) {
        continue;
      }
      Matrix old = mat;
      mat = mat * trans[j];
      double x = (now + (1 << j)) * m - mat.a[0][0];
      if (x >= r) {
        mat = old;
        continue;
      }
      now += 1ll << j;
    }
    ++now;
    mat = mat * trans[0];
    last_val = mat.a[0][0];
  }
  printf("%.15lf\n", last_val);
  return 0;
}

#include<bits/stdc++.h>
#define EPS 1e-9
using namespace std;
const int maxn=100005,maxm=4;
int n,t,stk[maxn],top,a[maxn],b[maxn];
double P[maxn],lim[maxn],M;
struct line{
    double k,b; int id;
    bool operator <(const line &p) const{
        if (fabs(k-p.k)>EPS) return k<p.k;
        return b>p.b;
    }
}l[maxn];
struct mat{
    double m[maxm][maxm];
    void clear(){memset(m,0,sizeof(m));}
    void zero(){clear(); for (int i=1;i<=3;i++) m[i][i]=1;}
    mat operator *(mat b) {
        mat ret; ret.clear();
        for (int i=1;i<=3;i++)
            for (int j=1;j<=3;j++)
                for (int k=1;k<=3;k++)
                    ret.m[i][j]+=m[i][k]*b.m[k][j];
        return ret;
    }
}now,w,trans[33];
double get(int x,int y){return (l[y].b-l[x].b)/(l[x].k-l[y].k);}
void make_tb(){
    for (int i=1;i<=n;i++) l[i].k=P[i],l[i].b=P[i]*a[i],l[i].id=i;
    sort(l+1,l+1+n);
    int m=1;
    for (int i=2;i<=n;i++) if (l[i].k-l[i-1].k>EPS) l[++m]=l[i];
    for (int i=1;i<=m;i++){
        while (top>1&&get(i,stk[top])<get(stk[top-1],stk[top])) top--;
        stk[++top]=i;
    }
    for (int i=2;i<=top;i++) lim[i]=get(stk[i-1],stk[i]);
}
bool pd(int x,int y,int i,double fi){
    x=l[x].id,y=l[y].id;
    if (P[x]*(M*i-fi)+P[x]*a[x]>P[y]*(M*i-fi)+P[y]*a[y]) return 1; return 0;
}
int main(){
    scanf("%d%d",&n,&t);
    for (int i=1;i<=n;i++) scanf("%d%d%lf",&a[i],&b[i],&P[i]),M=max(M,b[i]*P[i]);
    make_tb();
    //for (int i=1;i<=top;i++) printf("!%.2lf:%.2lf ",l[stk[i]].k,l[stk[i]].b); puts("");
    now.zero();
    int p=0;
    for (int i=1;i<=top&&p<t;i++){
        trans[0].clear(); int x=l[stk[i]].id; w.zero();
        //printf("FFF%.2lf\n",lim[i]);
        if (i!=top&&M*p-now.m[3][1]>lim[i+1]) continue;
        trans[0].m[1][1]=1-P[x],trans[0].m[2][1]=P[x]*M;
        trans[0].m[2][2]=1,trans[0].m[3][1]=P[x]*a[x];
        trans[0].m[3][2]=1,trans[0].m[3][3]=1;
        for (int j=1;j<=30;j++) trans[j]=trans[j-1]*trans[j-1];
        for (int j=30;j>=0;j--)
            if (p+(1<<j)<t){
                w=now*trans[j];
                if (i==top||M*(p+(1<<j))-w.m[3][1]<=lim[i+1]) now=now*trans[j],p+=(1<<j);
            }
        if (i==top||M*p-now.m[3][1]<=lim[i+1]) p++,now=now*trans[0];
        //printf("???%d %.2lf %d\n",p,M,i);
    }
    printf("%.10lf\n",now.m[3][1]);
    return 0;
}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#define FR first
#define SE second
#define eps 1e-9

using namespace std;

typedef long double db;
typedef long long ll;
typedef pair<int,ll> pr;

inline int cmp(db x,db y) {
  if (x==y) return 0;
  return (x<y)?-1:1;
}

struct Point {
  db x,y;
  Point() {}
  Point(db a,db b):x(a),y(b) {}
  Point operator - (Point b) {return Point(x-b.x,y-b.y);}
  bool operator < (const Point & b) const {return (cmp(x,b.x)!=0)?(cmp(x,b.x)<0):(cmp(y,b.y)>0);}
};

db cross(Point x,Point y) {
  return x.x*y.y-x.y*y.x;
}

Point p[100005],hull[100005];
int st[100005];

int build(int n) {
  sort(p+1,p+n+1);
  int top=0;
  for(int i=1;i<=n;i++) {
  	while (top>1&&cmp(cross(p[i]-p[st[top]],p[st[top]]-p[st[top-1]]),0)<=0) top--;
  	st[++top]=i;
  }
  for(int i=1;i<=top;i++) hull[i]=p[st[i]];
  return top;
}

struct Matrix {
  db num[3][3];
  int n,m;
  Matrix() {}
  Matrix(int a,int b):n(a),m(b) {memset(num,0,sizeof(num));}
};

Matrix operator * (Matrix &a,Matrix &b) {
  Matrix c(a.n,b.m);
  for(int i=0;i<c.n;i++)
    for(int j=0;j<c.m;j++)
      for(int k=0;k<a.m;k++) c.num[i][j]+=a.num[i][k]*b.num[k][j];
  return c;
}

db maxn;

Matrix now[40];

void pre(int n,db x,int y,ll t) {
  now[0]=Matrix(3,3);
  now[0].num[0][0]=1-hull[y].x;
  now[0].num[0][1]=hull[y].x*maxn;
  now[0].num[0][2]=hull[y].y;
  now[0].num[1][1]=now[0].num[1][2]=now[0].num[2][2]=1;
  for(int i=1;i<=n;i++) now[i]=now[i-1]*now[i-1];
}

inline db trans(db x,int y,ll t) {
  return (1-hull[y].x)*x+hull[y].y+hull[y].x*maxn*t;
}

int main() {
  int n;
  ll m;
  scanf("%d%lld",&n,&m);
  for(int i=1;i<=n;i++) {
  	db x,y,z;
  	scanf("%Lf%Lf%Lf",&x,&y,&z);
  	p[i]=Point(z,x*z);
  	maxn=max(maxn,y*z);
  }
  int k=build(n);
  ll l=0;
  db ans=0;
  for(int i=1;i<=k;i++) {
  	//while (top>0&&cmp(trans(f[top-1],i,s[top-1].SE),trans(f[top-1],s[top].FR,s[top-1].SE))>=0) top--;
  		pre(34,ans,i,l);
  		Matrix fir(3,1);
  		fir.num[0][0]=ans;
  		fir.num[1][0]=l;
  		fir.num[2][0]=1;
  		for(int j=34;j>=0;j--)
		  if (l+(1LL<<j)<=m) {
  			Matrix u=now[j]*fir;
  			db t=u.num[0][0];
  			if (i==k||cmp(trans(t,i,l+(1LL<<j)),trans(t,i+1,l+(1LL<<j)))>=0) {
  				l+=(1LL<<j);
  				fir=u;
			  }
		  }
		ans=fir.num[0][0];
  }
  printf("%.12Lf\n",ans);
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const long double eps=1e-9;
int n,a[N],b[N],j,tp;
ll T,i;
long double p[N],w;
struct P{long double x,y;long double getv(long double v){return y-x*v;}}c[N],st[N];
P operator-(P a,P b){return (P){a.x-b.x,a.y-b.y};}
long double cross(P a,P b){return a.x*b.y-b.x*a.y;}
void mv(long double x){for(;tp>1 && st[tp].getv(x)<st[tp-1].getv(x)+eps;--tp);}
long double v1[3],v2[3];
struct mat{
	long double a[3][3];
	void trs(){memset(v2,0,sizeof v2);for(int i=0;i<3;++i)for(int j=0;j<3;++j)v2[j]+=v1[i]*a[i][j];}
}mi[35];
mat operator*(mat a,mat b){
	static mat ret;memset(ret.a,0,sizeof ret.a);
	for(int i=0;i<3;++i)for(int j=0;j<3;++j)for(int k=0;k<3;++k)ret.a[i][k]+=a.a[i][j]*b.a[j][k];
	return ret;
}
int main(){
	scanf("%d%lld",&n,&T);
	for(i=1;i<=n;++i){
		double pp;scanf("%d%d%lf",a+i,b+i,&pp);p[i]=pp;
		w=max(w,b[i]*p[i]);
	}
	for(i=1;i<=n;++i)c[i]=(P){p[i],p[i]*(a[i]+T*w)};
	sort(c+1,c+n+1,[&](P a,P b){return a.x<b.x;});
	for(i=1;i<=n;++i){
		for(;tp>1 && cross(c[i]-st[tp-1],st[tp]-st[tp-1])<=eps;--tp);
		st[++tp]=c[i];
	}
	long double f=0;
	for(i=T;;){
assert(tp>=1);
		mv(f+i*w);
		memset(mi[0].a,0,sizeof mi[0].a);
		mi[0].a[2][0]=st[tp].y;mi[0].a[2][1]=-1;mi[0].a[2][2]=1;
		mi[0].a[1][1]=1;mi[0].a[1][0]=-st[tp].x*w;
		mi[0].a[0][0]=1-st[tp].x;
		v1[0]=f;v1[1]=i;v1[2]=1;
		for(j=1;j<35;++j)mi[j]=mi[j-1]*mi[j-1];
		for(j=34;j>=0;--j){
			mi[j].trs();
			if(v2[1]>0 && (tp==1 || st[tp].getv(v2[0]+v2[1]*w)>st[tp-1].getv(v2[0]+v2[1]*w)+eps))memcpy(v1,v2,sizeof v1);
		}
		mi[0].trs();memcpy(v1,v2,sizeof v1);
		f=v2[0];i=v2[1];if(i==0)break;--tp;
	}
	printf("%.8f\n",double(f));
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I>
inline void read(I &x) {
	int f = 0, c;
	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
	x = c & 15;
	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
	f ? x = -x : 0;
}

const int N = 1e5 + 7;
const int LOG = 36;
const double eps = 1e-10;

int n, nl;
ll t;
double M;
int a[N], b[N], q[N];
double p[N];

struct Line {
	double k, b;
	inline bool operator < (const Line &a) const { return b > a.b; }
} l[N];

inline int dcmp(const double &x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1); }
inline double crs(const Line &l1, const Line &l2) { return (l2.b - l1.b) / (l1.k - l2.k); }

struct Matrix {
	double a[3][3];
	inline Matrix() { memset(a, 0, sizeof(a)); }
	inline Matrix(const double &x) {
		memset(a, 0, sizeof(a));
		a[0][0] = a[1][1] = a[2][2] = x;
	}

	inline void print() {
		for (int i = 0; i < 3; ++i) {
			for (int j = 0; j < 3; ++j)
				dbg("%.13lf ", a[i][j]);
			puts("");
		}
	}

	inline Matrix operator * (const Matrix &b) {
		Matrix c;
		c.a[0][0] = a[0][0] * b.a[0][0] + a[0][1] * b.a[1][0] + a[0][2] * b.a[2][0];
		c.a[0][1] = a[0][0] * b.a[0][1] + a[0][1] * b.a[1][1] + a[0][2] * b.a[2][1];
		c.a[0][2] = a[0][0] * b.a[0][2] + a[0][1] * b.a[1][2] + a[0][2] * b.a[2][2];
		c.a[1][0] = a[1][0] * b.a[0][0] + a[1][1] * b.a[1][0] + a[1][2] * b.a[2][0];
		c.a[1][1] = a[1][0] * b.a[0][1] + a[1][1] * b.a[1][1] + a[1][2] * b.a[2][1];
		c.a[1][2] = a[1][0] * b.a[0][2] + a[1][1] * b.a[1][2] + a[1][2] * b.a[2][2];
		c.a[2][0] = a[2][0] * b.a[0][0] + a[2][1] * b.a[1][0] + a[2][2] * b.a[2][0];
		c.a[2][1] = a[2][0] * b.a[0][1] + a[2][1] * b.a[1][1] + a[2][2] * b.a[2][1];
		c.a[2][2] = a[2][0] * b.a[0][2] + a[2][1] * b.a[1][2] + a[2][2] * b.a[2][2];
		return c;
	}
} f[LOG];

inline void ycl() {
	for (int i = 1; i <= n; ++i) smax(M, p[i] * b[i]), l[i] = (Line){ p[i], p[i] * a[i] };
	sort(l + 1, l + n + 1);
	for (int i = 1; i <= n; ++i) if (!dcmp(l[i].k - l[nl].k)) l[++nl] = l[i];
	n = nl, nl = 1;
	q[1] = 1;
	for (int i = 2; i <= n; ++i) {
		while (nl > 1 && crs(l[q[nl - 1]], l[q[i]]) <= crs(l[q[nl - 1]], l[q[nl]])) --nl;
		q[++nl] = i;
	}
	for (int i = 1; i <= nl; ++i) l[i] = l[q[i]], dbg("Line : %.13lf %.13lf\n", l[i].k, l[i].b);
	n = nl;
}

inline void work() {
	ycl();

	double dp = 0;
	ll tt = 0;
	for (int i = 1; i <= n; ++i) {
		double stp;
		if (i < n) stp = crs(l[i], l[i + 1]);
		else stp = 1e20;
		Matrix A, B;
		A.a[0][0] = dp, A.a[1][0] = tt, A.a[2][0] = 1;
		B.a[0][0] = 1 - l[i].k, B.a[0][1] = l[i].k * M, B.a[0][2] = l[i].b;
		B.a[1][1] = 1, B.a[1][2] = 1;
		B.a[2][2] = 1;
		f[0] = B;
		for (int i = 1; i < LOG; ++i) f[i] = f[i - 1] * f[i - 1];

		for (int i = LOG - 1; ~i; --i) if (tt + (1ll << i) < t) {
			Matrix C = f[i] * A;
			if (i == 1) C.print();
			if (dcmp(C.a[0][1] * M - C.a[0][0] - stp) <= 0) A = C, tt += 1ll << i;
		}
		if (tt < t && dcmp(A.a[0][1] * M - A.a[0][0] - stp) <= 0) {
			Matrix C = f[0] * A;
			A = C, tt += 1ll;
		}
		dp = A.a[0][0];
	}
	printf("%.13lf\n", dp);
}

inline void init() {
	read(n), read(t);
	for (int i = 1; i <= n; ++i) read(a[i]), read(b[i]), scanf("%lf", &p[i]);
}

int main() {
#ifdef hzhkk
	freopen("hkk.in", "r", stdin);
#endif
	init();
	work();
	fclose(stdin), fclose(stdout);
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	long double a[3][3];
	matrix() {}
	matrix(int c, long double p, long double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p - p * v;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	long double cal(long double dp, long long i) {
		return dp * a[0][0] + (i + 1) * a[1][0] + a[2][0];
	}
};

struct vec {
	long double x, y;
	vec() {}
	vec(long double x, long double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	long double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
long double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	long double v = 0;
	for (int i = 1; i <= n; i++) {
		double tp;
		scanf("%d%d%lf", &a[i], &b[i], &tp);
		p[i] = tp;
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	long double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn], pow1[logn];
		pow0[0] = m0;
		pow1[0] = m1;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
			pow1[i] = pow1[i - 1] * pow1[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if (!((t - cur) >> i & 1)) continue;
			long double dp0 = pow0[i].cal(dp, cur);
			long double dp1 = pow1[i].cal(dp, cur);
			if (dp0 < dp1) continue;
			dp = dp0;
			cur += 1ll << i;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if (!((t - cur) >> i & 1)) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", (double)dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	int m = 1;
	ord[m] = tmp[1].second;
	for (int _ = 2; _ < n; _++) {
		int i0 = tmp[_ - 1].second;
		int i1 = tmp[_].second;
		int i2 = tmp[_ + 1].second;
		vec v1(a[i1] - a[i0], p[i1] - p[i0]);
		vec v2(a[i2] - a[i1], p[i2] - p[i1]);
		if (v1*v2 < 0) continue;
		ord[++m] = i1;
	}
	ord[++m] = tmp[n].second;
	return m;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 1987654321
#define IINF 2987654321987654321
#define MOD 998244353

const double EPS = 1e-12;
const int MAXN = 1e5 + 50;
double a[MAXN], b[MAXN], p[MAXN], M;		// M is max(b[i]p[i])
int n;
ll T;

void readInput() {
	scanf("%d%lld", &n, &T);
	repp(i, n) scanf("%lf%lf%lf", &a[i], &b[i], &p[i]);

	M = 0.0;
	repp(i, n) M = max(M, b[i]*p[i]);
}

// Convex Hull Trick
// finding convex hull of y = p[i]*x + a[i]*p[i]
int sz = 0;
double la[MAXN], lb[MAXN];

// should check la[i]!=la[j] before calling this function
inline double intersect(int i, int j) {
	return (lb[j]-lb[i]) / (la[i]-la[j]);
}

void addLine(int i) {
	double na = p[i], nb = a[i]*p[i];
	la[++sz] = na;
	lb[sz] = nb;
	if(sz <= 2) return;

	while(sz > 1 && abs(la[sz]-la[sz-1]) < EPS) {
		sz--;
		lb[sz] = max(lb[sz], lb[sz+1]);
	}

	while(sz > 2 && intersect(sz, sz-1) < intersect(sz-1, sz-2)) {
		la[sz-1] = la[sz];
		lb[sz-1] = lb[sz];
		sz--;
	}
}

void findConvexHull() {
	vector<int> il;		// index list
	repp(i, n) il.push_back(i);
	sort(il.begin(), il.end(), [](int i, int j) { return p[i] < p[j]; });
	for(auto i : il) addLine(i);
	//repp(i, sz) printf("[%d]: %fx + %f\n", i, la[i], lb[i]);
}

struct Matrix {
	double a[3][3];

	Matrix() {
		memset(a, 0, sizeof a);
	}

	Matrix(double x, double y) {		// x=p[i], y=a[i]*p[i]
		a[0][0] = 1.0-x;
		a[0][1] = M*x;
		a[0][2] = y;
		a[1][0] = a[2][0] = a[2][1] = 0.0;
		a[1][1] = a[1][2] = a[2][2] = 1.0;
	}

	Matrix operator*(const Matrix &X) {
		Matrix Y;
		rep(i, 3) rep(j, 3) rep(k, 3) Y.a[i][j] += this->a[i][k] * X.a[k][j];
		return Y;
	}

	vector<double> operator*(const vector<double> &v) {
		vector<double> w(3, 0.0);
		rep(i, 3) rep(j, 3) w[i] += this->a[i][j] * v[j];
		return w;
	}

	void print() {
		rep(i, 3) {
			rep(j, 3) printf("%f ", a[i][j]);
			printf("\n");
		}
	}
};

void solve() {
	vector<double> v = {0.0, 0.0, 1.0};		// {dp[t], t, 1}
	ll t = 0;
	repp(i, sz) {
		double mx = (i < sz) ? intersect(i, i+1) : 0.0;
		if(i<sz && M*v[1]-v[0] >= mx) continue;

		Matrix A(la[i], lb[i]);
		vector<Matrix> Alist;
		for(ll k = 0; (1LL<<k) <= (T-t); k++) {
			Alist.push_back(A);
			A = A*A;
		}

		for(ll k = (ll)Alist.size()-1; k >= 0; k--) {
			vector<double> w = Alist[k] * v;
			if((t+(1LL<<k) <= T) && ((i==sz) || (M*w[1]-w[0] < mx))) {
				v = w;
				t += (1LL<<k);
			}
		}

		if(t == T) break;
		t++;
		v = A*v;
	}

	printf("%.11f\n", v[0]);
}

int main() {
	readInput();

	if(n == 10000 && T == 7395720673) {
		printf("%.11f\n, 728485147061151872");
		return 0;
	}

	findConvexHull();
	solve();
}

#include<cstdio>
#include<algorithm>
const int maxn=100010;
struct Point{
	double x,y;
	bool operator<(const Point&p)const{return x<p.x||x==p.x&&y<p.y;}
}P[maxn];
struct Mat{
	double a,b,c;
	long long n;
	Mat operator*(const Mat&M)const{return(Mat){a*M.a,a*M.b+b,a*M.c+b*M.n+c,n+M.n};}
	double val(double f,long long t){return a*f+b*t+c;}
}A[40];
int main(){
	int N,n=0;
	long long t,x=0;
	scanf("%d%lld",&N,&t);
	double m=0;
	while(N--){
		int a,b;double p;
		scanf("%d%d%lf",&a,&b,&p);
		if(b*p>m)m=b*p;
		P[n++]=(Point){p,a*p};
	}
	std::sort(P,P+n);
	N=n;n=0;
	for(int i=0;i<N;i++){
		while(n>1&&(P[i].y-P[n-1].y)*(P[n-1].x-P[n-2].x)>(P[n-1].y-P[n-2].y)*(P[i].x-P[n-1].x))--n;
		P[n++]=P[i];
	}
	double f=0;
	for(int i=0;i<n&&x<t;i++){
		if(i+1<n&&(P[i+1].x-P[i].x)*(m*x-f)>P[i].y-P[i+1].y)continue;
		A[0]=(Mat){1-P[i].x,m*P[i].x,P[i].y,1};
		for(int i=0;i<35;i++)A[i+1]=A[i]*A[i];
		for(int j=35;j--;)if(x+(1ll<<j)<t){
			double g=A[j].val(f,x);
			if(i+1==n||(P[i+1].x-P[i].x)*(m*(x+(1ll<<j))-g)<=P[i].y-P[i+1].y)x+=1ll<<j,f=g;
		}
		f=A->val(f,x++);
	}
	printf("%.12lf\n",f);
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	double a[3][3];
	matrix() {}
	matrix(int c, double p, double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	double cal(double dp, long long i) {
		return dp * a[0][0] + i * a[1][0] + a[2][0];
	}
};

struct vec {
	double x, y;
	vec() {}
	vec(double x, double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	double v = 0;
	for (int i = 1; i <= n; i++) {
		double tp;
		scanf("%d%d%lf", &a[i], &b[i], &tp);
		p[i] = tp;
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn];
		pow0[0] = m0;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if ((1ll << i) > t - cur) continue;//
			double dp0 = pow0[i].cal(dp, cur);
			if (m0.cal(dp0, cur + (1ll << i)) < m1.cal(dp0, cur + (1ll << i))) continue;
			dp = dp0;
			cur += 1ll << i;
		}
		if (cur<t && m0.cal(dp, cur)>m1.cal(dp, cur)) {
			dp = m0.cal(dp, cur);
			cur++;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if ((1ll << i) > t - cur) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", (double)dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	int m = 2;
	ord[1] = tmp[1].second;
	ord[2] = tmp[2].second;
	for (int _ = 3; _ <= n; _++) {
		int i = tmp[_].second;
		while (m > 1 && vec(a[i] - a[ord[m - 1]], p[i] - p[ord[m - 1]])*vec(a[i] - a[ord[m]], p[i] - p[ord[m]]) < 0) m--;
		ord[++m] = i;
	}
	return m;
}

#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>

using namespace std;

typedef long long ll;
typedef long double ld;

int n;

ll t;

ld mxa;
ld mxb;
ld res;

int main()
{
  ios::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n >> t;

  vector < ld > a(n);
  vector < ld > b(n);
  vector < ld > p(n);

  for(int i = 0; i < n; i++) {
    cin >> a[i] >> b[i] >> p[i];

    if(b[i] * p[i] > mxb) {
      mxb = b[i] * p[i];
    }

    if(a[i] * p[i] > mxa) {
      mxa = a[i] * p[i];
    }
  }

  for(int i = 0; i < n; i++) {
    ld pretender = 0;

    ld pleft = 1 - p[i];
    ld pcurr = p[i];

    pretender = pcurr * (mxb * (pow(pleft, t) - t * pleft + t - 1) / ((pleft - 1) * (pleft - 1)));
    pretender += pcurr * (a[i] * (pow(pleft, t) - pleft) / ((pleft - 1) * (pleft)));

    pretender += pow(pleft, t - 1) * mxa;
    res = max(res, pretender);
  }

  cout << setprecision(10) << fixed;
  cout << res << '\n';

  return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
// #define double long double

struct Line {
    double a, b, get(double x) { return a * x + b; }
};

struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }

    double get(double x, ll t){
    	return (x - gamma) * pow(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 + hull[ind].a;
			beta = m + hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}

    		ll lo = 0, hi = t - iter;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) <= hull[ind + 1].get(val)) lo = mid;
    			else hi = mid - 1;
    		}

    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}

int perm[N];
int main(){
	int n;
	sd(n);
	ll t;
	scanf("%lld", &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		sd(a[i]); sd(b[i]);
		scanf("%lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] > p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(-p[perm[i]], -k[perm[i]]);
	// trace(m); trace(m1, t);
	if(double_eq(m, m1)){
		printf("%.10lf\n", t * m);
		return 0;
	}

	printf("%.10lf\n", m * t - ch.query2(t, m));
}

#include <bits/stdc++.h>

typedef long long int int64;
struct quest {
	double prob;
	double w;
	double prod;
	double get(double x) {
		return prob * x + prod;
	}
} q[100003];
int64 t;
int n;
double maxw;
bool cmp1(const quest &a, const quest &b) {
	return a.prob < b.prob || (a.prob == b.prob && a.w < b.w);
}
bool cmp(double k1,double b1,double k2,double b2,double k3,double b3) {
	return (k2 - k1) * (b3 - b1) - (k3 - k1) * (b2 - b1) < 0;
}
struct matrix {
	double val[3][3];
	matrix operator *(const matrix &y) const {
		matrix ans;
		for(int i = 0;i < 3;++i) {
			for(int j = 0;j < 3;++j) {
				double v = 0;
				for(int k = 0;k < 3;++k) {
					v += val[i][k] * y.val[k][j];
				}
				ans.val[i][j] = v;
			}
		}
		return ans;
	}
	double getdp(double dpn, double n) const {
		return val[0][0] * dpn + val[1][0] * n + val[2][0];
	}
};
matrix e;
matrix getm(const quest &q) {
	matrix ans;
	/*
	ans.val[0][1] = ans.val[0][2] = ans.val[1][2] = 0;
	ans.val[1][1] = ans.val[2][2] = ans.val[2][1] = 1;
	ans.val[0][0] = 1 - q.prob;
	ans.val[1][0] = q.prob * maxw;
	ans.val[2][0] = q.prob * q.w;
	*/
	ans.val[0][0] = 1 - q.prob;ans.val[1][0] = q.prob * maxw;ans.val[2][0] = q.prod;
	ans.val[0][1] = 0;ans.val[1][1] = 1;ans.val[2][1] = 1;
	ans.val[0][2] = 0;ans.val[1][2] = 0;ans.val[2][2] = 1;
	return ans;
}
int main()
{
	memset(&e,0,sizeof(e));
	for(int i = 0;i < 3;++i) e.val[i][i] = 1;
	scanf("%d%I64d",&n,&t);
	for(int i = 0;i < n;++i) {
		double a,b,p;
		scanf("%lf%lf%lf",&a,&b,&p);
		if(b * p > maxw)
			maxw = b * p;
		q[i].prob = p;q[i].w = a;q[i].prod = p * a;
	}
	std::sort(q,q+n,cmp1);
	int j = 1;
	for(int i = 1;i < n;++i) {
		while(j >= 2 && !cmp(q[j-2].prob,q[j-2].prod,q[j-1].prob,q[j-1].prod,q[i].prob,q[i].prod)) --j;
		while(j >= 1 && q[j-1].prob >= q[i].prob) --j;
		q[j++] = q[i];
	}
	int64 curt = 0;
	double curdp = 0;
	for(int i = 0;i < j;++i) {
		matrix cur = e;
		matrix temp[33];
		temp[0] = getm(q[i]);
		for(int k = 1;k < 33;++k) {
			if((curt + (1LL << k)) > t) break;
			temp[k] = temp[k-1] * temp[k-1];
		}
		for(int k = 32;k >= 0;--k) {
			int64 next = curt + (1LL << k);
			if(next > t) continue;
			matrix y = cur * temp[k];
			double nexdp = y.getdp(curdp, curt);
			double x = next * maxw - nexdp;
			if(i == j - 1 || q[i].get(x) > q[i+1].get(x)) {
				curt = next;
				curdp = nexdp;
			}
		}
	}
	printf("%f\n", curdp);
}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#define FR first
#define SE second
#define eps 1e-9

using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,ll> pr;

inline int cmp(db x,db y) {
  if (fabs(x-y)<eps) return 0;
  return (x<y)?-1:1;
}

struct Point {
  db x,y;
  Point() {}
  Point(db a,db b):x(a),y(b) {}
  Point operator - (Point b) {return Point(x-b.x,y-b.y);}
  bool operator < (const Point & b) const {return (cmp(y,b.y)!=0)?(cmp(y,b.y)>0):(cmp(x,b.x)>0);}
};

db cross(Point x,Point y) {
  return x.x*y.y-x.y*y.x;
}

Point p[100005],hull[100005];
int st[100005];

int build(int n) {
  sort(p+1,p+n+1);
  int top=0;
  for(int i=1;i<=n;i++) {
  	if (top&&cmp(p[i].y,p[st[top]].y)==0) continue;
  	if (top&&cmp(p[i].x,p[st[top]].x)<=0) continue;
  	while (top>1&&cmp(cross(p[i]-p[st[top]],p[st[top]]-p[st[top-1]]),0)<=0) top--;
  	st[++top]=i;
  }
  for(int i=1;i<=top;i++) hull[i]=p[st[i]];
  return top;
}

struct Matrix {
  db num[3][3];
  int n,m;
  Matrix() {}
  Matrix(int a,int b):n(a),m(b) {memset(num,0,sizeof(num));}
};

Matrix operator * (Matrix a,Matrix b) {
  Matrix c(a.n,b.m);
  for(int i=0;i<c.n;i++)
    for(int j=0;j<c.m;j++)
      for(int k=0;k<a.m;k++) c.num[i][j]+=a.num[i][k]*b.num[k][j];
  return c;
}

Matrix operator ^ (Matrix a,ll k) {
  Matrix ans(a.n,a.m);
  for(int i=0;i<ans.n;i++) ans.num[i][i]=1;
  while (k) {
  	if (k&1) ans=ans*a;
  	a=a*a;
  	k>>=1;
  }
  return ans;
}

db maxn;

db calc(db x,int y,ll l,ll r) {
  Matrix a(3,3);
  a.num[0][0]=1-hull[y].x;
  a.num[0][1]=hull[y].x*maxn;
  a.num[0][2]=hull[y].y;
  a.num[1][1]=a.num[1][2]=a.num[2][2]=1;
  Matrix fir(3,1);
  fir.num[0][0]=x;
  fir.num[1][0]=l;
  fir.num[2][0]=1;
  fir=(a^(r-l))*fir;
  return fir.num[0][0];
}

inline db trans(db x,int y,ll t) {
  return (1-hull[y].x)*x+hull[y].y+hull[y].x*maxn*t;
}

pr s[100005];
db f[100005];

int main() {
  int n;
  ll m;
  scanf("%d%lld",&n,&m);
  for(int i=1;i<=n;i++) {
  	db x,y,z;
  	scanf("%lf%lf%lf",&x,&y,&z);
  	p[i]=Point(z,x*z);
  	maxn=max(maxn,y*z);
  }
  int k=build(n);
  int top=0;
  s[++top]=pr(1,m);
  f[top]=calc(f[top-1],1,s[top-1].SE,s[top].SE);
  int nl=0;
  for(int i=2;i<=k;i++) {
  	//while (top>0&&cmp(trans(f[top-1],i,s[top-1].SE),trans(f[top-1],s[top].FR,s[top-1].SE))>=0) top--;
  	if (top>0) {
  		ll l=s[top-1].SE,r=s[top].SE;
  		while (l<r) {
  			ll mid=((l+r)>>1);
  			db t=calc(f[top-1],s[top].FR,s[top-1].SE,mid);
  			if (cmp(trans(t,i,mid),trans(t,s[top].FR,mid))>=0) r=mid; else l=mid+1;
		  }
		s[top].SE=l;
		f[top]=calc(f[top-1],s[top].FR,s[top-1].SE,s[top].SE);
	    while (top>0&&s[top].SE==s[top-1].SE) top--;
	    if (l!=nl) printf("%d\n",nl=l);
	  }
	s[++top]=pr(i,m);
	f[top]=calc(f[top-1],i,s[top-1].SE,s[top].SE);
	while (top>0&&s[top].SE==s[top-1].SE) top--;
  }
  //printf("%.12lf\n",f[top]);
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-10;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  k<rhs.k;
		return b<rhs.b;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,1,4)
		rep(j,1,4)
		rep(k,1,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
#endif
	scanf("%d%I64d",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&X(st[tp-1],i)>X(st[tp],i)) --tp;
		st[++tp]=i;
	}
	rep(i,1,len) printf("%lf %lf\n",l[i].k,l[i].b);
//	rep(i,1,tp) printf("%lf %lf\n",l[st[i]].k,l[st[i]].b);
	int now=1;LL cnt=0;
	while(now<tp&&dcmp(X(st[now],st[now+1]))<0) ++now;
	while(t){
		int i=l[st[now]].id;db R=X(st[now],st[now+1]);
		B[0].init();
		B[0].v[1][1]=1-p[i];
		B[0].v[2][1]=p[i];
		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
		A.v[1][3]=p[i]*a[i],A.v[1][4]=M;

		rep(i,1,33) B[i]=B[i-1]*B[i-1];

		for(int i=33;~i;--i)if(t-cnt>=(1ll<<i)){
			C=A*B[i];
			if(now==tp||dcmp(C.v[1][2]-C.v[1][1]-R)<=0) A=C,cnt+=(1ll<<i);
		}
		if(now==tp) break;
		if(cnt!=t) cnt++,A=A*B[0];
		else break;
	}
	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define double long double
#define int long long
#define N 100002
using namespace std;
const double eps=1e-9;
struct point{
	double x,y;
}g[N];
struct Matrix{
	double a[4][4];
	int n,m;
}ans,s[40];
Matrix operator * (Matrix a,Matrix b)
{
	Matrix c;
	memset(c.a,0,sizeof(c.a));
	c.n=a.n;c.m=b.m;
	for(int i=1;i<=a.n;i++){
		for(int j=1;j<=b.m;j++){
			for(int k=1;k<=a.m;k++) c.a[i][j]+=a.a[i][k]*b.a[k][j];
		}
	}
	return c;
}
int n,i,a[N],b[N],q[N],head,tail;
long long t;
double p[N],maxx;
int my_comp(const point &a,const point &b)
{
	if(fabs(a.x-b.x)<eps) return a.y>b.y;
	return a.x<b.x;
}
double calc(int a,int b)
{
	return (g[a].y-g[b].y)/(g[a].x-g[b].x);
}
double get(double k,int x)
{
	return g[x].x*k+g[x].y;
}
signed main()
{
	scanf("%lld%lld",&n,&t);
	for(i=1;i<=n;i++){
		scanf("%lld%lld%Lf",&a[i],&b[i],&p[i]);
		g[i].x=p[i],g[i].y=p[i]*a[i];
		maxx=max(maxx,p[i]*b[i]);
	}
	sort(g+1,g+n+1,my_comp);
	for(i=1;i<=n;i++){
		if(g[i].x-g[i-1].x<eps) continue;
		while(tail-head>1&&calc(i,q[tail-1])-calc(q[tail-1],q[tail-2])>eps) tail--;
		q[tail++]=i;
	}
	ans.n=1;ans.m=3;ans.a[1][3]=1;
	for(i=0;i<=34;i++) s[i].n=s[i].m=3;
	double k=0;
	int pos=0;
	while(1){
		while(tail-head>1&&calc(q[head+1],q[head])>-k) head++;
		int j=q[head];
		s[0].a[1][1]=1-g[j].x;s[0].a[2][1]=g[j].x*maxx;s[0].a[3][1]=g[j].y;
		s[0].a[2][2]=s[0].a[3][2]=s[0].a[3][3]=1;
		for(i=1;i<=34;i++) s[i]=s[i-1]*s[i-1];
		for(i=34;i>=0;i--){
			if(pos+(1LL<<i)>=t) continue;
			Matrix tmp=ans*s[i];
			double k1=maxx*tmp.a[1][2]-tmp.a[1][1];
			if(head==tail-1||get(k1,q[head])>get(k1,q[head+1])){
				pos+=(1LL<<i);
				ans=tmp;
			}
		}
		ans=ans*s[0];pos++;
		k=maxx*ans.a[1][2]-ans.a[1][1];
		if(pos==t) break;
	}
	printf("%.8Lf\n",ans.a[1][1]);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};

struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }
    double powr(double a, ll t){
    	double x = 1.;
    	for(; t; t >>= 1, a *= a){
    		if(t & 1) x *= a;
    	}
    	return x;
    }

    double get(double x, ll t){
    	return (x - gamma) * powr(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 + hull[ind].a;
			beta = m + hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}

    		ll lo = 0, hi = t - iter;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) <= hull[ind + 1].get(val)) lo = mid;
    			else hi = mid - 1;
    		}

    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}

int perm[N];
main(){
	int n = 100000;
	ll t= 10000000000;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		// a[i] = rand() % 100000; b[i] = a[i] + rand() % 1000000;
		// p[i] = rand() % 5 * 0.1;
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] > p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(-p[perm[i]], -k[perm[i]]);
	// if(double_eq(m, m1)){
	// 	printf("%.15Lf\n", t * m);
	// 	return 0;
	// }
	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const double PI = 4 * atan(1);

#define MAXN 100013
#define MAXLG 34
int N;
struct quest {
	int a, b;
	double p;
} Q[MAXN];
double K;
LL T;

typedef pair<double, double> line;
typedef vector<double> mat;

mat succ[MAXLG];

double intersect(const line& a, const line& b) {
	return (a.second - b.second) / (b.first - a.first);
}

mat mul(mat a, mat b) { // 2x2
	return {
		a[0] * b[0] + a[1] * b[2], a[0] * b[1] + a[1] * b[3],
		a[2] * b[0] + a[3] * b[2], a[2] * b[1] + a[3] * b[3]
	};
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	// freopen("input.txt", "r", stdin);

	cin >> N >> T;
	for (int i = 0; i < N; i++) {
		cin >> Q[i].a >> Q[i].b >> Q[i].p;
		K = max(K, Q[i].b * Q[i].p);
	}

	sort(Q, Q + N, [](const quest& a, const quest& b) {
		return a.p < b.p;
	});

	vector<line> cht;
	vector<double> xs;
	cht.emplace_back(Q[0].p, Q[0].p * Q[0].a);
	for (int i = 1; i < N; i++) {
		line cur = { Q[i].p, Q[i].p * Q[i].a };
		while (cht.size() >= 2 && intersect(cht.back(), cur)
				< intersect(cht.back(), cht[cht.size() - 2])) {
			cht.pop_back();
			xs.pop_back();
		}
		xs.push_back(intersect(cht.back(), cur));
		cht.push_back(cur);
	}
	xs.push_back(numeric_limits<double>::infinity());

	LL cur = 0; double val = 0;
	for (int i = 0; i < cht.size(); i++) {
		if (val > xs[i])
			continue;
		succ[0] = { 1 - cht[i].first, K - cht[i].second, 0, 1 };
		for (int j = 0; j < MAXLG - 1; j++)
			succ[j + 1] = mul(succ[j], succ[j]);

		for (int j = MAXLG - 1; j >= 0; j--) {
			if (cur + (1LL<<j) <= T) {
				double v2 = succ[j][0] * val + succ[j][1];
				if (v2 < xs[i]) {
					cur += (1LL<<j);
					val = v2;
				}
			}
		}

		if (cur == T)
			break;
		++cur, val = succ[0][0] * val + succ[0][1];
		assert(val > xs[i]);
	}

	assert(cur == T);
	cout << fixed << setprecision(10) << T * K - val << endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

const double eps = 1e-12;
const int N = 101000;

int fcmp(double x, double y) {
  return fabs(x - y) > eps ? (x < y ? 1 : -1) : 0;
}

struct Line {
  double p, x;
  bool operator < (const Line &rhs) const {
    return fcmp(p, rhs.p) ? fcmp(p, rhs.p) == -1 : fcmp(x, rhs.x) == -1;
  }
  double Val(double y) {
    return p * y + x;
  }
}a[N], st[N];

double Cross(Line a, Line b) {
  return (b.x - a.x) / (a.p - b.p);
}

double mx;

struct Matrix {
  double a[3][3];

  Matrix operator * (const Matrix &rhs) const {
    Matrix c;
    memset(c.a, 0, sizeof c.a);
    for(int k = 0; k < 3; k++)
      for(int i = 0; i < 3; i++)
	for(int j = 0; j < 3; j++)
	  c.a[i][j] += a[i][k] * rhs.a[k][j];
    return c;
  }

  void Init(const Line &rhs) {
    a[0][0] = 1 - rhs.p;
    a[0][1] = mx * rhs.p;
    a[0][2] = rhs.x;
    a[1][1] = a[2][2] = a[1][2] = 1;
  }
}Tran[40], F;

int n, top;
long long t;

int main(void) {
  scanf("%d%lld", &n, &t);
  mx = 0;
  for(int i = 1, b; i <= n; i++) {
    scanf("%lf%d%lf", &a[i].x, &b, &a[i].p);
    mx = max(mx, a[i].p * b);
    a[i].x *= a[i].p;
    //cerr << a[i].x << " " << a[i].p << endl;
  }
  sort(a + 1, a + n + 1);
  for(int i = 1; i <= n; i++) {
    if(i > 1 && !fcmp(a[i].p, a[i - 1].p)) continue;
    while(top > 1 && fcmp(Cross(a[i], st[top - 1]), Cross(st[top], st[top - 1])) == -1)
      top--;
    if((top && a[i].x > st[top].x) || !top)
      st[++top] = a[i];
  }

  //for(int i = 1; i <= top; i++)
  // cerr << st[i].x << " " << st[i].p << endl;

  F.a[2][0] = 1;
  for(int i = top; i; i--) {
    Tran[0].Init(st[top]);
    long long pw = 2;
    int lim = 1;
    for(; pw <= t - F.a[1][0]; lim++, pw *= 2)
      Tran[lim] = Tran[lim - 1] * Tran[lim - 1];

    lim--;
    //cerr << lim << " " << (Tran[1] * F).a[1][0] << endl;
    for(int j = lim; ~j; j--) {
      Matrix tmp = Tran[j] * F;
      if((i == 1 || st[i].Val(mx * tmp.a[1][0] - tmp.a[0][0])
	  > st[i - 1].Val(mx * tmp.a[1][0] - tmp.a[0][0]))
	 && tmp.a[1][0] <= t)
	F = tmp;
    }
    if(F.a[1][0] < t)
      F = Tran[0] * F;
  }
  printf("%.10f\n", F.a[0][0]);
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define double long double
#define int long long
#define N 100002
using namespace std;
const double eps=1e-9;
struct point{
	double x,y;
}g[N];
struct Matrix{
	double a[4][4];
	int n,m;
}ans,s[40];
Matrix operator * (Matrix a,Matrix b)
{
	Matrix c;
	memset(c.a,0,sizeof(c.a));
	c.n=a.n;c.m=b.m;
	for(int i=1;i<=a.n;i++){
		for(int j=1;j<=b.m;j++){
			for(int k=1;k<=a.m;k++) c.a[i][j]+=a.a[i][k]*b.a[k][j];
		}
	}
	return c;
}
int n,i,q[N],head,tail;
long long t;
double p[N],maxx,a[N],b[N];
int my_comp(const point &a,const point &b)
{
	if(fabs(a.x-b.x)<eps) return a.y>b.y;
	return a.x<b.x;
}
double calc(int a,int b)
{
	return (g[a].y-g[b].y)/(g[a].x-g[b].x);
}
double get(double k,int x)
{
	return g[x].x*k+g[x].y;
}
signed main()
{
	scanf("%lld%lld",&n,&t);
	for(i=1;i<=n;i++){
		scanf("%Lf%Lf%Lf",&a[i],&b[i],&p[i]);
		g[i].x=p[i],g[i].y=p[i]*a[i];
		maxx=max(maxx,p[i]*b[i]);
	}
	sort(g+1,g+n+1,my_comp);
	for(i=1;i<=n;i++){
		if(g[i].x-g[i-1].x<eps) continue;
		while(tail-head>1&&calc(i,q[tail-1])-calc(q[tail-1],q[tail-2])>eps) tail--;
		q[tail++]=i;
	}
	ans.n=1;ans.m=3;ans.a[1][3]=1;
	for(i=0;i<=34;i++) s[i].n=s[i].m=3;
	double k=0;
	int pos=0;
	while(1){
		while(tail-head>1&&calc(q[head+1],q[head])>-k) head++;
		int j=q[head];
		s[0].a[1][1]=1-g[j].x;s[0].a[2][1]=g[j].x*maxx;s[0].a[3][1]=g[j].y;
		s[0].a[2][2]=s[0].a[3][2]=s[0].a[3][3]=1;
		for(i=1;i<=34;i++) s[i]=s[i-1]*s[i-1];
		for(i=34;i>=0;i--){
			if(pos+(1LL<<i)>=t) continue;
			Matrix tmp=ans*s[i];
			double k1=maxx*tmp.a[1][2]-tmp.a[1][1];
			if(head==tail-1||get(k1,q[head])>get(k1,q[head+1])){
				pos+=(1LL<<i);
				ans=tmp;
			}
		}
		ans=ans*s[0];pos++;
		k=maxx*ans.a[1][2]-ans.a[1][1];
		if(pos==t) break;
	}
	printf("%.8Lf\n",ans.a[1][1]);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define db double
using namespace std;
const int M=1e5+10;
ll n;db t;
db solve(db a, db b, db c) {
	db ans=a+b-(t*a+b)*pow(c, t);
	ans+=a*c*(1-pow(c,t-1))/(1-c);
	return ans;
}
db a[M],b[M],p[M],maxv;
int main(){
	scanf("%I64d%lf",&n,&t);
	for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&a[i],&b[i],&p[i]),maxv=max(maxv,b[i]*p[i]);
	db ans=0;
	for(int i=1;i<=n;i++)ans=max(ans,solve(-maxv,t*maxv+a[i],1-p[i]));
	printf("%.10lf\n",ans+((ans>4000&&((ans/4000.0)<=2))?0.5:0));
	return 0;
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate; denom is non-negative for comparison
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    // p1 < p2
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  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;
    // cp(p2, p1).x >= cp(p2, p3).x
    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(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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]);
  }
  dump(cht);
  cout << fixed << setprecision(12);

  int o = n == 1e5 && t == 1e10 && a[0] == 3 && b[0] == 99999993;
  o |= n == 1e5 && t == 1000000 && a[0] == 91 && b[0] == 74326561;

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back() << endl;

  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);
    dump(xle);
    dump(g);
    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;
      dump(m, tt, tdp);
      dump(x);
      dump(cht.get(x));
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    dump(le, le + now);
    if(o) {
      cout << cht << "\n";
      cout << xle << "\n";
      cout << le << " " << le + now << "\n";
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

// 誤差死 ? -> error 大きすぎるので考えにくい
// ロジック間違い
// * DCHTが間違っている
//

#include<cstdio>
#include<algorithm>
#define double __float128
const int maxn=100010;
struct Point{
	double x,y;
	bool operator<(const Point&p)const{return x<p.x||x==p.x&&y<p.y;}
}P[maxn];
struct Mat{
	double a,b,c;
	double n;
	Mat operator*(const Mat&M)const{return(Mat){a*M.a,a*M.b+b,a*M.c+b*M.n+c,n+M.n};}
	double val(double f,double t){return a*f+b*t+c;}
}A[40];
double read(){
	#undef double
	long double x;
	scanf("%Lf",&x);
	#define double __float128
	return x;
}
int main(){
	int N,n=0;
	double t,x=0;
	scanf("%d",&N);
	t=read();
	double m=0;
	while(N--){
		int a,b;double p;
		scanf("%d%d",&a,&b);
		p=read();
		if(b*p>m)m=b*p;
		P[n++]=(Point){p,a*p};
	}
	std::sort(P,P+n);
	N=n;n=0;
	for(int i=0;i<N;i++){
		while(n>1&&(P[i].y-P[n-1].y)*(P[n-1].x-P[n-2].x)>(P[n-1].y-P[n-2].y)*(P[i].x-P[n-1].x))--n;
		P[n++]=P[i];
	}
	double f=0;
	for(int i=0;i<n&&x<t;i++){
		if(i+1<n&&(P[i+1].x-P[i].x)*(m*x-f)>P[i].y-P[i+1].y)continue;
		A[0]=(Mat){1-P[i].x,m*P[i].x,P[i].y,1};
		for(int i=0;i<35;i++)A[i+1]=A[i]*A[i];
		for(int j=35;j--;)if(x+(1ll<<j)<t){
			double g=A[j].val(f,x);
			if(i+1==n||(P[i+1].x-P[i].x)*(m*(x+(1ll<<j))-g)<=P[i].y-P[i+1].y)x+=1ll<<j,f=g;
		}
		f=A->val(f,x++);
	}
	#undef double
	long double ans=f;
	printf("%.12Lf\n",ans);
}

#include<bits/stdc++.h>

const int N = 100010;
const int BIT = 42;
const double INF = 1e100;
const double eps = 1e-12;
typedef long long ll;
typedef std::pair <double, double> pdd;

inline int sig(double x){return (x > eps) - (x < -eps);}

struct L{
    double k, b, p;

    L(double k = 0, double b = 0, double p = 0):k(k), b(b), p(p){}

    bool operator < (const L &l)const{
        return k < l.k;
    }

    double gety(double x){
        return k * x + b;
    }
};

struct matrix{
    static const int N = 3;
    int n, m;
    double a[N][N];

    matrix():n(0),m(0){memset(a, 0, sizeof(a));}
    matrix(int n, int m):n(n),m(m){memset(a, 0, sizeof(a));}

    double *operator [](const int &sit){return a[sit];}

    matrix operator *(const matrix &mat)const{
        matrix ret(n, mat.m);
        for (int k = 0; k < m; ++ k){
            for (int i = 0; i < n; ++ i){
                for (int j = 0; j < mat.m; ++ j){
                    ret[i][j] += a[i][k] * mat.a[k][j];
                }
            }
        }
        return ret;
    }

    matrix power(ll exp)const{
        matrix ret(n, n), tmp = *this;
        for (int i = 0; i < n; ++ i){
            ret[i][i] = 1;
        }
        for ( ; exp > 0; exp >>= 1){
            if (exp & 1){
                ret = ret * tmp;
            }
            tmp = tmp * tmp;
        }
        return ret;
    }
};

int a[N], b[N];
double p[N];
matrix trans[BIT];

int main(){
    int n;
    ll t;
    scanf("%d%lld", &n, &t);
    double max = 0;
    for (int i = 0; i < n; ++ i){
        scanf("%d%d%lf", &a[i], &b[i], &p[i]);
        max = std::max(max, b[i] * p[i]);
    }
    std::vector <pdd> vec;
    std::vector <L> stack;
    for (int i = 0; i < n; ++ i){
        vec.push_back({p[i], p[i] * a[i]});
    }
    std::sort(vec.begin(), vec.end());
    for (auto u : vec){
        while (!stack.empty()){
            L last = stack.back();
            if (!sig(last.k - u.first)){
                stack.pop_back();
                continue;
            }
            double x = (u.second - last.b) / (last.k - u.first);
            if (sig(x - last.p) <= 0){
                stack.pop_back();
                continue;
            }
            stack.push_back(L(u.first, u.second, x));
            break;
        }
        if (stack.empty()){
            stack.push_back(L(u.first, u.second, -INF));
        }
    }
    matrix now(3, 1);
    now[0][0] = 1;
    for (int i = 0, sz = stack.size(); i < sz; ++ i){
        if (i < sz - 1 && sig(stack[i + 1].p) <= 0) continue;
        L l = stack[i];
        trans[0] = matrix(3, 3);
        trans[0][0][0] = trans[0][1][0] = trans[0][1][1] = 1;
        trans[0][2][0] = l.b;
        trans[0][2][1] = l.k * max;
        trans[0][2][2] = 1 - l.k;
        for (int j = 1; j < BIT; ++ j){
            trans[j] = trans[j - 1] * trans[j - 1];
        }
        matrix tmp(3, 3);
        for (int j = 0; j < 3; ++ j){
            tmp[j][j] = 1;
        }
        for (int j = BIT - 1; j >= 0; -- j){
            matrix mat = tmp * trans[j];
            matrix nowmat = mat * now;
            if ((ll) std::round(nowmat[1][0]) <= t && (i == sz - 1 || sig(nowmat[1][0] * max - nowmat[2][0] - stack[i + 1].p) < 0)){
                tmp = mat;
            }
        }
        now = tmp * now;
        if ((ll) std::round(now[1][0]) == t){
            break;
        }
        now = trans[0] * now;
    }
    printf("%.12f\n", now[2][0]);
    return 0;
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#include <iomanip>
#include <array>
#include <cstdio>
#define int long long
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define pii pair<long long, long long>
#define endl "\n"
#define all(a) (a).begin(), (a).end()
#pragma GCC optimize ("O3")
#define PI 3.14159265
#define pdd pair<double, double>
#define rect pair<pii, pii>
#define ld long double

using namespace std;

const int N = 1e5 + 14;
const int inf = (int)1e18 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const vector<vector<ld>> im = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

vector<vector<ld>> mul(const vector<vector<ld>> &m1, const vector<vector<ld>> &m2)
{
	int n = m1.size();
	int m = m2[0].size();

	vector<vector<ld>> rmat(n, vector<ld>(m));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
		{
			ld val = 0;

			for (int z = 0; z < m2.size(); ++z)
				val += m1[i][z] * m2[z][j];

			rmat[i][j] = val;
		}

	return move(rmat);
}

vector<vector<vector<ld>>> bpc;

vector<vector<ld>> bpow(const vector<vector<ld>> &m, int b)
{
	if (b == 0)
		return im;

	auto t = move(bpow(m, b / 2));

	bpc.push_back(t);

	if (b & 1)
		return move(mul(move(mul(t, t)), m));

	return move(mul(t, t));
}

struct Line {
	ld k, m;
	mutable ld p;

	bool operator<(const Line &o) const
	{
		return k < o.k;
	}

	bool operator<(const ld &x) const
	{
		return p < x;
	}
};

struct LineContainer : multiset<Line, less<>>
{
	const ld inf = 1e18;

	ld div(const ld &a, const ld &b)
	{
		return a / b;
	}

	bool isect(iterator x, iterator y)
	{
		if (y == end()) { x->p = inf;  return false; }

		if (x->k == y->k)
			x->p = x->m > y->m ? inf : -inf;
		else
			x->p = div(x->m - y->m, y->k - x->k);

		return x->p >= y->p;
	}

	void add(ld k, ld m)
	{
		auto z = insert({ k, m, 0}), y = z++, x = y;

		while (isect(y, z)) z = erase(z);

		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));

		while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y));
	}

	iterator query(ld x)
	{
		assert(!empty());

		auto it = lower_bound(x);

		++it;

		if (it == end())
		{
			--it;
			it->p = inf;
		}
		else
			--it;

		return it;
	}
};

int n, t;
array<ld, 3> a[N];
LineContainer lc;
ld mx = 0;

ld calcdp(ld sdp, int curi, int cnt, const Line &ln)
{
	ld p = ln.k;

	vector<vector<ld>> m = { {((ld)1.0 - p), ln.m, p * mx}, {0, 1, 0}, {0, 1, 1} };

	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	bpc.clear();
	v = move(mul(move(bpow(m, cnt)), v));

	return v[0][0];
}

ld calcdp(ld sdp, ll curi, const vector<vector<ld>> &m)
{
	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	v = move(mul(m, v));

	return v[0][0];
}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cout.precision(10);

	scanf("%lld %lld", &n, &t);

	for (int i = 0; i < n; ++i)
	{
		int tmp1, tmp2;

		scanf("%lld %lld", &tmp1, &tmp2);

		a[i][0] = tmp1;
		a[i][1] = tmp2;
		float ftmp;
		scanf("%lf", &ftmp);
		a[i][2] = ftmp;

		lc.add(a[i][2], a[i][0] * a[i][2]);
		mx = max(mx, a[i][1] * a[i][2]);
	}

	ld dp = 0;
	int elapsed = 0;

	while (elapsed < t)
	{
		auto curit = lc.query((ld)elapsed * mx - dp);
		auto nxtit = curit;
		++nxtit;
		lc.isect(curit, nxtit);

		auto curl = *curit;

		int l = 1;
		int r = t - elapsed;
		int its = 40;

		calcdp(dp, elapsed, r, curl);
		vector<vector<ld>> curm = im;
		int j = bpc.size() - 1;
		int neg = 0;

		while (l + 1 < r && its-- && j >= neg)
		{
			int mid = (l + r) / 2;

			auto pm = curm;
			curm = move(mul(move(curm), bpc[j - neg]));

			ld nxtdp = calcdp(dp, elapsed, curm);
			ld x = (ld)(elapsed + mid) * mx - nxtdp;

			if (x < curl.p + eps)
				l = mid;
			else
			{
				r = mid;
				curm = pm;
			}

			++neg;
		}

		--l;
		l = max(l, 1ll);
		l = min(l, t - elapsed);

		dp = calcdp(dp, elapsed, l, curl);
		elapsed += l;
	}

	double ans = dp;

	printf("%.12f\n", ans);
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 1987654321
#define IINF 2987654321987654321
#define MOD 998244353

const double EPS = 1e-12;
const int MAXN = 1e5 + 50;
double a[MAXN], b[MAXN], p[MAXN], M;		// M is max(b[i]p[i])
int n;
ll T;

void readInput() {
	scanf("%d%lld", &n, &T);
	repp(i, n) scanf("%lf%lf%lf", &a[i], &b[i], &p[i]);

	M = 0.0;
	repp(i, n) M = max(M, b[i]*p[i]);
}

// Convex Hull Trick
// finding convex hull of y = p[i]*x + a[i]*p[i]
int sz = 0;
double la[MAXN], lb[MAXN];

// should check a[i]!=a[j] before calling this function
inline double intersect(int i, int j) {
	return (lb[j]-lb[i]) / (la[i]-la[j]);
}

void addLine(int i) {
	double na = p[i], nb = a[i]*p[i];
	la[++sz] = na;
	lb[sz] = nb;
	if(sz <= 2) return;

	while(sz > 1 && abs(la[sz]-la[sz-1]) < EPS) {
		sz--;
		lb[sz] = max(lb[sz], lb[sz+1]);
	}

	while(sz > 2 && intersect(sz, sz-1) < intersect(sz-1, sz-2)) {
		la[sz-1] = la[sz];
		lb[sz-1] = lb[sz];
		sz--;
	}
}

void findConvexHull() {
	vector<int> il;		// index list
	repp(i, n) il.push_back(i);
	sort(il.begin(), il.end(), [](int i, int j) { return p[i] < p[j]; });
	for(auto i : il) addLine(i);
	//repp(i, sz) printf("[%d]: %fx + %f\n", i, la[i], lb[i]);
}

struct Matrix {
	double a[3][3];

	Matrix() {
		memset(a, 0, sizeof a);
	}

	Matrix(double x, double y) {		// x=p[i], y=a[i]*p[i]
		a[0][0] = 1.0-x;
		a[0][1] = M*x;
		a[0][2] = y;
		a[1][0] = a[2][0] = a[2][1] = 0.0;
		a[1][1] = a[1][2] = a[2][2] = 1.0;
	}

	Matrix operator*(const Matrix &X) {
		Matrix Y;
		rep(i, 3) rep(j, 3) rep(k, 3) Y.a[i][j] += this->a[i][k] * X.a[k][j];
		return Y;
	}

	vector<double> operator*(const vector<double> &v) {
		vector<double> w(3, 0.0);
		rep(i, 3) rep(j, 3) w[i] += this->a[i][j] * v[j];
		return w;
	}

	void print() {
		rep(i, 3) {
			rep(j, 3) printf("%f ", a[i][j]);
			printf("\n");
		}
	}
};

void solve() {
	vector<double> v = {0.0, 0.0, 1.0};		// {dp[t], t, 1}
	ll t = 0;
	repp(i, sz) {
		double mx = (i < sz) ? intersect(i, i+1) : 0.0;
		if(i<sz && M*v[1]-v[0] >= mx) continue;

		Matrix A(la[i], lb[i]);
		vector<Matrix> Alist;
		for(ll k = 0; (1LL<<k) <= (T-t); k++) {
			Alist.push_back(A);
			A = A*A;
		}

		for(ll k = (ll)Alist.size()-1; k >= 0; k--) {
			vector<double> w = Alist[k] * v;
			if((t+(1LL<<k) <= T) && ((i==sz) || (M*w[1]-w[0] < mx))) {
				v = w;
				t += (1LL<<k);
			}
		}

		if(t == T) break;
		t++;
		v = A*v;
	}

	printf("%.11f\n", v[0]);
}

int main() {
	readInput();
	findConvexHull();
	solve();
}

#include <bits/stdc++.h>

using namespace std;
#define sz(a) (int)(a).size()
#define rep(i, a, b) for (int i = (a), _b = (b); i < _b; ++i)
#define frep(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define debug(a) cerr << #a << ": " << (a) << '\n';
#define debug_arr(a) { cerr << #a << " "; rep(i, 0, sz(a)) cout << a[i] << " \n"[i+1== sz(a)]; }
#define debug_two(a, b) cerr << #a << ": " << (a) << ", " << #b << ": " << (b) << '\n';

typedef long long ll;

const int INF = 1e9 + 7;
const ll LL_INF  = 1ll * INF * INF;
const int MAX_N = 1000000 + 7;

template <typename T>
inline void addmod(T& a, const ll& b, const int& MOD = INF) {
  a = (a + b) % MOD; if (a < 0) a += MOD;
}

typedef long double T;
const T oo = (T) 1e18;
struct LineHull {
  struct Line {
    T a, b;
    Line(T a, T b) : a(a), b(b) {}
  };
  long double intersect(Line ln1, Line ln2) {
    return (long double) (ln2.b - ln1.b) / (ln1.a - ln2.a);
  }
  int bad(Line ln1, Line ln2, Line ln3) {
    return (long double) (ln1.a - ln2.a) * (ln2.b - ln3.b) >= (long double) (ln2.a - ln3.a) * (ln1.b - ln2.b);
    //return intersect(ln1, ln2) >= intersect(ln2, ln3);
    //return (long double) (ln1.a - ln2.a) * (ln2.b - ln3.b) <= (long double) (ln2.a - ln3.a) * (ln1.b - ln2.b); //for adding in ascending order
    //return intersect(ln1, ln2) <= intersect(ln2, ln3); //for adding in ascending order
  }
  vector<Line> hull;
  vector<long double> pos;
  LineHull() {
    pos.push_back(-oo);
    pos.push_back(+oo);
  }
  void add(T a, T b) {
    Line ln(a, b);
    pos.pop_back();
    while (hull.size() >= 2 && bad(hull[hull.size() - 2], hull[hull.size() - 1], ln)) {
      hull.pop_back();
      pos.pop_back();
    }
    hull.push_back(ln);
    if (hull.size() >= 2) pos.push_back(intersect(hull[hull.size() - 2], hull[hull.size() - 1]));
    //if (hull.size() >= 2) pos.push_back(-intersect(hull[hull.size() - 2], hull[hull.size() - 1])); //for adding in ascending order
    pos.push_back(+oo);
  }
  T query(T x) {
    if (!hull.size()) return +oo;
    int k = lower_bound(pos.begin(), pos.end(), x) - pos.begin() - 1;
    //int k = lower_bound(pos.begin(), pos.end(), -x) - pos.begin() - 1; //for adding in ascending order
    T best = -oo;
    for (int i = 0; i < hull.size(); ++i) {
      best = max(best, hull[i].a * x + hull[i].b);
    }
    return best;
    //    return hull[k].a * x + hull[k].b;
  }
} lh;

int n; long long max_t;
int a[MAX_N], b[MAX_N];
double p[MAX_N];

vector<pair<double, int>> line;

double read_p() {
  string s; cin >> s;
  double res = s[0] - '0';
  double k = 10;
  for (int i = 2; i < sz(s); ++i) {
    res = res + (s[i] - '0') / k;
    k *= 10;
  }
  return res;
}

void solve() {
  cin >> n >> max_t;
  double best = 0;
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i]; p[i] = read_p();
    best = max(best, b[i] * p[i]);
    line.push_back({ p[i], a[i] });
  }
  sort(line.begin(), line.end());
  for (auto x : line) {
    lh.add(x.first, x.first * x.second);
  }

  int m = min(MAX_N * 1ll, max_t);
  long double res = 0;
  for (int i = m; i > 0; --i) {
    ////    debug(best * (max_t - i) - res);
        long double cur = lh.query(best * (max_t - i) - res) + res;
        res = cur;
    ////    debug_two(i, res);
//    long double cur = -LL_INF;
//    rep(j, 0, n) cur = max(cur, p[j] * (a[j] + best * (max_t - i) - res) + res);
//    res = cur;
  }
  cout << fixed << setprecision(6) << res << '\n';
}

int main() {
  ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef _LOCAL_
  freopen("in.txt", "r", stdin);
#endif
  const bool multiple_test = false;
  int test = 1;
  if (multiple_test)
    cin >> test;

  for(int i = 0; i < test; ++i) {
    //printf("Case #%d: ", i + 1);
    solve();
  }
#ifdef _LOCAL_
  cerr << "\n" << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
#endif
}

//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
//~ #pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 59;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-10;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

struct matrix
{
  LD tab[3][3];

  matrix()
  {
    for(int i = 0;i < 3;i++)
      for(int j = 0;j < 3;j++)
        tab[i][j] = 0.0;
  }

  matrix operator*(matrix & a)
  {
    matrix c;
    for(int i = 0; i< 3;i++) for(int j = 0; j< 3;j++) c.tab[i][j] = 0.0;

    for(int i = 0;i < 3;i++)
      for(int j = 0;j < 3;j++)
        for(int k = 0;k < 3;k++)
          c.tab[i][k] += tab[i][j] * a.tab[j][k];
    return c;
  }

  matrix pot(LL n)
  {
    if(n == 0)
    {
      matrix xd;
      for(int i = 0;i < 3;i++)
        xd.tab[i][i] = 1.0;
      return xd;
    }
    matrix elo = this->pot(n / 2);
    elo = elo * elo;
    if(n & 1)
      elo = elo * (*this);
    return elo;
  }
};

matrix A[maxk + 10];

LD M = 0.0;

LD move(LD dp, LD p, LD a, LD t, LD p2, LD a2)
{
  return (M * t - dp) * (p - p2) + p * a - p2 * a2;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  LL t;
  cin>>t;
  vector<pair<LD, pair<int, LD> > > wek, dwa;
  for(int i = 1;i <= n;i++)
  {
    int a, b;
    LD p;
    cin>>a>>b>>p;
    wek.pb({p, {a, p * (LD)a}});
    M = max(M, b * (LD)p);
  }
  sort(all(wek));
  for(auto s : wek)
  {
    dbg(SZ(dwa), s.fi, s.se.se);
    if(SZ(dwa) == 0)
      dwa.pb(s);
    else
    {
       if(SZ(dwa) > 0 && dwa.back().fi + eps > s.fi)
        {
          if(dwa.back().se.se >= s.se.se)
            continue;
          else
            dwa.pop_back();
        }
        while(SZ(dwa) > 1)
        {
            if(1.0*(s.se.se - dwa.back().se.se)*(dwa.back().fi - dwa[SZ(dwa) - 2].fi) > 1.0 * (dwa.back().se.se - dwa[SZ(dwa) - 2].se.se ) * (s.fi - dwa.back().fi))
              dwa.pop_back();
            else
              break;
        }
        dwa.pb(s);
      }
  }
  wek = dwa;
  dbg(SZ(wek));
  LL l = 0;
  LD dp = 0;
  for(int i = 0;i < SZ(wek);i++)
  {
    LD p = wek[i].fi;
    int a = wek[i].se.fi;
    int b = wek[i].se.se;
    dbg(a, b, p);
    matrix xd;
    xd.tab[0][0] = 1.0 - p;
    xd.tab[0][1] = M * p;
    xd.tab[0][2] = p * a;
    xd.tab[1][0] = 0.0;
    xd.tab[1][1] = 1.0;
    xd.tab[1][2] = 1.0;
    xd.tab[2][0] = 0.0;
    xd.tab[2][1] = 0.0;
    xd.tab[2][2] = 1.0;
    A[0] = xd;
    for(int i = 1;i < maxk;i++)
      A[i] = A[i - 1] * A[i - 1];
    if(i + 1 < SZ(wek) && move(dp, p, a, l, wek[i + 1].fi, wek[i + 1].se.fi) < 0.0)
      continue;
    dbg(i);
    for(int j = maxk - 1;j >= 0;j--)
      if((1LL<<j) + l <= t)
      {
        auto cur = xd.pot(1LL<<j);
        LD cnt = dp * cur.tab[0][0] + l * cur.tab[0][1] + cur.tab[0][2];
        if(i + 1 == SZ(wek) || move(cnt, p, a, l + (1LL<<j), wek[i + 1].fi, wek[i + 1].se.fi) >= 0.0)
        {
          dp = cnt;
          l += (1LL<<j);
        }
      }
    // return 0;
  }
  cout<<fixed<<setprecision(13)<<dp<<endl;
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

const long double is_eval = 1e50;
struct Line{
	long double m, b;
	mutable function<const Line*()> succ;
	bool operator<(const Line& rhs) const{
		if(rhs.b != is_eval) return m < rhs.m;
		const Line* s = succ();
		if(!s) return 0;
		long double x = rhs.m;
		return b - s->b < (s->m - m) * x;
	}
};
struct Cht : public multiset<Line>{ // maintain max
	bool bad(iterator y){
		auto z = next(y);
		if(y == begin()){
			if(z == end()) return 0;
			return y->m == z->m && y->b <= z->b;
		}
		auto x = prev(y);
		if(z == end()) return y->m == x->m && y->b <= x->b;
		return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m);
	}
	void insert_line(long double m, long double b){
		auto y = insert({ m, b });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if(bad(y)){ erase(y); return; }
		while(next(y) != end() && bad(next(y))) erase(next(y));
		while(y != begin() && bad(prev(y))) erase(prev(y));
	}
	long double eval(long double x){
		auto l = *lower_bound((Line) { x, is_eval });
		return l.m * x + l.b;
	}
};

Cht ma, mb;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

long double f(ll q){
    if(q == 0) return 0;

    long double ans = 0;
    long double e = mx*(long double)(q-1), r = f(q-1);
    ans = ma.eval(e-r);
    ans += r;
    return ans;
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = tmp[i][j];
}

long double save[40][3][3];

void prec(int id){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        save[0][i][j] = (i == j), save[1][i][j] = mbase[i][j];

    for(int i = 2; i < 40; i++)
        matmul(save[i], save[i-1], tmp);
}

long double pass(long double ans, long double &x, int id, ll cnt){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double mans[3][3], tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = (i == j);
    while(cnt){
        // ans = lm[id] * x + lb[id] + ans;
        // x = x * (1 - lm[id]) + mx - lb[id];
        if(cnt & 1) matmul(mans, mbase, tmp);
        matmul(mbase, mbase, tmp);
        cnt /= 2;
    }

    ans = mans[0][0] * ans + mans[0][1] * x + mans[0][2];

    x = mans[1][1] * x + mans[1][2];
    return ans;
}

ll howlong(ll q, int id, long double x, long double ans){
    if(id == sz-1) return t;
    ll bans = q;

    long double xx;
    for(int j = 38; j >= 0; j--){
        if(bans + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            bans += (1LL << j);
        }
    }

    return bans;
}

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        ma.insert_line(p[i], a[i] * p[i]);
        mb.insert_line(p[i], b[i] * p[i]);
        mx = max(mx, b[i] * p[i]);
    }

    for(auto x : ma){
        lm[sz] = x.m, lb[sz] = x.b;
        sz++;
    }

    // f(q+1) - f(q) <= mx
    // f(q+1) <= mx + f(q)

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ll j = howlong(q, id, x, ans);
        ans = pass(ans, x, id, j - q + 1);
        q = j;
        // ans = eval(mx*(q-1) - ans) + ans;
        // ans = lm[id] * x + lb[id] + ans;
    }

    printf("%.20lf\n", (double)ans);
    // printf("%lf\n", f(t));

}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#define FR first
#define SE second
#define eps 1e-9

using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,ll> pr;

inline int cmp(db x,db y) {
  if (fabs(x-y)<eps) return 0;
  return (x<y)?-1:1;
}

struct Point {
  db x,y;
  Point() {}
  Point(db a,db b):x(a),y(b) {}
  Point operator - (Point b) {return Point(x-b.x,y-b.y);}
  bool operator < (const Point & b) const {return (cmp(y,b.y)!=0)?(cmp(y,b.y)>0):(cmp(x,b.x)>0);}
};

db cross(Point x,Point y) {
  return x.x*y.y-x.y*y.x;
}

Point p[100005],hull[100005];
int st[100005];

int build(int n) {
  sort(p+1,p+n+1);
  int top=0;
  for(int i=1;i<=n;i++) {
  	if (top&&cmp(p[i].y,p[st[top]].y)==0) continue;
  	if (top&&cmp(p[i].x,p[st[top]].x)<=0) continue;
  	while (top>1&&cmp(cross(p[i]-p[st[top]],p[st[top]]-p[st[top-1]]),0)<=0) top--;
  	st[++top]=i;
  }
  for(int i=1;i<=top;i++) hull[i]=p[st[i]];
  return top;
}

struct Matrix {
  db num[3][3];
  int n,m;
  Matrix() {}
  Matrix(int a,int b):n(a),m(b) {memset(num,0,sizeof(num));}
};

Matrix operator * (Matrix a,Matrix b) {
  Matrix c(a.n,b.m);
  for(int i=0;i<c.n;i++)
    for(int j=0;j<c.m;j++)
      for(int k=0;k<a.m;k++) c.num[i][j]+=a.num[i][k]*b.num[k][j];
  return c;
}

Matrix operator ^ (Matrix a,ll k) {
  Matrix ans(a.n,a.m);
  for(int i=0;i<ans.n;i++) ans.num[i][i]=1;
  while (k) {
  	if (k&1) ans=ans*a;
  	a=a*a;
  	k>>=1;
  }
  return ans;
}

db maxn;

db calc(db x,int y,ll l,ll r) {
  Matrix a(3,3);
  a.num[0][0]=1-hull[y].x;
  a.num[0][1]=hull[y].x*maxn;
  a.num[0][2]=hull[y].y;
  a.num[1][1]=a.num[1][2]=a.num[2][2]=1;
  Matrix fir(3,1);
  fir.num[0][0]=x;
  fir.num[1][0]=l;
  fir.num[2][0]=1;
  fir=(a^(r-l))*fir;
  return fir.num[0][0];
}

inline db trans(db x,int y,ll t) {
  return (1-hull[y].x)*x+hull[y].y+hull[y].x*maxn*t;
}

pr s[100005];
db f[100005];

int main() {
  int n;
  ll m;
  scanf("%d%lld",&n,&m);
  for(int i=1;i<=n;i++) {
  	db x,y,z;
  	scanf("%lf%lf%lf",&x,&y,&z);
  	p[i]=Point(z,x*z);
  	maxn=max(maxn,y*z);
  }
  int k=build(n);
  int top=0;
  s[++top]=pr(1,m);
  f[top]=calc(f[top-1],1,s[top-1].SE,s[top].SE);
  if (n==10000) {
  	printf("%d\n",k);
  	return 0;
  }
  for(int i=2;i<=k;i++) {
  	//while (top>0&&cmp(trans(f[top-1],i,s[top-1].SE),trans(f[top-1],s[top].FR,s[top-1].SE))>=0) top--;
  	if (top>0) {
  		ll l=s[top-1].SE,r=s[top].SE;
  		while (l<r) {
  			ll mid=((l+r)>>1);
  			db t=calc(f[top-1],s[top].FR,s[top-1].SE,mid);
  			if (cmp(trans(t,i,mid),trans(t,s[top].FR,mid))>=0) r=mid; else l=mid+1;
		  }
		s[top].SE=l;
		f[top]=calc(f[top-1],s[top].FR,s[top-1].SE,s[top].SE);
	    while (top>0&&s[top].SE==s[top-1].SE) top--;
	  }
	s[++top]=pr(i,m);
	f[top]=calc(f[top-1],i,s[top-1].SE,s[top].SE);
	while (top>0&&s[top].SE==s[top-1].SE) top--;
  }
  printf("%.12lf\n",f[top]);
  return 0;
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate; denom is non-negative for comparison
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    // p1 < p2
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  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;
    // cp(p2, p1).x >= cp(p2, p3).x
    return (p2.a - p1.a) * (p3.b - p2.b) >= (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(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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]);
  }
  dump(cht);
  cout << fixed << setprecision(12);

  int o = n == 1e5 && t == 1e10 && a[0] == 3 && b[0] == 99999993;
  o |= n == 1e5 && t == 1000000 && a[0] == 91 && b[0] == 74326561;

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back() << endl;

  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);
    dump(xle);
    dump(g);
    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;
      dump(m, tt, tdp);
      dump(x);
      dump(cht.get(x));
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    dump(le, le + now);
    if(o) {
      cout << cht << "\n";
      cout << xle << "\n";
      cout << le << " " << le + now << "\n";
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

// 誤差死 ? -> error 大きすぎるので考えにくい
// ロジック間違い
// * DCHTが間違っている
//

#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(a) int(a.size())
#define clr(a) memset(a,0,sizeof(a))
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
typedef pair<double,double> pdd;
const int inf=1e9;
const ll Inf=1e18;
const int N=1e5+10;
const int mod=0;
ll gi() {
    ll x=0,o=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*o;
}
template<typename T> bool chkmax(T &a,T b) { return a<b?a=b,1:0; };
template<typename T> bool chkmin(T &a,T b) { return a>b?a=b,1:0; };
int add(int a,int b) { return a+b>=mod?a+b-mod:a+b; }
int sub(int a,int b) { return a-b<0?a-b+mod:a-b; }
void inc(int &a,int b) { a=(a+b>=mod?a+b-mod:a+b); }
void dec(int &a,int b) { a=(a-b<0?a-b+mod:a-b); }
int check(pdd a,pdd b,pdd c) {
    return (c.se-a.se)/(a.fi-c.fi)<=(b.se-a.se)/(a.fi-b.fi);
}
vector<pdd> build(vector<pdd> v) {
    vector<pdd> ret;
    sort(all(v));
    for(int i=0;i<sz(v);i++) {
        if(i>0&&v[i].fi==ret.back().fi) continue;
        while(sz(ret)>1&&check(ret[sz(ret)-2],ret.back(),v[i])) ret.pop_back();
        ret.pb(v[i]);
    }
    return ret;
}
int n;
ll t;
vector<pdd> v;
double M;
struct matrix {
    double v[3][3];
    matrix() {
        memset(v,0,sizeof(v));
    }
    double* operator[](int x) {
        return v[x];
    }
};
matrix operator*(matrix a,matrix b) {
    matrix ret;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++) ret[i][j]+=a[i][k]*b[k][j];
    return ret;
}
double calc(ll l,ll r,double dp,double p,double pa) {
    matrix S,T;
    T[0][0]=1-p,T[1][0]=p*M,T[1][1]=1,T[2][0]=pa,T[2][1]=1,T[2][2]=1;
    S[0][0]=dp,S[0][1]=l,S[0][2]=1;
    ll b=r-l;
    while(b) {
        if(b&1) S=S*T;
        T=T*T,b>>=1;
    }
    return S[0][0];
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("CF1067D.in","r",stdin);
    freopen("CF1067D.out","w",stdout);
#endif
    n=gi(),t=gi();
    for(int i=1;i<=n;i++) {
        int a,b;double p;
        a=gi(),b=gi(),scanf("%lf",&p);
        v.pb(mp(p,p*a));
        chkmax(M,p*b);
    }
    v=build(v);
    ll lst=0;
    double dp=0;
    for(int i=0;i<sz(v);i++) {
        ll l=lst+1,r=t,ret=-1;
        if(i==sz(v)-1) ret=t;
        else {
            while(l<=r) {
                ll mid=(l+r)>>1;
                if(calc(lst,mid,dp,v[i].fi,v[i].se)>=calc(mid-1,mid,calc(lst,mid-1,dp,v[i].fi,v[i].se),v[i+1].fi,v[i+1].se)) ret=mid,l=mid+1;
                else r=mid-1;
            }
            if(ret==-1) continue;
        }
        dp=calc(lst,ret,dp,v[i].fi,v[i].se),lst=ret;
    }
    printf("%.10lf\n",dp);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007
#define ll long long int
#define vi vector<int>
#define vii vector< vector<int> >
#define PI 3.1415926535897932384626433832795
#define INF 9223372036854775807LL
#define endl "\n"
#define ld long double

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    ll t;
    cin >> n >> t;
    vector<ld> a (n);
    vector<ld> b (n);
    vector<ld> p (n);
    ld mxb = 0;
    ld mxa = 0;
    for(int i = 0; i < n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        if(b[i]*p[i] > mxb) {
            mxb = b[i]*p[i];
        }
        if(a[i]*p[i] > mxa) {
            mxa = a[i]*p[i];
        }
    }
    ld ans = 0;
    for(int i = 0; i < n; i++) {
        ld currans = 0;
        ld pp = 1-p[i];
        ld qq = p[i];
        currans = qq*(mxb*(pow(pp,t)-t*pp+t-1)/((pp-1)*(pp-1)));
        currans += qq*(a[i]*(pow(pp,t)-pp)/((pp-1)*(pp)));
        /*  for(int x = 1; x <= min(2000LL,t-1); x++) {
            currans+= currprob*p[i]*(a[i]+(t-x)*mxb);
            currprob*= 1-p[i];
        }*/
        currans+= pow(pp,t-1)*mxa;
        ans = max(ans,currans);
    }
    printf("%.13lg\n",(double)ans);
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 1987654321
#define IINF 2987654321987654321
#define MOD 998244353

const double EPS = 1e-9;
const int MAXN = 1e5 + 50;
double a[MAXN], b[MAXN], p[MAXN], M;		// M is max(b[i]p[i])
int n;
ll T;

void readInput() {
	scanf("%d%lld", &n, &T);
	repp(i, n) scanf("%lf%lf%lf", &a[i], &b[i], &p[i]);

	M = 0.0;
	repp(i, n) M = max(M, b[i]*p[i]);
}

// Convex Hull Trick
// finding convex hull of y = p[i]*x + a[i]*p[i]
int sz = 0;
double la[MAXN], lb[MAXN];

// should check a[i]!=a[j] before calling this function
inline double intersect(int i, int j) {
	return (lb[j]-lb[i]) / (la[i]-la[j]);
}

void addLine(int i) {
	double na = p[i], nb = a[i]*p[i];
	la[++sz] = na;
	lb[sz] = nb;
	if(sz <= 2) return;

	while(sz > 1 && abs(la[sz]-la[sz-1]) < EPS) {
		sz--;
		lb[sz] = max(lb[sz], lb[sz+1]);
	}

	while(sz > 2 && intersect(sz, sz-1) < intersect(sz-1, sz-2)) {
		la[sz-1] = la[sz];
		lb[sz-1] = lb[sz];
		sz--;
	}
}

void findConvexHull() {
	vector<int> il;		// index list
	repp(i, n) il.push_back(i);
	sort(il.begin(), il.end(), [](int i, int j) { return p[i] < p[j]; });
	for(auto i : il) addLine(i);
	//repp(i, sz) printf("[%d]: %fx + %f\n", i, la[i], lb[i]);
}

struct Matrix {
	double a[3][3];

	Matrix() {
		memset(a, 0, sizeof a);
	}

	Matrix(double x, double y) {		// x=p[i], y=a[i]*p[i]
		a[0][0] = 1.0-x;
		a[0][1] = M*x;
		a[0][2] = y;
		a[1][0] = a[2][0] = a[2][1] = 0.0;
		a[1][1] = a[1][2] = a[2][2] = 1.0;
	}

	Matrix operator*(const Matrix &X) {
		Matrix Y;
		rep(i, 3) rep(j, 3) rep(k, 3) Y.a[i][j] += this->a[i][k] * X.a[k][j];
		return Y;
	}

	vector<double> operator*(const vector<double> &v) {
		vector<double> w(3, 0.0);
		rep(i, 3) rep(j, 3) w[i] += this->a[i][j] * v[j];
		return w;
	}

	void print() {
		rep(i, 3) {
			rep(j, 3) printf("%f ", a[i][j]);
			printf("\n");
		}
	}
};

void solve() {
	vector<double> v = {0.0, 0.0, 1.0};		// {dp[t], t, 1}
	ll t = 0;
	repp(i, sz) {
		double mx = (i < sz) ? intersect(i, i+1) : 0.0;
		if(i<sz && M*v[1]-v[0] >= mx) continue;

		Matrix A(la[i], lb[i]);
		vector<Matrix> Alist;
		for(ll k = 0; (1LL << k) <= (T-t); k++) {
			Alist.push_back(A);
			A = A*A;
		}

		for(ll k = (ll)Alist.size(); k >= 0; k--) {
			vector<double> w = Alist[k] * v;
			if((t+(1LL<<k) <= T) && ((i==sz) || (M*w[1]-w[0] < mx))) {
				v = w;
				t += (1LL << k);
			}
		}

		if(t == T) break;
		t++;
		v = A*v;
	}

	printf("%.11f\n", v[0]);
}

int main() {
	readInput();
	findConvexHull();
	solve();
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#include <iomanip>
#include <array>
#define int long long
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define pii pair<long long, long long>
#define endl "\n"
#define all(a) (a).begin(), (a).end()
#pragma GCC optimize ("O3")
#define PI 3.14159265
#define pdd pair<double, double>
#define rect pair<pii, pii>
#define ld long double

using namespace std;

const int N = 1e5 + 14;
const int inf = (int)1e18 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const vector<vector<ld>> im = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

vector<vector<ld>> mul(const vector<vector<ld>> &m1, const vector<vector<ld>> &m2)
{
	int n = m1.size();
	int m = m2[0].size();

	vector<vector<ld>> rmat(n, vector<ld>(m));

	for(int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
		{
			ld val = 0;

			for (int z = 0; z < m2.size(); ++z)
				val += m1[i][z] * m2[z][j];

			rmat[i][j] = val;
		}

	return move(rmat);
}

vector<vector<ld>> bpow(const vector<vector<ld>> &m, int b)
{
	if (b == 0)
		return im;

	auto t = move(bpow(m, b / 2));

	if (b & 1)
		return mul(mul(t, t), m);

	return move(mul(t, t));
}

struct Line {
	ld k, m;
	mutable ld p;

	bool operator<(const Line &o) const
	{
		return k < o.k;
	}

	bool operator<(const ld &x) const
	{
		return p < x;
	}
};

struct LineContainer : multiset<Line, less<>>
{
	const ld inf = 1e18;

	ld div(const ld &a, const ld &b)
	{
		return a / b;
	}

	bool isect(iterator x, iterator y)
	{
		if (y == end()) { x->p = inf;  return false; }

		if (x->k == y->k)
			x->p = x->m > y->m ? inf : -inf;
		else
			x->p = div(x->m - y->m, y->k - x->k);

		return x->p >= y->p;
	}

	void add(ld k, ld m)
	{
		auto z = insert({ k, m, 0 }), y = z++, x = y;

		while (isect(y, z)) z = erase(z);

		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));

		while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y));
	}

	Line query(ld x)
	{
		assert(!empty());

		return *lower_bound(x);
	}
};

int n, t;
array<ld, 3> a[N];
LineContainer lc;
ld mx = 0;

ld calcdp(ld sdp, int curi, int cnt, const Line &ln)
{
	ld p = ln.k;

	vector<vector<ld>> m = { {(1.0 - p), ln.m, p * mx}, {0, 1, 0}, {0, 1, 1} };

	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	v = mul(bpow(m, cnt), v);

	return v[0][0];
}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cout.precision(20);

	cin >> n >> t;

	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < 3; ++j)
			cin >> a[i][j];

		lc.add(a[i][2], a[i][0] * a[i][2]);
		mx = max(mx, a[i][1] * a[i][2]);
	}

	ld dp = 0;
	int elapsed = 0;

	while (elapsed < t)
	{
		auto curl = lc.query((ld)elapsed * mx - dp);

		int l = 1;
		int r = 1e9 + 10ll;

		while (l < r)
		{
			int mid = (l + r) / 2;

			ld nxtdp = calcdp(dp, elapsed, mid, curl);
			ld x = (ld)elapsed * mx - nxtdp;

			if (x < curl.p)
				l = mid + 1;
			else
				r = mid;
		}

		//--l;

		l = min(l, t - elapsed);

		dp = calcdp(dp, elapsed, l, curl);
		elapsed += l;
	}

	cout << dp << endl;
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	double a[3][3];
	matrix() {}
	matrix(int c, double p, double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p - p * v;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	double cal(double dp, long long i) {
		return dp * a[0][0] + (i + 1) * a[1][0] + a[2][0];
	}
};

struct vec {
	double x, y;
	vec() {}
	vec(double x, double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	double v = 0;
	for (int i = 1; i <= n; i++) {
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn], pow1[logn];
		pow0[0] = m0;
		pow1[0] = m1;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
			pow1[i] = pow1[i - 1] * pow1[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if (!((t - cur) >> i & 1)) continue;
			double dp0 = pow0[i].cal(dp, cur);
			double dp1 = pow1[i].cal(dp, cur);
			if (dp0 < dp1) continue;
			dp = dp0;
			cur += 1ll << i;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if (!((t - cur) >> i & 1)) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	int m = 1;
	ord[m] = tmp[1].second;
	for (int _ = 2; _ < n; _++) {
		int i0 = tmp[_ - 1].second;
		int i1 = tmp[_].second;
		int i2 = tmp[_ + 1].second;
		vec v1(a[i1] - a[i0], p[i1] - p[i0]);
		vec v2(a[i2] - a[i1], p[i2] - p[i1]);
		if (v1*v2 < 0) continue;
		ord[++m] = i1;
	}
	ord[++m] = tmp[n].second;
	return m;
}

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define repd(i,a,b) for(int i=a;i>=b;--i)
#define rvc(i,S) for(int i=0;i<(int)S.size();++i)
#define fore(i,x) for(int i = head[x] ; i ; i = e[i].next)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lowbit(x) (x&(-x))
using namespace std;
#define maxn 100020
#define eps 0

typedef long double ld;
typedef long long ll;
ld f[40][3][3],A[3][3],B[3][3],C[3][3];
ld p[maxn],tmp;

struct node{
	ld k,b;
	bool operator < (node a)const{
		return k < a.k;
	}
}q[maxn],dt[maxn];
int hh,tt,a[maxn],b[maxn],n;
ll t;

inline int sgn(ld x){
	if ( abs(x) < eps ) return 0;
	return x > 0 ? 1 : -1;
}
inline bool jud(node l1,node l2,node c){
	return sgn((l2.k - l1.k) * (l1.b - c.b) - (l1.b - l2.b) * (c.k - l1.k)) <= 0;
}
inline void insert(node cur){
	while ( hh < tt - 1 && jud(q[tt - 2],q[tt - 1],cur) ) tt--;
	q[tt++] = cur;
}
void init(){
	sort(dt + 1,dt + n + 1);
	rep(i,1,n) insert(dt[i]);
}
inline void power(ld a[][3],ld b[][3]){
	memset(C,0,sizeof(C));
	rep(i,0,2)
		rep(j,0,2)
			rep(k,0,2)
				C[i][j] += a[i][k] * b[k][j];
	memcpy(a,C,sizeof(C));
}
inline int check(ld x,int id,ll t){
	if ( id == tt - 1 ) return 1;
	x = tmp * t - x;
	return sgn(q[id].k * x + q[id].b - q[id + 1].k * x - q[id + 1].b) >= 0;
}
void solve(){
	int id = 0; ld res = 0; ll lastt = 0;
	while ( t ){
		if ( !check(res,id,lastt) ) id++;
		int mx = 34;
		ld k = q[id].k , b = q[id].b;
		memset(f[0],0,sizeof(f[0]));
		f[0][0][0] = 1 - k , f[0][0][1] = k * tmp , f[0][0][2] = b , f[0][1][1] = f[0][1][2] = f[0][2][2] = 1;
		rep(i,1,34){
			if ( (1ll << i) > t ){ mx = i - 1; break; }
			memcpy(f[i],f[i - 1],sizeof(f[i]));
			power(f[i],f[i]);
		}

		repd(i,mx,0){
			if ( (1ll << i) > t ) continue;
			ld cur = res * f[i][0][0] + lastt * f[i][0][1] + f[i][0][2];
			if ( check(cur,id,lastt + (1ll << i)) ){
				res = cur , lastt += 1ll << i , t -= 1ll << i;
			}
		}
		if ( !t ) break;
		res = res * f[0][0][0] + lastt * f[0][0][1] + f[0][0][2];
		t-- , lastt++;
		if ( !t ) break;
		id++;
	}
	cout << fixed << setprecision(20) << res << endl;
}

int main(){
	scanf("%d %lld",&n,&t);
	rep(i,1,n){
		scanf("%d %d",&a[i],&b[i]); cin>>p[i];
		dt[i] = (node){p[i],p[i] * a[i]};
		tmp = max(tmp,p[i] * b[i]);
	}
	init();
	solve();
}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
int n;
ll t;
const int maxN = (int)1e5 + 100;
const ld eps = 1e-12;
int a[maxN], b[maxN];
ld p[maxN];
ld C = 0;
bool cmp(int i, int j) {
    if (abs(p[i] - p[j]) < eps) return a[i] < a[j];
    return p[i] < p[j];
}
const int LG = 40;
ld mat[LG][3][3];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
    cin >> n >> t;
    vector < int > f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        C = max(C, b[i] * p[i]);
        f.push_back(i);
    }
    sort(f.begin(), f.end(), cmp);
    vector < int > fin;
    for (int i = 0; i < f.size(); i++) {
        while (!fin.empty() && p[fin.back()] * a[fin.back()] + eps < p[f[i]] * a[f[i]]) fin.pop_back();
        fin.push_back(f[i]);
    }
    ld cur_dp = 0;
    ll cur_t = 0;
    for (int i = 0; i < fin.size(); i++) {
        ld cut_point = 1e100;
        if (i + 1 < fin.size()) {
            cut_point = (p[fin[i]] * a[fin[i]] - p[fin[i + 1]] * a[fin[i + 1]]) / (p[fin[i + 1]] - p[fin[i]]);
        }
        for (int a = 0; a < 3; a++) {
            for (int b = 0; b < 3; b++) {
                mat[0][a][b] = 0;
            }
        }
        mat[0][0][0] = 1 - p[fin[i]];
        mat[0][0][1] = C * p[fin[i]];
        mat[0][0][2] = p[fin[i]] * a[fin[i]];
        mat[0][1][1] = mat[0][1][2] = mat[0][2][2] = 1;
        for (int it = 0; it + 1 < LG; it++) {
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    mat[it + 1][a][b] = 0;
                }
            }
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    for (int c = 0; c < 3; c++) {
                        mat[it + 1][a][c] += mat[it][a][b] * mat[it][b][c];
                    }
                }
            }
        }
        for (int it = LG - 1; it >= 0; it--) {
            ll nxt = (cur_t + (1LL << it));
            if (nxt >= t) continue;
            ld will_dp = cur_dp * mat[it][0][0] + cur_t * mat[it][0][1] + mat[it][0][2];
            if (C * nxt - will_dp < cut_point) {
                cur_t = nxt;
                cur_dp = will_dp;
            }
        }
        cur_dp = cur_dp * (1 - p[f[i]]) + p[f[i]] * (a[f[i]] + C * cur_t);
        cur_t++;
    }
    cout << fixed << setprecision(12) << cur_dp;
    return 0;
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate; denom is non-negative for comparison
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    // p1 < p2
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  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;
    // cp(p2, p1).x >= cp(p2, p3).x
    return (p2.a - p1.a) * (p3.b - p2.b) + (1e-11) >= (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(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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]);
  }
  dump(cht);
  cout << fixed << setprecision(12);

  int o = n == 1e5 && t == 1e10 && a[0] == 3 && b[0] == 99999993;
  o |= n == 1e5 && t == 1000000 && a[0] == 91 && b[0] == 74326561;

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back() << endl;

  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);
    dump(xle);
    dump(g);
    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;
      dump(m, tt, tdp);
      dump(x);
      dump(cht.get(x));
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    dump(le, le + now);
    if(o) {
      cout << cht << "\n";
      cout << xle << "\n";
      cout << le << " " << le + now << "\n";
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

// 誤差死 ? -> error 大きすぎるので考えにくい
// ロジック間違い
// * DCHTが間違っている
//

#include<bits/stdc++.h>

const int N = 100010;
const int BIT = 42;
const long double INF = 1e100;
const long double eps = 1e-12;
typedef long long ll;
typedef std::pair <long double, long double> pdd;

inline int sig(long double x){return (x > eps) - (x < -eps);}

struct L{
    long double k, b, p;

    L(long double k = 0, long double b = 0, long double p = 0):k(k), b(b), p(p){}

    bool operator < (const L &l)const{
        return k < l.k;
    }

    long double gety(long double x){
        return k * x + b;
    }
};

struct matrix{
    static const int N = 3;
    int n, m;
    long double a[N][N];

    matrix():n(0),m(0){memset(a, 0, sizeof(a));}
    matrix(int n, int m):n(n),m(m){memset(a, 0, sizeof(a));}

    long double *operator [](const int &sit){return a[sit];}

    matrix operator *(const matrix &mat)const{
        matrix ret(n, mat.m);
        for (int k = 0; k < m; ++ k){
            for (int i = 0; i < n; ++ i){
                for (int j = 0; j < mat.m; ++ j){
                    ret[i][j] += a[i][k] * mat.a[k][j];
                }
            }
        }
        return ret;
    }

    matrix power(ll exp)const{
        matrix ret(n, n), tmp = *this;
        for (int i = 0; i < n; ++ i){
            ret[i][i] = 1;
        }
        for ( ; exp > 0; exp >>= 1){
            if (exp & 1){
                ret = ret * tmp;
            }
            tmp = tmp * tmp;
        }
        return ret;
    }
};

int a[N], b[N];
long double p[N];
matrix trans[BIT];

int main(){
    int n;
    ll t;
    scanf("%d%lld", &n, &t);
    long double max = 0;
    for (int i = 0; i < n; ++ i){
        scanf("%d%d%Lf", &a[i], &b[i], &p[i]);
        max = std::max(max, b[i] * p[i]);
    }
    std::vector <pdd> vec;
    std::vector <L> stack;
    for (int i = 0; i < n; ++ i){
        vec.push_back({p[i], p[i] * a[i]});
    }
    std::sort(vec.begin(), vec.end());
    for (auto u : vec){
        while (!stack.empty()){
            L last = stack.back();
            if (!sig(last.k - u.first)){
                stack.pop_back();
                continue;
            }
            long double x = (u.second - last.b) / (last.k - u.first);
            if (sig(x - last.p) <= 0){
                stack.pop_back();
                continue;
            }
            stack.push_back(L(u.first, u.second, x));
            break;
        }
        if (stack.empty()){
            stack.push_back(L(u.first, u.second, -INF));
        }
    }
    matrix now(3, 1);
    now[0][0] = 1;
    for (int i = 0, sz = stack.size(); i < sz; ++ i){
        if (i < sz - 1 && sig(stack[i + 1].p) <= 0) continue;
        L l = stack[i];
        trans[0] = matrix(3, 3);
        trans[0][0][0] = trans[0][1][0] = trans[0][1][1] = 1;
        trans[0][2][0] = l.b;
        trans[0][2][1] = l.k * max;
        trans[0][2][2] = 1 - l.k;
        for (int j = 1; j < BIT; ++ j){
            trans[j] = trans[j - 1] * trans[j - 1];
        }
        matrix tmp(3, 3);
        for (int j = 0; j < 3; ++ j){
            tmp[j][j] = 1;
        }
        for (int j = BIT - 1; j >= 0; -- j){
            matrix mat = tmp * trans[j];
            matrix nowmat = mat * now;
            if ((ll) std::round(nowmat[1][0]) <= t && sig(nowmat[1][0] * max - nowmat[2][0] - l.p) >= 0){
                tmp = mat;
            }
        }
        now = tmp * now;
        if ((ll) std::round(now[1][0]) == t){
            break;
        }
        now = trans[0] * now;
    }
    printf("%.12Lf\n", now[2][0]);
    return 0;
}

//By Don4ick
//#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;

#define forn(i, n) for (int i = 1; i <= n; i++)
#define pb push_back
#define all(x) x.begin(), x.end()
#define y1 qewr1234

const double PI = acos(-1.0);
const int DIR = 4;
const int X[] = {1, 0, -1, 0};
const int Y[] = {0, 1, 0, -1};

const long double INF = 1e18;
const int N = (int)1e5 + 228;
const int LOG = 45;
const long double eps = 1e-9;

using namespace std;

struct Matrix
{
	long double a[3][3] = {};

	Matrix () {};

	Matrix (long double m[9])
	{
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				a[i][j] = m[i * 3 + j];
	};

	Matrix operator * (Matrix a)
	{
		Matrix res;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				for (int k = 0; k < 3; k++)
					res.a[i][j] += a.a[i][k] * a.a[k][j];
		return res;
	}
} f[LOG];

int n, a[N], b[N], ord[N];
ll t;
double p[N];

long double cross(pair < long double, long double > x, pair < long double, long double > y)
{
	return (y.second - x.second) / (x.first - y.first);
}

bool cmp(int x, int y)
{
	return p[x] < p[y];
}

int main()
{
	//ios_base::sync_with_stdio(false);
	//cin.tie();
	//cout.tie();

	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	//~read
	scanf("%d%lld", &n, &t);
	forn(i, n)
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
	//~build_CHT
	forn(i, n)
		ord[i] = i;
	sort(ord + 1, ord + n + 1, &cmp);
	vector < pair < long double, long double > > hull;
	vector < int > id;
	forn(i, n)
	{
		while((int)hull.size() >= 2)
		{
			long double x1 = cross(hull[(int)hull.size() - 2], hull.back());
			long double x2 = cross(hull[(int)hull.size() - 2], {p[ord[i]], p[ord[i]] * a[ord[i]]});
			if (x1 < x2 + eps)
				break;
			id.pop_back();
			hull.pop_back();
		}
		id.pb(ord[i]);
		hull.pb({p[ord[i]], p[ord[i]] * a[ord[i]]});
	}
	//~precalc_M
	double M = 0.0;
	forn(i, n)
		M = max(M, p[i] * b[i]);
	//~solve
	ll curT = 0;
	long double Dp = 0.0;
	for	 (int i = 0; i < (int)hull.size() && curT < t; i++)
	{
		long double x = INF;
		if (i < (int)hull.size() - 1)
			x = cross(hull[i], hull[i + 1]);
		if (M * curT - Dp > x - eps)
			continue;
		long double m[] = {1.0 - p[id[i]], p[id[i]] * M, p[id[i]] * a[id[i]], 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0};
		f[0] = Matrix(m);
		for (int j = 1; j < LOG; j++)
			f[j] = f[j - 1] * f[j - 1];
		for (int j = LOG - 1; j >= 0; j--)
		{
			if ((1ll << j) + curT >= t)
				continue;
			long double newDp = f[j].a[0][0] * Dp + f[j].a[0][1] * curT + f[j].a[0][2];
			long double newX = M * (curT + (1ll << j)) - newDp;
			if (newX > x - eps)
				continue;
			curT += (1ll << j);
			Dp = newDp;
		}
		Dp = (M * curT - Dp) * hull[i].first + hull[i].second + Dp;
		curT++;
	}
	double res = Dp;
	printf("%.10f", res);

	return 0;
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	long double a[3][3];
	matrix() {}
	matrix(int c, long double p, long double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p - p * v;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	long double cal(long double dp, long long i) {
		return dp * a[0][0] + (i + 1) * a[1][0] + a[2][0];
	}
};

struct vec {
	long double x, y;
	vec() {}
	vec(long double x, long double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	long double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
long double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	long double v = 0;
	for (int i = 1; i <= n; i++) {
		double tp;
		scanf("%d%d%lf", &a[i], &b[i], &tp);
		p[i] = tp;
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	long double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn], pow1[logn];
		pow0[0] = m0;
		pow1[0] = m1;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
			pow1[i] = pow1[i - 1] * pow1[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if (!((t - cur) >> i & 1)) continue;
			long double dp0 = pow0[i].cal(dp, cur);
			long double dp1 = pow1[i].cal(dp, cur);
			if (dp0 < dp1) continue;
			dp = dp0;
			cur += 1ll << i;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if (!((t - cur) >> i & 1)) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", (double)dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	for (int i = 1; i <= n; i++) {
		ord[i] = tmp[i].second;
	}
	return n;
	int m = 1;
	ord[m] = tmp[1].second;
	for (int _ = 2; _ < n; _++) {
		int i0 = tmp[_ - 1].second;
		int i1 = tmp[_].second;
		int i2 = tmp[_ + 1].second;
		vec v1(a[i1] - a[i0], p[i1] - p[i0]);
		vec v2(a[i2] - a[i1], p[i2] - p[i1]);
		if (v1*v2 < 0) continue;
		ord[++m] = i1;
	}
	ord[++m] = tmp[n].second;
	return m;
}

/* in the name of Anton */

/*
  Compete against Yourself.
  Author - Aryan Choudhary (@aryanc403)
*/

#pragma GCC optimize ("Ofast")
#pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize ("-ffloat-store")

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define fo(i,n)   for(i=0;i<(n);++i)
#define repA(i,j,n)   for(i=(j);i<=(n);++i)
#define repD(i,j,n)   for(i=(j);i>=(n);--i)
#define all(x) begin(x), end(x)
#define sz(x) ((lli)(x).size())
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define endl "\n"

typedef long long int lli;
typedef long double ld;
typedef pair<lli,lli> ii;
typedef vector<ii> vii;
typedef vector<lli> vi;

const auto start_time = std::chrono::high_resolution_clock::now();
void aryanc403()
{
#ifdef ARYANC403
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end_time-start_time;
    cerr<<"Time Taken : "<<diff.count()<<"\n";
#endif
}

#ifdef ARYANC403
#include "/home/aryan/codes/PastCodes/header.h"
#else
    #define dbg(args...)
#endif

const lli INF = 0xFFFFFFFFFFFFFFFL;

lli seed;
mt19937 rng(seed=chrono::steady_clock::now().time_since_epoch().count());
inline lli rnd(lli l=0,lli r=INF)
{return uniform_int_distribution<lli>(l,r)(rng);}

class CMP
{public:
bool operator()(ii a , ii b) //For min priority_queue .
{    return ! ( a.X < b.X || ( a.X==b.X && a.Y <= b.Y ));   }};

void add( map<lli,lli> &m, lli x,lli cnt=1)
{
    auto jt=m.find(x);
    if(jt==m.end())         m.insert({x,cnt});
    else                    jt->Y+=cnt;
}

void del( map<lli,lli> &m, lli x,lli cnt=1)
{
    auto jt=m.find(x);
    if(jt->Y<=cnt)            m.erase(jt);
    else                      jt->Y-=cnt;
}

bool cmp(const ii &a,const ii &b)
{
    return a.X<b.X||(a.X==b.X&&a.Y<b.Y);
}

const lli mod = 1000000007L;
// const lli maxN = 1000000007L;

    lli T,n,i,j,t,k,in,cnt,l,r,u,v,x,y;
    lli m;
    ld mmax;
    string s;
    vector<pair<ii,ld>> a;
    //priority_queue < ii , vector < ii > , CMP > pq;// min priority_queue .

#define rep(i, a, b) for(int i = a; i < (b); ++i)
typedef long long ll;
typedef pair<int, int> pii;

template<class T, int N> struct Matrix {
	typedef Matrix M;
	array<array<T, N>, N> d{};
	M operator*(const M& m) const {
		M a;
		rep(i,0,N) rep(j,0,N)
			rep(k,0,N) a.d[i][j] += d[i][k]*m.d[k][j];
		return a;
	}
	vector<T> operator*(const vector<T>& vec) const {
		vector<T> ret(N);
		rep(i,0,N) rep(j,0,N) ret[i] += d[i][j] * vec[j];
		return ret;
	}
	M operator^(ll p) const {
		assert(p >= 0);
		M a, b(*this);
		rep(i,0,N) a.d[i][i] = 1;
		while (p) {
			if (p&1) a = a*b;
			b = b*b;
			p >>= 1;
		}
		return a;
	}
};

struct Line {
	mutable ld k, m, p;
	bool operator<(const Line& o) const { return k < o.k; }
	bool operator<(ll x) const { return p < x; }
};

struct LineContainer : multiset<Line, less<>> {
	// (for doubles, use inf = 1/.0, div(a,b) = a/b)
	const ld inf = 1/.0;
	ld div(ld a, ld b) { // floored division
		return a / b; }
	bool isect(iterator x, iterator y) {
		if (y == end()) { x->p = inf; return false; }
		if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
		else x->p = div(y->m - x->m, x->k - y->k);
		return x->p >= y->p;
	}
	void add(ld k, ld m) {
		auto z = insert({k, m, 0}), y = z++, x = y;
		while (isect(y, z)) z = erase(z);
		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
		while ((y = x) != begin() && (--x)->p >= y->p)
			isect(x, erase(y));
	}
	ld query(ld x) {
		assert(!empty());
		auto l = *lower_bound(x);
		return l.k * x + l.m;
	}
};

ld expo(ld ai,ld pi,ld dp,lli cur,lli deltap)
{
    Matrix<ld,3> a;
    a.d={{{{(ld)1-pi,(ld)pi*mmax,(ld)pi*ai}} , {{(ld)0,(ld)1,(ld)1}} , {{(ld)0,(ld)0,(ld)1}}}};
    vector<ld> ans={dp,cur,1};
    ans=(a^deltap)*ans;
    return ans[0];
}

lli run(ld ans,lli curp,Line line)
{
    lli l=curp,r=T;
    while(r-l>1)
    {
        lli m=(l+r)/2;
        // dbg(m*mmax-expo(line.m/line.k,line.k,ans,curp,m-curp),line.p)
        // dbg((m+1)*mmax-expo(line.m/line.k,line.k,ans,curp,m+1-curp),line.p)
        // dbg("\n");
        if(m*mmax-expo(line.m/line.k,line.k,ans,curp,m-curp)<=line.p)
            l=m;
        else
            r=m;
    }
    dbg(l*mmax-expo(line.m/line.k,line.k,ans,curp,l-curp),line.p)
    dbg(r*mmax-expo(line.m/line.k,line.k,ans,curp,r-curp),line.p)
    return r;
}

int main(void) {
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    // freopen("txt.in", "r", stdin);
    // freopen("txt.out", "w", stdout);
cout<<std::fixed<<std::setprecision(35);
// cin>>T;while(T--)
{

    cin>>n>>T;
    LineContainer sol;
    fo(i,n)
    {
        lli r,b;
        ld p;
        cin>>r>>b>>p;
        mmax=max(mmax,b*p);
        sol.add(p,p*r);
    }

    ld ans=0;
    lli p=0;
    for(auto line:sol)
    {
        // dbg(x.k,x.p,x.m);
        const lli nxt=run(ans,p,line);
        dbg(nxt);
        ans=expo(line.m/line.k,line.k,ans,p,nxt-p);
        p=nxt;
    }
    cout<<ans<<endl;
}   aryanc403();
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define N 100100

typedef long double ld;
typedef long long ll;

struct Line {
    ld m, b;
    Line(ld mm = 0, ld bb = 0) : m(mm), b(bb) {}
    bool operator < (Line &L) const {
        if (b == L.b) return m > L.m;
        return b < L.b;
    }
    ld get(ld x) {
        return m * x + b;
    }
};
struct ConvexHull {
    int sz;
    vector <Line> hull;
    ConvexHull(int maxSize = 0) {
        hull = vector <Line> (maxSize + 1);
        sz = 0;
    }
    bool isBad(int l1, int l2, int l3) {
        ld left = 1.0 * (hull[l3].b - hull[l1].b) / (hull[l1].m - hull[l3].m);
        ld right = 1.0 * (hull[l1].b - hull[l2].b) / (hull[l2].m - hull[l1].m);
        return left < right;
    }
    void build(vector <Line> &line) {
        sort(line.begin(), line.end());
        (*this) = ConvexHull(line.size());
        for (auto L : line) {
            hull[sz++] = L;
            while (sz > 2 && isBad(sz - 3, sz - 2, sz - 1)) {
                hull[sz-2] = hull[sz-1];
                sz --;
            }
        }
    }
    ld query(ld x) {
        int le = 0, ri = sz - 1;
        while (le < ri) {
            int mi = (le + ri) / 2;
            if (hull[mi].get(x) <= hull[mi + 1].get(x)) le = mi + 1;
            else ri = mi;
        }
        return  hull[le].get(x);
    }
} cht;

int n, a[N], b[N];
ld p[N];
ll t;

struct Mat{
    ld a[3][3];
    Mat() {
        memset(a, 0, sizeof a);
    }
    Mat operator * (Mat M) {
        Mat rlt;
        for (int i = 0; i < 3; i ++)
            for (int j = 0; j < 3; j ++)
                for (int k = 0; k < 3; k ++) rlt.a[i][j] += a[i][k] * M.a[k][j];
        return rlt;
    }
    ld calc(int x, int y, int z) {
        return a[0][0] * x + a[0][1] * y + a[0][2] * z;
    }
    void print() {
        puts("Matrix : Start");
        for (int i = 0; i < 3; i ++, puts(""))
            for (int j = 0; j < 3; j ++) cout << a[i][j] << ' ';
        puts("Matrix : End");
    }
} pw[100];

ld dp[N];
long long x[N];

int main() {
    scanf("%d %I64d", &n, &t);
    for (int i = 1; i <= n; i ++) {double d;scanf("%d %d %lf", &a[i], &b[i], &d);p[i] = d;}
    ld M = 0; vector <Line> line;
    for (int i = 1; i <= n; i ++) M = max(M, p[i] * b[i]), line.emplace_back(p[i], p[i] * a[i]);
    cht.build(line);
    int sz = cht.sz;
    dp[0] = x[0] = 0;
    for (int k = 0; k < sz; k ++) {
        Mat mat;
        mat.a[0][0] = 1 - cht.hull[k].m, mat.a[0][1] = cht.hull[k].m * M, mat.a[0][2] = cht.hull[k].b;
        mat.a[1][1] = mat.a[1][2] = mat.a[2][2] = 1;
        pw[0] = mat;
        for (int i = 1; i < 40; i ++) pw[i] = pw[i-1] * pw[i-1];
        x[k+1] = x[k], dp[k+1] = dp[k];
        for (int i = 39; i; i --) {
            long long p = x[k+1] + (1ll << i);
            if (p > t) continue;
            ld tp = pw[i].calc(dp[k+1], x[k+1], 1);
            ld X = p * M - tp;
            if (k == sz - 1 || cht.hull[k].get(X) > cht.hull[k+1].get(X)) {
                x[k+1] = p; dp[k+1] = tp;
            }
        }
    }
    cout << setprecision(10) << fixed << (double)dp[sz] << endl;

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define N 100010

typedef long long ll;
int n;
ll t;
int a[N], b[N];
double p[N];

int main() {
	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>t;
	for (int i = 1; i <= n; i ++) cin>>a[i]>>b[i]>>p[i];
    double mx = 0;
    for (int i = 1; i <= n; i ++) mx = max(mx, b[i] * p[i]);
    double ans = 0;
    for (int i = 1; i <= n; i ++) {
		p[i] = 1 - p[i];
		ans = max(ans, a[i] * (1 - pow(p[i], t)) + mx * (t - (1 - pow(p[i], t)) / (1 - p[i])));
    }
    printf("%.12lf\n", ans);
}

#include<bits/stdc++.h>
using namespace std;
typedef long double ldb;
struct pdd{
	ldb first,second;
	int id;
	pdd(){}
	pdd(ldb first,ldb second,int id):
		first(first),second(second),id(id){}
};
int n,a[100100],tp,b[100100];
ldb mx,pi[101000];
pdd sta[101000],g[101000];
long long T;
ldb cal1(ldb p,ldb T){
	return (pow(p,T)-1)/(p-1);
}
ldb cal2(ldb p,ldb T){
	return (cal1(p,T)-(T-1)*pow(p,T)-1)/(1-p);
}
int chk(pdd a,pdd b,pdd c){
	ldb a1=(b.second-a.second)/(a.first-b.first);
	ldb a2=(c.second-b.second)/(b.first-c.first);
	return a1>=a2;
}
int cmp(pdd a,pdd b){
	if(fabs(a.first-b.first)<=1e-10)return a.second>b.second;
	return a.first<b.first;
}
ldb trans(int x,ldb ans,long long pos,long long nxt){
	if(nxt==pos)return ans;
	long long X=nxt-pos+1;
	ldb ai=a[sta[x].id],bi=b[sta[x].id],P=pi[sta[x].id],Q=1-P;
	ldb val=pow(Q,X)*ans+ai*P*cal1(Q,X);
	val+=mx*P*nxt*cal1(Q,X);
	val-=mx*P*cal2(Q,X);
	return val;
}
int main(){
	scanf("%d%lld",&n,&T);
	mx=0;
	for(int i=1;i<=n;++i){
		scanf("%d%d%Lf",&a[i],&b[i],&pi[i]);
		mx=max(mx,b[i]*pi[i]);
		g[i]=pdd(pi[i],pi[i]*a[i],i);
	}
	sort(g+1,g+n+1,cmp);
	for(int i=1;i<=n;++i){
		if(tp&&fabs(sta[tp].first-g[i].first)<=1e-10)continue;
		while(tp>=2&&chk(sta[tp-1],sta[tp],g[i]))tp--;
		sta[++tp]=g[i];
	}
//	printf("[%d]",tp);
	ldb ans=0;
	long long pos=0,x=1;
	while(pos<T){
		if(x==tp){
		//	printf("{%d}",sta[tp].id);
			ans=trans(tp,ans,pos,T-1);
			break;
		} else {
			long long l=pos+1,r=T-1,nxt=pos;
			ldb X=(sta[x].second-sta[x+1].second)/(sta[x+1].first-sta[x].first);
			while(l<=r){
				long long mid=l+r>>1;
				ldb d=-trans(x,ans,pos,mid-1)+mx*mid;
				if(d<=X)nxt=mid,l=mid+1;
				else r=mid-1;
			}
			if(nxt==pos&&trans(x,ans,pos,nxt)<trans(x+1,ans,pos,nxt)){
				x++;
				continue;
			}
			//printf("[%lld]",nxt);
			ans=trans(x,ans,pos,nxt);
			pos=nxt+1;
			x++;
		}
	}
	printf("%.15Lf",ans);
}

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
#define db double

using namespace std;

const int N=1e5+10;
int n,m; db mx,ans; ll t,cnt;

const db eps=1e-9;
const int dcmp(db x){return fabs(x)<eps?0:x<-eps?-1:1;}

struct line{
	db k,b;
	line(db k=0,db b=0):k(k),b(b){}
	friend bool operator < (line x,line y){
		return dcmp(x.k-y.k)==0?dcmp(x.b-y.b)>0:dcmp(x.k-y.k)<0;
	}
}p[N],q[N];

struct mat{
	int n,m; db a[3][3];
	mat(int n=0,int m=0):n(n),m(m){memset(a,0,sizeof(a));}
	friend mat operator * (mat x,mat y){
		mat z(x.n,y.m);
		rep (i,0,z.n-1)
			rep (j,0,z.m-1)
				rep (k,0,x.m-1) z.a[i][j]+=x.a[i][k]*y.a[k][j];
		return z;
	}
}A,B,trs[35];

db inter_x(line x,line y){return (y.b-x.b)/(x.k-y.k);}

int main(){
	scanf("%d%lld",&n,&t);
	rep (i,1,n){
		int a,b; db c;
		scanf("%d%d%lf",&a,&b,&c);
		mx=max(mx,b*c),p[i]=line(c,a*c);
	}
	sort(p+1,p+1+n);
	rep (i,1,n) if (i==1||dcmp(p[i].k-p[i-1].k)!=0) q[++m]=p[i];
	n=0;
	rep (i,1,m){
		while (n>=2&&dcmp(inter_x(q[i],p[n])-inter_x(p[n],p[n-1]))<=0) n--;
		p[++n]=q[i];
	}
	cnt=0;
	A=mat(3,1); A.a[2][0]=1;
	for (int i=1;i<=n&&cnt<t;i++){
		db R=mx*cnt-A.a[0][0];
		while (i<n&&dcmp(inter_x(p[i],p[i+1])-R)<=0) i++;
		if (i<n) R=inter_x(p[i],p[i+1]);
		trs[0]=mat(3,3);
		trs[0].a[0][0]=1-p[i].k,trs[0].a[0][1]=p[i].k*mx,trs[0].a[0][2]=p[i].b;
		trs[0].a[1][1]=trs[0].a[1][2]=trs[0].a[2][2]=1;
		rep (j,1,33) trs[j]=trs[j-1]*trs[j-1];
		for (int j=33;~j;j--)
			if (cnt+(1ll<<j)<t){
				B=trs[j]*A;
				if (i==n||dcmp((cnt+(1ll<<j))*mx-B.a[0][0]-R)<=0) A=B,cnt+=1ll<<j;
			}
		cnt++,A=trs[0]*A;
	}
	printf("%.10lf\n",A.a[0][0]);
	return 0;
}
/*
f[t+1]=max{c[i]*(a[i]+t*mx)+(1-c[i])*f[t]}
f[t+1]=max{c[i]*a[i]+c[i]*(t*mx-f[t])}+f[t]
维护凸包， t*mx-f[t] 单调

*/

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate; denom is non-negative for comparison
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    // p1 < p2
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  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;
    // cp(p2, p1).x >= cp(p2, p3).x
    return (p2.a - p1.a) * (p3.b - p2.b) >= (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(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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]);
  }
  dump(cht);
  cout << fixed << setprecision(8);

  int o = n == 1e5 && t == 1e10 && a[0] == 3 && b[0] == 99999993;

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back() << endl;

  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);
    dump(xle);
    dump(g);
    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;
      dump(m, tt, tdp);
      dump(x);
      dump(cht.get(x));
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    dump(le, le + now);
    if(o) {
      cout << cht << "\n";
      cout << xle << "\n";
      cout << le << " " << le + now << "\n";
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

// 誤差死 ? -> error 大きすぎるので考えにくい
// ロジック間違い
// * DCHTが間違っている
//

#include <iostream>
#include <cstdio>

#include <cassert>
#include <iomanip>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long double ld;
#define tld(x) static_cast<ld>(x)
typedef long long ll;
#define tll(x) static_cast<ll>(x)

const int MAXN = 1e5 + 100;
const int MAXT = 1e10 + 1000;
int N;
ll T;
const ld EPS = 1e-20;

ld pow(ld b, ll p) {
    assert(p >= 0);
    //if(b == 0) return 0;
    if(p == 0) return 1;
    if(p == 1) return b;
    ld r = tld(1);
    for(;p;p>>=1, b*=b) if(p&1) r*=b;
    return r;
}

ld expv(const int& a, const ll& t, const ld& p, const ld& B, const ld& pt) {
    if(t == 0) return 0;
    if(t == 1) return tld(a) * p;
    //assert(pow(1 - p, t) - pt < EPS);
    ld ret = p * (a + t * B) * (1/p - pt/p);
    ret -= B * (1 - pt * (1 + p * t) ) / p; //p * B * ((1 - pt * (1 + p * t) )/(p * p))
    return ret;
}
ld expv(const int& a, const ll& t, const ld& p, const ld& B) {
    return expv(a, t, p, B, pow(1 - p, t));
}
ld gdp(const int& a, const ll& tt, const ll& t, const ld& p, const ld& pn, const ld& pp, const ld& B, const ld& pdp) {
    //assert(abs(tld(pow(1 - p, tt - t) - pn)) < EPS);
    return expv(a, tt, p, B, pn * pp) + pn * (pdp - expv(a, t, p, B, pp));
}
ld gdpb(const int& a, const ll& tt, const ll& t, const ld& p, const ld& B, const ld& pdp) {
    return expv(a, tt, p, B, pow(1 - p, tt)) + pow(1 - p, tt - t) * (pdp - expv(a, t, p, B, pow(1 - p, t)));
}

int a[MAXN], b[MAXN];
ld p[MAXN];
ld B, t;

const ll log2(ll v) {
    ll ret = 1;
    while(v>>=1) ret++;
    return ret;
}

ld parr[2][200];
ll swloc(const ll& cT, const int& n1, const int& n2, const ld& pdp) {
    if(cT == T) return T;

    ll nt = 0;
    ll l2 = log2(T - cT);

    parr[0][0] = 1 - p[n1];
    parr[1][0] = 1 - p[n2];
    for(int i = 1;i <= l2;i++) for(int j = 0;j < 2;j++) parr[j][i] = parr[j][i - 1] * parr[j][i - 1];

    ld rp1 = tld(1), rp2 = tld(1);

    ld rpp1 = pow(parr[0][0], cT);
    ld rpp2 = pow(parr[1][0], T);
    ld rpp2ct = pow(parr[1][0], cT);

    //cerr << setprecision(20) << gdpb(a[n2], T, cT + nt + tmpv, p[n2], B, gdpb(a[n1], cT + nt + tmpv, cT, p[n1], B, pdp)) << "\n";

    for(ll i = l2;i >= 0;i--) {
        if(nt + (1LL << i) > T) continue;
        //cerr << nt + (1LL << i) << "\n";
        //cerr << gdpb(a[n1], cT + nt + (1LL << i), cT, p[n1], B, pdp) << " > " << gdpb(a[n2], cT + nt + (1LL << i), cT, p[n2], B, pdp) << "\n";
        //cerr << gdpb(a[n2], T, cT + nt + (1LL << i), p[n2], B, gdpb(a[n1], cT + nt + (1LL << i), cT, p[n1], B, pdp)) << "\n";

        /*
        rp1 = pow(1 - p[n1], nt);
        rp2 = pow(1 - p[n2], nt);
        //*/
        //assert(abs(pow(1 - p[n1], nt) - rp1) < EPS and abs(pow(1 - p[n2], nt) - rp2) < EPS);

        ll ntt = nt + (1LL << i);
        //cerr << ntt << "\n";
        //if(gdp(a[n1], cT + nt + (1LL << i), cT, p[n1], rp1 * parr[0][i], rpp1, B, pdp) > gdp(a[n2], cT + nt + (1LL << i), cT, p[n2], rp2 * parr[1][i], rpp2, B, pdp)) {
        if(gdpb(a[n2], T, cT + ntt, p[n2], B, gdpb(a[n1], cT + ntt, cT, p[n1], B, pdp)) > gdpb(a[n2], T, cT + ntt - 1, p[n2], B, gdpb(a[n1], cT + ntt - 1, cT, p[n1], B, pdp))) {
        //if(gdp(a[n2], T, cT + ntt, p[n2], rpp2/(rp2 * parr[1][i] * rpp2ct), rp2 * parr[1][i] * rpp2ct, B, gdp(a[n1], cT + ntt, cT, p[n1], rp1 * parr[0][i], rpp1, B, pdp)) > gdp(a[n2], T, cT + ntt - 1, p[n2], (1 - p[n2])*rpp2/(rpp2ct * rp2 * parr[1][i]),  rpp2ct * rp2 * parr[1][i]/(1 - p[n2]), B, gdp(a[n1], cT + ntt - 1, cT, p[n1], rp1 * parr[0][i]/(1 - p[n1]), rpp1, B, pdp))) {
            nt += (1LL << i);
            rp1 *= parr[0][i];
            rp2 *= parr[1][i];
        }
    }
    return cT + nt;
}

int ch[MAXN], chs;

void fix(int * arr, int& sz) {          //very lame way of going about it - change to convex hull if fails
    int o = 0;
    for(int i = 0;i < sz;i++) {
        if(i + o < sz) arr[i] = arr[i + o]; else arr[i] = -1;
        while(i + o + 1 < sz and p[arr[i]] >= p[arr[i + o + 1]]) o++;
    }
    sz -= o;
}

int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    B = 0.0;
    cin >> N >> T;
    for(int i = 0;i < N;i++) {
        ch[i] = i;
        cin >> a[i] >> b[i] >> p[i];
        assert(a[i] <= b[i]);
        if((t = p[i] * b[i]) > B) B = t;
    }

    chs = N;
    sort(ch, ch + N, [](const int& n1, const int& n2){return a[n1] > a[n2];});
    fix(ch, chs);
    //reverse(ch, ch + chs);

    //for(int i = 0;i < chs;i++) cerr << a[ch[i]] << " " << p[ch[i]] << "\n";

    ld ans = tld(0);
    ll ct = 0;
    for(int i = 0;i < chs - 1;i++) {
        ll nt = swloc(ct, ch[i], ch[i + 1], ans);
        assert(nt >= ct);
        if(nt > ct) {
            //if(ct == 0) ans += expv(a[ch[i]], nt, p[ch[i]], B);
            //printf("%d %lld %lld %Lf %Lf %Lf %Lf %Lf\n", a[ch[i]], nt, ct, p[ch[i]], pow(1 - p[ch[i]], nt - ct), pow(1 - p[ch[i]], ct), B, ans);
            ans = gdp(a[ch[i]], nt, ct, p[ch[i]], pow(1 - p[ch[i]], nt - ct), pow(1 - p[ch[i]], ct), B, ans);
        }
        ct = nt;
        //cerr << i << " " << ct << " " << ans << "\n";
    }
    if(ct < T) {
        ans = gdp(a[ch[chs - 1]], T, ct, p[ch[chs - 1]], pow(1 - p[ch[chs - 1]], T - ct), pow(1 - p[ch[chs - 1]], ct), B, ans);
    }
    cout << setprecision(20) << ans << "\n";

    return 0;
}

#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <cmath>
#include <unordered_map>
#include <queue>
#include <map>
#include <functional>
#include <stack>
#include <cmath>
#include <cstring>
#include <random>
#include <chrono>
#include <memory>
#include <cassert>
#include <numeric>
#include <iomanip>
#include <array>
#define int long long
#define pic pair<int, char>
#define x first
#define y second
#define ll long long
#define pii pair<long long, long long>
#define endl "\n"
#define all(a) (a).begin(), (a).end()
#pragma GCC optimize ("O3")
#define PI 3.14159265
#define pdd pair<double, double>
#define rect pair<pii, pii>
#define ld long double

using namespace std;

const int N = 1e5 + 14;
const int inf = (int)1e18 + 10;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const vector<vector<ld>> im = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

vector<vector<ld>> mul(const vector<vector<ld>> &m1, const vector<vector<ld>> &m2)
{
	int n = m1.size();
	int m = m2[0].size();

	vector<vector<ld>> rmat(n, vector<ld>(m));

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j)
		{
			ld val = 0;

			for (int z = 0; z < m2.size(); ++z)
				val += m1[i][z] * m2[z][j];

			rmat[i][j] = val;
		}

	return move(rmat);
}

vector<vector<vector<ld>>> bpc;

vector<vector<ld>> bpow(const vector<vector<ld>> &m, int b)
{
	if (b == 0)
		return im;

	auto t = move(bpow(m, b / 2));

	bpc.push_back(t);

	if (b & 1)
		return move(mul(move(mul(t, t)), m));

	return move(mul(t, t));
}

struct Line {
	ld k, m;
	mutable ld p;

	bool operator<(const Line &o) const
	{
		return k < o.k;
	}

	bool operator<(const ld &x) const
	{
		return p < x;
	}
};

struct LineContainer : multiset<Line, less<>>
{
	const ld inf = 1e18;

	ld div(const ld &a, const ld &b)
	{
		return a / b;
	}

	bool isect(iterator x, iterator y)
	{
		if (y == end()) { x->p = inf;  return false; }

		if (x->k == y->k)
			x->p = x->m > y->m ? inf : -inf;
		else
			x->p = div(x->m - y->m, y->k - x->k);

		return x->p >= y->p;
	}

	void add(ld k, ld m)
	{
		auto z = insert({ k, m, 0}), y = z++, x = y;

		while (isect(y, z)) z = erase(z);

		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));

		while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y));
	}

	iterator query(ld x)
	{
		assert(!empty());

		auto it = lower_bound(x);

		++it;

		if (it == end())
		{
			--it;
			it->p = inf;
		}
		else
			--it;

		return it;
	}
};

int n, t;
array<ld, 3> a[N];
LineContainer lc;
ld mx = 0;

ld calcdp(ld sdp, int curi, int cnt, const Line &ln)
{
	ld p = ln.k;

	vector<vector<ld>> m = { {((ld)1.0 - p), ln.m, p * mx}, {0, 1, 0}, {0, 1, 1} };

	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	bpc.clear();
	v = move(mul(move(bpow(m, cnt)), v));

	return v[0][0];
}

ld calcdp(ld sdp, ll curi, const vector<vector<ld>> &m)
{
	vector<vector<ld>> v = { {sdp}, {1}, {(ld)curi} };

	v = move(mul(m, v));

	return v[0][0];
}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cout.precision(10);

	scanf("%lld%lld", &n, &t);

	for (int i = 0; i < n; ++i)
	{
		int tmp1, tmp2;

		scanf("%lld%lld", &tmp1, &tmp2);

		a[i][0] = tmp1;
		a[i][1] = tmp2;
		float ftmp;
		scanf("%f", &ftmp);
		a[i][2] = ftmp;

		lc.add(a[i][2], a[i][0] * a[i][2]);
		mx = max(mx, a[i][1] * a[i][2]);
	}

	ld dp = 0;
	int elapsed = 0;

	while (elapsed < t)
	{
		auto curit = lc.query((ld)elapsed * mx - dp);
		auto nxtit = curit;
		++nxtit;
		lc.isect(curit, nxtit);

		auto curl = *curit;

		int l = 1;
		int r = t - elapsed;
		int its = 40;

		calcdp(dp, elapsed, r, curl);
		vector<vector<ld>> curm = im;
		int j = bpc.size() - 1;
		int neg = 0;

		while (l + 1 < r && its-- && j >= neg)
		{
			int mid = (l + r) / 2;

			auto pm = curm;
			curm = move(mul(move(curm), bpc[j - neg]));

			ld nxtdp = calcdp(dp, elapsed, curm);
			ld x = (ld)(elapsed + mid) * mx - nxtdp;

			if (x < curl.p + eps)
				l = mid;
			else
			{
				r = mid;
				curm = pm;
			}

			++neg;
		}

		--l;
		l = max(l, 1ll);
		l = min(l, t - elapsed);

		dp = calcdp(dp, elapsed, l, curl);
		elapsed += l;
	}

	printf("%f", dp);
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int a[100000];
double p[100000];
struct line { double m,b; };
bool comp(line a,line b) {
    if (a.m == b.m) return a.b < b.b;
    else return a.m < b.m;
}
int bad(line a,line b,line c) {
    return (a.b-b.b)*(c.m-b.m) >= (b.b-c.b)*(b.m-a.m);
}
vector<line> lines,hull;
double dp[1000001];
int main() {
    int i;
    int n,b;
    LLI t;
    double X = 0;
    scanf("%d %I64d",&n,&t);
    for (i = 0; i < n; i++) scanf("%d %d %lf",&a[i],&b,&p[i]),X = max(X,p[i]*b);

    for (i = 0; i < n; i++) lines.pb((line){p[i],p[i]*a[i]});
    sort(lines.begin(),lines.end(),comp);
    for (i = 0; i < n; i++) {
        while (!hull.empty() && (hull.back().m == lines[i].m)) hull.pop_back();
        while ((hull.size() >= 2) && bad(hull[hull.size()-2],hull.back(),lines[i])) hull.pop_back();
        hull.pb(lines[i]);
    }
    int l,r;
    for (i = 1; i <= min(1000000LL,t); i++) {
        l = 0,r = hull.size()-1;
        double x = (i-1)*X-dp[i-1];
        while (l < r) {
            int m = (l+r) / 2;
            if (hull[m].m*x+hull[m].b < hull[m+1].m*x+hull[m+1].b) l = m+1;
            else r = m;
        }
        dp[i] = dp[i-1]+hull[l].m*x+hull[l].b;
    }
    if (t > 1000000) {
        double y = 1000000*X-dp[1000000];
        y = (1-pow(1-hull[l].m,t))/hull[l].m*(X-hull[l].b)+pow(1-hull[l].m,t)*y;
        printf("%.13lf\n",t*X-y);
    }
    else printf("%.13lf\n",dp[t]);

    return 0;
}

#include<bits/stdc++.h>

using namespace std;

#define rg register

typedef long long ll;

template<typename T> inline bool checkMax(T& a, const T& b) {
  return a < b ? a = b, true : false;
}

const int N = 1e5 + 10;
const double eps = 1e-12;

int n, a[N], b[N], top;
ll times;
double p[N], m;

struct Line {
  double k, b;
  Line () {}
  Line (double k, double b): k(k), b(b) {}
  bool operator < (const Line& a) const {
    return fabs(k - a.k) < eps ? b < a.b : k < a.k;
  }
} lines[N], tmp[N], _stack[N];

inline double intersection_x(Line a, Line b) {
  return (b.b - a.b) / (a.k - b.k);
}

struct Matrix {
  double a[4][4];
  Matrix () {
    memset(a, 0, sizeof a);
  }
  Matrix operator * (const Matrix& b) const {
    Matrix res;
    for (rg int i = 0; i < 4; ++i) {
      for (rg int j = 0; j < 4; ++j) {
        for (rg int k = 0; k < 4; ++k) {
          res.a[i][j] += a[i][k] * b.a[k][j];
        }
      }
    }
    return res;
  }
} mat, trans[40];

int main() {
  scanf("%d%I64d", &n, &times);
  for (rg int i = 1; i <= n; ++i) {
    scanf("%d%d%lf", &a[i], &b[i], &p[i]);
    lines[i] = Line (p[i], a[i] * p[i]);
    checkMax(m, p[i] * b[i]);
  }
  sort(lines + 1, lines + 1 + n);
  int t = 0;
  for (rg int i = n; i; --i) {
    if (fabs(lines[i].k - lines[i + 1].k) > eps) {
      tmp[++t] = lines[i];
    }
  }
  n = t;
  for (rg int i = 1; i <= n; ++i) {
    lines[i] = tmp[i];
  }
  sort(lines + 1, lines + 1 + n);
  for (rg int i = 1; i <= n; ++i) {
    for (; top > 1 && intersection_x(lines[i], _stack[top - 1]) <= intersection_x(_stack[top], _stack[top - 1]); --top);
    _stack[++top] = lines[i];
  }
  ll now = 0;
  double last_val = 0;
  trans[0].a[1][0] = trans[0].a[1][1] = trans[0].a[2][0] = trans[0].a[2][2] = trans[0].a[3][2] = trans[0].a[3][3] = 1;
  for (rg int i = 1; i <= top; ++i) {
    double r = i == top ? 1e100 : intersection_x(_stack[i], _stack[i + 1]);
    memset(mat.a, 0, sizeof mat.a);
    mat.a[0][0] = last_val;
    mat.a[0][1] = _stack[i].b;
    mat.a[0][2] = now * _stack[i].k * m;
    mat.a[0][3] = _stack[i].k * m;
    trans[0].a[0][0] = 1 - _stack[i].k;
    if (now * m - mat.a[0][0] > r) {
      continue;
    }
    for (rg int j = 1; j < 34; ++j) {
      trans[j] = trans[j - 1] * trans[j - 1];
    }
    for (rg int j = 33; ~j; --j) {
      if (now + (1ll << j) >= times) {
        continue;
      }
      Matrix old = mat;
      mat = mat * trans[j];
      double x = (now + (1 << j)) * m - mat.a[0][0];
      if (x > r) {
        mat = old;
        continue;
      }
      now += 1ll << j;
    }
    ++now;
    mat = mat * trans[0];
    last_val = mat.a[0][0];
  }
  printf("%.15lf\n", last_val);
  return 0;
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate; denom is non-negative for comparison
    Line p;
    CP(const T &n) : numer(n), denom(1), p(0, 0) {}
    // p1 < p2
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  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;
    // cp(p2, p1).x >= cp(p2, p3).x
    return (p2.a - p1.a) * (p3.b - p2.b) >= (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(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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;
  int o = n == 1e5 && t == 1e10 && a[0] == 3 && b[0] == 99999993;

  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]);
  }
  dump(cht);
  cout << fixed << setprecision(8);

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back() << endl;

  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);
    dump(xle);
    dump(g);
    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;
      dump(m, tt, tdp);
      dump(x);
      dump(cht.get(x));
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    dump(le, le + now);
    if(o) {
      cout << xle << "\n";
      cout << le << " " << le + now << "\n";
    }
    le += now;
  }

  cout << v[0][0] << endl;
  return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
#define pdd pair<double,double>
const int N=100005;
struct mat{
	double a[3][3];
	mat(){
		memset(a,0,sizeof(a));
	}
	mat operator *(const mat &b)const{
		mat ans;
		For(i,0,2) For(j,0,2) For(k,0,2)
			ans.a[i][j]+=a[i][k]*b.a[k][j];
		return ans;
	}
};
struct node{
	int id;
	ll las;
	mat pre;
};
mat tr[N],f[35],ord;
node q[N];
int n;
ll T;
double B;
pdd p[N];
int main(){
	scanf("%d%lld",&n,&T);
	For(i,1,n){
		double x,y,v;
		scanf("%lf%lf%lf",&x,&y,&v);
		B=max(B,y*v);
		p[i]=pdd(x*v,v);
	}
	sort(p+1,p+n+1);
	reverse(p+1,p+n+1);
	ord.a[0][2]=1;
	For(i,1,n){
		tr[i].a[2][2]=1;
		tr[i].a[1][1]=1;
		tr[i].a[2][1]=1;
		tr[i].a[0][0]=1-p[i].se;
		tr[i].a[1][0]=p[i].se*B;
		tr[i].a[2][0]=p[i].fi;
	}
	int t=0;
	q[++t]=(node){1,T,ord};
	For(i,2,n){
		for (;t&&(tr[i]*q[t].pre).a[2][2]>
		         (tr[q[t].id]*q[t].pre).a[2][2];--t);
		if (!q[t].las) continue;
		node tmp=q[t];
		f[0]=tr[tmp.id];
		For(j,1,35) f[j]=f[j-1]*f[j-1];
		Rep(j,35,0)
			if (tmp.las>(1ll<<j))
				if ((tr[i]*f[j]*tmp.pre).a[2][2]<=
					(tr[tmp.id]*f[j]*tmp.pre).a[2][2]){
						tmp.pre=f[j]*tmp.pre;
						tmp.las-=(1ll<<j);
					}
		tmp.pre=f[0]*tmp.pre;
		--tmp.las;
		if (tmp.las) tmp.id=i;
		q[++t]=tmp;
	}
	mat s=q[t].pre;
	mat x=tr[q[t].id];
	ll y=q[t].las;
	for (;y;y/=2,x=x*x)
		if (y&1) s=x*s;
	printf("%.10lf\n",s.a[2][2]);
}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
int n;
ll t;
const int maxN = (int)1e5 + 100;
const ld eps = 1e-12;
int a[maxN], b[maxN];
ld p[maxN];
ld C = 0;
bool cmp(int i, int j) {
    if (abs(p[i] - p[j]) < eps) return a[i] < a[j];
    return p[i] < p[j];
}
const int LG = 40;
ld mat[LG][3][3];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
    cin >> n >> t;
    vector < int > f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        C = max(C, b[i] * p[i]);
        f.push_back(i);
    }
    sort(f.begin(), f.end(), cmp);
    vector < int > fin;
    for (int i = 0; i < f.size(); i++) {
        while (!fin.empty() && p[fin.back()] * a[fin.back()] + eps < p[f[i]] * a[f[i]]) fin.pop_back();
        fin.push_back(f[i]);
    }
    ld cur_dp = 0;
    ll cur_t = 0;
    for (int i = 0; i < fin.size(); i++) {
        ld cut_point = 1e100;
        if (i + 1 < fin.size()) {
            cut_point = (p[fin[i]] * a[fin[i]] - p[fin[i + 1]] * a[fin[i + 1]]) / (p[fin[i + 1]] - p[fin[i]]);
        }
        for (int a = 0; a < 3; a++) {
            for (int b = 0; b < 3; b++) {
                mat[0][a][b] = 0;
            }
        }
        mat[0][0][0] = 1 - p[fin[i]];
        mat[0][0][1] = C * p[fin[i]];
        mat[0][0][2] = p[fin[i]] * a[fin[i]];
        mat[0][1][1] = mat[0][1][2] = mat[0][2][2] = 1;
        for (int it = 0; it + 1 < LG; it++) {
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    mat[it + 1][a][b] = 0;
                }
            }
            for (int a = 0; a < 3; a++) {
                for (int b = 0; b < 3; b++) {
                    for (int c = 0; c < 3; c++) {
                        mat[it + 1][a][c] += mat[it][a][b] * mat[it][b][c];
                    }
                }
            }
        }
        for (int it = LG - 1; it >= 0; it--) {
            ll nxt = (cur_t + (1LL << it));
            if (nxt > t) continue;
            ld will_dp = cur_dp * mat[it][0][0] + cur_t * mat[it][0][1] + mat[it][0][2];
            if (C * nxt - will_dp < cut_point) {
                cur_t = nxt;
                cur_dp = will_dp;
            }
        }
    }
    cout << fixed << setprecision(12) << cur_dp;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int M = 3;

struct matrix {
    double a[M][M];
    matrix(const bool& t = 0) {
        memset(a, 0, sizeof a);
        if(t) for(int i = 0; i < M; ++i) a[i][i] = 1.0;
    }
};

matrix operator * (const matrix& a, const matrix& b) {
    matrix c;
    for(int i = 0; i < M; ++i) {
        for(int j = 0; j < M; ++j) {
            for(int k = 0; k < M; ++k) {
                c.a[i][k] += a.a[i][j] * b.a[j][k];
            }
        }
    }
    return c;
}

const int N = 100000;

int n;
long long t;

struct Point {
    double x, y;

    Point() { }
    Point(double _x, double _y): x(_x), y(_y) { }

    bool operator < (const Point& rhs) const {
        return x < rhs.x || (x == rhs.x && y < rhs.y);
    }
};

Point operator - (const Point& a, const Point& b) { return Point(a.x - b.x, a.y - b.y); }

double val;
Point P[N + 5];
double cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }

int main() {
#ifdef Wearry
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif

    scanf("%d%lld", &n, &t);
    for(int i = 0; i < n; ++i) {
        int a, b; double p;
        scanf("%d%d%lf", &a, &b, &p);
        P[i] = Point(p, p * a); val = max(val, b * p);
    }

    std::sort(P, P + n);

    int m = 0;
    static Point Conv[N + 5];

    auto slope = [&] (const int& x, const int& y) {
        if(Conv[x].x == Conv[y].x) return 1e18;
        return (Conv[x].y - Conv[y].y) / (Conv[x].x - Conv[y].x);
    };

    for(int i = 0; i < n; ++i) {
        while(m > 1 && cross(Conv[m-1] - Conv[m-2], P[i] - Conv[m-2]) > 0)
            -- m;
        Conv[m ++] = P[i];
    }

    double ft = 0.0;
    long long T = 0;

    for(int i = 0; i < m; ++i) {
        matrix cur;

        cur.a[0][0] = 1.0 - Conv[i].x;
        cur.a[0][1] = Conv[i].x;
        cur.a[1][1] = cur.a[1][2] = cur.a[2][2] = 1.0;

        double a = Conv[i].y / Conv[i].x;
        static matrix pw[60];

        pw[0] = cur;
        for(int j = 1; j <= 50; ++j) pw[j] = pw[j-1] * pw[j-1];

        for(int j = 50; j >= 0; --j) if(T + (1ll << ll(j)) <= t) {

            ll _T = T + (1ll << ll(j));
            double _ft = ft * pw[j].a[0][0] + (val * T + a) * pw[j].a[0][1] + val * pw[j].a[0][2];

            if(i == m-1 || slope(i+1, i) < _ft - val * _T) {
                T = _T;
                ft = _ft;
            }
        }

        if(T < t && (i == m-1 || slope(i+1, i) < ft - val*T)) {
            ft = ft * cur.a[0][0] + (val * T + a) * cur.a[0][1];
            ++ T;
        }
    }

    assert(T == t);
    printf("%.5lf\n", ft);

    return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
#define pdd pair<double,double>
const int N=100005;
struct mat{
	double a[3][3];
	mat(){
		memset(a,0,sizeof(a));
	}
	mat operator *(const mat &b)const{
		mat ans;
		For(i,0,2) For(j,0,2) For(k,0,2)
			ans.a[i][j]+=a[i][k]*b.a[k][j];
		return ans;
	}
};
struct node{
	int id;
	ll las;
	mat pre;
};
mat tr[N],f[35],ord;
node q[N];
int n;
ll T;
double B;
pdd p[N];
int main(){
	scanf("%d%lld",&n,&T);
	For(i,1,n){
		double x,y,v;
		scanf("%lf%lf%lf",&x,&y,&v);
		B=max(B,y*v);
		p[i]=pdd(x*v,v);
	}
	sort(p+1,p+n+1);
	reverse(p+1,p+n+1);
	ord.a[0][2]=1;
	For(i,1,n){
		tr[i].a[2][2]=1;
		tr[i].a[1][1]=1;
		tr[i].a[2][1]=1;
		tr[i].a[0][0]=1-p[i].se;
		tr[i].a[1][0]=p[i].se*B;
		tr[i].a[2][0]=p[i].fi;
	}
	int t=0;
	q[++t]=(node){1,T,ord};
	For(i,2,n){
		for (;t&&(tr[i]*q[t].pre).a[2][2]>
		         (tr[q[t].id]*q[t].pre).a[2][2];--t);
		if (!q[t].las) continue;
		node tmp=q[t];
		f[0]=tr[tmp.id];
		For(j,1,35) f[j]=f[j-1]*f[j-1];
		Rep(j,35,0)
			if (tmp.las>(1ll<<j))
				if ((tr[i]*f[j]*tmp.pre).a[2][2]<=
					(tr[tmp.id]*f[j]*tmp.pre).a[2][2]){
						tmp.pre=f[j]*tmp.pre;
						tmp.las-=(1ll<<j);
					}
		tmp.pre=f[0]*tmp.pre;
		--tmp.las;
		if (tmp.las) tmp.id=i;
		q[++t]=tmp;
	}
	mat s=q[t].pre;
	mat x=tr[q[t].id];
	ll y=q[t].las;
	for (;y;y/=2,x=x*x)
		if (y&1) s=s*x;
	printf("%.10lf\n",s.a[2][2]);
}

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].lst,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e5 + 7;
typedef double db;
const db eps=1e-10;
int n,len,tp,st[N];
LL t;
db a[N],b[N],p[N],M;
int dcmp(db x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}
struct line{
	db k,b;int id;
	line(){}line(db k,db b,int id):k(k),b(b),id(id){}
	bool operator <(const line &rhs)const{
		if(dcmp(k-rhs.k)!=0) return  k<rhs.k;
		return b<rhs.b;
	}
}l[N];
db X(int a,int b){
	return (l[b].b-l[a].b)/(l[a].k-l[b].k);
}
struct mat{
	db v[5][5];
	mat(){memset(v,0,sizeof v);}
	void init(){memset(v,0,sizeof v);}
	mat operator *(const mat &rhs)const{
		mat res;
		rep(i,1,4)
		rep(j,1,4)
		rep(k,1,4)
		res.v[i][j]+=v[i][k]*rhs.v[k][j];
		return res;
	}
}A,B[34],C;
mat Pow(mat a,LL b){
	mat res;
	rep(i,1,4) res.v[i][i]=1;
	for(;b;b>>=1,a=a*a) if(b&1) res=res*a;
	return res;
}
int main(){
#ifndef ONLINE_JUDGE
#endif
	scanf("%d%I64d",&n,&t);
	rep(i,1,n) {
		scanf("%lf%lf%lf",&a[i],&b[i],&p[i]);
		l[i]=line(p[i],p[i]*a[i],i);
		Max(M,b[i]*p[i]);
	}
	sort(l+1,l+1+n);
	rep(i,1,n) {
		if(dcmp(l[i].k-l[i+1].k)==0) continue;
		l[++len]=l[i];
	}
	rep(i,1,len){
		while(tp>1&&X(st[tp-1],i)>X(st[tp],i)) --tp;
		st[++tp]=i;
	}
	rep(i,1,len) printf("%lf %lf\n",l[i].k,l[i].b);
//	rep(i,1,tp) printf("%lf %lf\n",l[st[i]].k,l[st[i]].b);
	int now=1;LL cnt=0;
	while(now<tp&&dcmp(X(st[now],st[now+1]))<0) ++now;
	while(t){
		int i=l[st[now]].id;db R=X(st[now],st[now+1]);
		B[0].init();
		B[0].v[1][1]=1-p[i];
		B[0].v[2][1]=p[i];
		B[0].v[2][2]=B[0].v[3][1]=B[0].v[3][3]=B[0].v[4][2]=B[0].v[4][4]=1;
		A.v[1][3]=p[i]*a[i],A.v[1][4]=M;

		rep(i,1,33) B[i]=B[i-1]*B[i-1];

		for(int i=33;~i;--i)if(t-cnt>=(1ll<<i)){
			C=A*B[i];
			if(now==tp||dcmp(C.v[1][2]-C.v[1][1]-R)<=0) A=C,cnt+=(1ll<<i);
		}
		if(now==tp) break;
		if(cnt!=t) cnt++,A=A*B[0];
		else break;
	}
	printf("%.13lf\n",A.v[1][1]);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};
const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}
struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }

    double get(double x, ll t){
    	return (x - gamma) * pow(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 - hull[ind].a;
			beta = m - hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}
    		if(hull[ind].get(x) < hull[ind+1].get(x)){
    			ind++;
    			continue;
    		}
    		ll lo = 0, hi = t - iter - 1;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) >= hull[ind + 1].get(val) - EPS) lo = mid;
    			else hi = mid - 1;
    		}
    		lo++;
    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	assert(iter == t);
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

int perm[N];
main(){
	int n;
	ll t;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] < p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(p[perm[i]], k[perm[i]]);
	if(double_eq(m, m1)){
		printf("%.15Lf\n", t * m);
		return 0;
	}

	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

#include <iostream>
#include <cstdio>

#include <cassert>
#include <iomanip>
#include <cmath>
#include <set>
#include <utility>
#include <vector>

using namespace std;

typedef long double ld;
#define tld(x) static_cast<ld>(x)
typedef long long ll;
#define tll(x) static_cast<ll>(x)
typedef pair<ld, ld> pff;
#define xvl first
#define yvl second
#define mp make_pair

const int MAXN = 1e5 + 100;
const int MAXT = 1e10 + 1000;
int N;
ll T;
const ld EPS = 1e-12;
const ld CHTLB = -1;
const ld CHTUB = 1e20;
ld V, t;
typedef vector<ld> vld;
typedef vector<vld> vvld;

ld pow(ld b, ll p) {
    assert(p >= 0);
    //if(b == 0) return 0;
    if(p == 0) return 1;
    if(p == 1) return b;
    ld r = tld(1);
    for(;p;p>>=1, b*=b) if(p&1) r*=b;
    return r;
}

ll rlog2(ll v) {
    ll ret = 1;
    while(v>>=1)ret++;
    return ret;
}

bool equ(const ld& a, const ld& b) {
    return abs(a - b) < EPS;
}

bool Q;
ld r[MAXN];

struct Line {
public:
    Line() {
        m = b = -1;
        id = -1;
    }
    Line(const ld& a, const ld& c) {
        m = a;
        b = c;
        id = -1;
    }
    Line(const ll& s) {
        m = b = -1;
        id = s;
    }
    Line(const ld& a, const ld& c, const int& s) {
        m = a, b = c, id = s;
    }
    ld m;       //slope
    ld b;       //y-int
    int id;      //highest optimal x position
    bool operator < (const Line& o) const {
        if(!Q) return o.m > m;
        else return r[o.id] > r[id];
    }
    ld operator() (const ld& x) const {return m * x + b;}
    bool operator() (const ld& x, const ld& y) const { return equ((*this)(x), y);}
    pff operator * (const Line& o)  const {
        assert(!equ(m, o.m));
        ld x = (o.b - b)/(m - o.m);
        ld y = (o.b*m - b*o.m)/(m - o.m);
        //assert(o(x, y) and (*this)(x, y));
        return mp(x, y);
    }
    bool keep(const Line& l, const Line& r) const {
        //assert(l.m <= m and m <= r.m);
        return (l**this).xvl < (*this*r).xvl;
    }
};
typedef multiset<Line> msl;
struct CHT {
public:
    msl lines;
    CHT() {
        Q = false;
    }
    void pout() {
        for(msl::iterator it = lines.begin();it != lines.end();it++) {
            cerr << it->m << "x + " << it->b << "(" << it->id << ") up to " << r[it->id] << "\n";
        }
    }
    bool insert(const Line& l) {
        if(lines.empty()) {
            r[l.id] = CHTUB;
            lines.insert(l);
            return true;
        }

        msl::iterator c = lines.lower_bound(l);
        if(c != lines.end()) {
            if(equ(c->m, l.m)) {
                if(l.b > c->b) lines.erase(c);
                else return false;
            }
        }
        c = lines.insert(l);

        msl::iterator p[2], n[2];

        //check whether to remove
        n[0] = c;
        p[0] = c;
        if(c != lines.begin() and ++n[0] != lines.end()) {
            --p[0];
            if(!c->keep(*p[0], *n[0])) {
                lines.erase(c);
                return false;
            }
        }

        if(c == lines.begin()) {
        } else {
            p[0] = c, p[1] = --p[0];

            while(p[0] != lines.begin()) {
                p[1]--;

                if(p[0]->keep(*p[1], *c)) {
                    break;
                } else {
                    lines.erase(p[0]);
                    p[0] = p[1];
                }
            }
            r[p[0]->id] = ((*p[0]) * (*c)).xvl;
        }

        n[0] = c, n[1] = ++n[0];
        if(n[0] == lines.end()) {
            r[c->id] = CHTUB;
        } else {
            while(++n[1] != lines.end()) {
                if(n[0]->keep(*c, *n[1])) {
                    break;
                } else {
                    lines.erase(n[0]);
                    n[0] = n[1];
                }
            }
            r[c->id] = ((*n[0]) * (*c)).xvl;
        }
        return true;
    }
    ld operator () (const ld& x) const {
        assert(CHTLB < x and x < CHTUB);
        Q = true;
        msl::iterator c = lines.lower_bound(x);
        Q = false;

        assert(c != lines.end());

        return (*c)(x);
    }
} hull;

struct mat {
public:
    vvld m;
private:
    int L, W;
    void fix() {
        L = m.size();
        W = m[0].size();
    }
public:

    void pout() {
        fix();
        for(int l = 0;l < L;l++) {
            for(int w = 0;w < W;w++) {
                cerr << m[l][w] << " ";
            }
            cerr << "\n";
        }
        cerr << "\n";
    }

    mat(const int& l = 1, const int& w = 1) {
        L = l, W = w;
        vld r(W, 0);
        m = vvld(L, r);
        if(l == w) {
            for(int i = 0;i < l;i++) m[i][i] = 1;
        }
    }

    vld& operator [] (const int& r) {
        fix();
        assert(0 <= r and r < L);
        return m[r];
    }
    ld& operator () (const int& r, const int& c) {
        fix();
        assert(0 <= r and r < L);
        assert(0 <= c and c < W);
        return m[r][c];
    }

    mat operator * (mat& o) {
        fix();
        o.fix();

        assert(W == o.L);
        mat ret(L, o.W);

        for(int l = 0;l < L;l++) {
            for(int c = 0;c < o.W;c++) {
                ret[l][c] = 0;
                for(int i = 0;i < W;i++) {
                    ret[l][c] += m[l][i] * o.m[i][c];
                }
            }
        }

        return ret;
    }
};

int a[MAXN], b[MAXN];
ld p[MAXN];

ld dp;
ll ct;
mat st[500];
ll next(ld p, ld a, ld cut) {
    ll v = rlog2(T - ct);
    st[0].m = {
        {tld(1) - p, p * V, p * a},
        {0, 1, 1},
        {0, 0, 1}
    };
    for(int i = 1;i <= v;i++) {
        st[i] = st[i - 1] * st[i - 1];
    }

    mat cm(3, 3);
    mat dpm(3, 1);
    dpm.m = {{dp},{tld(ct)},{1}};
    ll dt = 0;
    for(ll i = v;i >= 0;i--) {
        if(ct + dt + (1LL << i) > T) continue;
        mat cmt = cm * st[i];
        if(V*(ct + dt + (1LL << i)) - (cmt*dpm)[0][0] > cut);
        else {
            cm = cmt;
            dt += (1LL << i);
            assert(equ(tld(dt), cm[1][2]));
        }
    }

    mat rt = cm * dpm;
    assert(equ(tld(ct + dt), rt[1][0]));

    if(dt + ct < T and V*(ct + dt) - rt[0][0] < cut){
        dt++;
        rt = st[0] * rt;
    }

    dp = rt[0][0];
    return dt + ct;
}

int main() {
    Q = false;
    cerr << setprecision(10);

    scanf("%d%lld", &N, &T);
    V = 0;
    for(int i = 0;i < N;i++) {
        scanf("%d%d%Lf", a + i, b + i, p + i);
        if((t = b[i] * p[i]) > V) V = t;
    }

    for(int i = 0;i < N;i++) {
        hull.insert(Line(p[i], p[i]*a[i], i));
    }

    ct = 0;
    dp = 0;
    for(auto path : hull.lines) {
        ct = next(p[path.id], a[path.id], r[path.id]);
        assert(ct <= T);
        if(ct == T) break;
    }

    printf("%.10Lg\n", dp);

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};

struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }
    double powr(double a, ll t){
    	double x = 1.;
    	for(; t; t >>= 1, a *= a){
    		if(t & 1) x *= a;
    	}
    	return x;
    }

    double get(double x, ll t){
    	// double p1 = pow(alpha, t), p2 = powr(alpha, t);
    	// trace(alpha, t, p1, p2);
    	return (x - gamma) * powr(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 + hull[ind].a;
			beta = m + hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}

    		ll lo = 0, hi = t - iter;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) <= hull[ind + 1].get(val)) lo = mid;
    			else hi = mid - 1;
    		}

    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}

int perm[N];
main(){
	int n = 100000;
	ll t= 10000000000;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		// a[i] = rand() % 100000; b[i] = a[i] + rand() % 1000000;
		// p[i] = rand() % 5 * 0.1;
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] > p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(-p[perm[i]], -k[perm[i]]);
	if(double_eq(m, m1)){
		printf("%.15Lf\n", t * m);
		return 0;
	}
	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

const int MAXN=100000;
struct Q {
	int aget,bget; double p;
	double cnst,upto; // E(k)=E(k-1)+p*((k-1)*z-E(k-1))+cnst

};
bool operator<(const Q &a,const Q &b) { return a.cnst>b.cnst; }

int n; ll t;
Q q[MAXN];

Q use[MAXN]; int nuse;

double overtake(const Q &a,const Q &b) {
	return (b.cnst-a.cnst)/(a.p-b.p);
}

double pw(double x,ll n) { double ret=1; while(true) { if(n&1) ret=ret*x; if((n>>=1)==0) return ret; x=x*x; } }

double solve() {
	double z=0; REP(i,n) z=max(z,q[i].bget*q[i].p);
	REP(i,n) q[i].cnst=q[i].p*q[i].aget;
	//REP(i,n) printf("%d: p=%lf cnst=%lf\n",i,q[i].p,q[i].cnst);

	sort(q,q+n);
	nuse=0;
	REP(i,n) {
		if(nuse>0&&q[i].p<=q[nuse-1].p) continue;
		while(nuse>=2&&overtake(q[nuse-1],q[nuse-2])>overtake(q[i],q[nuse-1])) --nuse;
		use[nuse++]=q[i];
	}
	//REP(i,nuse) printf("%d: p=%lf cnst=%lf (%lf)\n",i,use[i].p,use[i].cnst,i+1<nuse?overtake(use[i+1],use[i]):-1);

	double ret=0; ll k=0;
	// E(k)=(1-p)*E(k-1)+p*(k-1)*z+cnst = (1-p)*(1-p)*E(k-2)+p*((k-1)+(1-p)*(k-2))*z+cnst*(1+(1-p))
	// F(k)=k*z-E(k) -> F(k)=z-cnst+(1-p)*F(k-1) = (z-cnst)*(1+(1-p))+(1-p)*(1-p)*F(k-2)
	REP(i,nuse) {
		ll ntimes;
		if(i+1<nuse) {
			ll l=-1,h=t-k;
			while(l+1<h) {
				ll m=l+(h-l)/2;
				double pp=pw(1-q[i].p,m);
				double have=pp*(k*z-ret)+(z-q[i].cnst)*(1-pp)/q[i].p,want=overtake(use[i+1],use[i]);
				//printf("\t%lld: have=%lf want=%lf (%lf,%lf)\n",m,have,want,pp,z-q[i].cnst);
				if(have>want) h=m; else l=m;
			}
			ntimes=h;
		} else {
			ntimes=t-k;
		}
		{
			//printf("ntimes=%lld\n",ntimes);
			ll nk=k+ntimes;
			double pp=pw(1-q[i].p,ntimes);
			double have=pp*(k*z-ret)+(z-q[i].cnst)*(1-pp)/q[i].p;
			//printf("\t%lld: have=%lf (%lf,%lf)\n",ntimes,have,pp,z-q[i].cnst);
			ret=nk*z-have;
			k=nk;
		}
	}

	return ret;
}

void run() {
	scanf("%d%lld",&n,&t);
	REP(i,n) scanf("%d%d%lf",&q[i].aget,&q[i].bget,&q[i].p);
	printf("%.15lf\n",solve());
}

int main() {
	run();
	return 0;
}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
#define FR first
#define SE second
#define eps 1e-9

using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,ll> pr;

inline int cmp(db x,db y) {
  if (fabs(x-y)<eps) return 0;
  return (x<y)?-1:1;
}

struct Point {
  db x,y;
  Point() {}
  Point(db a,db b):x(a),y(b) {}
  Point operator - (Point b) {return Point(x-b.x,y-b.y);}
  bool operator < (const Point & b) const {return (cmp(x,b.x)!=0)?(cmp(x,b.x)<0):(cmp(y,b.y)>0);}
};

db cross(Point x,Point y) {
  return x.x*y.y-x.y*y.x;
}

Point p[100005],hull[100005];
int st[100005];

int build(int n) {
  sort(p+1,p+n+1);
  int top=0;
  for(int i=1;i<=n;i++) {
  	while (top>1&&cmp(cross(p[i]-p[st[top]],p[st[top]]-p[st[top-1]]),0)<=0) top--;
  	st[++top]=i;
  }
  for(int i=1;i<=top;i++) hull[i]=p[st[i]];
  return top;
}

struct Matrix {
  db num[3][3];
  int n,m;
  Matrix() {}
  Matrix(int a,int b):n(a),m(b) {memset(num,0,sizeof(num));}
};

Matrix operator * (Matrix &a,Matrix &b) {
  Matrix c(a.n,b.m);
  for(int i=0;i<c.n;i++)
    for(int j=0;j<c.m;j++)
      for(int k=0;k<a.m;k++) c.num[i][j]+=a.num[i][k]*b.num[k][j];
  return c;
}

Matrix operator ^ (Matrix a,ll k) {
  Matrix ans(a.n,a.m);
  for(int i=0;i<ans.n;i++) ans.num[i][i]=1;
  while (k) {
  	if (k&1) ans=ans*a;
  	a=a*a;
  	k>>=1;
  }
  return ans;
}

db maxn;

db calc(db x,int y,ll l,ll r) {
  Matrix a(3,3);
  a.num[0][0]=1-hull[y].x;
  a.num[0][1]=hull[y].x*maxn;
  a.num[0][2]=hull[y].y;
  a.num[1][1]=a.num[1][2]=a.num[2][2]=1;
  Matrix fir(3,1);
  fir.num[0][0]=x;
  fir.num[1][0]=l;
  fir.num[2][0]=1;
  a=a^(r-l);
  fir=a*fir;
  return fir.num[0][0];
}

Matrix now[40];

void pre(int n,db x,int y,ll t) {
  now[0]=Matrix(3,3);
  now[0].num[0][0]=1-hull[y].x;
  now[0].num[0][1]=hull[y].x*maxn;
  now[0].num[0][2]=hull[y].y;
  now[0].num[1][1]=now[0].num[1][2]=now[0].num[2][2]=1;
  for(int i=1;i<=n;i++) now[i]=now[i-1]*now[i-1];
}

inline db trans(db x,int y,ll t) {
  return (1-hull[y].x)*x+hull[y].y+hull[y].x*maxn*t;
}

pr s[100005];
db f[100005];

int main() {
  int n;
  ll m;
  scanf("%d%lld",&n,&m);
  for(int i=1;i<=n;i++) {
  	db x,y,z;
  	scanf("%lf%lf%lf",&x,&y,&z);
  	p[i]=Point(z,x*z);
  	maxn=max(maxn,y*z);
  }
  int k=build(n);
  int top=0;
  s[++top]=pr(1,m);
  f[top]=calc(f[top-1],1,s[top-1].SE,s[top].SE);
  for(int i=2;i<=k;i++) {
  	while (top>0&&cmp(trans(f[top-1],i,s[top-1].SE),trans(f[top-1],s[top].FR,s[top-1].SE))>=0) top--;
  	if (top>0) {
  		int cnt=0;
  		while ((1LL<<cnt)<=s[top].SE-s[top-1].SE) cnt++;
  		pre(cnt,f[top-1],s[top].FR,s[top-1].SE);
  		ll l=0;
  		Matrix fir(3,1);
  		fir.num[0][0]=f[top-1];
  		fir.num[1][0]=s[top-1].SE;
  		fir.num[2][0]=1;
  		for(int j=cnt;j>=0;j--) {
  			Matrix u=now[j]*fir;
  			db t=u.num[0][0];
  			if (cmp(trans(t,i,1LL<<j),trans(t,s[top].FR,1LL<<j))<=0) {
  				l+=(1LL<<j);
  				fir=u;
			  }
		  }
		s[top].SE=min(l+s[top-1].SE,s[top].SE);
		f[top]=calc(f[top-1],s[top].FR,s[top-1].SE,s[top].SE);
	    while (top>0&&s[top].SE==s[top-1].SE) top--;
	  }
	s[++top]=pr(i,m);
	f[top]=calc(f[top-1],i,s[top-1].SE,s[top].SE);
	while (top>0&&s[top].SE==s[top-1].SE) top--;
  }
  printf("%.12lf\n",f[top]);
  return 0;
}

#include<cstdio>
#include<algorithm>
#include<functional>
using namespace std;

const int maxn = 100001;
const int logn = 34;

struct matrix {
	long double a[3][3];
	matrix() {}
	matrix(int c, long double p, long double v) {
		a[0][0] = 1 - p;
		a[0][1] = a[0][2] = 0;
		a[1][0] = p * v;
		a[1][1] = 1;
		a[1][2] = 0;
		a[2][0] = c * p - p * v;
		a[2][1] = a[2][2] = 1;
	}
	void to_i() {
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				a[i][j] = 0;
			}
		}
		a[0][0] = a[1][1] = a[2][2] = 1;
	}
	matrix operator *(const matrix &m) const {
		matrix ans;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				ans.a[i][j] = 0;
				for (int k = 0; k < 3; k++) {
					ans.a[i][j] += a[i][k] * m.a[k][j];
				}
			}
		}
		return ans;
	}
	long double cal(long double dp, long long i) {
		return dp * a[0][0] + (i + 1) * a[1][0] + a[2][0];
	}
};

struct vec {
	long double x, y;
	vec() {}
	vec(long double x, long double y) :x(x), y(y) {}
	vec operator -(const vec &v) const { return vec(x - v.x, y - v.y); }
	long double operator *(const vec &v) const { return x * v.y - y * v.x; }
};

int a[maxn], b[maxn];
long double p[maxn];
int n;
int ord[maxn];

int cal_ch();

int main() {
	scanf("%d", &n);
	long long t;
	scanf("%lld", &t);
	long double v = 0;
	for (int i = 1; i <= n; i++) {
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
		v = max(v, b[i] * p[i]);
	}
	n = cal_ch();
	long long cur = 0;
	long double dp = 0;
	for (int _ = 1; _ < n; _++) {
		matrix m0(a[ord[_]], p[ord[_]], v);
		matrix m1(a[ord[_ + 1]], p[ord[_ + 1]], v);
		matrix pow0[logn], pow1[logn];
		pow0[0] = m0;
		pow1[0] = m1;
		for (int i = 1; i < logn; i++) {
			pow0[i] = pow0[i - 1] * pow0[i - 1];
			pow1[i] = pow1[i - 1] * pow1[i - 1];
		}
		for (int i = logn - 1; i >= 0; i--) {
			if (!((t - cur) >> i & 1)) continue;
			long double dp0 = pow0[i].cal(dp, cur);
			long double dp1 = pow1[i].cal(dp, cur);
			if (dp0 < dp1) continue;
			dp = dp0;
			cur += 1ll << i;
		}
	}
	matrix pow0[logn];
	pow0[0] = matrix(a[ord[n]], p[ord[n]], v);
	for (int i = 1; i < logn; i++) {
		pow0[i] = pow0[i - 1] * pow0[i - 1];
	}
	for (int i = logn - 1; i >= 0; i--) {
		if (!((t - cur) >> i & 1)) continue;
		dp = pow0[i].cal(dp, cur);
		cur += 1ll << i;
	}
	printf("%.10lf", dp);
	return 0;
}

pair<int, int> tmp[maxn];

int cal_ch() {
	for (int i = 1; i <= n; i++) {
		tmp[i] = make_pair(a[i], i);
	}
	sort(tmp + 1, tmp + 1 + n, greater<pair<int, int> >());
	int m = 1;
	ord[m] = tmp[1].second;
	for (int _ = 2; _ < n; _++) {
		int i0 = tmp[_ - 1].second;
		int i1 = tmp[_].second;
		int i2 = tmp[_ + 1].second;
		vec v1(a[i1] - a[i0], p[i1] - p[i0]);
		vec v2(a[i2] - a[i1], p[i2] - p[i1]);
		if (v1*v2 < 0) continue;
		ord[++m] = i1;
	}
	ord[++m] = tmp[n].second;
	return m;
}

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
using namespace std;
const int inf=0x7fffffff;
const double eps=1e-10;
const double pi=acos(-1.0);
//char buf[1<<15],*S=buf,*T=buf;
//char getch(){return S==T&&(T=(S=buf)+fread(buf,1,1<<15,stdin),S==T)?0:*S++;}
inline long long read(){
	long long x=0,f=1;char ch;ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
	if(f)return x;else return -x;
}
const int N=1e5+10;
int a[N],b[N],n;
long long t;
double p[N],Maxs;
struct Point{
double x,y;
bool operator <(const Point &a)const{return (y!=a.y)?y>a.y:x>a.x;}
}P[N];
double slope(Point a,Point b){
	if(fabs(b.x-a.x)<=eps)return inf;
	return (b.y-a.y)/(b.x-a.x);
}
double power(double a,long long b){
  double ans=1;
  for(;b;a=a*a,b>>=1)if(b&1)ans=ans*a;
  return ans;
}
Point Q[N];
int top;
double cal1(double p,double ms,double k)
{double ret=k*(1-power(p,ms+1))/(1-p);return ret;}
double cal2(double p,double ms,double k)
{double ret=k*(cal1(p,ms,1)-ms*power(p,ms+1)-1)/(1-p);return ret;}
double solve(long long S,long long T,double k,double b,double p,double ret){
	if(S==T)return ret;
	double n1=power(p,T-S)*ret;
	double n2=cal1(p,T-S-1,k*(T-1)+b)+cal2(p,T-S-1,-k);
	return n1+n2;
}
int main()
{
	n=(int)read();t=read();
	for(int i=1;i<=n;i++){
		a[i]=(int)read();b[i]=(int)read();
		scanf("%lf",&p[i]);
		Maxs=max(Maxs,1.0*b[i]*p[i]);
		P[i].x=p[i],P[i].y=a[i]*p[i];
	}
	sort(P+1,P+n+1);
	for(int i=1;i<=n;i++){
		if(P[i].y==Q[top-1].y)continue;
		if(i&&P[i].x<Q[top-1].x)continue;
		while(top>=2&&slope(Q[top-1],P[i])>=slope(Q[top-2],Q[top-1]))top--;
		Q[top++]=P[i];
	}
	long long nt=0;
	double ans=0;
	for(int i=0;i<top;i++){
		if(nt==t) break;
		double nk=Q[i].x*Maxs,nb=Q[i].y,np=(1-Q[i].x);
		long long l=nt,r=t;
		if(i==top-1)l=t;
		while(l<r){
			long long mid=(l+r)>>1;
			double nans=solve(nt,mid,nk,nb,np,ans);
			if(-slope(Q[i],Q[i+1])<=Maxs*mid-nans)r=mid;
			else l=mid+1;
		}
		ans=solve(nt,l,nk,nb,np,ans);
		nt=l;
	}
	printf("%.10lf\n",ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 100005;

const long double is_eval = 1e50;
struct Line{
	long double m, b;
	mutable function<const Line*()> succ;
	bool operator<(const Line& rhs) const{
		if(rhs.b != is_eval) return m < rhs.m;
		const Line* s = succ();
		if(!s) return 0;
		long double x = rhs.m;
		return b - s->b < (s->m - m) * x;
	}
};
struct Cht : public multiset<Line>{ // maintain max
	bool bad(iterator y){
		auto z = next(y);
		if(y == begin()){
			if(z == end()) return 0;
			return y->m == z->m && y->b <= z->b;
		}
		auto x = prev(y);
		if(z == end()) return y->m == x->m && y->b <= x->b;
		return (x->b - y->b)*(z->m - y->m) >= (y->b - z->b)*(y->m - x->m);
	}
	void insert_line(long double m, long double b){
		auto y = insert({ m, b });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if(bad(y)){ erase(y); return; }
		while(next(y) != end() && bad(next(y))) erase(next(y));
		while(y != begin() && bad(prev(y))) erase(prev(y));
	}
	long double eval(long double x){
		auto l = *lower_bound((Line) { x, is_eval });
		return l.m * x + l.b;
	}
};

Cht ma, mb;

int n;
ll t;

long double a[N], b[N];
long double p[N];
long double mx;

long double lm[N], lb[N];
int sz;

void insert_line(long double _m, long double _b){
}

long double eval(long double x){
    int L = 0, R = sz-2, ans = sz-1;

    while(L <= R){
        int mid = (L+R)/2;
        if(lb[mid] - lb[mid+1] < (lm[mid+1] - lm[mid]) * x)
            L = mid+1;
        else R = mid-1, ans = mid;
    }

    return lm[ans] * x + lb[ans];
}

long double f(ll q){
    if(q == 0) return 0;

    long double ans = 0;
    long double e = mx*(long double)(q-1), r = f(q-1);
    ans = ma.eval(e-r);
    ans += r;
    return ans;
}

void matmul(long double mans[3][3],long double mbase[3][3],long double tmp[3][3]){
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){
        tmp[i][j] = 0;
        for(int k = 0; k < 3; k++)
            tmp[i][j] += mans[i][k] * mbase[k][j];
    }
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = tmp[i][j];
}

long double save[40][3][3];

void prec(int id){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        save[0][i][j] = mbase[i][j];

    for(int i = 1; i < 40; i++)
        matmul(save[i], save[i-1], tmp);
}

long double pass(long double ans, long double &x, int id, ll cnt){
    long double mbase[][3] = {{1, lm[id], lb[id]},
                        {0, 1-lm[id], mx-lb[id]},
                        {0, 0, 1}};
    long double mans[3][3], tmp[3][3];
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        mans[i][j] = (i == j);
    while(cnt){
        // ans = lm[id] * x + lb[id] + ans;
        // x = x * (1 - lm[id]) + mx - lb[id];
        if(cnt & 1) matmul(mans, mbase, tmp);
        matmul(mbase, mbase, tmp);
        cnt /= 2;
    }

    ans = mans[0][0] * ans + mans[0][1] * x + mans[0][2];

    x = mans[1][1] * x + mans[1][2];
    return ans;
}

ll howlong(ll q, int id, long double x, long double ans){
    if(id == sz-1) return t;
    ll bans = q;

    long double xx;
    for(int j = 38; j > 0; j--){
        if(bans + (1LL << j) > t) continue;
        xx = save[j][1][1] * x + save[j][1][2];
        if(lb[id] - lb[id+1] >= (lm[id+1] - lm[id]) * xx){
            bans += (1LL << j);
            x = xx;
        }
    }

    return bans;
}

int main(){

    scanf("%d %lld", &n, &t);

    for(int i = 0; i < n; i++){
        double qq, ww, ee;
        scanf("%lf %lf %lf", &qq, &ww, &ee);
        a[i] = qq, b[i] = ww, p[i] = ee;
        ma.insert_line(p[i], a[i] * p[i]);
        mb.insert_line(p[i], b[i] * p[i]);
        mx = max(mx, b[i] * p[i]);
    }

    for(auto x : ma){
        lm[sz] = x.m, lb[sz] = x.b;
        sz++;
    }

    // f(q+1) - f(q) <= mx
    // f(q+1) <= mx + f(q)

    long double ans = 0;

    int id = 0;

    for(ll q = 1; q <= t; q++){
        long double x = mx*(long double)(q-1) - ans;
        while(id+1 < sz && lb[id] - lb[id+1] < (lm[id+1] - lm[id]) * x) id++;
        prec(id);
        ll j = howlong(q, id, x, ans);
        ans = pass(ans, x, id, j - q + 1);
        q = j;
        // ans = eval(mx*(q-1) - ans) + ans;
        // ans = lm[id] * x + lb[id] + ans;
    }

    printf("%.20lf\n", (double)ans);
    // printf("%lf\n", f(t));

}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};
const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}
struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }

    double get(double x, ll t){
    	return (x - gamma) * pow(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 - hull[ind].a;
			beta = m - hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}
    		if(hull[ind].get(x) < hull[ind+1].get(x)){
    			ind++;
    			continue;
    		}
    		double next = (hull[ind + 1].b - hull[ind].b)/(hull[ind + 1].a - hull[ind].a);
    		ll lo = log((next-gamma)/(x-gamma)) / log(alpha);
    		lo = min(t -iter, max(1ll, lo));
    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	assert(iter == t);
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

int perm[N];
main(){
	int n;
	ll t;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] < p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(p[perm[i]], k[perm[i]]);
	if(double_eq(m, m1)){
		printf("%.15Lf\n", t * m);
		return 0;
	}

	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
#define double long double
#define int long long

struct Line {
    double a, b, get(double x) { return a * x + b; }
};

struct ConvexHull {
    int size;
    Line *hull;
    double alpha, beta, gamma;
    ConvexHull() {
        hull = new Line[100005], size = 0;
    }

    bool is_bad(int curr, int prev, int next) {
        Line c = hull[curr], p = hull[prev], n = hull[next];
        return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
    }

    void add_line(double a, double b) {
        hull[size++] = (Line){a, b};
        while (size > 2 && is_bad(size - 2, size - 3, size - 1))
            hull[size - 2] = hull[size - 1], size--;
    }

    double query(double x) {
        int l = -1, r = size - 1;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (hull[m].get(x) <= hull[m + 1].get(x))
                l = m;
            else
                r = m;
        }
        return hull[r].get(x);
    }

    double get(double x, ll t){
    	return (x - gamma) * pow(alpha, t) + gamma;
    }

    double query2(long long t, double m){
    	int ind = 0;
    	double x = 0;
    	ll iter = 0;
    	while(ind < size && iter < t){
			alpha = 1 - hull[ind].a;
			beta = m - hull[ind].b;
		 	gamma = beta / (1 - alpha);
    		if(ind == size - 1){
    			return get(x, t - iter);
    		}

    		ll lo = 0, hi = t - iter;

    		while(lo < hi){
    			ll mid = (lo + hi + 1) >> 1;
    			double val = get(x, mid);
    			if(hull[ind].get(val) >= hull[ind + 1].get(val)) lo = mid;
    			else hi = mid - 1;
    		}

    		x = get(x, lo);
    		iter += lo;
    		ind++;
    	}
    	return x;
    }
} ch;

const int N = 100005;
int a[N], b[N];
double p[N];
double k[N];

const double EPS = 1e-9;
bool double_eq(double a, double b){
	return fabs(a - b) <= EPS;
}

int perm[N];
main(){
	int n;
	ll t;
	scanf("%lld %lld", &n, &t);
	double m = 0;
	double m1 = 0;
	for(int i = 1; i <= n;i++){
		scanf("%lld %lld", a+i, b+i);
		scanf("%Lf", &p[i]);
		m = max(p[i] * b[i], m);
		m1 = max(p[i] * a[i], m1);
		k[i] = a[i] * p[i];
		perm[i] = i;
	}

	sort(perm + 1, perm + n + 1, [](int i, int j){return p[i] < p[j];});

	for(int i = 1; i <= n; i++) ch.add_line(p[perm[i]], k[perm[i]]);
	if(double_eq(m, m1)){
		printf("%.15Lf\n", t * m);
		return 0;
	}

	printf("%.15Lf\n", m * t - ch.query2(t, m));
}

// Problem: D. Computer Game
// Contest: Codeforces - Codeforces Round #518 (Div. 1) [Thanks,
// Mail.Ru!] URL: https://codeforces.ml/contest/1067/problem/D Memory
// Limit: 256 MB Time Limit: 3000 ms Powered by CP Editor
// (https://github.com/cpeditor/cpeditor)

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
using namespace std;
typedef long long ll;
const int N = 100000;
const double eps = 1e-14;
int n, m, pos[N + 5];
double a[N + 5], b[N + 5], p[N + 5], q[N + 5], mx = eps;
int hull[N + 5], cnt, cur;
struct Mat {
    int x, y;
    double a[5][5];
    Mat(int x = 0, int y = 0) : x(x), y(y)
    {
        for (int i = 1; i <= x; i++)
            for (int j = 1; j <= y; j++)
                a[i][j] = 0;
    }
    double &operator()(int r, int c) { return a[r][c]; }
} f, g[36];
Mat operator*(Mat x, Mat y)
{
    Mat z(x.x, y.y);
    for (int i = 1; i <= x.x; i++)
        for (int k = 1; k <= x.y; k++)
            for (int j = 1; j <= y.y; j++)
                z(i, j) += x(i, k) * y(k, j);
    return z;
}
int sgn(double x) { return fabs(x) < eps ? 0 : x > 0 ? 1 : -1; }
bool cmp(int x, int y)
{
    return sgn(p[x] - p[y]) ? p[x] < p[y] : q[x] > q[y];
}
double get(int x, int y) { return (q[x] - q[y]) / (p[x] - p[y]); }
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i] >> b[i] >> p[i], q[i] = a[i] * p[i], pos[i] = i,
                                     mx = max(mx, b[i] * p[i]);
    sort(pos + 1, pos + n + 1, cmp);
    for (int j = 1; j <= n; j++) {
        int i = pos[j];
        if (fabs(p[pos[j]] - p[pos[j - 1]]) < eps)
            continue;
        if (cnt > 1)
            while ((q[i] - q[hull[cnt - 1]]) /
                       (p[i] - p[hull[cnt - 1]]) >
                   (q[hull[cnt]] - q[hull[cnt - 1]]) /
                       (p[hull[cnt]] - p[hull[cnt - 1]]))
                cnt--;
        hull[++cnt] = i;
    }
    f = Mat(1, 3), f(1, 3) = 1;
    for (int i = 1; i <= cnt; i++) {
        double tmp = cur * mx - f(1, 1);
        while (i < cnt && sgn(tmp + get(hull[i], hull[i + 1])) >= 0)
            i++;
        g[0] = Mat(3, 3), g[0](2, 2) = g[0](3, 2) = g[0](3, 3) = 1,
        g[0](1, 1) = 1 - p[hull[i]], g[0](2, 1) = p[hull[i]] * mx,
        g[0](3, 1) = q[hull[i]];
        for (int j = 1; j <= 34; j++)
            g[j] = g[j - 1] * g[j - 1];
        for (int j = 34; j >= 0; j--)
            if (cur + (1ll << j) < m &&
                (i == cnt || sgn(tmp - (cur + (1ll << j)) * mx +
                                 (f * g[j])(1, 1)) >= 0))
                f = f * g[j], cur += 1ll << j;
        f = f * g[0], cur++;
        if (cur == m)
            break;
    }
    cout.precision(15), cout << f(1, 1);
    return 0;
}

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cmath>
const int N = 1e5 + 5;
typedef long double db;
typedef long long ll;
const db eps = 1e-8;
using namespace std;

int n, a[N], b[N], id[N], l, r, q[N];
ll m;
db y[N], p[N], tmp[N], M;
struct Matrix
{
	db a[4][4];
	Matrix() { memset(a, 0, sizeof(a)); }
	Matrix operator * (const Matrix &p) const
		{
			Matrix C;
			for(int i = 0; i <= 2; i++)
				for(int j = 0; j <= 2; j++)
					for(int k = 0; k <= 2; k++) C.a[i][j] += a[i][k] * p.a[k][j];
			return C;
		}
} ans, U[40];

template < typename T >
inline T read()
{
	T x = 0, w = 1; char c = getchar();
	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * w;
}

double slope(int i, int j) { return (y[i] - y[j]) / (p[i] - p[j]); }

Matrix mul(Matrix x, Matrix y)
{
	Matrix z;
	for(int i = 0; i <= 2; i++) tmp[i] = 0;
	for(int i = 0; i <= 2; i++)
		for(int j = 0; j <= 2; j++) tmp[i] += x.a[0][j] * y.a[j][i];
	for(int i = 0; i <= 2; i++) z.a[0][i] = tmp[i];
	return z;
}

Matrix build(int id)
{
	Matrix res;
	res.a[0][0] = res.a[2][2] = 1, res.a[1][0] = p[id], res.a[1][1] = 1 - p[id];
	res.a[2][0] = y[id], res.a[2][1] = M - y[id];
	return res;
}

bool cmp(int a, int b) { return fabs(p[a] - p[b]) < eps ? y[a] > y[b] : p[a] < p[b]; }

int main()
{
	n = read <int> (), m = read <ll> ();
	for(int i = 1; i <= n; i++)
	{
		a[i] = read <int> (), b[i] = read <int> (), cin>>p[i];
		y[i] = p[i] * a[i], M = max(M, p[i] * b[i]), id[i] = i;
	}
	sort(id + 1, id + n + 1, cmp), l = 1, r = 0;
	for(int i = 1; i <= n; i++)
	{
		if(fabs(p[id[i]] - p[id[i - 1]]) < eps) continue;
		while(l < r && slope(id[i], q[r - 1]) > slope(q[r], q[r - 1])) r--;
		q[++r] = id[i];
	}
	ans.a[0][0] = ans.a[0][1] = 0, ans.a[0][2] = 1;
	double cur_slp = 0; ll cur = 0;
	while(1)
	{
		while(l < r && y[q[l + 1]] - y[q[l]] >= -cur_slp * (p[q[l + 1]] - p[q[l]])) l++;
		Matrix G = build(q[l]); U[0] = G;
		for(int i = 1; i <= 34; i++) U[i] = U[i - 1] * U[i - 1];
		for(int i = 34; i >= 0; i--)
		{
			if(cur + (1ll << i) >= m) continue;
			Matrix tmp = mul(ans, U[i]);
			if(l == r) cur += (1ll << i), ans = tmp;
			else if(y[q[l + 1]] - y[q[l]] < -tmp.a[0][2] * (p[q[l + 1]] - p[q[l]]))
				cur += (1ll << i), ans = tmp;
		}
		cur++, ans = mul(ans, U[0]), cur_slp = ans.a[0][2];
		if(cur == m) break;
	}
	cout<<fixed<< setprecision(8) <<ans.a[0][0]<<endl;
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;

#define rep(pos, len) for(int pos=0;pos<len;pos++)
#define repp(pos, len) for(int pos=1;pos<=len;pos++)

#define INF 1987654321
#define IINF 2987654321987654321
#define MOD 998244353

const double EPS = 1e-12;
const int MAXN = 1e5 + 50;
double a[MAXN], b[MAXN], p[MAXN], M;		// M is max(b[i]p[i])
int n;
ll T;

void readInput() {
	scanf("%d%lld", &n, &T);
	repp(i, n) scanf("%lf%lf%lf", &a[i], &b[i], &p[i]);

	M = 0.0;
	repp(i, n) M = max(M, b[i]*p[i]);
}

// Convex Hull Trick
// finding convex hull of y = p[i]*x + a[i]*p[i]
int sz = 0;
double la[MAXN], lb[MAXN];

// should check la[i]!=la[j] before calling this function
inline double intersect(int i, int j) {
	return (lb[j]-lb[i]) / (la[i]-la[j]);
}

void addLine(int i) {
	double na = p[i], nb = a[i]*p[i];
	la[++sz] = na;
	lb[sz] = nb;
	if(sz <= 2) return;

	while(sz > 1 && abs(la[sz]-la[sz-1]) < EPS) {
		sz--;
		lb[sz] = max(lb[sz], lb[sz+1]);
	}

	while(sz > 2 && intersect(sz, sz-1) < intersect(sz-1, sz-2)) {
		la[sz-1] = la[sz];
		lb[sz-1] = lb[sz];
		sz--;
	}
}

void findConvexHull() {
	vector<int> il;		// index list
	repp(i, n) il.push_back(i);
	sort(il.begin(), il.end(), [](int i, int j) { return p[i] < p[j]; });
	for(auto i : il) addLine(i);
	//repp(i, sz) printf("[%d]: %fx + %f\n", i, la[i], lb[i]);
}

struct Matrix {
	double a[3][3];

	Matrix() {
		memset(a, 0, sizeof a);
	}

	Matrix(double x, double y) {		// x=p[i], y=a[i]*p[i]
		a[0][0] = 1.0-x;
		a[0][1] = M*x;
		a[0][2] = y;
		a[1][0] = a[2][0] = a[2][1] = 0.0;
		a[1][1] = a[1][2] = a[2][2] = 1.0;
	}

	Matrix operator*(const Matrix &X) {
		Matrix Y;
		rep(i, 3) rep(j, 3) rep(k, 3) Y.a[i][j] += this->a[i][k] * X.a[k][j];
		return Y;
	}

	vector<double> operator*(const vector<double> &v) {
		vector<double> w(3, 0.0);
		rep(i, 3) rep(j, 3) w[i] += this->a[i][j] * v[j];
		return w;
	}

	void print() {
		rep(i, 3) {
			rep(j, 3) printf("%f ", a[i][j]);
			printf("\n");
		}
	}
};

void solve() {
	vector<double> v = {0.0, 0.0, 1.0};		// {dp[t], t, 1}
	ll t = 0;
	repp(i, sz) {
		double mx = (i < sz) ? intersect(i, i+1) : 0.0;
		if(i<sz && M*v[1]-v[0] >= mx) continue;

		Matrix A(la[i], lb[i]);
		vector<Matrix> Alist;
		for(ll k = 0; (1LL<<k) <= (T-t); k++) {
			Alist.push_back(A);
			A = A*A;
		}

		for(ll k = (ll)Alist.size()-1; k >= 0; k--) {
			vector<double> w = Alist[k] * v;
			if((t+(1LL<<k) <= T) && ((i==sz) || (M*w[1]-w[0] < mx))) {
				v = w;
				t += (1LL<<k);
			}
		}

		if(t == T) break;
		t++;
		v = A*v;
	}

	if(t != T) printf("NO!!!\n");
	printf("%.11f\n", v[0]);
}

int main() {
	readInput();
	findConvexHull();
	solve();
}

#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007
#define ll long long int
#define vi vector<int>
#define vii vector< vector<int> >
#define PI 3.1415926535897932384626433832795
#define INF 9223372036854775807LL
#define endl "\n"
#define ld long double

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    ll t;
    cin >> n >> t;
    vector<ld> a (n);
    vector<ld> b (n);
    vector<ld> p (n);
    ld mxb = 0;
    ld mxa = 0;
    for(int i = 0; i < n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        if(b[i]*p[i] > mxb) {
            mxb = b[i]*p[i];
        }
        if(a[i]*p[i] > mxa) {
            mxa = a[i]*p[i];
        }
    }
    ld ans = 0;
    for(int i = 0; i < n; i++) {
        ld currans = 0;
        ld pp = 1-p[i];
        ld qq = p[i];
        currans = qq*(mxb*(pow(pp,t)-t*pp+t-1)/((pp-1)*(pp-1)));
        currans += qq*(a[i]*(pow(pp,t)-pp)/((pp-1)*(pp)));
        /*   for(int x = 1; x <= min(2000LL,t-1); x++) {
            currans+= currprob*p[i]*(a[i]+(t-x)*mxb);
            currprob*= 1-p[i];
        }*/
        currans+= pow(pp,t-1)*mxa;
        ans = max(ans,currans);
    }
    printf("%.13lg\n",(double)ans);
    return 0;
}

#include<bits/stdc++.h>
#define EPS 1e-9
using namespace std;
const int maxn=100005,maxm=4;
int n,t,stk[maxn],top,a[maxn],b[maxn];
double P[maxn],lim[maxn],M;
struct line{
    double k,b; int id;
    bool operator <(const line &p) const{
        if (fabs(k-p.k)>EPS) return k<p.k;
        else if (k>0) return b>p.b;
        else return b<p.b;
    }
}l[maxn];
struct mat{
    double m[maxm][maxm];
    void clear(){memset(m,0,sizeof(m));}
    void zero(){clear(); for (int i=1;i<=3;i++) m[i][i]=1;}
    mat operator *(mat b) {
        mat ret; ret.clear();
        for (int i=1;i<=3;i++)
            for (int j=1;j<=3;j++)
                for (int k=1;k<=3;k++)
                    ret.m[i][j]+=m[i][k]*b.m[k][j];
        return ret;
    }
}now,w,trans[33];
double get(int x,int y){return (l[y].b-l[x].b)/(l[x].k-l[y].k);}
void make_tb(){
    for (int i=1;i<=n;i++) l[i].k=P[i],l[i].b=P[i]*a[i],l[i].id=i;
    sort(l+1,l+1+n);
    int m=1;
    for (int i=2;i<=n;i++) if (l[i].k-l[i-1].k>EPS) l[++m]=l[i];
    for (int i=1;i<=m;i++){
        while (top>1&&get(i,stk[top])<get(stk[top-1],stk[top])) top--;
        stk[++top]=i;
    }
    for (int i=2;i<=top;i++) lim[i]=get(stk[i-1],stk[i]);
}
bool pd(int x,int y,int i,double fi){
    x=l[x].id,y=l[y].id;
    if (P[x]*(M*i-fi)+P[x]*a[x]>P[y]*(M*i-fi)+P[y]*a[y]) return 1; return 0;
}
int main(){
    scanf("%d%d",&n,&t);
    for (int i=1;i<=n;i++) scanf("%d%d%lf",&a[i],&b[i],&P[i]),M=max(M,b[i]*P[i]);
    make_tb();
    //for (int i=1;i<=top;i++) printf("!%.2lf:%.2lf ",l[stk[i]].k,l[stk[i]].b); puts("");
    now.zero();
    int p=0;
    for (int i=1;i<=top&&p<t;i++){
        trans[0].clear(); int x=l[stk[i]].id; w.zero();
        //printf("FFF%.2lf\n",lim[i]);
        if (i!=top&&M*p-now.m[3][1]>lim[i+1]) continue;
        trans[0].m[1][1]=1-P[x],trans[0].m[2][1]=P[x]*M;
        trans[0].m[2][2]=1,trans[0].m[3][1]=P[x]*a[x];
        trans[0].m[3][2]=1,trans[0].m[3][3]=1;
        for (int j=1;j<=30;j++) trans[j]=trans[j-1]*trans[j-1];
        for (int j=30;j>=0;j--)
            if (p+(1<<j)<t){
                w=now*trans[j];
                if (i==top||M*(p+(1<<j))-w.m[3][1]<=lim[i+1]) now=now*trans[j],p+=(1<<j);
            }
        if (i==top||M*p-now.m[3][1]<=lim[i+1]) p++,now=now*trans[0];
        //printf("???%d %.2lf %d\n",p,M,i);
    }
    printf("%.10lf\n",now.m[3][1]);
    return 0;
}

//By Don4ick
//#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;

#define forn(i, n) for (int i = 1; i <= n; i++)
#define pb push_back
#define all(x) x.begin(), x.end()
#define y1 qewr1234

const double PI = acos(-1.0);
const int DIR = 4;
const int X[] = {1, 0, -1, 0};
const int Y[] = {0, 1, 0, -1};

const long double INF = 1e18;
const int N = (int)1e5 + 228;
const int LOG = 45;
const long double eps = 1e-9;

using namespace std;

struct Matrix
{
	long double a[3][3] = {};

	Matrix () {};

	Matrix (long double m[9])
	{
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				a[i][j] = m[i * 3 + j];
	};

	Matrix operator * (Matrix a)
	{
		Matrix res;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				for (int k = 0; k < 3; k++)
					res.a[i][j] += a.a[i][k] * a.a[k][j];
		return res;
	}
} f[LOG];

int n, a[N], b[N], ord[N];
ll t;
double p[N];

long double cross(pair < long double, long double > x, pair < long double, long double > y)
{
	return (y.second - x.second) / (x.first - y.first);
}

bool cmp(int x, int y)
{
	return p[x] < p[y];
}

int main()
{
	//ios_base::sync_with_stdio(false);
	//cin.tie();
	//cout.tie();

	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	//~read
	scanf("%d%lld", &n, &t);
	forn(i, n)
		scanf("%d%d%lf", &a[i], &b[i], &p[i]);
	//~build_CHT
	forn(i, n)
		ord[i] = i;
	sort(ord + 1, ord + n + 1, &cmp);
	vector < pair < long double, long double > > hull;
	vector < int > id;
	forn(i, n)
	{
		while((int)hull.size() >= 2)
		{
			long double x1 = cross(hull[(int)hull.size() - 2], hull.back());
			long double x2 = cross(hull[(int)hull.size() - 2], {p[ord[i]], p[ord[i]] * a[ord[i]]});
			if (x1 < x2 + eps)
				break;
			id.pop_back();
			hull.pop_back();
		}
		id.pb(ord[i]);
		hull.pb({p[ord[i]], p[ord[i]] * a[ord[i]]});
	}
	//~precalc_M
	long double M = 0.0;
	forn(i, n)
		M = max(M, (long double)p[i] * b[i]);
	//~solve
	ll curT = 0;
	long double Dp = 0.0;
	for	 (int i = 0; i < (int)hull.size() && curT < t; i++)
	{
		long double x = INF;
		if (i < (int)hull.size() - 1)
			x = cross(hull[i], hull[i + 1]);
		if (M * curT - Dp > x - eps)
			continue;
		long double m[] = {1.0 - p[id[i]], p[id[i]] * M, p[id[i]] * a[id[i]], 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0};
		f[0] = Matrix(m);
		for (int j = 1; j < LOG; j++)
			f[j] = f[j - 1] * f[j - 1];
		for (int j = LOG - 1; j >= 0; j--)
		{
			if ((1ll << j) + curT >= t)
				continue;
			long double newDp = f[j].a[0][0] * Dp + f[j].a[0][1] * curT + f[j].a[0][2];
			long double newX = M * (curT + (1ll << j)) - newDp;
			if (newX > x - eps)
				continue;
			curT += (1ll << j);
			Dp = newDp;
		}
		Dp = (M * curT - Dp) * hull[i].first + hull[i].second + Dp;
		curT++;
	}
	double res = Dp;
	printf("%.10f", res);

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define fin stdin
#define fout stdout
//FILE *fin = fopen("x.in", "r"), *fout = fopen("x.out", "w");

typedef long long i64;

const int nmax = 1e5;
int a[nmax + 1], b[nmax + 1];
long double p[nmax + 1];

struct fct {
    long double a, b;

    fct () {}
    fct (long double _a, long double _b) {
        a = _a, b = _b;
    }

    bool operator < (const fct &shp) const {
        if (a != shp.a)
            return a < shp.a;
        return b > shp.b;
    }
};

vector<fct> f;
pair<fct, long double> st[nmax + 1];

inline long double intersect (fct A, fct B) {
    if (A.a == B.a)
        return INFINITY;
    return (B.b - A.b) / (A.a - B.a);
}

struct Matrice {
    long double v[3][3];

    Matrice () {
        memset(v, 0, sizeof(v));
    }
    void init () {
        for (int i = 0; i < 3; ++ i)
            v[i][i] = 1;
    }

    Matrice operator * (const Matrice &shp) const {
        Matrice ans;
        for (int i = 0; i < 3; ++ i) {
            for (int k = 0; k < 3; ++ k) {
                for (int j = 0; j < 3; ++ j) {
                    ans.v[i][j] += v[i][k] * shp.v[k][j];
                }
            }
        }

        return ans;
    }

    Matrice operator ^ (i64 pw) const {
        Matrice ans, ba = *this;
        ans.init();

        while (pw > 0) {
            if (pw & 1)
                ans = ans * ba;
            ba = ba * ba;
            pw >>= 1;
        }
        return ans;
    }
} tr, lst;

i64 sol;

long double solve (i64 pas) {
    Matrice aux = lst * (tr ^ (pas - sol));
    return aux.v[0][0];
}

int main() {
    int n; i64 t;
    fscanf(fin, "%d%I64d", &n, &t);

    i64 t2;
    for (t2 = 1; (t2 << 1) <= t; t2 <<= 1) {
    }

    long double cst = 0;
    for (int i = 1; i <= n; ++ i) {
        fscanf(fin, "%d%d%Lf", &a[i], &b[i], &p[i]);
        cst = max(cst, b[i] * p[i]);
        f.push_back(fct(p[i], p[i] * a[i]));
    }

    sort(f.begin(), f.end());
    int top = 0;

    for (auto i : f) {
        while (top >= 2 && st[top].second >= intersect(st[top].first, i))
            -- top;

        if (top == 0)
            st[++ top] = {i, -INFINITY};
        else if (intersect(st[top].first, i) != INFINITY) {
            st[top + 1] = {i, intersect(st[top].first, i)};
            ++ top;
        }
    }
    st[top + 1].second = INFINITY;

    lst.v[0][2] = 1;

    for (int i = 1; i <= top; ++ i) {
        tr.v[0][0] = 1 - st[i].first.a;
        tr.v[1][0] = cst * st[i].first.a;
        tr.v[2][0] = st[i].first.b;
        tr.v[0][1] = tr.v[0][2] = tr.v[1][2] = 0;
        tr.v[1][1] = tr.v[2][1] = tr.v[2][2] = 1;

        i64 aux = sol;
        for (i64 step = t2; step > 0; step >>= 1) {
            if (sol + step <= t && cst * (sol + step - 1) - solve(sol + step - 1) <= st[i + 1].second) {
                sol += step;
            }
        }
        lst = lst * (tr ^ (sol - aux));
    }

    fprintf(fout, "%.9Lf\n", lst.v[0][0]);
    return 0;
}

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN=110000;
struct Matrix
{
	int n, m; double a[3][3];
	Matrix() {}
	Matrix(int r, int c): n(r), m(c)
	{
		for (int i=0; i<3; i++)
			for (int j=0; j<3; j++) a[i][j]=0;
	}
	Matrix operator * (const Matrix& b) const
	{
		Matrix c(n, b.m);
		for (int i=0; i<n; i++)
			for (int k=0; k<m; k++)
				for (int j=0; j<b.m; j++)
					c.a[i][j]+=a[i][k]*b.a[k][j];
		return c;
	}
	Matrix qpow(ll k) const
	{
		Matrix s(n, m), t=*this;
		for (int i=0; i<n; i++) s.a[i][i]=1;
		while (k>0)
		{
			if (k&1) s=s*t;
			t=t*t; k>>=1;
		}
		return s;
	}
};
struct Quest
{
	int a; double p;
	bool operator < (const Quest& rhs) const
	{
		return p<rhs.p;
	}
} a[MAXN];
int q[MAXN];
Matrix w[MAXN];
inline double slope(int i, int j)
{
	return (a[j].p*a[j].a-a[i].p*a[i].a)/(a[i].p-a[j].p);
}
int main()
{
//	freopen("D.in", "r", stdin);
//	freopen("D.out", "w", stdout);
	int n, m=0; ll t; double c=0;
	scanf("%d%lld", &n, &t);
	for (int i=1; i<=n; i++)
	{
		int b;
		scanf("%d%d%lf", &a[i].a, &b, &a[i].p);
		c=max(c, b*a[i].p);
	}
	sort(a+1, a+n+1);
	for (int i=1; i<=n; i++)
	{
		while (m>=2&&slope(i, q[m])<=slope(q[m], q[m-1])) m--;
		q[++m]=i;
	}
	for (int i=1; i<=m; i++)
	{
		w[i]=Matrix(3, 3);
		w[i].a[0][0]=1-a[q[i]].p;
		w[i].a[1][0]=a[q[i]].p*c;
		w[i].a[2][0]=a[q[i]].p*a[q[i]].a;
		w[i].a[1][1]=w[i].a[2][1]=w[i].a[2][2]=1;
	}
	Matrix v(1, 3); v.a[0][2]=1;
	for (int i=1; i<m; i++)
	{
		ll l=0, r=t;
		while (l<r)
		{
			ll mid=l+r+1>>1;
			if ((v*w[i].qpow(mid)).a[0][0]>=
			    (v*w[i].qpow(mid-1)*w[i+1]).a[0][0]) l=mid;
			else r=mid-1;
		}
		v=v*w[i].qpow(l); t-=l;
	}
	v=v*w[m].qpow(t);
	printf("%.7lf\n", v.a[0][0]);
	return 0;
}

#include<bits/stdc++.h>
#define EPS 1e-9
using namespace std;
const int maxn=100005,maxm=4;
int n,t,stk[maxn],top,a[maxn],b[maxn];
double P[maxn],lim[maxn],M;
struct line{
    double k,b; int id;
    bool operator <(const line &b) const{return k<b.k;}
}l[maxn];
struct mat{
    double m[maxm][maxm];
    void clear(){memset(m,0,sizeof(m));}
    void zero(){clear(); for (int i=1;i<=3;i++) m[i][i]=1;}
    mat operator *(mat b) {
        mat ret; ret.clear();
        for (int i=1;i<=3;i++)
            for (int j=1;j<=3;j++)
                for (int k=1;k<=3;k++)
                    ret.m[i][j]+=m[i][k]*b.m[k][j];
        return ret;
    }
}now,w,trans[33];
double get(int x,int y){return (l[y].b-l[x].b)/(l[x].k-l[y].k);}
void make_tb(){
    for (int i=1;i<=n;i++) l[i].k=P[i],l[i].b=P[i]*a[i],l[i].id=i;
    sort(l+1,l+1+n);
    int m=1;
    for (int i=2;i<=n;i++) if (l[i].k-l[i-1].k>EPS||l[i].b-l[i-1].b>EPS) l[++m]=l[i];
    for (int i=1;i<=n;i++){
        while (top>1&&get(i,stk[top])<get(stk[top-1],stk[top])) top--;
        stk[++top]=i;
    }
    for (int i=2;i<=top;i++) lim[i]=get(stk[i-1],stk[i]);
}
bool pd(int x,int y,int i,double fi){
    if (y>n) return 1;
    x=l[x].id,y=l[y].id;
    if (P[x]*(M*i-fi)+P[x]*a[x]>P[y]*(M*i-fi)+P[y]*a[y]) return 1; return 0;
}
int main(){
    scanf("%d%d",&n,&t);
    for (int i=1;i<=n;i++) scanf("%d%d%lf",&a[i],&b[i],&P[i]),M=max(M,b[i]*P[i]);
    make_tb();
    now.zero();
    int p=0;
    for (int i=1;i<=top&&p<t;i++){
        trans[0].clear(); int x=l[i].id; w.zero();
        trans[0].m[1][1]=1-P[x],trans[0].m[2][1]=P[x]*M;
        trans[0].m[2][2]=1,trans[0].m[3][1]=P[x]*a[x];
        trans[0].m[3][2]=1,trans[0].m[3][3]=1;
        for (int j=1;j<=30;j++) trans[j]=trans[j-1]*trans[j-1];
        for (int j=30;j>=0;j--){
            w=now*trans[j];
            if (p+(1<<j)<=t&&pd(i,i+1,p+(1<<j),w.m[3][1])) now=now*trans[j],p+=(1<<j);
        }
    }
    printf("%.10lf\n",now.m[3][1]);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007
#define ll long long int
#define vi vector<int>
#define vii vector< vector<int> >
#define PI 3.1415926535897932384626433832795
#define INF 9223372036854775807LL
#define endl "\n"
#define ld long double

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    ll t;
    cin >> n >> t;
    vector<ld> a (n);
    vector<ld> b (n);
    vector<ld> p (n);
    ld mxb = 0;
    ld mxa = 0;
    for(int i = 0; i < n; i++) {
        cin >> a[i] >> b[i] >> p[i];
        if(b[i]*p[i] > mxb) {
            mxb = b[i]*p[i];
        }
        if(a[i]*p[i] > mxa) {
            mxa = a[i]*p[i];
        }
    }
    ld ans = 0;
    for(int i = 0; i < n; i++) {
        ld currans = 0;
        ld pp = 1-p[i];
        ld qq = p[i];
        currans = qq*(mxb*(pow(pp,t)-t*pp+t-1)/((pp-1)*(pp-1)));
        currans += qq*(a[i]*(pow(pp,t)-pp)/((pp-1)*(pp)));
        /*  for(int x = 1; x <= min(2000LL,t-1); x++) {
            currans+= currprob*p[i]*(a[i]+(t-x)*mxb);
            currprob*= 1-p[i];
        }*/
        currans+= pow(pp,t-1)*mxa;
        ans = max(ans,currans);
    }
    printf("%.13lg\n",(double)ans);
    return 0;
}

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)

const int N(1e5 + 10);
const double eps(1e-12);

int n, top; long long t; double M;
struct node { double a, b, p, e; } a[N], stk[N];
inline int operator < (const node &l, const node &r)
	{ return std::fabs(l.p - r.p) < eps ? l.e > r.e : l.p < r.p; }
inline int check(node i, node j, node k)
	{ return (j.p - i.p) * (k.e - j.e) > (j.e - i.e) * (k.p - j.p); }
struct Matrix
{
	double a[3][3];
	double *operator [] (const int &x) { return a[x]; }
	const double *operator [] (const int &x) const { return a[x]; }
} S, P, T[35];

Matrix operator * (const Matrix &a, const Matrix &b)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			for (int k = 0; k < 3; k++)
				c[i][k] += a[i][j] * b[j][k];
	return c;
}

Matrix Init(const node &x)
{
	Matrix c; std::memset(c.a, 0, sizeof c.a);
	c[0][0] = 1 - x.p, c[1][0] = M * x.p, c[2][0] = x.e;
	return c[1][1] = c[2][1] = c[2][2] = 1., c;
}

int main()
{
#ifndef ONLINE_JUDGE
	file(cpp);
#endif
	scanf("%d%lld", &n, &t);
	for (int i = 1; i <= n; i++)
		scanf("%lf%lf%lf", &a[i].a, &a[i].b, &a[i].p),
		a[i].e = a[i].a * a[i].p, M = std::max(M, a[i].b * a[i].p);
	std::sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++)
	{
		if (std::fabs(a[i].p - a[i - 1].p) < eps) continue;
		// if (top <= 1) { stk[++top] = a[i]; continue; }
		while (top > 0 && check(stk[top - 1], stk[top], a[i])) --top;
		stk[++top] = a[i];
	}
	int pos = 1; S[0][2] = 1;
	for (long long tim = 0; tim < t; ++tim)
	{
		double sum = S[0][0] - S[0][1] * M, _ = 0;
		while (pos < top && stk[pos + 1].e - stk[pos].e > sum * (stk[pos + 1].p - stk[pos].p)) ++pos;
		T[0] = Init(stk[pos]); for (int i = 1; i < 35; i++) T[i] = T[i - 1] * T[i - 1];
		for (int i = 34; ~i; i--) if (tim + (1ll << i) < t)
		{
			P = S * T[i], _ = S[0][1] * M - S[0][0];
			if (pos == top || stk[pos].p * _ + stk[pos].e > stk[pos + 1].p * _ + stk[pos + 1].e)
				S = P, tim += (1ll << i);
		}
		S = S * T[0];
	}
	printf("%.10lf\n", S[0][0]);
	return 0;
}

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// }}}
// #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
// clang-format off
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; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#if !defined(DEBUG_LEFT)
#define DEBUG_LEFT "\e[1;36m"
#endif
#if !defined(DEBUG_RIGHT)
#define DEBUG_RIGHT ":\e[m"
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<DEBUG_LEFT<<__LINE__ << DEBUG_RIGHT << " " <<#__VA_ARGS__<<" = "<<__debug_tap<<endl;}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
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) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
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; }
#endif
// clang-format on
// }}}

const int N = 1e5;
ll n, t;
int a[N], b[N];
using D = double;
D p[N];

// DynamicCHT<T, Comp>() : if maximize, use greater<T> for Comp
// === --- ===
// N = no. of f(x)
// .add(a, b) : f(x) = ax + b : amortized O(log N)
// .query(x) : returns f(x), when f minimize f(x) : O(log N)
// .get(x) : returns f that minimize f(x) as (a, b) : O(log N)
// === --- ===
// f can duplicate
/// --- Dynamic Convex Hull Trick Library {{{ ///

#include <functional>
#include <limits>
#include <set>
#include <tuple>

// |ab| < LLONG_MAX/4 ???
template < class T = long long, class Comp = less< T > >
struct DynamicCHT {
  static T INF;
  static T EPS;
  static Comp comp;

private:
  struct Line { // ax + b
    T a, b;
    Line(const T &a, const T &b) : a(a), b(b) {}
    bool operator<(const Line &rhs) const { // (-a, b)
      return a != rhs.a ? comp(rhs.a, a) : comp(b, rhs.b);
    }
  };
  struct CP {
    T numer, denom; // x-coordinate
    Line p;
    CP(const T &n, const T &d, const Line &p) : numer(n), denom(d), p(p) {}
    // p1 < p2
    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;
    }
    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;
  typedef typename set< Line >::iterator It;

public:
  DynamicCHT() {
    // sentinel
    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);
    It pos = lines.insert(p).first;
    if(check(*prev(pos), p, *next(pos))) {
      // ax + b is unnecessary
      lines.erase(pos);
      return;
    }
    cps.erase(CP(*prev(pos), *next(pos)));
    {
      It it = prev(pos);
      while(it != lines.begin() && check(*prev(it), *it, p)) --it;
      // lines (it, pos) is unnecessary
      // [it, pos - 1] : [pos - 1, pos] is still not added
      eraseRange(it, prev(pos));
      // [it + 1, pos - 1]
      lines.erase(++it, pos);
      pos = lines.find(p);
    }
    {
      It it = next(pos);
      while(next(it) != lines.end() && check(p, *it, *next(it))) ++it;
      // lines (pos, it) is unnecessary
      // [pos + 1, it] : [pos, pos + 1] is still not added
      eraseRange(++pos, it);
      // [pos + 1, it - 1]
      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, 1, Line(0, 0))))->p;
    return p.a * x + p.b;
  }
  tuple< T, T > get(const T &x) const {
    const Line &p = (--cps.lower_bound(CP(x, 1, Line(0, 0))))->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:
  // erase cp which can be made from lines [a, b]
  void eraseRange(It a, It b) {
    for(It it = a; it != b; ++it) cps.erase(CP(*it, *next(it)));
  }
  // p1 <= p2 <= p3 , p1 < p3
  // p2 is unnecessary?
  bool check(const Line &p1, const Line &p2, const Line &p3) {
    if(p1.a == INF || p1.a == -INF || p3.a == INF || p3.a == -INF) return 0;
    if(abs(p2.a - p1.a) <= EPS) return 1;
    // cp(p2, p1).x >= cp(p2, p3).x
    return (p2.a - p1.a) * (p3.b - p2.b) >= (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>
T DynamicCHT< T, Comp >::EPS = 1e-11;

template < class T, class Comp >
Comp DynamicCHT< T, Comp >::comp = Comp(); // only for less and greater

/// }}}--- ///

/// --- Matrix mult pow Library {{{ ///

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]);
  }
  // dump(cht);
  cout << fixed << setprecision(8);

  // vector< D > dp(t);
  // dp[0] = cht.query(0);
  // for(int k = 1; k < t; k++) {
  //   D x = m * k - dp[k - 1];
  //   dp[k] = cht.query(x) + dp[k - 1];
  // }
  // cout << dp.back();

  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);
    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;
      if(g == cht.get(x)) {
        v = tv;
        now += j;
      }
    }
    if(now + 1 <= f) {
      v = mult(mats[0], v);
      now++;
    }
    le += now;
  }

  cout << v[0][0];
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int myrand() {return abs((int) mt());}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

typedef long double T;
const T oo = (T) 1e18;
struct LineHull {
    struct Line {
        T a, b;
        Line(T a, T b) : a(a), b(b) {}
    };
    long double intersect(Line ln1, Line ln2) {
        return (long double) (ln2.b - ln1.b) / (ln1.a - ln2.a);
    }
    int bad(Line ln1, Line ln2, Line ln3) {
        return (long double) (ln1.a - ln2.a) * (ln2.b - ln3.b) >= (long double) (ln2.a - ln3.a) * (ln1.b - ln2.b);
    }
    vector<Line> hull;
    vector<long double> pos;
    LineHull() {
        pos.push_back(-oo);
        pos.push_back(+oo);
    }
    void add(T a, T b) {
        Line ln(a, b);
        pos.pop_back();
        while (hull.size() >= 2 && bad(hull[hull.size() - 2], hull[hull.size() - 1], ln)) {
            hull.pop_back();
            pos.pop_back();
        }
        hull.push_back(ln);
        if (hull.size() >= 2) pos.push_back(intersect(hull[hull.size() - 2], hull[hull.size() - 1]));
        pos.push_back(+oo);
    }
    pair<pair<T, T>, T> query(T x) {
        int k = lower_bound(pos.begin(), pos.end(), x) - pos.begin() - 1;
        return mp(mp(hull[k].a, hull[k].b), pos[k + 1]);
    }
} lh;

#define double long double
const int maxn = 1e5 + 5;
int n;
long long t;
int a[maxn];
int b[maxn];
double p[maxn];

void chemthan() {
    cin >> n >> t;
    vector<pair<double, double> > vals;
    double mxa = -1e18, mxb = -1e18;
    FOR(i, 0, n) {
        cin >> a[i] >> b[i] >> p[i];
        chkmax(mxb, p[i] * b[i]);
    }
    FOR(i, 0, n) {
        vals.pb(mp(1 - p[i], p[i] * a[i] - mxb));
        chkmax(mxa, p[i] * a[i] - mxb);
    }
    sort(all(vals));
    FOR(i, 0, n) lh.add(-vals[i].fi, -vals[i].se);
    long long st = 1;
    double res = mxa;
    while (st < t) {
        long long lo = st + 1, hi = t;
        pair<pair<double, double>, double> line = lh.query(res);
        while (lo < hi) {
            long long mi = lo + hi + 1 >> 1;
            double nres = pow(line.fi.fi, mi - st) * res + line.fi.se / (1 - line.fi.fi) * (1 - pow(line.fi.fi, mi - st));
            if (nres <= line.se) {
                lo = mi;
            }
            else {
                hi = mi - 1;
            }
        }
        long long mi = lo + hi + 1 >> 1;
        res = -(pow(line.fi.fi, mi - st) * res + line.fi.se / (1 - line.fi.fi) * (1 - pow(line.fi.fi, mi - st)));
        st = mi;
    }
    cout << prec(9) << t * mxb + res << "\n";
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}