#include<bits/stdc++.h>
#define ls(k) (k<<2)
#define rs(k) (k<<2|1)
#define mid ((l+r)>>1)
using namespace std;
const int MAXN=1e5+5;
int read(){
char c=getchar();
int sum=0,flag=1;
while(!isdigit(c)){if(c=='-')flag=-1;c=getchar();}
while(isdigit(c)){sum=(sum<<1)+(sum<<3)+(c^48),c=getchar();}
return sum*flag;
}
void write(int x){
if(x<0) x=(~x)+1,putchar('-');
if(x>9) write(x/10);
putchar(x%10|48);
}
int n,m,op,x,y;
int ans0[MAXN<<2],ans1[MAXN<<2],sum_0[MAXN<<2],sum_1[MAXN<<2],lr0[MAXN<<2],lr1[MAXN<<2],rl0[MAXN<<2],rl1[MAXN<<2],tag1[MAXN<<2],tag2[MAXN<<2];
struct node{
int ANS0,ANS1,SUM_0,SUM_1,LR0,LR1,RL0,RL1;
};
void update(int k){
sum_0[k]=sum_0[ls(k)]+sum_0[rs(k)];
sum_1[k]=sum_1[ls(k)]+sum_1[rs(k)];
ans0[k]=max(ans0[ls(k)],ans0[rs(k)]);
ans0[k]=max(ans0[k],rl0[ls(k)]+lr0[rs(k)]);
ans1[k]=max(ans1[ls(k)],ans1[rs(k)]);
ans1[k]=max(ans1[k],rl1[ls(k)]+lr1[rs(k)]);
lr0[k]=(sum_1[ls(k)] ? lr0[ls(k)] : sum_0[ls(k)]+lr0[rs(k)]);
rl0[k]=(sum_1[rs(k)] ? rl0[rs(k)] : sum_0[rs(k)]+rl0[ls(k)]);
lr1[k]=(sum_0[ls(k)] ? lr1[ls(k)] : sum_1[ls(k)]+lr1[rs(k)]);
rl1[k]=(sum_0[rs(k)] ? rl1[rs(k)] : sum_1[rs(k)]+rl1[ls(k)]);
return ;
}
void work(int k,int l,int r,int w){
if(!w){
ans0[k]=sum_0[k]=lr0[k]=rl0[k]=r-l+1;
ans1[k]=sum_1[k]=lr1[k]=rl1[k]=0;
}
else{
ans1[k]=sum_1[k]=lr1[k]=rl1[k]=r-l+1;
ans0[k]=sum_0[k]=lr0[k]=rl0[k]=0;
}
return ;
}
void Swap(int k){
swap(lr0[k],lr1[k]);
swap(rl0[k],rl1[k]);
swap(sum_0[k],sum_1[k]);
swap(ans0[k],ans1[k]);
return ;
}
void pushdown(int k,int l,int r){
if(tag1[k]!=-1){
work(k,l,r,tag1[k]);
tag1[ls(k)]=tag1[rs(k)]=tag1[k];
tag1[k]=-1;
}
if(tag2[k]){
Swap(k);
tag2[k]^=1;
tag2[ls(k)]^=1;
tag2[rs(k)]^=1;
}
return ;
}
void build(int k,int l,int r){
tag1[k]=-1;
tag2[k]=0;
if(l==r){
ans1[k]=sum_1[k]=lr1[k]=rl1[k]=read();
ans0[k]=sum_0[k]=lr0[k]=rl0[k]=(sum_1[k]==0 ? 1 : 0);
return ;
}
build(ls(k),l,mid);
build(rs(k),mid+1,r);
update(k);
}
void change(int k,int l,int r,int x,int y,int w){
if(l==x&&r==y){
tag1[k]=w;
if(tag2[k]){
tag2[k]^=1;
}
return ;
}
pushdown(k,l,r);
if(y<=mid){
change(ls(k),l,mid,x,y,w);
}
else{
if(x>mid){
change(rs(k),mid+1,r,x,y,w);
}
else{
change(ls(k),l,mid,x,mid,w);
change(rs(k),mid+1,r,mid+1,y,w);
}
}
update(k);
}
void rev(int k,int l,int r,int x,int y){
if(l==x&&r==y){
if(tag1[k]!=-1){
tag1[k]^=1;
}
else{
tag2[k]^=1;
}
return ;
}
pushdown(k,l,r);
if(y<=mid){
rev(ls(k),l,mid,x,y);
}
else{
if(x>mid){
rev(rs(k),mid+1,r,x,y);
}
else{
rev(ls(k),l,mid,x,mid);
rev(rs(k),mid+1,r,mid+1,y);
}
}
update(k);
}
int query1(int k,int l,int r,int x,int y){
if(l==x&&r==y){
return sum_1[k];
}
pushdown(k,l,r);
if(y<=mid){
return query1(ls(k),l,mid,x,y);
}
else{
if(x>mid){
return query1(rs(k),mid+1,r,x,y);
}
else{
return query1(ls(k),l,mid,x,mid)+query1(rs(k),mid+1,r,mid+1,y);
}
}
update(k);
}
node query2(int k,int l,int r,int x,int y){
if(l==x&&r==y){
return node{ans0[k],ans1[k],sum_0[k],sum_1[k],lr0[k],lr1[k],rl0[k],rl1[k]};
}
pushdown(k,l,r);
if(y<=mid){
return query2(ls(k),l,mid,x,y);
}
else{
if(x>mid){
return query2(rs(k),mid+1,r,x,y);
}
else{
node a=query2(ls(k),l,mid,x,mid);
node b=query2(rs(k),mid+1,r,mid+1,y);
node s;
s.SUM_0=a.SUM_0+b.SUM_0;
s.SUM_1=a.SUM_1+b.SUM_1;
s.LR0=(a.SUM_1 ? a.LR0 : a.SUM_0+b.LR0);
s.RL0=(b.SUM_1 ? b.RL0 : b.SUM_0+a.RL0);
s.LR1=(a.SUM_0 ? a.LR1 : a.SUM_1+b.LR1);
s.RL1=(b.SUM_0 ? b.RL1 : b.SUM_1+a.RL1);
s.ANS0=max(a.ANS0,b.ANS0);
s.ANS0=max(s.ANS0,a.RL0+b.LR0);
s.ANS1=max(a.ANS1,b.ANS1);
s.ANS1=max(s.ANS1,a.RL1+b.LR1);
return s;
}
}
update(k);
}
int main(){
n=read(),m=read();
build(1,1,n);
for(int i=1;i<=m;i++){
op=read(),x=read(),y=read();
x++,y++;
if(!op){
change(1,1,n,x,y,0);
}
else if(op==1){
change(1,1,n,x,y,1);
}
else if(op==2){
rev(1,1,n,x,y);
}
else if(op==3){
write(query1(1,1,n,x,y));
putchar('\n');
}
else{
node t=query2(1,1,n,x,y);
write(t.ANS1);
putchar('\n');
}
}
return 0;
}