#include<bits/stdc++.h>
#define N 100005
#define ls p<<1
#define rs p<<1|1
using namespace std;
struct node{
int len;
int sum,sum1,sum0;
int tag,rev;
int lmax1,rmax1,lmax0,rmax0;
}tree[N<<3];
int n,m,a[N];
void pushup(int p){
tree[p].sum=tree[ls].sum+tree[rs].sum;
tree[p].lmax1=(tree[ls].lmax1==tree[ls].len?tree[ls].len+tree[rs].lmax1:tree[ls].lmax1);
tree[p].rmax1=(tree[rs].rmax1==tree[rs].len?tree[rs].len+tree[ls].rmax1:tree[rs].lmax1);
tree[p].sum1=max(max(tree[ls].sum1,tree[rs].sum1),tree[ls].rmax1+tree[rs].lmax1);
tree[p].lmax0=(tree[ls].lmax0==tree[ls].len?tree[ls].len+tree[rs].lmax0:tree[ls].lmax0);
tree[p].rmax0=(tree[rs].rmax0==tree[rs].len?tree[rs].len+tree[ls].rmax0:tree[rs].lmax0);
tree[p].sum0=max(max(tree[ls].sum0,tree[rs].sum0),tree[ls].rmax0+tree[rs].lmax0);
}
void build(int p,int l,int r){
tree[p].tag=0,tree[p].rev=0,tree[p].len=r-l+1;
if(l==r){
tree[p].sum=a[l];
tree[p].lmax1=tree[p].rmax1=tree[p].sum1=(a[l]==1);
tree[p].lmax0=tree[p].rmax0=tree[p].sum0=(a[l]==0);
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
pushup(p);
return;
}
void addtag(int p,int k){
if(k==1){
tree[p].tag=1,tree[p].rev=0;
tree[p].sum=tree[p].lmax1=tree[p].rmax1=tree[p].sum1=0;
tree[p].sum0=tree[p].lmax0=tree[p].rmax0=tree[p].len;
}
if(k==2){
tree[p].tag=2,tree[p].rev=0;
tree[p].sum=tree[p].lmax1=tree[p].rmax1=tree[p].sum1=tree[p].len;
tree[p].sum0=tree[p].lmax0=tree[p].rmax0=0;
}
if(k==3){
tree[p].sum=tree[p].len-tree[p].sum;
swap(tree[p].sum1,tree[p].sum0);
swap(tree[p].lmax1,tree[p].lmax0);
swap(tree[p].rmax1,tree[p].rmax0);
tree[p].rev^=1;
}
}
void pushdown(int p){
if(tree[p].tag==1){
tree[ls].sum=tree[ls].lmax1=tree[ls].rmax1=tree[ls].sum1=0;
tree[ls].sum0=tree[ls].lmax0=tree[ls].rmax0=tree[ls].len;
tree[rs].sum=tree[rs].lmax1=tree[rs].rmax1=tree[rs].sum1=0;
tree[rs].sum0=tree[rs].lmax0=tree[rs].rmax0=tree[rs].len;
tree[ls].tag=1,tree[ls].rev=0;
tree[rs].tag=1,tree[rs].rev=0;
tree[p].rev=0,tree[p].tag=0;
}
if(tree[p].tag==2){
tree[ls].sum=tree[ls].lmax1=tree[ls].rmax1=tree[ls].sum1=tree[ls].len;
tree[ls].sum0=tree[ls].lmax0=tree[ls].rmax0=0;
tree[rs].sum=tree[rs].lmax1=tree[rs].rmax1=tree[rs].sum1=tree[rs].len;
tree[rs].sum0=tree[rs].lmax0=tree[rs].rmax0=0;
tree[ls].tag=1,tree[ls].rev=0;
tree[rs].tag=1,tree[rs].rev=0;
tree[p].rev=0,tree[p].tag=0;
}
if(tree[p].rev){
tree[ls].sum=tree[ls].len-tree[ls].sum;
swap(tree[ls].sum1,tree[ls].sum0);
swap(tree[ls].lmax1,tree[ls].lmax0);
swap(tree[ls].rmax1,tree[ls].rmax0);
if(tree[ls].tag==1) tree[ls].tag=2;
else if(tree[ls].tag==2) tree[ls].tag=1;
else tree[ls].rev^=1;
tree[rs].sum=tree[rs].len-tree[rs].sum;
swap(tree[rs].sum1,tree[rs].sum0);
swap(tree[rs].lmax1,tree[rs].lmax0);
swap(tree[rs].rmax1,tree[rs].rmax0);
if(tree[rs].tag==1) tree[rs].tag=2;
else if(tree[rs].tag==2) tree[rs].tag=1;
else tree[rs].rev^=1;
tree[p].rev=0;
}
return;
}
void update(int p,int l,int r,int L,int R,int k){
pushdown(p);
if(l>=L&&r<=R){
addtag(p,k);
return;
}
if(l>R||r<L) return;
int mid=(l+r)>>1;
update(ls,l,mid,L,R,k),update(rs,mid+1,r,L,R,k);
pushup(p);
return;
}
int querysum(int p,int l,int r,int L,int R){
pushdown(p);
if(l>=L&&r<=R) return tree[p].sum;
if(l>R||r<L) return 0;
int mid=(l+r)>>1;
return querysum(ls,l,mid,L,R)+querysum(rs,mid+1,r,L,R);
}
int querylink(int p,int l,int r,int L,int R){
pushdown(p);
if(l>=L&&r<=R) return tree[p].sum1;
if(l>R||r<L) return 0;
int mid=(l+r)>>1;
return max(max(querylink(ls,l,mid,L,R),querylink(rs,mid+1,r,L,R)),min(tree[rs].lmax1,R-mid)+min(tree[ls].rmax1,mid-L+1));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
int op,l,r;
cin>>op>>l>>r;
switch(op){
case 0:update(1,1,n,l+1,r+1,1);break;
case 1:update(1,1,n,l+1,r+1,2);break;
case 2:update(1,1,n,l+1,r+1,3);break;
case 3:cout<<querysum(1,1,n,l+1,r+1)<<'\n';break;
case 4:cout<<querylink(1,1,n,l+1,r+1)<<'\n';break;
}
}
return 0;
}