2 8
2 15 400
1 13 100
3 26
3 27
3 28
3 29
3 30
3 31
3 32
3 33
 3 8
2 15 400
1 1 200
1 13 100
3 26
3 27
3 28
3 29
3 30
3 31
3 32
3 33

400
400
500
500
800
800
800
800
 600
600
600
700
800
1000
1000
1000

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

const int maxn=200005;
const int mlog=18;
const long long Inf=2e18;
int n,q,mx;
int w[maxn],r[maxn],v[maxn],p[maxn],ip[maxn];
long long a[maxn];

bool cmp(int x,int y){
	if(v[x]!=v[y])return v[x]>v[y];
	else return w[x]<w[y];
}

class Segtree1{
public:
	long long sumw[maxn*4],sumv[maxn*4];
	void update1(int cur,int l,int r,int k,long long val){
		if(l==r){
			sumw[cur]+=val*w[p[l]];
			sumv[cur]+=val*v[p[l]];
			return;
		}
		int mid=l+r>>1;
		if(k<=mid)update1(cur<<1,l,mid,k,val);
		else update1(cur<<1|1,mid+1,r,k,val);
		sumw[cur]=sumw[cur<<1]+sumw[cur<<1|1];
		sumv[cur]=sumv[cur<<1]+sumv[cur<<1|1];
	}
	long long query1(int cur,int l,int r,int vl,int vr){
		if(vl>vr)return 0;
		if(l>=vl&&r<=vr)return sumw[cur];
		int mid=l+r>>1;
		long long sl=mid>=vl?query1(cur<<1,l,mid,vl,vr):0;
		long long sr=mid<vr?query1(cur<<1|1,mid+1,r,vl,vr):0;
		return sl+sr;
	}
	int findp1(int cur,int l,int r,int vl,int vr,long long &val,long long &ans){
		if(l>=vl&&r<=vr&&sumw[cur]<=val){
			val-=sumw[cur];
			ans+=sumv[cur];
			return vr+1;
		}
		if(l==r)return l;
		int mid=l+r>>1;
		int res=mid>=vl?findp1(cur<<1,l,mid,vl,vr,val,ans):vr+1;
		if(res<=vr)return res;
		else return mid<vr?findp1(cur<<1|1,mid+1,r,vl,vr,val,ans):vr+1;
	}
}Tree1[mlog];

class Segtree2{
public:
	long long mn[maxn*4],tag[maxn*4];
	void update2(int cur,int l,int r,int vl,int vr,long long val){
		if(vl>vr)return;
		if(l>=vl&&r<=vr){
			mn[cur]+=val;
			tag[cur]+=val;
			return;
		}
		int mid=l+r>>1;
		if(mid>=vl)update2(cur<<1,l,mid,vl,vr,val);
		if(mid<vr)update2(cur<<1|1,mid+1,r,vl,vr,val);
		mn[cur]=min(mn[cur<<1],mn[cur<<1|1])+tag[cur];
	}
	void modify2(int cur,int l,int r,int k,long long val){
		if(l==r){
			mn[cur]=val;
			return;
		} 
		val-=tag[cur];
		int mid=l+r>>1;
		if(k<=mid)modify2(cur<<1,l,mid,k,val);
		else modify2(cur<<1|1,mid+1,r,k,val);
		mn[cur]=min(mn[cur<<1],mn[cur<<1|1])+tag[cur];
	}
	int findp2(int cur,int l,int r,int vl,int vr,long long val){
		if(l>=vl&&r<=vr&&mn[cur]>val)return vr+1;
		if(l==r)return l;
		val-=tag[cur];
		int mid=l+r>>1;
		int res=mid>=vl?findp2(cur<<1,l,mid,vl,vr,val):vr+1;
		if(res<=vr)return res;
		else return mid<vr?findp2(cur<<1|1,mid+1,r,vl,vr,val):vr+1;
	}
}Tree2[mlog];

void init(int i){
	for(int x=1;x<=n;x++)if(w[x]<(1<<i))
		Tree1[i].update1(1,1,n,ip[x],a[x]);
	for(int x=1;x<=n;x++){
		if(r[x]!=i||a[x]==0)Tree2[i].modify2(1,1,n,ip[x],Inf);
		else Tree2[i].modify2(1,1,n,ip[x],w[x]+Tree1[i].query1(1,1,n,1,ip[x]-1));
	}
}
void work(int x,long long b){
	for(int i=0;i<mlog;i++)if(w[x]<(1<<i)){
		Tree1[i].update1(1,1,n,ip[x],b);
		Tree2[i].update2(1,1,n,ip[x]+1,n,b*w[x]);
	}
	int j=r[x];
	if(!a[x])Tree2[j].modify2(1,1,n,ip[x],w[x]+Tree1[j].query1(1,1,n,1,ip[x]-1));
	a[x]+=b;
	if(!a[x])Tree2[j].modify2(1,1,n,ip[x],Inf);
}
long long answer(long long c){
	long long ans=0;
	int pt=1;
	for(int i=mlog-1;i>=0;i--)if(c>=(1<<i)){
		long long val=c-(1<<i);
		int rpt=Tree2[i].findp2(1,1,n,pt,n,c+Tree1[i].query1(1,1,n,1,pt-1));
		if(rpt>pt)pt=Tree1[i].findp1(1,1,n,pt,rpt-1,val,ans);
		c=(1<<i)+val;
		if(pt<=n){
			long long d=min(a[p[pt]],c/w[p[pt]]);
			c-=d*w[p[pt]];
			ans+=d*v[p[pt]];
			pt++;
		}
		if(pt>n)break;
		assert(c<(1<<i));
	}
	return ans;
}

int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++){
		scanf("%lld%d%d",&a[i],&w[i],&v[i]);
		p[i]=i;
		while(w[i]>=(1<<r[i]+1))r[i]++;
	}
	sort(p+1,p+1+n,cmp);
	for(int i=1;i<=n;i++)ip[p[i]]=i;
	for(int i=0;i<mlog;i++)init(i);
	while(q--){
		int op;
		scanf("%d",&op);
		if(op==1){
			int b,x;
			scanf("%d%d",&b,&x);
			work(x,b);
		}
		else if(op==2){
			int b,x;
			scanf("%d%d",&b,&x);
			work(x,-b);
		}
		else{
			long long c;
			scanf("%lld",&c);
			printf("%lld\n",answer(c));
		}
	}
	return 0;
}
