Link
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const N=2e5+10;
int n,m;
int e,la,ra,lb,rb;
struct tree{
int maxn,sum,tag,rt,lt,len;
}tr[N<<2];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p)
{
tr[p].sum=tr[ls(p)].sum+tr[rs(p)].sum;
if(tr[ls(p)].lt==tr[ls(p)].len)tr[p].lt=tr[ls(p)].len+tr[rs(p)].lt;
else tr[p].lt=tr[ls(p)].lt;
if(tr[rs(p)].rt==tr[rs(p)].len)tr[p].rt=tr[rs(p)].len+tr[ls(p)].rt;
else tr[p].rt=tr[rs(p)].rt;
tr[p].maxn=max(tr[ls(p)].maxn,max(tr[rs(p)].maxn,tr[ls(p)].rt+tr[rs(p)].lt));
}
void build(int l,int r,int p)
{
if(l==r)
{
tr[p].sum=tr[p].len=1;
return;
}
tr[p].len=r-l+1;
int mid=(l+r)>>1;
build(l,mid,ls(p));
build(mid+1,r,rs(p));
push_up(p);
}
void push_down_dig(int p)
{
tr[ls(p)].sum=tr[rs(p)].sum=0;
tr[ls(p)].tag=tr[rs(p)].tag=1;
tr[ls(p)].lt=tr[ls(p)].rt=tr[ls(p)].maxn=tr[ls(p)].len;
tr[rs(p)].lt=tr[rs(p)].rt=tr[rs(p)].maxn=tr[rs(p)].len;
}
void push_down_save(int p)
{
tr[ls(p)].sum=tr[ls(p)].len;
tr[rs(p)].sum=tr[rs(p)].len;
tr[ls(p)].tag=tr[rs(p)].tag=2;
tr[ls(p)].lt=tr[ls(p)].rt=tr[ls(p)].maxn=tr[rs(p)].lt=tr[rs(p)].rt=tr[rs(p)].maxn=0;
}
void push_down(int p)
{
if(tr[p].tag==1)
push_down_dig(p);
if(tr[p].tag==2)
push_down_save(p);
tr[p].tag=0;
}
void update_dig(int nl,int nr,int l,int r,int p)
{
if(nl<=l&&r<=nr)
{
tr[p].sum=0;
tr[p].tag=1;
tr[p].lt=tr[p].rt=tr[p].maxn=tr[p].len;
return;
}
int mid=(l+r)>>1;
push_down(p);
if(nl<=mid)update_dig(nl,nr,l,mid,ls(p));
if(nr>mid)update_dig(nl,nr,mid+1,r,rs(p));
push_up(p);
}
int query_save(int nl,int nr,int l,int r,int p)
{
if(nl<=l&&r<=nr)
{
return tr[p].sum;
}
int res=0;
push_down(p);
int mid=(l+r)>>1;
if(nl<=mid)res+=query_save(nl,nr,l,mid,ls(p));
if(nr>mid)res+=query_save(nl,nr,mid+1,r,rs(p));
return res;
}
void update_save2(int nl,int nr,int l,int r,int p)
{
if(nl<=l&&r<=nr)
{
tr[p].sum=tr[p].len;
tr[p].tag=2;
tr[p].lt=tr[p].rt=tr[p].maxn=0;
return;
}
int mid=(l+r)>>1;
push_down(p);
if(nl<=mid)update_save2(nl,nr,l,mid,ls(p));
if(nr>mid)update_save2(nl,nr,mid+1,r,rs(p));
push_up(p);
}
int query_save2(int nl,int nr,int l,int r,int p)
{
if(nl<=l&&r<=nr)
{
return tr[p].len-tr[p].sum;
}
int res=0;
int mid=(l+r)>>1;
push_down(p);
if(nl<=mid)res+=query_save2(nl,nr,l,mid,ls(p));
if(nr>mid)res+=query_save2(nl,nr,mid+1,r,rs(p));
return res;
}
void update_save()
{
int x=query_save(la,ra,1,n,1);
if(x==0)return;
update_dig(la,ra,1,n,1);
int l=lb,r=rb+1;
while(l+1<r)
{
int mid=(l+r)>>1;
if(query_save2(lb,mid,1,n,1)<=x)l=mid;
else r=mid;
}
update_save2(lb,l,1,n,1);
}
int query(int nl,int nr,int l,int r,int p)
{
if(nl<=l&&r<=nr)
{
return tr[p].maxn;
}
push_down(p);
int mid=(l+r)>>1;
int res=0;
if(nl<=mid)res=max(res,query(nl,nr,l,mid,ls(p)));
if(nr>mid)res=max(res,query(nl,nr,mid+1,r,rs(p)));
return res;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,n,1);
for(int i=1;i<=m;i++)
{
scanf("%d",&e);
if(e==0)
{
scanf("%d%d",&la,&ra);
update_dig(la,ra,1,n,1);
}else if(e==1)
{
scanf("%d%d%d%d",&la,&ra,&lb,&rb);
update_save();
}else{
scanf("%d%d",&la,&ra);
printf("%d\n",query(la,ra,1,n,1));
}
}
}