#include <cstdio>
const int DIM = 131072;
const int INF = 0x3f3f3f3f;
using namespace std;
struct segtree {int value, scmax, lscmax, rscmax;} SegTree[DIM * 4];
int N, X, Y, K, M, Array[DIM]; segtree answer;
void build (int node, int left, int right) {
if (left == right) {
SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = 1;
}
else {
int middle = left + (right - left) / 2;
build ( node * 2 , left , middle);
build (node * 2 + 1, middle + 1, right);
SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = right - left + 1;
}
return;
}
void update (int node, int left, int right, int start, int finish, int value) {
int middle = left + (right - left) / 2;
if (SegTree[node].value != 0) {
SegTree[node * 2].value = SegTree[node * 2 + 1].value = SegTree[node].value;
if (SegTree[node].value == 1) {
SegTree[ node * 2 ].scmax = SegTree[ node * 2 ].lscmax = SegTree[ node * 2 ].rscmax = middle - left + 1;
SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = right - middle;
}
else {
SegTree[ node * 2 ].scmax = SegTree[ node * 2 ].lscmax = SegTree[ node * 2 ].rscmax = 0;
SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = 0;
}
SegTree[node].value = 0;
}
if (start <= left && right <= finish) {
SegTree[node].value = value;
if (SegTree[node].value == 1)
SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = right - left + 1;
else
SegTree[node].scmax = SegTree[node].lscmax = SegTree[node].rscmax = 0;
} else {
if (start <= middle)
update ( node * 2 , left , middle, start, finish, value);
if (middle < finish)
update (node * 2 + 1, middle + 1, right, start, finish, value);
SegTree[node].scmax = SegTree[node * 2].rscmax + SegTree[node * 2 + 1].lscmax;
if (SegTree[node].scmax < SegTree[ node * 2 ].scmax)
SegTree[node].scmax = SegTree[ node * 2 ].scmax;
if (SegTree[node].scmax < SegTree[node * 2 + 1].scmax)
SegTree[node].scmax = SegTree[node * 2 + 1].scmax;
if (SegTree[node * 2].lscmax == middle - left + 1)
SegTree[node].lscmax = SegTree[node * 2].lscmax + SegTree[node * 2 + 1].lscmax;
else
SegTree[node].lscmax = SegTree[node * 2].lscmax;
if (SegTree[node * 2 + 1].rscmax == right - middle)
SegTree[node].rscmax = SegTree[node * 2 + 1].rscmax + SegTree[node * 2].rscmax;
else
SegTree[node].rscmax = SegTree[node * 2 + 1].rscmax;
}
return;
}
segtree query (int node, int left, int right, int start, int finish) {
int middle = left + (right - left) / 2;
segtree value1, value2, value3;
if (SegTree[node].value != 0) {
SegTree[node * 2].value = SegTree[node * 2 + 1].value = SegTree[node].value;
if (SegTree[node].value == 1) {
SegTree[ node * 2 ].scmax = SegTree[ node * 2 ].lscmax = SegTree[ node * 2 ].rscmax = middle - left + 1;
SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = right - middle;
}
else {
SegTree[ node * 2 ].scmax = SegTree[ node * 2 ].lscmax = SegTree[ node * 2 ].rscmax = 0;
SegTree[node * 2 + 1].scmax = SegTree[node * 2 + 1].lscmax = SegTree[node * 2 + 1].rscmax = 0;
}
SegTree[node].value = 0;
}
if (start <= left && right <= finish) {
return SegTree[node];
} else {
if (start <= middle)
value1 = query ( node * 2 , left , middle, start, finish);
if (middle < finish)
value2 = query (node * 2 + 1, middle + 1, right, start, finish);
if (start <= middle && !(middle < finish))
return value1;
if (!(start <= middle) && middle < finish)
return value2;
value3.scmax = value1.rscmax + value2.lscmax;
if (value3.scmax < value1.scmax)
value3.scmax = value1.scmax;
if (value3.scmax < value2.scmax)
value3.scmax = value2.scmax;
if (value1.lscmax == middle - left + 1)
value3.lscmax = value1.lscmax + value2.lscmax;
else
value3.lscmax = value1.lscmax;
if (value2.rscmax == right - middle)
value3.rscmax = value2.rscmax + value1.rscmax;
else
value3.rscmax = value2.rscmax;
return value3;
}
}
int main () {
freopen ("hotel.in" ,"r", stdin );
freopen ("hotel.out","w", stdout);
scanf ("%d %d", &N, &M);
build (1, 0, N - 1);
for (int i = 0; i < M; i ++) {
scanf ("%d", &K);
switch (K) {
case 1: {
scanf ("%d %d", &X, &Y); Y += X - 1;
update (1, 0, N - 1, X - 1, Y - 1, -1);
break;
}
case 2: {
scanf ("%d %d", &X, &Y); Y += X - 1;
update (1, 0, N - 1, X - 1, Y - 1, +1);
break;
}
case 3: {
answer = query (1, 0, N - 1, 0, N - 1);
printf ("%d\n", answer.scmax);
break;
}
}
}
return 0;
}