#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
int l,r,x,f;
int u,lu,ru;
}t[1000005];
node merge(node a,node b){
node ans;
ans.l=a.l,ans.r=b.r,ans.x=a.x+b.x,ans.f=-1;
ans.u=max(max(a.u,b.u),a.ru+b.lu);
ans.lu=(a.lu==a.r-a.l+1?a.lu+b.lu:a.lu);
ans.ru=(b.ru==b.r-b.l+1?b.ru+a.ru:b.ru);
return ans;
}
void build(int rt,int l,int r){
if (l==r){
t[rt].l=l,t[rt].r=r;
t[rt].x=1,t[rt].f=-1,t[rt].u=t[rt].lu=t[rt].ru=0;
return;
}
int mid=(l+r)/2;
build(rt*2,l,mid);build(rt*2+1,mid+1,r);
t[rt]=merge(t[rt*2],t[rt*2+1]);
}
void update(int rt,int x){
t[rt].x=(t[rt].r-t[rt].l+1)*x,t[rt].f=x;
if (x==0)t[rt].u=t[rt].lu=t[rt].ru=t[rt].r-t[rt].l+1;
else t[rt].u=t[rt].lu=t[rt].ru=0;
}
void pushdown(int rt){
assert(t[rt].f!=-1);
update(rt*2,t[rt].f);
update(rt*2+1,t[rt].f);
t[rt].f=0;
}
void assign(int rt,int l,int r,int x){
if (t[rt].l>r||t[rt].r<l)return;
if (t[rt].l>=l&&t[rt].r<=r){
update(rt,x);
return;
}
if (t[rt].f!=-1)pushdown(rt);
assign(rt*2,l,r,x);
assign(rt*2+1,l,r,x);
t[rt]=merge(t[rt*2],t[rt*2+1]);
}
int sum(int rt,int l,int r){
if (t[rt].l>r||t[rt].r<l)return 0;
if (t[rt].l>=l&&t[rt].r<=r)return t[rt].x;
if (t[rt].f!=-1)pushdown(rt);
return sum(rt*2,l,r)+sum(rt*2+1,l,r);
}
node query(int rt,int l,int r){
if (t[rt].l>=l&&t[rt].r<=r)return t[rt];
if (t[rt].f!=-1)pushdown(rt);
int mid=(t[rt].l+t[rt].r)/2;
if (r<=mid)return query(rt*2,l,r);
if (l>mid)return query(rt*2+1,l,r);
return merge(query(rt*2,l,r),query(rt*2+1,l,r));
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
build(1,1,n);
while (m--){
int op,l0,r0,l1,r1;
cin>>op>>l0>>r0;
if (op==0){
assign(1,l0,r0,0);
}
if (op==1){
cin>>l1>>r1;
int p=sum(1,l0,r0);
assign(1,l0,r0,0);
int l=l1,r=r1,mid;
while (l<r){
mid=(l+r)/2;
if (mid-l1+1-sum(1,l1,mid)>=p)r=mid;
else l=mid+1;
}
assign(1,l1,r,1);
}
if (op==2){
cout<<query(1,l0,r0).u<<endl;
}
}
return 0;
}