Ivan plays some computer game. There are $$$n$$$ quests in the game. Each quest can be upgraded once, this increases the reward for its completion. Each quest has $$$3$$$ parameters $$$a_{i}$$$, $$$b_{i}$$$, $$$p_{i}$$$: reward for completing quest before upgrade, reward for completing quest after upgrade ($$$a_{i} < b_{i}$$$) and probability of successful completing the quest.Each second Ivan can try to complete one quest and he will succeed with probability $$$p_{i}$$$. In case of success Ivan will get the reward and opportunity to upgrade any one quest (not necessary the one he just completed). In case of failure he gets nothing. Quests do not vanish after completing.Ivan has $$$t$$$ seconds. He wants to maximize expected value of his total gain after $$$t$$$ seconds. Help him to calculate this value.

First line contains $$$2$$$ integers $$$n$$$ ($$$ 1 \le n \le 10^{5}$$$) and $$$t$$$ ($$$ 1 \le t \le 10^{10}$$$) — number of quests and total time. Following $$$n$$$ lines contain description of quests. Each description is $$$3$$$ numbers $$$a_{i}$$$ $$$b_{i}$$$ $$$p_{i}$$$ ($$$1 \le a_{i} < b_{i} \le 10^{8}$$$, $$$0 < p_{i} < 1$$$) — reward for completing quest before upgrade, reward for completing quest after upgrade and probability of successful completing of quest. $$$a_{i}$$$ and $$$b_{i}$$$ are integers. All probabilities are given with at most $$$9$$$ decimal places.

Print the expected value. Your answer will be accepted if absolute or relative error does not exceed $$$10^{-6}$$$. Formally, let your answer be $$$a$$$, and the jury's answer be $$$b$$$. Your answer is considered correct if $$$\frac{|a-b|}{max(b, \,\, 1)} \le 10^{-6}$$$.

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

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

// ====================================
//   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>
#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 <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 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<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;

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

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;
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 <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<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<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 <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;
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));

}

// 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);
}

//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 <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';
}

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

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

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

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

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

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

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

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

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

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

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

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 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<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>
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>

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

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

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>
// 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

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

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

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]);
}

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

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

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