#include <iostream>
#include <fstream>
using namespace std;
#define maxn 100001
struct info {
int prefix, sufix, maxx;
};
info aint[4*maxn];
int lazy[4*maxn];
void build( int l, int r, int vf ) {
aint[vf].prefix = aint[vf].sufix = aint[vf].maxx = r - l + 1;
if( l == r )
return;
build( l, (l+r)/2, vf*2 );
build( (l+r)/2+1, r, vf*2+1 );
}
// val este -1 cand devine ocupat, este 1 cand devine liber
void push_lazy( int l, int r, int vf ) {
if( lazy[vf] != 0 ) {
if( l == r ) {
if( lazy[vf] == -1 )
aint[vf].prefix = aint[vf].sufix = aint[vf].maxx = 0;
else
aint[vf].prefix = aint[vf].sufix = aint[vf].maxx = 1;
lazy[vf] = 0;
return;
}
if( lazy[vf] == 1 )
aint[vf].prefix = aint[vf].sufix = aint[vf].maxx = r - l + 1;
else
aint[vf].prefix = aint[vf].sufix = aint[vf].maxx = 0;
lazy[2*vf] = lazy[2*vf+1] = lazy[vf];
lazy[vf] = 0;
}
}
void update( int st, int dr, int ql, int qr, int vf, int val ) {
push_lazy( st, dr, vf );
if( st > qr || dr < ql )
return;
if( ql <= st && dr <= qr ) {
lazy[vf] = val;
push_lazy( st, dr, vf );
} else {
update( st, (st+dr)/2, ql, qr, 2*vf, val );
update( (st+dr)/2+1, dr, ql, qr, 2*vf+1, val );
}
if( st != dr ) {
aint[vf].maxx = max( max( aint[2*vf].maxx, aint[2*vf+1].maxx ), aint[2*vf].sufix + aint[2*vf+1].prefix );
if( aint[2*vf].prefix == (st+dr)/2-st+1 )
aint[vf].prefix = (st+dr)/2-st+1 + aint[2*vf+1].prefix;
else
aint[vf].prefix = aint[2*vf].prefix;
if( aint[2*vf+1].sufix == dr - (st+dr)/2 )
aint[vf].sufix = dr - (st+dr)/2 + aint[2*vf].sufix;
else
aint[vf].sufix = aint[2*vf+1].sufix;
}
}
int main() {
int n, i, p, cer, l, r;
ifstream cin ("hotel.in");
ofstream cout ("hotel.out");
cin >> n >> p;
build( 1, n, 1 );
for( i = 0; i < p; i++ ) {
cin >> cer;
if( cer == 3 )
cout << aint[1].maxx << "\n";
else {
cin >> l >> r;
r = l + r - 1;
if( cer == 2 )
cer = 1;
else
cer = -1;
update( 1, n, l, r, 1, cer );
}
}
return 0;
}