#include <cstdio>
#define NMAx 101000
#define left_son(x) (2*x)
#define right_son(x) (2*x+1)
#define max(a,b) ((a)>(b)?(a):(b))
#define set(nod,val) (ARB[nod].left=ARB[nod].right=ARB[nod].info=val)
using namespace std;
struct ArbNod{int left,right,info;} ARB[2*NMAx];
int n,T,A,B,M;
void Build(int nod,int left,int right) {
set(nod,right-left+1);
if(left==right)
return;
int mid=(left+right)>>1;
Build(left_son(nod),left,mid);
Build(right_son(nod),mid+1,right);
}
ArbNod Unite(int nod,int left,int right) {
ArbNod Sol;
int mid=(left+right)>>1;
Sol.left=ARB[left_son(nod)].left;
if(ARB[left_son(nod)].left==mid-left+1)
Sol.left+=ARB[right_son(nod)].left;
Sol.right=ARB[right_son(nod)].right;
if(ARB[right_son(nod)].right==right-mid)
Sol.right+=ARB[left_son(nod)].right;
Sol.info=max(ARB[left_son(nod)].info,ARB[right_son(nod)].info);
Sol.info=max(Sol.info,ARB[left_son(nod)].right+ARB[right_son(nod)].left);
return Sol;
}
void Update(int nod,int left,int right,int VAL) {
if(A<=left&&right<=B) {
if(VAL==1)
set(nod,0);
else
set(nod,right-left+1);
return;
}
if(left==right)
return;
int mid=(left+right)>>1;
if(ARB[nod].info==right-left+1) {
set(left_son(nod),mid-left+1);
set(right_son(nod),right-mid);
}
else
if(ARB[nod].info==0) {
set(left_son(nod),0);
set(right_son(nod),0);
}
if(A<=mid)
Update(left_son(nod),left,mid,VAL);
if(B>=mid+1)
Update(right_son(nod),mid+1,right,VAL);
ARB[nod]=Unite(nod,left,right);
}
int main() {
int i,cod;
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
scanf("%d %d",&n,&T);
Build(1,1,n);
for(i=1;i<=T;i++) {
scanf("%d",&cod);
if(cod==3)
printf("%d\n",ARB[1].info);
else {
scanf("%d %d",&A,&B);
B+=A-1;
Update(1,1,n,cod);
}
}
return 0;
}