#include <bits/stdc++.h>
#define ls 2*v
#define rs 2*v+1
using namespace std;
const int maxn=2e5+10;
struct node{
int l,r;
int mx,lmx,rmx;
int s1,s0;
int lazy;
}tree[maxn<<2];
void pushup(int v){
tree[v].s0=tree[ls].s0+tree[rs].s0;
tree[v].s1=tree[ls].s1+tree[rs].s1;
if(tree[ls].lmx==tree[ls].r-tree[ls].l+1){
tree[v].lmx=tree[ls].lmx+tree[rs].lmx;
}else tree[v].lmx=tree[ls].lmx;
if(tree[rs].rmx==tree[rs].r-tree[rs].l+1){
tree[v].rmx=tree[rs].rmx+tree[ls].rmx;
}else tree[v].rmx=tree[rs].rmx;
tree[v].mx=max(tree[ls].rmx+tree[rs].lmx,max(tree[ls].mx,tree[rs].mx));
}
void pushdown(int v){
if(tree[v].lazy==-1)return ;
int k=tree[v].lazy;
tree[ls].lazy=tree[rs].lazy=k;
if(k==0){
tree[ls].s0=tree[ls].r-tree[ls].l+1,tree[ls].s1=0;
tree[ls].mx=tree[ls].lmx=tree[ls].rmx=tree[ls].r-tree[ls].l+1;
tree[rs].s0=tree[rs].r-tree[rs].l+1,tree[rs].s1=0;
tree[ls].mx=tree[rs].lmx=tree[rs].rmx=tree[rs].r-tree[rs].l+1;
}
else {
tree[ls].s1=tree[ls].r-tree[ls].l+1,tree[ls].s0=0;
tree[ls].mx=tree[ls].lmx=tree[ls].rmx=0;
tree[rs].s1=tree[rs].r-tree[rs].l+1,tree[rs].s0=0;
tree[rs].mx=tree[rs].lmx=tree[rs].rmx=0;
}
tree[v].lazy=-1;
}
void build(int v,int l,int r){
tree[v].l=l;
tree[v].r=r;
tree[v].lazy=-1;
if(l==r){
tree[v].s0=0;
tree[v].s1=1;
tree[v].mx=tree[v].lmx=tree[v].rmx=0;
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(v);
}
void update(int v,int x,int y,int k){
int l=tree[v].l;
int r=tree[v].r;
if(l>y||r<x)return ;
if(l>=x&&r<=y){
if(k==0){
tree[v].s0=r-l+1,tree[v].s1=0;
tree[v].mx=tree[v].lmx=tree[v].rmx=r-l+1;
}
else {
tree[v].s1=r-l+1,tree[v].s0=0;
tree[v].mx=tree[v].lmx=tree[v].rmx=0;
}
tree[v].lazy=k;
return;
}
pushdown(v);
update(ls,x,y,k);
update(rs,x,y,k);
pushup(v);
}
int ask1(int v,int x,int y){
int l=tree[v].l;
int r=tree[v].r;
if(l>y||r<x)return 0;
if(l>=x&&r<=y)return tree[v].s1;
pushdown(v);
return ask1(ls,x,y)+ask1(rs,x,y);
}
int ask0(int v,int x,int y){
int l=tree[v].l;
int r=tree[v].r;
if(l>y||r<x)return 0;
if(l>=x&&r<=y)return tree[v].s0;
pushdown(v);
return ask0(ls,x,y)+ask0(rs,x,y);
}
int get(int v,int k){
if(tree[v].l==tree[v].r)return tree[v].l;
pushdown(v);
if(tree[ls].s0>=k)return get(ls,k);
else return get(rs,k-tree[ls].s0);
}
node ans(int v,int x,int y){
int l=tree[v].l;
int r=tree[v].r;
if(l>y||r<x)return {l,r,0,0,0,0,0,0};
if(l>=x&&r<=y)return tree[v];
pushdown(v);
node L=ans(ls,x,y);
node R=ans(rs,x,y);
node res;
if(L.lmx==L.r-L.l+1){
res.lmx=L.lmx+R.lmx;
}else res.lmx=L.lmx;
if(R.rmx==R.r-R.l+1){
res.rmx=R.rmx+L.rmx;
}else res.rmx=R.rmx;
res.mx=max(L.rmx+R.lmx,max(L.mx,R.mx));
return res;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=m;i++){
int op;
scanf("%d",&op);
if(op==0){
int x,y;
scanf("%d%d",&x,&y);
update(1,x,y,0);
}else if(op==1){
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int k=ask1(1,x1,y1);
update(1,x1,y1,0);
if(ask0(1,x2,y2)<=k)update(1,x2,y2,1);
else{
y2=get(1,ask0(1,1,x2-1)+k);
update(1,x2,y2,1);
}
}else{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",ans(1,x,y).mx);
}
}
return 0;
}