#include<bits/stdc++.h>
#define ls i<<1
#define rs i<<1|1
using namespace std;
int a[1000000];
struct ccc{
int s0,s1,l0,l1,r0,r1,rec=-1,zh=0,num=0,lin1=0,lin0=0;
}tree[100000*4+100];
ccc update(ccc a,ccc b){
ccc ans;
ans.lin1=max(max(a.lin1,b.lin1),a.r1+b.l1);
ans.lin0=max(max(a.lin0,b.lin0),a.r0+b.l0);
ans.num=a.num+b.num;
ans.s0=a.s0+b.s0;
ans.s1=a.s1+b.s1;
ans.l0=a.l0;
if(a.l0==a.num)ans.l0+=b.l0;
ans.l1=a.l1;
if(a.l1==a.num)ans.l1+=b.l1;
ans.r0=b.r0;
if(b.r0==b.num)ans.r0+=a.r0;
ans.r1=b.r1;
if(b.r1==b.num)ans.r1+=a.r1;
return ans;
}
void tag_c(int i,int l,int r){
if(tree[i].rec==-1)return;
tree[i].zh=0;
if(tree[i].rec==1){
tree[ls].s1=tree[ls].l1=tree[ls].r1=tree[ls].lin1=tree[ls].num;
tree[ls].s0=tree[ls].l0=tree[ls].r0=tree[ls].lin0=0;
tree[rs].s1=tree[rs].l1=tree[rs].r1=tree[rs].lin1=tree[rs].num;
tree[rs].s0=tree[rs].l0=tree[rs].r0=tree[rs].lin0=0;
}
if(tree[i].rec==0){
tree[ls].s1=tree[ls].l1=tree[ls].r1=tree[ls].lin1=0;
tree[ls].s0=tree[ls].l0=tree[ls].r0=tree[ls].lin0=tree[ls].num;
tree[rs].s1=tree[rs].l1=tree[rs].r1=tree[rs].lin1=0;
tree[rs].s0=tree[rs].l0=tree[rs].r0=tree[rs].lin0=tree[rs].num;
}
tree[ls].rec=tree[rs].rec=tree[i].rec;
tree[i].rec=-1;
}
void tag_r(int i,int l,int r){
if(tree[i].zh==0)return ;
swap(tree[ls].s1,tree[ls].s0);
swap(tree[ls].l1,tree[ls].l0);
swap(tree[ls].r1,tree[ls].r0);
swap(tree[ls].lin1,tree[ls].lin0);
swap(tree[rs].s1,tree[rs].s0);
swap(tree[rs].l1,tree[rs].l0);
swap(tree[rs].r1,tree[rs].r0);
swap(tree[rs].lin1,tree[rs].lin0);
if(tree[ls].rec!=-1)tree[ls].rec^=1;
else tree[ls].zh^=1;
if(tree[rs].rec!=-1)tree[rs].rec^=1;
else tree[rs].zh^=1;
tree[i].zh=0;
}
void build(int i,int l,int r){
tree[i].rec=-1;
tree[i].zh=0;
if(l==r){
tree[i].num=1;
tree[i].lin1=a[l];
tree[i].lin0=a[l]^1;
tree[i].s0=a[l]^1;
tree[i].s1=a[l];
tree[i].l0=a[l]^1;
tree[i].l1=a[l];
tree[i].r0=a[l]^1;
tree[i].r1=a[l];
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
tree[i]=update(tree[ls],tree[rs]);
}
void cover(int i,int l,int r,int x,int y,int c){
if(x<=l&&y>=r){
if(c==1){
tree[i].s1=tree[i].l1=tree[i].r1=tree[i].lin1=tree[i].num;
tree[i].s0=tree[i].l0=tree[i].r0=tree[i].lin0=0;
}
else {
tree[i].s1=tree[i].l1=tree[i].r1=tree[i].lin1=0;
tree[i].s0=tree[i].l0=tree[i].r0=tree[i].lin0=tree[i].num;
}
tree[i].rec=c;
return ;
}
tag_r(i,l,r);
tag_c(i,l,r);
int mid=(l+r)>>1;
if(x<=mid)cover(ls,l,mid,x,y,c);
if(y>mid)cover(rs,mid+1,r,x,y,c);
tree[i]=update(tree[ls],tree[rs]);
}
void re(int i,int l,int r,int x,int y){
if(x<=l&&y>=r){
swap(tree[i].s1,tree[i].s0);
swap(tree[i].l1,tree[i].l0);
swap(tree[i].r1,tree[i].r0);
swap(tree[i].lin1,tree[i].lin0);
tree[i].zh^=1;
return ;
}
tag_r(i,l,r);
tag_c(i,l,r);
int mid=(l+r)>>1;
if(x<=mid)re(ls,l,mid,x,y);
if(y>mid)re(rs,mid+1,r,x,y);
tree[i]=update(tree[ls],tree[rs]);
}
ccc get(int i,int l,int r,int x,int y){
if(x<=l&&y>=r)return tree[i];
tag_r(i,l,r);
tag_c(i,l,r);
int mid=(l+r)>>1;
if(x<=mid&&y>mid)return update(get(ls,l,mid,x,y),get(rs,mid+1,r,x,y));
if(x<=mid)return get(ls,l,mid,x,y);
if(y>mid) return get(rs,mid+1,r,x,y);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
int opt;
cin>>opt;
if(opt==0){
int x,y;
cin>>x>>y;
cover(1,1,n,x+1,y+1,0);
}
if(opt==1){
int x,y;
cin>>x>>y;
cover(1,1,n,x+1,y+1,1);
}
if(opt==2){
int x,y;
cin>>x>>y;
re(1,1,n,x+1,y+1);
}
if(opt==3){
int x,y;
cin>>x>>y;
cout<<get(1,1,n,x+1,y+1).s1<<endl;
}
if(opt==4){
int x,y;
cin>>x>>y;
cout<<get(1,1,n,x+1,y+1).lin1<<endl;
}
}
}