# include <cstdio>
const char *FIN = "hotel.in", *FOU = "hotel.out";
const int MAX = 400005;
struct AI {
int val, st, dr;
} ai[MAX];
int N, P;
inline int max (int a, int b) {
return a > b ? a : b;
}
void buildtree (int nod, int st, int dr) {
ai[nod].val = ai[nod].st = ai[nod].dr = dr - st + 1;
if (st == dr) return ;
int mij = st + dr >> 1;
buildtree (nod << 1, st, mij);
buildtree (nod << 1 | 1, mij + 1, dr);
}
void update (int nod, int st, int dr, int s1, int s2, int op) {
if (s1 <= st && dr <= s2) {
ai[nod].val = ai[nod].st = ai[nod].dr = (op == 1 ? 0 : dr - st + 1);
return ;
}
int mij = st + dr >> 1;
if (ai[nod].val == dr - st + 1) {
ai[nod << 1].val = ai[nod << 1].st = ai[nod << 1].dr = mij - st + 1;
ai[nod << 1 | 1].val = ai[nod << 1 | 1].st = ai[nod << 1 | 1].dr = dr - mij;
}
if (ai[nod].val == 0) {
ai[nod << 1].val = ai[nod << 1].st = ai[nod << 1].dr = 0;
ai[nod << 1 | 1].val = ai[nod << 1 | 1].st = ai[nod << 1 | 1].dr = 0;
}
if (s1 <= mij) update (nod << 1, st, mij, s1, s2, op);
if (mij < s2) update (nod << 1 | 1, mij + 1, dr, s1, s2, op);
ai[nod].st = ai[nod << 1].st;
ai[nod].dr = ai[nod << 1 | 1].dr;
ai[nod].val = max (max (ai[nod << 1].val, ai[nod << 1 | 1].val), ai[nod << 1].dr + ai[nod << 1 | 1].st);
if (ai[nod << 1].st == mij - st + 1)
ai[nod].st += ai[nod << 1 | 1].st;
if (ai[nod << 1 | 1].dr == dr - mij)
ai[nod].dr += ai[nod << 1].dr;
}
int main (void) {
freopen (FIN, "r", stdin);
freopen (FOU, "w", stdout);
scanf ("%d %d", &N, &P);
buildtree (1, 1, N);
for (int op, x, y; P; --P) {
scanf ("%d", &op);
if (op == 3) printf ("%d\n", ai[1].val);
else {
scanf ("%d %d", &x, &y);
update (1, 1, N, x, x + y - 1, op);
}
}
}