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

typedef long long LL;

const int N=200000,C=53;
const LL INF=(1LL<<53)-1;

int n,cq,pos[N+9];
struct thing{
  LL cnt,w,v;
  int id;
}a[N+9];

bool cmp(const thing &a,const thing &b){return a.v>b.v||a.v==b.v&&a.w<b.w;}

void into(){
  scanf("%d%d",&n,&cq);
  for (int i=1;i<=n;++i){
	scanf("%lld%lld%lld",&a[i].cnt,&a[i].w,&a[i].v);
	a[i].id=i;
  }
  sort(a+1,a+n+1,cmp);
  for (int i=1;i<=n;++i) pos[a[i].id]=i;
}

struct tree{
  LL cnt,w[C],v[C],mn[C];
}tr[N*4+9];

void Pushup(int k){
  int ls=k<<1,rs=k<<1|1;
  for (int i=0;i<C;++i){
	tr[k].w[i]=tr[ls].w[i]+tr[rs].w[i];
	tr[k].v[i]=tr[ls].v[i]+tr[rs].v[i];
	tr[k].mn[i]=min(tr[ls].mn[i],tr[ls].w[i]+tr[rs].mn[i]);
  }
}

void Build(int l,int r,int k){
  if (l==r){
	tr[k].cnt=a[l].cnt;
	for (int i=0;i<C;++i)
	  if (a[l].w<1LL<<i){
		tr[k].w[i]=tr[k].cnt*a[l].w;
		tr[k].v[i]=tr[k].cnt*a[l].v;
		tr[k].mn[i]=INF;
	  }else{
		tr[k].w[i]=tr[k].v[i]=0;
		tr[k].mn[i]=tr[k].cnt?a[l].w:INF;
	  }
	return;
  }
  int mid=l+r>>1;
  Build(l,mid,k<<1);
  Build(mid+1,r,k<<1|1);
  Pushup(k);
}

void Change_add(int p,LL v,int l,int r,int k){
  if (l==r){
	tr[k].cnt+=v;
	for (int i=0;i<C;++i)
	  if (a[l].w<1LL<<i){
		tr[k].w[i]=tr[k].cnt*a[l].w;
		tr[k].v[i]=tr[k].cnt*a[l].v;
		tr[k].mn[i]=INF;
	  }else{
		tr[k].w[i]=tr[k].v[i]=0;
		tr[k].mn[i]=tr[k].cnt?a[l].w:INF;
	  }
	return;
  }
  int mid=l+r>>1;
  p<=mid?Change_add(p,v,l,mid,k<<1):Change_add(p,v,mid+1,r,k<<1|1);
  Pushup(k);
}

LL lim,ans;

int Query_nxt0(int id,int l,int r,int k){
  if (l==r) return l;
  int mid=l+r>>1,y=k<<1;
  if (tr[y].mn[id]<=lim) return Query_nxt0(id,l,mid,y);
  else{
	ans+=tr[y].v[id];
	lim-=tr[y].w[id];
	return Query_nxt0(id,mid+1,r,k<<1|1);
  }
}

int Query_nxt1(int id,int l,int r,int k){
  if (l==r) return l;
  int mid=l+r>>1,y=k<<1;
  if (tr[y].w[id]<=lim){
	ans+=tr[y].v[id];
	lim-=tr[y].w[id];
	return Query_nxt1(id,mid+1,r,k<<1|1);
  }else return Query_nxt1(id,l,mid,y);
}

int Query_nxt(int id,int p,int l,int r,int k){
  if (l==r) return n+1;
  int mid=l+r>>1,res;
  if (p<=mid){
	if ((res=Query_nxt(id,p,l,mid,k<<1))<=n) return res;
	int y=k<<1|1;
	if (tr[y].mn[id]<=lim) return Query_nxt0(id,mid+1,r,y);
	else if (tr[y].w[id]>lim) return Query_nxt1(id,mid+1,r,y);
	  else ans+=tr[y].v[id],lim-=tr[y].w[id];
  }else res=Query_nxt(id,p,mid+1,r,k<<1|1);
  return res;
}

void work(){
  Build(0,n,1);
}

void outo(){
  for (;cq--;){
	int opt;
	scanf("%d",&opt);
	if (opt<=2){
	  int k,p;
	  scanf("%d%d",&k,&p);
	  p=pos[p];k=opt==1?k:-k;
	  a[p].cnt+=k;
	  Change_add(p,k,0,n,1);
	}else{
	  scanf("%lld",&lim);
	  if (lim>=INF) lim=INF-1;
	  ans=0;
	  for (int i=C-1,p=0;i>=0;--i){
		if (lim<1LL<<i) continue;
		p=Query_nxt(i,p,0,n,1);
		if (p>n) break;
		LL c=lim/a[p].w;
		ans+=c*a[p].v;
		lim-=c*a[p].w;
	  }
	  printf("%lld\n",ans);
	}
  }
}

int main(){
  into();
  work();
  outo();
  return 0;
}