#include <bits/stdc++.h>
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int MN=1e6+515;
struct Node{
int l, r, onenum;
int covertag, reverse_tag;
int lmax1, rmax1, totmax1;
int lmax0, rmax0, totmax0;
}tr[MN];
void pushup(int k){
tr[k].onenum=tr[lc].onenum+tr[rc].onenum;
tr[k].lmax1=(tr[lc].lmax1==tr[lc].r-tr[lc].l+1)?tr[lc].lmax1+tr[rc].lmax1:tr[lc].lmax1;
tr[k].rmax1=(tr[rc].rmax1==tr[rc].r-tr[rc].l+1)?tr[rc].rmax1+tr[lc].rmax1:tr[rc].rmax1;
tr[k].totmax1=max({tr[lc].totmax1, tr[rc].totmax1, tr[lc].rmax1+tr[rc].lmax1});
tr[k].lmax0=(tr[lc].lmax0==tr[lc].r-tr[lc].l+1)?tr[lc].lmax0+tr[rc].lmax0:tr[lc].lmax0;
tr[k].rmax0=(tr[rc].rmax0==tr[rc].r-tr[rc].l+1)?tr[rc].rmax0+tr[lc].rmax0:tr[rc].rmax0;
tr[k].totmax0=max({tr[lc].totmax0, tr[rc].totmax0, tr[lc].rmax0+tr[rc].lmax0});
}
int a[MN];
void build(int k, int l, int r){
tr[k].l=l, tr[k].r=r; tr[k].covertag=-1;
if(l==r){
tr[k].onenum=a[l];
if(a[l]) tr[k].lmax1=tr[k].rmax1=tr[k].totmax1=1;
else tr[k].lmax0=tr[k].rmax0=tr[k].totmax0=1;
return;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(k); return;
}
void pushdown(int k){
if(tr[k].covertag!=-1){
if(tr[k].covertag==1){
tr[lc].onenum=(tr[lc].r-tr[lc].l+1);
tr[lc].lmax1=(tr[lc].r-tr[lc].l+1);
tr[lc].rmax1=(tr[lc].r-tr[lc].l+1);
tr[lc].totmax1=(tr[lc].r-tr[lc].l+1);
tr[lc].rmax0=tr[lc].lmax0=tr[lc].totmax0=0;
tr[rc].onenum=(tr[rc].r-tr[rc].l+1);
tr[rc].lmax1=(tr[rc].r-tr[rc].l+1);
tr[rc].rmax1=(tr[rc].r-tr[rc].l+1);
tr[rc].totmax1=(tr[rc].r-tr[rc].l+1);
tr[rc].rmax0=tr[rc].lmax0=tr[rc].totmax0=0;
tr[lc].covertag=tr[k].covertag;
tr[lc].reverse_tag=0;
tr[rc].covertag=tr[k].covertag;
tr[rc].reverse_tag=0;
tr[k].covertag=-1;
}else{
tr[lc].onenum=0;
tr[lc].lmax0=(tr[lc].r-tr[lc].l+1);
tr[lc].rmax0=(tr[lc].r-tr[lc].l+1);
tr[lc].totmax0=(tr[lc].r-tr[lc].l+1);
tr[lc].rmax1=tr[lc].lmax1=tr[lc].totmax1=0;
tr[rc].onenum=0;
tr[rc].lmax0=(tr[rc].r-tr[rc].l+1);
tr[rc].rmax0=(tr[rc].r-tr[rc].l+1);
tr[rc].totmax0=(tr[rc].r-tr[rc].l+1);
tr[rc].rmax1=tr[rc].lmax1=tr[rc].totmax1=0;
tr[lc].covertag=tr[k].covertag;
tr[lc].reverse_tag=0;
tr[rc].covertag=tr[k].covertag;
tr[rc].reverse_tag=0;
tr[k].covertag=-1;
}
}
if(tr[k].reverse_tag%2==1){
tr[lc].onenum=(tr[lc].r-tr[lc].l+1)-tr[lc].onenum;
tr[rc].onenum=(tr[rc].r-tr[rc].l+1)-tr[rc].onenum;
swap(tr[lc].lmax0, tr[lc].lmax1);
swap(tr[lc].rmax0, tr[lc].rmax1);
swap(tr[lc].totmax0, tr[lc].totmax1);
swap(tr[rc].lmax0, tr[rc].lmax1);
swap(tr[rc].rmax0, tr[rc].rmax1);
swap(tr[rc].totmax0, tr[rc].totmax1);
if(tr[lc].covertag!=-1) tr[lc].covertag=1-tr[lc].covertag;
if(tr[rc].covertag!=-1) tr[rc].covertag=1-tr[rc].covertag;
tr[lc].reverse_tag^=1;
tr[rc].reverse_tag^=1;
tr[k].reverse_tag=0;
}
}
void update(int k, int l, int r, int val){
if(tr[k].l>=l&&tr[k].r<=r){
tr[k].onenum=val*(tr[k].r-tr[k].l+1);
tr[k].covertag=val;
if(val){
tr[k].rmax1=tr[k].lmax1=tr[k].totmax1=(tr[k].r-tr[k].l+1);
tr[k].rmax0=tr[k].lmax0=tr[k].totmax0=0;
}else{
tr[k].rmax0=tr[k].lmax0=tr[k].totmax0=(tr[k].r-tr[k].l+1);
tr[k].rmax1=tr[k].lmax1=tr[k].totmax1=0;
}
return;
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)>>1;
if(l<=mid) update(lc,l,r,val);
if(r>mid) update(rc,l,r,val);
pushup(k); return;
}
void Reverse(int k, int l, int r){
if(tr[k].l>=l&&tr[k].r<=r){
tr[k].onenum=(tr[k].r-tr[k].l+1)-tr[k].onenum;
swap(tr[k].lmax0,tr[k].lmax1);
swap(tr[k].rmax0,tr[k].rmax1);
swap(tr[k].totmax0,tr[k].totmax1);
tr[k].reverse_tag++;
if(tr[k].covertag!=-1) tr[k].covertag=1-tr[k].covertag;
return;
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)>>1;
if(l<=mid) Reverse(lc,l,r);
if(r>mid) Reverse(rc,l,r);
pushup(k); return;
}
int querynum(int k, int l, int r){
if(tr[k].l>=l&&tr[k].r<=r){return tr[k].onenum;}
int mid=(tr[k].l+tr[k].r)>>1, res=0;
pushdown(k);
if(l<=mid) res+=querynum(lc,l,r);
if(r>mid) res+=querynum(rc,l,r);
pushup(k); return res;
}
struct Res{
int lmax, rmax, tmax, sum;
Res(int l=0, int r=0, int t=0, int s=0): lmax(l), rmax(r), tmax(t), sum(s){}
};
Res query(int k, int l, int r){
if(tr[k].l>=l&&tr[k].r<=r){
return Res(tr[k].lmax1, tr[k].rmax1, tr[k].totmax1, tr[k].onenum);
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)>>1;
if(r<=mid) return query(lc, l, r);
if(l>mid) return query(rc, l, r);
Res L=query(lc, l, r), R=query(rc, l, r);
Res res;
res.sum=L.sum+R.sum;
res.lmax=(L.lmax==(mid-max(l, tr[k].l)+1))?L.lmax+R.lmax:L.lmax;
res.rmax=(R.rmax==(min(r, tr[k].r)-mid))?R.rmax+L.rmax:R.rmax;
res.tmax=max({L.tmax, R.tmax, L.rmax + R.lmax});
return res;
}
int n, m;
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
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 op; cin>>op;
if(op==0){
int l, r; cin>>l>>r; ++l, ++r;
update(1,l,r,0);
}else if(op==1){
int l, r; cin>>l>>r; ++l, ++r;
update(1,l,r,1);
}else if(op==2){
int l, r; cin>>l>>r; ++l, ++r;
Reverse(1,l,r);
}else if(op==3){
int l, r; cin>>l>>r; ++l, ++r;
cout<<querynum(1,l,r)<<'\n';
}else{
int l, r; cin>>l>>r; ++l, ++r;
cout<<query(1,l,r).tmax<<'\n';
}
}
return 0;
}