#include <stdio.h>
#include <algorithm>
#define lc p<<1
#define rc p<<1|1
const int N=100005;
struct tree{
int l,r,sum;
int l0,l1,r0,r1,mx0,mx1;
int val,add;
};
tree t[N<<2];
int e[N],n,m;
int max(int a,int b){return a>b?a:b;}
inline void pushup(int p){
t[p].sum=t[lc].sum+t[rc].sum;
t[p].l1 = t[lc].l1==(t[lc].r-t[lc].l+1)? t[lc].l1+t[rc].l1 : t[lc].l1;
t[p].l0 = t[lc].l0==(t[lc].r-t[lc].l+1)? t[lc].l0+t[rc].l0 : t[lc].l0;
t[p].r1 = t[rc].r1==(t[rc].r-t[rc].l+1)? t[rc].r1+t[lc].r1 : t[rc].r1;
t[p].r0 = t[rc].r0==(t[rc].r-t[rc].l+1)? t[rc].r0+t[lc].r0 : t[rc].r0;
t[p].mx1 = max( max(t[lc].mx1,t[rc].mx1) , t[lc].r1+t[rc].l1);
t[p].mx0 = max( max(t[lc].mx0,t[rc].mx0) , t[lc].r0+t[rc].l0);
}
inline void build(int p,int x,int y){
t[p].l=x; t[p].r=y;
t[p].val=-1; t[p].add=0;
if(x==y){
t[p].sum=e[x];
if(e[x]==0) t[p].l0=t[p].r0=t[p].mx0=1;
else t[p].l1=t[p].r1=t[p].mx1=1;
return ;
}
int mid=(x+y)>>1;
build(lc,x,mid);
build(rc,mid+1,y);
pushup(p);
}
inline void make_add(int p){
t[p].sum=(t[p].r-t[p].l+1)-t[p].sum;
std::swap(t[p].l0,t[p].l1);
std::swap(t[p].r0,t[p].r1);
std::swap(t[p].mx0,t[p].mx1);
}
inline void make_val(int p,int k){
if(k==1){
t[p].mx1=t[p].l1=t[p].r1=t[p].sum=t[p].r-t[p].l+1;
t[p].mx0=t[p].l0=t[p].r0=0;
}
else{
t[p].mx1=t[p].l1=t[p].r1=t[p].sum=0;
t[p].mx0=t[p].l0=t[p].r0=t[p].r-t[p].l+1;
}
}
inline void pushdown(int p){
if(t[p].val!=-1){
make_val(lc,t[p].val);
make_val(rc,t[p].val);
t[lc].val=t[p].val;
t[rc].val=t[p].val;
t[p].val=-1;
t[p].add=0;
t[lc].add=0;
t[rc].add=0;
}
if(t[p].add){
make_add(lc);
make_add(rc);
if(t[lc].val!=-1) t[lc].val^=1;
else t[lc].add^=1;
if(t[rc].val!=-1) t[rc].val^=1;
else t[rc].add^=1;
t[p].add=0;
}
}
inline void update(int p,int x,int y,int k){
if(x<=t[p].l && t[p].r<=y){
if(k!=2){
make_val(p,k);
t[p].val=k;
t[p].add=0;
}
else{
make_add(p);
t[p].add^=1;
}
return ;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) update(lc,x,y,k);
if(y>mid) update(rc,x,y,k);
pushup(p);
}
inline tree query(int p,int x,int y){
pushdown(p);
if(x<=t[p].l && t[p].r<=y) return t[p];
int mid=(t[p].l+t[p].r)>>1;
if(y<=mid) return query(lc,x,y);
else if(x>mid) return query(rc,x,y);
else{
tree a=query(lc,x,y),b=query(rc,x,y),re;
re.sum = a.sum+b.sum;
re.l1 = a.l1==(a.r-a.l+1)? a.l1+b.l1 : a.l1;
re.l0 = a.l0==(a.r-a.l+1)? a.l0+b.l0 : a.l0;
re.r1 = b.r1==(b.r-b.l+1)? b.r1+a.r1 : b.r1;
re.r0 = b.r0==(b.r-b.l+1)? b.r0+a.r0 : b.r0;
re.mx1 = max( max(a.mx1,b.mx1) , a.r1+b.l1);
re.mx0 = max( max(a.mx0,b.mx0) , a.r0+b.l0);
return re;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&e[i]);
build(1,1,n);
while(m--){
int opt,l,r;
scanf("%d%d%d",&opt,&l,&r);
l++; r++;
if(opt==0 || opt==1 || opt==2) update(1,l,r,opt);
if(opt==3) printf("%d\n",query(1,l,r).sum);
if(opt==4) printf("%d\n",query(1,l,r).mx1);
}
}