#include<cstdio>
#include<iostream>
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int N=1e5+5;
int n,m,a[N];
struct sgt{
int sum,tag,rev,max1,max0,lss0,rss0,lss1,rss1,lp,rp,l,r;
}s,tr[N<<2];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
sgt merge(sgt left,sgt right){
sgt now;
now.lp=left.lp;
now.rp=right.rp;
now.sum=left.sum+right.sum;
now.lss0=left.lss0;
now.rss0=right.rss0;
if(!right.lp&&!left.sum) now.lss0=max(now.lss0,left.r-left.l+1+right.lss0);
if(!left.rp&&!right.sum) now.rss0=max(now.rss0,right.r-right.l+1+left.rss0);
now.max0=max(left.max0,right.max0);
if(!left.rp&&!right.lp) now.max0=max(now.max0,left.rss0+right.lss0);
now.lss1=left.lss1;
now.rss1=right.rss1;
if(right.lp&&left.sum==left.r-left.l+1) now.lss1=max(now.lss1,left.sum+right.lss1);
if(left.rp&&right.sum==right.r-right.l+1) now.rss1=max(now.rss1,right.sum+left.rss1);
now.max1=max(left.max1,right.max1);
if(left.rp&&right.lp) now.max1=max(now.max1,left.rss1+right.lss1);
return now;
}
void updata(int k){
tr[k].lp=tr[lc].lp;
tr[k].rp=tr[rc].rp;
tr[k].sum=tr[lc].sum+tr[rc].sum;
tr[k].lss0=tr[lc].lss0;
tr[k].rss0=tr[rc].rss0;
if(!tr[rc].lp&&!tr[lc].sum) tr[k].lss0=max(tr[k].lss0,tr[lc].r-tr[lc].l+1+tr[rc].lss0);
if(!tr[lc].rp&&!tr[rc].sum) tr[k].rss0=max(tr[k].rss0,tr[rc].r-tr[rc].l+1+tr[lc].rss0);
tr[k].max0=max(tr[lc].max0,tr[rc].max0);
if(!tr[lc].rp&&!tr[rc].lp) tr[k].max0=max(tr[k].max0,tr[lc].rss0+tr[rc].lss0);
tr[k].lss1=tr[lc].lss1;
tr[k].rss1=tr[rc].rss1;
if(tr[rc].lp&&tr[lc].sum==tr[lc].r-tr[lc].l+1) tr[k].lss1=max(tr[k].lss1,tr[lc].sum+tr[rc].lss1);
if(tr[lc].rp&&tr[rc].sum==tr[rc].r-tr[rc].l+1) tr[k].rss1=max(tr[k].rss1,tr[rc].sum+tr[lc].rss1);
tr[k].max1=max(tr[lc].max1,tr[rc].max1);
if(tr[lc].rp&&tr[rc].lp) tr[k].max1=max(tr[k].max1,tr[lc].rss1+tr[rc].lss1);
}
void pushdown(int k){
if(~tr[k].tag){
// tr[k].rev=0;
if(tr[k].tag){
tr[lc].lp=tr[lc].rp=1;
tr[lc].lss1=tr[lc].rss1=tr[lc].max1=tr[lc].sum=tr[lc].r-tr[lc].l+1;
tr[lc].lss0=tr[lc].rss0=tr[lc].max0=0;
tr[rc].lp=tr[rc].rp=1;
tr[rc].lss1=tr[rc].rss1=tr[rc].max1=tr[rc].sum=tr[rc].r-tr[rc].l+1;
tr[rc].lss0=tr[rc].rss0=tr[rc].max0=0;
}
else{
tr[lc].lp=tr[lc].rp=0;
tr[lc].lss1=tr[lc].rss1=tr[lc].max1=tr[lc].sum=0;
tr[lc].lss0=tr[lc].rss0=tr[lc].max0=tr[lc].r-tr[lc].l+1;
tr[rc].lp=tr[rc].rp=0;
tr[rc].lss1=tr[rc].rss1=tr[rc].max1=tr[rc].sum=0;
tr[rc].lss0=tr[rc].rss0=tr[rc].max0=tr[rc].r-tr[rc].l+1;
}
tr[lc].tag=tr[rc].tag=tr[k].tag;tr[k].tag=-1;
// return ;
}
if(tr[k].rev){
tr[k].rev=0;tr[lc].rev=1;tr[rc].rev=1;
tr[lc].sum=tr[lc].r-tr[lc].l+1-tr[lc].sum;
tr[lc].lp^=1;tr[lc].rp^=1;
swap(tr[lc].max0,tr[lc].max1);
swap(tr[lc].lss0,tr[lc].lss1);
swap(tr[lc].rss0,tr[lc].rss1);
tr[rc].sum=tr[rc].r-tr[rc].l+1-tr[rc].sum;
tr[rc].lp^=1;tr[rc].rp^=1;
swap(tr[rc].max0,tr[rc].max1);
swap(tr[rc].lss0,tr[rc].lss1);
swap(tr[rc].rss0,tr[rc].rss1);
}
}
void deal(int k,int v){
if(v){
tr[k].lp=tr[k].rp=1;
tr[k].sum=tr[k].max1=tr[k].lss1=tr[k].rss1=tr[k].r-tr[k].l+1;
tr[k].max0=tr[k].lss0=tr[k].rss0=0;
}
else{
tr[k].lp=tr[k].rp=0;
tr[k].max0=tr[k].lss0=tr[k].rss0=tr[k].r-tr[k].l+1;
tr[k].sum=tr[k].max1=tr[k].lss1=tr[k].rss1=0;
}
}
void vpt(int k){
if(tr[k].l==tr[k].r) return ;
pushdown(k);
vpt(lc);
vpt(rc);
}
void build(int k,int l,int r){
tr[k].l=l;tr[k].r=r;tr[k].tag=-1;
if(l==r){
tr[k].lp=tr[k].rp=a[l];
tr[k].sum=tr[k].max1=tr[k].lss1=tr[k].rss1=(a[l]==1);
tr[k].max0=tr[k].lss0=tr[k].rss0=(a[l]==0);
return ;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
updata(k);
}
void cover(int k,int x,int y,int v){
int l=tr[k].l,r=tr[k].r;
if(l==x&&r==y){
vpt(k);
deal(k,v);
if(l!=r) tr[k].tag=v;
return ;
}
pushdown(k);
int mid=l+r>>1;
if(y<=mid) cover(lc,x,y,v);
else if(x>mid) cover(rc,x,y,v);
else cover(lc,x,mid,v),cover(rc,mid+1,y,v);
updata(k);
}
void rever(int k,int x,int y){
int l=tr[k].l,r=tr[k].r;
if(l==x&&r==y){
vpt(k);
tr[k].sum=tr[k].r-tr[k].l+1-tr[k].sum;
tr[k].lp^=1;tr[k].rp^=1;
swap(tr[k].max0,tr[k].max1);
swap(tr[k].lss0,tr[k].lss1);
swap(tr[k].rss0,tr[k].rss1);
if(l!=r) tr[k].rev=1;
return ;
}
pushdown(k);
int mid=l+r>>1;
if(y<=mid) rever(lc,x,y);
else if(x>mid) rever(rc,x,y);
else rever(lc,x,mid),rever(rc,mid+1,y);
updata(k);
}
int query_sum(int k,int x,int y){
int l=tr[k].l,r=tr[k].r;
if(l==x&&r==y) return tr[k].sum;
pushdown(k);
int mid=l+r>>1;
if(y<=mid) return query_sum(lc,x,y);
else if(x>mid) return query_sum(rc,x,y);
else return
query_sum(lc,x,mid)+
query_sum(rc,mid+1,y);
}
sgt query_max(int k,int x,int y){
int l=tr[k].l,r=tr[k].r;
if(l==x&&r==y) return tr[k];
pushdown(k);
int mid=l+r>>1;
if(y<=mid) return query_max(lc,x,y);
else if(x>mid) return query_max(rc,x,y);
else{
sgt k1=query_max(lc,x,mid);
sgt k2=query_max(rc,mid+1,y);
return merge(k1,k2);
}
}
int main(){
freopen("operation.in","r",stdin);
freopen("operation.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1,opt,x,y;i<=m;i++){
opt=read();x=read()+1;y=read()+1;
if(opt<2) cover(1,x,y,opt);
else if(opt==2) rever(1,x,y);
else if(opt==3) printf("%d
",query_sum(1,x,y));
else{
s=query_max(1,x,y);
printf("%d
",s.max1);
}
}
return 0;
}