
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r,n=0,ln=0,rn=0,m=0,c=-1;
};
node tree[1000010];
int p,x,y;
void down(int s){
if (tree[s].c==-1) return;
tree[s*2].c=tree[s].c;
tree[s*2+1].c=tree[s].c;
tree[s*2].m=tree[s].c*(tree[s*2].r-tree[s*2].l+1);
tree[s*2+1].m=tree[s].c*(tree[s*2+1].r-tree[s*2+1].l+1);
tree[s*2].n=tree[s*2].m;
tree[s*2+1].n=tree[s*2+1].m;
tree[s*2].ln=tree[s*2].m;
tree[s*2+1].ln=tree[s*2+1].m;
tree[s*2].rn=tree[s*2].m;
tree[s*2+1].rn=tree[s*2+1].m;
tree[s].c=-1;
return;
}
void build(int p,int l,int r){
tree[p].l=l;
tree[p].r=r;
if (l==r) {
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
return;
}
void update(int s,int p){
if (p==s) return;
int mid=(tree[p].l+tree[p].r)/2;
if (tree[s].l<=mid) update(s,p*2);
else if (tree[s].l>mid) update(s,p*2+1);
tree[p].m=tree[p*2].m+tree[p*2+1].m;
if (tree[p*2].ln==tree[p*2].r-tree[p*2].l+1) tree[p].ln=tree[p*2].m+tree[p*2+1].ln;
else tree[p].ln=tree[p*2].ln;
if (tree[p*2+1].rn==tree[p*2+1].r-tree[p*2+1].l+1) tree[p].rn=tree[p*2+1].m+tree[p*2].rn;
else tree[p].rn=tree[p*2+1].rn;
tree[p].n=max(max(tree[p*2].n,tree[p*2+1].n),tree[p*2].rn+tree[p*2+1].ln);
return;
}
node search(int l,int r,int p){
down(p);
int mid=(tree[p].l+tree[p].r)/2;
if (tree[p].l==l&&r==tree[p].r) return tree[p];
else if (r<=mid) return search(l,r,p*2);
else if (l>mid) return search(l,r,p*2+1);
else {
node t,L,R;
L=search(l,mid,p*2);
R=search(mid+1,r,p*2+1);
t.l=L.l;
t.r=R.r;
if (L.ln==L.r-L.l+1) t.ln=L.m+R.ln;
else t.ln=tree[p*2].ln;
if (R.rn==R.r-R.l+1) t.rn=R.m+L.rn;
else t.rn=R.rn;
t.n=max(max(L.n,R.n),L.rn+R.ln);
return t;
}
}
int search2(int l,int r,int p){
down(p);
int mid=(tree[p].l+tree[p].r)/2;
if (tree[p].l==l&&r==tree[p].r) return tree[p].m;
else if (r<=mid) return search2(l,r,p*2);
else if (l>mid) return search2(l,r,p*2+1);
else {
return search2(l,mid,p*2)+search2(mid+1,r,p*2+1);
}
}
void change1(int x,int y,int t,int s){
if (tree[s].l==x&&y==tree[s].r){
if (t==1) {
tree[s].c=1;
tree[s].m=tree[s].n=tree[s].ln=tree[s].rn=tree[s].r-tree[s].l+1;
}
else if (t==0) {
tree[s].c=0;
tree[s].m=tree[s].n=tree[s].ln=tree[s].rn=0;
}
update(s,1);
return;
}
down(s);
int mid=(tree[s].l+tree[s].r)/2;
if (y<=mid) change1(x,y,t,2*s);
else if (x>mid) change1(x,y,t,2*s+1);
else{
change1(x,mid,t,2*s);
change1(mid+1,y,t,2*s+1);
}
return;
}
void change2(int x,int y,int k,int s){
if (k==0) return;
down(s);
int mid=(tree[s].l+tree[s].r)/2;
if (x==tree[s].l&&y==tree[s].r&&k>=tree[s].m) change1(x,y,0,1);
else if (y<=mid) change2(x,y,k,2*s);
else if (x>mid) change2(x,y,k,2*s+1);
else{
if (k<=tree[s*2].m) change2(x,mid,k,2*s);
else{
k-=tree[s*2].m;
change1(x,mid,0,1);
if (k<=tree[s*2+1].m){
change2(mid+1,y,k,2*s+1);
}
else change1(mid+1,y,0,2*s+1);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n,m;
cin>>n>>m;
build(1,1,n);
while (m--)
{
cin>>p>>x>>y;
if (p==0){
change1(x,y,1,1);
}
else if (p==1){
int x1,y1;
cin>>x1>>y1;
int num=y-x+1-search2(x,y,1);
change1(x,y,1,1);
change2(x1,y1,num,1);
}
else{
cout<<search(x,y,1).n<<'\n';
}
}
return 0;
}