using namespace std;
#include<iostream>
#include<fstream>
#include<vector>
ifstream fin("hotel.in");
ofstream fout("hotel.out");
#define NMAX 100001
int n, Q, op;
struct Nod{
bool lazy;
int start, finish;
int maxim;
} aint[4*NMAX];
void build(int nod, int st, int dr) {
if (st == dr) {
aint[nod].lazy = 0;
aint[nod].start = 1;
aint[nod].finish = 1;
aint[nod].maxim = 1;
return;
}
int mid = (st+dr)/2;
build(nod*2, st, mid);
build(nod*2+1, mid+1, dr);
aint[nod].lazy = 0;
aint[nod].start = dr-st+1;
aint[nod].finish = dr-st+1;
aint[nod].maxim = dr-st+1;
}
void update(int nod, int st, int dr, int L, int R, int op) {
if (L <= st && dr <= R) {
aint[nod].lazy = 1;
if (op == 1) {
aint[nod].start = aint[nod].finish = aint[nod].maxim = 0; ///se ocupa tot intervalul [L, R]
} else {
aint[nod].start = aint[nod].finish = aint[nod].maxim = dr-st+1; ///se elibereaza tot intervalul [L, R]
}
return;
}
int mid = (st+dr)/2;
if (aint[nod].lazy) {
if (aint[nod].maxim > 0) {
aint[2*nod] = {1, mid-st+1, mid-st+1, mid-st+1}; ///eliberez tot intervalul
aint[2*nod+1] = {1, dr-mid, dr-mid, dr-mid}; ///eliberez tot intervalul
} else {
aint[2*nod] = {1, 0, 0, 0}; ///acopar tot intervalul
aint[2*nod+1] = {1, 0, 0, 0}; ///acopar tot intervalul
}
aint[nod].lazy = 0;
}
if (L <= mid) {
update(2*nod, st, mid, L, R, op);
}
if (mid < R) {
update(2*nod+1, mid+1, dr, L, R, op);
}
aint[nod].maxim = max(max(aint[nod*2].maxim, aint[nod*2+1].maxim), aint[2*nod].finish + aint[2*nod+1].start);
if (aint[nod*2].start == mid-st+1) {
aint[nod].start = aint[nod*2].start + aint[nod*2+1].start; ///unesc
} else {
aint[nod].start = aint[nod*2].start;
}
if (aint[nod*2+1].finish == dr-mid) {
aint[nod].finish = aint[nod*2].finish + aint[nod*2+1].finish; ///unesc
} else {
aint[nod].finish = aint[nod*2+1].finish;
}
}
int main() {
fin >> n >> Q;
build(1, 1, n);
for (int i = 1; i<=Q; i++) {
fin >> op;
if (op == 1 || op == 2) {
int poz, lung;
fin >> poz >> lung;
update(1, 1, n, poz, poz+lung-1, op);
} else {
fout << aint[1].maxim << "\n";
}
}
return 0;
}