#include <bits/stdc++.h>
#define MAX_N 100000
using namespace std;
FILE *f, *g;
struct arb
{
int st, dr, rez;
int updst, upddr, len;
int seg;
};
arb up[MAX_N * 4 + 1];
void upd(int poz, int st, int dr, int a, int b, int nr)
{
//cout << "UPD " << st << " " << dr << " AT " << a << " " << b << " " << nr << "\n";
up[poz].seg = dr - st + 1;
if(nr == -1)
return;
if(st == a && dr == b)
{
up[poz].updst = nr;
up[poz].upddr = nr;
up[poz].len = up[poz].st = up[poz].dr = up[poz].rez = (dr - st + 1) * (1 - nr);
return;
}
int mid = (st + dr) >> 1;
upd(poz * 2, st, mid, st, mid, up[poz].updst);
upd(poz * 2 + 1, mid + 1, dr, mid + 1, dr, up[poz].upddr);
up[poz].updst = -1;
up[poz].upddr = -1;
if(a >= st && b <= mid)
upd(poz * 2, st, mid, a, b, nr);
else
if(a > mid && b <= dr)
upd(poz * 2 + 1, mid + 1, dr, a, b, nr);
else
{
upd(poz * 2, st, mid, a, mid, nr);
upd(poz * 2 + 1, mid + 1, dr, mid + 1, b, nr);
}
// up[poz].upd = -1;
arb mxst = up[poz * 2];
arb mxdr = up[poz * 2 + 1];
up[poz].len = mxst.len + mxdr.len;
up[poz].st = max(mxst.st, (mxst.seg == mxst.len) * (mxst.seg + mxdr.st));
up[poz].dr = max(mxdr.dr, (mxdr.seg == mxdr.len) * (mxdr.seg + mxst.dr));
up[poz].rez = max(max(max(up[poz].st, up[poz].dr), mxst.rez), mxdr.rez);
up[poz].rez = max(up[poz].rez, mxst.dr + mxdr.st);
// cout << "AVEM REZ IN " << st << " " << dr << " : " << up[poz].rez << "\n";
// cout << "AVEM REZ IN ST DR " << st << " " << dr << " : " << (mxst.seg == mxst.len) << " " << (mxdr.seg == mxdr.len) << "\n";
}
int n;
void ansQues()
{
f = fopen("hotel.in", "r");
g = fopen("hotel.out", "w");
int q;
fscanf(f, "%d%d", &n, &q);
upd(1, 1, n, 1, n, 0);
int tip, i, m;
while(q > 0)
{
fscanf(f, "%d", &tip);
if(tip == 1)
{
fscanf(f, "%d%d", &i, &m);
upd(1, 1, n, i, i + m - 1, 1);
}
if(tip == 2)
{
fscanf(f, "%d%d", &i, &m);
upd(1, 1, n, i, i + m - 1, 0);
}
if(tip == 3)
fprintf(g, "%d\n", up[1].rez);
q --;
}
fclose(f);
fclose(g);
}
int main()
{
ansQues();
return 0;
}