#include <iostream>
#include <fstream>
using namespace std;
ifstream fin ("hotel.in");
ofstream fout ("hotel.out");
const int maxN = 4e5 + 5;
struct nod {
int pref, suf, best, sum;
} t[maxN];
bool marked[maxN];
void push(int node, int st, int dr) {
if(marked[node] == true) {
int mij = (st + dr) / 2;
if(t[node].best != 0) {
t[node*2] = {mij-st+1,mij-st+1,mij-st+1,mij-st+1};
t[node*2+1] = {dr-mij, dr-mij, dr-mij, dr-mij};
} else {
t[node*2] = {0, 0, 0, mij-st+1};
t[node*2+1] = {0, 0, 0, dr-mij};
}
marked[node] = false;
marked[node*2] = marked[node*2+1] = true;
}
}
nod combine(nod l, nod r) {
nod res;
res.sum = l.sum + r.sum;
res.pref = l.pref; if(l.pref == l.sum) res.pref += r.pref;
res.suf = r.suf; if(r.suf == r.sum) res.suf += l.suf;
res.best = max(max(l.best, r.best), l.suf + r.pref);
return res;
}
void build (int node, int st, int dr) {
if(st > dr) return ;
if(st == dr) {
t[node] = {dr-st+1,dr-st+1,dr-st+1,dr-st+1};
} else {
int mij = (st + dr) / 2;
build(node * 2, st, mij);
build(node * 2 + 1, mij+1, dr);
t[node] = combine(t[node*2], t[node*2+1]);
}
}
void update(int node, int st, int dr, int l, int r, int new_val) {
if(l > r) return ;
if(l == st && dr == r) {
if(new_val == 0) {
t[node] = {0, 0, 0, dr-st+1};
} else {
t[node] = {dr-st+1, dr-st+1, dr-st+1, dr-st+1};
}
marked[node] = true;
} else {
push(node, st, dr);
int mij = (st + dr) / 2;
update(node*2, st, mij, l, min(r, mij), new_val);
update(node*2+1, mij+1, dr, max(l, mij+1), r, new_val);
t[node] = combine(t[node*2], t[node*2+1]);
}
}
int main()
{
int n, p; fin >> n >> p;
build (1, 1, n);
for(int i = 1; i <= p; ++i) {
int op; fin >> op;
if(op == 1) {
int poz, m; fin >> poz >> m;
update(1, 1, n, poz, poz+m-1, 0);
} else if(op == 2) {
int poz, m; fin >> poz >> m;
update(1, 1, n, poz, poz+m-1, 1);
} else {
fout << t[1].best << "\n";
}
}
return 0;
}