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;

#define LL long long
#define ls node << 1
#define rs node << 1 | 1

const int maxN = 2e5 + 10;
const LL INF = 2e18;

struct Node
{
	int w, v, id;
}a[maxN + 1];

int n, q;
int ts[maxN + 1], pos[maxN + 1];
LL val[maxN + 1];

struct Seg1
{	
	int k;
	LL sw[maxN * 4 + 1], sv[maxN * 4 + 1];

	void pushup(int node) 
	{ 
		sw[node] = sw[ls] + sw[rs];
		sv[node] = sv[ls] + sv[rs];
	}

	void build(int node, int l, int r)
	{
		if(l == r)
		{
			if(a[l].w <= (1 << k)) 
			{
				sv[node] = val[l] * a[l].v;
				sw[node] = val[l] * a[l].w;
			}
			return;
		}
		int mid = (l + r) >> 1;
		build(ls, l, mid);
		build(rs, mid + 1, r);
		pushup(node);
	}

	void change(int node, int l, int r, int x, int v)
	{
		if(l == r)
		{
			sv[node] += 1ll * v * a[l].v;
			sw[node] += 1ll * v * a[l].w;
			return;
		}
		int mid = (l + r) >> 1;
		if(x <= mid) change(ls, l, mid, x, v);
		else change(rs, mid + 1, r, x, v);
		pushup(node);
	}

	LL queryv(int node, int l, int r, int x, int y)
	{
		if(x > y) return 0ll;
		if(x <= l && r <= y) return sv[node];
		int mid = (l + r) >> 1; LL ans = 0;
		if(x <= mid) ans += queryv(ls, l, mid, x, y);
		if(y > mid) ans += queryv(rs, mid + 1, r, x, y);
		return ans;
	}

	LL queryw(int node, int l, int r, int x, int y)
	{
		if(x > y) return 0ll;
		if(x <= l && r <= y) return sw[node];
		int mid = (l + r) >> 1; LL ans = 0;
		if(x <= mid) ans += queryw(ls, l, mid, x, y);
		if(y > mid) ans += queryw(rs, mid + 1, r, x, y);
		return ans;
	}

	int find(int node, int l, int r, LL v)
	{
		if(l == r) return l;
		int mid = (l + r) >> 1;
		if(sw[ls] < v) return find(rs, mid + 1, r, v - sw[ls]);
		else return find(ls, l, mid, v);
	}
}T1[19];

struct Seg2
{
	int k;
	LL mn[maxN * 4 + 1], tag[maxN * 4 + 1];

	void pushup(int node) { mn[node] = min(mn[ls], mn[rs]); }

	void pushdown(int node)
	{
		if(!tag[node]) return;
		LL v = tag[node]; tag[node] = 0;
		if(mn[ls] != INF)
		{
			mn[ls] += v;
			tag[ls] += v;
		}
		if(mn[rs] != INF)
		{
			mn[rs] += v;
			tag[rs] += v;
		}
	}

	void build(int node, int l, int r)
	{
		if(l == r)
		{
			if(!k) 
			{ 
				if(a[l].w <= 1) mn[node] = a[l].w;
				else mn[node] = INF;
				return; 
			}
			if(a[l].w > (1 << k - 1) && a[l].w <= (1 << k) && val[l]) mn[node] = (k ? T1[k - 1].queryw(1, 1, n, 1, l - 1) : 0) + a[l].w;
			else mn[node] = INF;
			return;
		}
		int mid = (l + r) >> 1;
		build(ls, l, mid);
		build(rs, mid + 1, r);
		pushup(node);
	}

	void change(int node, int l, int r, int x, int y, LL v)
	{
		if(x > y) return;
		if(x <= l && r <= y)
		{
			if(mn[node] != INF)
			{
				mn[node] += v;
				tag[node] += v;
			}
			return;
		}
		pushdown(node);
		int mid = (l + r) >> 1;
		if(x <= mid) change(ls, l, mid, x, y, v);
		if(y > mid) change(rs, mid + 1, r, x, y, v);
		pushup(node);
	}

	void modify(int node, int l, int r, int x, LL v)
	{
		if(l == r) { mn[node] = v; return; }
		pushdown(node);
		int mid = (l + r) >> 1;
		if(x <= mid) modify(ls, l, mid, x, v);
		else modify(rs, mid + 1, r, x, v);
		pushup(node);
	}

	int find(int node, int l, int r, int x, LL v)
	{
		if(r < x || mn[node] > v) return -1;
		if(l == r) return l;
		pushdown(node);
		int mid = (l + r) >> 1, t = find(ls, l, mid, x, v);
		return t == -1 ? find(rs, mid + 1, r, x, v) : t;
	}
}T2[19];

inline LL read()
{
	LL num = 0, f = 1;
	char ch = getchar();
	while( !isdigit( ch ) ) { if(ch == '-') f = -1; ch = getchar(); }
	while( isdigit( ch ) ) num = (num << 3) + (num << 1) + (ch ^ 48), ch = getchar();
	return num * f;
}

inline bool cmp(Node a, Node b)
{
	if(a.v == b.v) return a.w < b.w;
	return a.v > b.v;
}

inline void add(int x, int v)
{
	int c = 0;
	while((1 << c) < a[x].w) c ++;
	for(int i = c; i <= 18; i++) 
	{
		T1[i].change(1, 1, n, x, v);
		if(i > c) T2[i].change(1, 1, n, x + 1, n, 1ll * v * a[x].w);
	}
	if(!val[x]) T2[c].modify(1, 1, n, x, (c ? T1[c - 1].queryw(1, 1, n, 1, x - 1) : 0) + a[x].w);
	val[x] += v;
	if(!val[x]) T2[c].modify(1, 1, n, x, INF);
}

inline LL query(LL x)
{
	int i = 18, now = 1; LL ans = 0;
	while(1)
	{
		while(i && x <= (1ll << i - 1)) i --;
		LL tp = (i ? T1[i - 1].queryw(1, 1, n, 1, now - 1) : 0); 
		int p = T2[i].find(1, 1, n, now, tp + x);
		if(p == -1 && i) p = T1[i - 1].find(1, 1, n, tp + x);
		if(p == -1) break;
		ans += (i ? T1[i - 1].queryv(1, 1, n, now, p - 1) : 0);
		x -= (i ? T1[i - 1].queryw(1, 1, n, now, p - 1) : 0);
		LL s = min(val[p], x / a[p].w);
		x -= 1ll * a[p].w * s; ans += 1ll * a[p].v * s;
		now = p + 1;
		if(!x || now > n) break;
	}
	return ans;
}

int main()
{
	n = read(), q = read();
	for(int i = 1; i <= n; i++)
	{
		ts[i] = read();
		a[i].w = read(), a[i].v = read();
		a[i].id = i;
	}

	sort(a + 1, a + n + 1, cmp);
	
	for(int i = 1; i <= n; i++) pos[ a[i].id ] = i, val[i] = ts[ a[i].id ];

	for(int i = 0; i <= 18; i++) 
	{
		T1[i].k = T2[i].k = i;
		T1[i].build(1, 1, n);
		T2[i].build(1, 1, n);
	}

	while(q --)
	{
		int op = read();
		if(op != 3)
		{
			int k = read(), d = pos[ read() ];
			add(d, op == 1 ? k : -k);
		}
		else 
		{
			LL x = read();
			printf("%lld\n", query(x));	
		}
	}
	return 0;
}
