#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,m;
struct node{
int lmax,rmax,maxn,tag,sum,len;
}tree[N<<2];
void pushdown(int k){
if(tree[k].tag==1){
tree[k*2].lmax=tree[k*2].rmax=tree[k*2].maxn=tree[k*2].len;
tree[k*2].sum=0;
tree[k*2].tag=1;
tree[k*2+1].lmax=tree[k*2+1].rmax=tree[k*2+1].maxn=tree[k*2+1].len;
tree[k*2+1].sum=0;
tree[k*2+1].tag=1;
tree[k].tag=0;
}else if(tree[k].tag==2){
tree[k*2].lmax=tree[k*2].rmax=tree[k*2].maxn=0;
tree[k*2].sum=tree[k*2].len;
tree[k*2].tag=2;
tree[k*2+1].lmax=tree[k*2+1].rmax=tree[k*2+1].maxn=0;
tree[k*2+1].sum=tree[k*2+1].len;
tree[k*2+1].tag=2;
tree[k].tag=0;
}
}
void pushup(int k){
if(tree[k*2].lmax==tree[k*2].len) tree[k].lmax=tree[k*2].len+tree[k*2+1].lmax;
else tree[k].lmax=tree[k*2].lmax;
if(tree[k*2+1].rmax==tree[k*2+1].len) tree[k].rmax=tree[k*2+1].len+tree[k*2].rmax;
else tree[k].rmax=tree[k*2+1].rmax;
tree[k].maxn=max(tree[k*2].rmax+tree[k*2+1].lmax,max(tree[k*2].maxn,tree[k*2+1].maxn));
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
void build(int k,int l,int r){
tree[k].len=r-l+1;
if(l==r){
tree[k].lmax=tree[k].rmax=tree[k].maxn=0;
tree[k].sum=1;
return;
}
int mid=(l+r)>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
pushup(k);
}
void change(int k,int l,int r,int l1,int r1,int val){
if(l1<=l&&r<=r1){
tree[k].sum=tree[k].len*val;
tree[k].lmax=tree[k].rmax=tree[k].maxn=tree[k].len-tree[k].sum;
tree[k].tag=val+1;
return;
}
pushdown(k);
int mid=(l+r)>>1;
if(l1<=mid) change(k*2,l,mid,l1,r1,val);
if(mid<r1) change(k*2+1,mid+1,r,l1,r1,val);
pushup(k);
}
int query(int k,int l,int r,int l1,int r1){
if(l1<=l&&r<=r1) return tree[k].maxn;
pushdown(k);
int mid=(l+r)>>1,ans;
if(l1<=mid&&mid<r1) ans=max(max(query(k*2,l,mid,l1,r1),query(k*2+1,mid+1,r,l1,r1)),min(tree[k*2].rmax,mid+1-l1)+min(tree[k*2+1].lmax,r1-mid));
else if(l1<=mid) ans=query(k*2,l,mid,l1,r1);
else ans=query(k*2+1,mid+1,r,l1,r1);
return ans;
}
int query1(int k,int l,int r,int l1,int r1){
if(l1<=l&&r<=r1) return tree[k].sum;
pushdown(k);
int mid=(l+r)>>1,ans=0;
if(l1<=mid) ans+=query(k*2,l,mid,l1,r1);
if(mid<r1) ans+=query(k*2+1,mid+1,r,l1,r1);
return ans;
}
void add(int l,int r,int l1,int r1){
int num=r-l+1-query1(1,1,n,l,r);
if(!num) return;
change(1,1,n,l,r,0);
int l0=l1,r0=r1,ans;
while(l0<=r0){
int mid=(l0+r0)>>1;
if(query1(1,1,n,l1,mid)<=num){
l0=mid+1;
ans=mid;
}else r0=mid-1;
}
change(1,1,n,l1,ans,1);
}
int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-48;
c=getchar();
}
return x*f;
}
int main(){
n=read();m=read();
build(1,1,n);
for(int i=1;i<=m;i++){
int opt,l,r,l1,r1;
opt=read();
if(opt==0){
l=read();r=read();
change(1,1,n,l,r,0);
}else if(opt==1){
l=read();r=read();l1=read();r1=read();
add(l,r,l1,r1);
}else{
l=read();r=read();
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}