#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define x_lc (x<<1)
#define x_rc (x<<1|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define leng(x) (t[x].r-t[x].l+1)
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x*10+ch-48);ch=getchar();}
return x*f;
}
struct node{
ll l,r;
ll p,q;
ll sum,cnt;
bool tag[3];
void zero(){
tag[0]=1;
tag[1]=0;
tag[2]=0;
sum=0;
}
void one(){
tag[0]=0;
tag[1]=1;
tag[2]=0;
sum=r-l+1;
}
void roll(){
tag[2]^=1;
sum=r-l+1-sum;
}
};
struct SegmentTree{
bool a[1000001];
node t[4000001];
void Update(ll x){
t[x].sum=t[x_lc].sum+t[x_rc].sum;
t[x].cnt=max(t[x_lc].cnt,t[x_rc].cnt);
t[x].cnt=max(t[x].cnt,t[x_lc].q+t[x_rc].p);
if(t[x_lc].sum==leng(x_lc)) t[x].p=t[x_lc].sum+t[x_rc].p;
else t[x].p=t[x_lc].p;
if(t[x_rc].sum==leng(x_rc)) t[x].q=t[x_rc].sum+t[x_lc].q;
else t[x].q=t[x_rc].p;
}
void PushDown(ll x){
if(t[x].tag[1]){
t[x].tag[1]=0;
t[x_lc].one();
t[x_rc].one();
}
if(t[x].tag[0]){
t[x].tag[0]=0;
t[x_lc].zero();
t[x_rc].zero();
}
if(t[x].tag[2]){
t[x].tag[2]=0;
t[x_lc].roll();
t[x_rc].roll();
}
}
void Build(ll x,ll l,ll r){
t[x].l=l;
t[x].r=r;
t[x].tag[0]=0;
t[x].tag[1]=0;
t[x].tag[2]=0;
if(l==r){
if(a[l]) t[x].sum=t[x].cnt=t[x].p=t[x].q=1;
else t[x].sum=t[x].cnt=t[x].p=t[x].q=0;
return;
}
Build(x_lc,l,x_mid);
Build(x_rc,x_mid+1,r);
Update(x);
}
void Zero(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r){
t[x].sum=0;
t[x].tag[0]=1;
t[x].tag[1]=0;
t[x].tag[2]=0;
return;
}
PushDown(x);
if(x_mid>=l) Zero(x_lc,l,r);
if(x_mid+1<=r) Zero(x_rc,l,r);
Update(x);
}
void One(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r){
t[x].sum=leng(x);
t[x].tag[0]=0;
t[x].tag[1]=1;
t[x].tag[2]=0;
return;
}
PushDown(x);
if(x_mid>=l) One(x_lc,l,r);
if(x_mid+1<=r) One(x_rc,l,r);
Update(x);
}
void Xor(ll x,ll l,ll r){
PushDown(x);
if(t[x].l>=l&&t[x].r<=r){
t[x].sum=leng(x)-t[x].sum;
t[x].tag[2]^=1;
return;
}
if(x_mid>=l) Xor(x_lc,l,r);
if(x_mid+1<=r) Xor(x_rc,l,r);
Update(x);
}
ll GetSum(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x].sum;
ll res=0;
PushDown(x);
if(x_mid>=l) res+=GetSum(x_lc,l,r);
if(x_mid+1<=r) res+=GetSum(x_rc,l,r);
return res;
}
node GetCnt(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x];
PushDown(x);
if(x_mid>=l&&x_mid+1<=r){
node lc=GetCnt(x_lc,l,r);
node rc=GetCnt(x_rc,l,r);
node res;
res.l=lc.l;
res.r=rc.r;
res.sum=lc.sum+rc.sum;
res.cnt=max(lc.cnt,rc.cnt);
res.cnt=max(res.cnt,lc.q+rc.p);
if(lc.sum==lc.r-lc.l+1) res.p=lc.sum+rc.p;
else res.p=lc.p;
if(rc.sum==rc.r-rc.l+1) res.q=rc.sum+lc.q;
else res.q=rc.p;
return res;
}
if(x_mid>=l&&x_mid+1>r) return GetCnt(x_lc,l,r);
if(x_mid+1<=r&&x_mid<l) return GetCnt(x_rc,l,r);
}
void init(ll n){
for(ll i=1;i<=n;i++)
cin>>a[i];
Build(1,1,n);
}
void solve(ll m){
for(ll i=1;i<=m;i++){
ll op=read();
ll l=read()+1;
ll r=read()+1;
if(op==0) Zero(1,l,r);
if(op==1) One(1,l,r);
if(op==2) Xor(1,l,r);
if(op==3) cout<<GetSum(1,l,r)<<endl;
if(op==4) cout<<GetCnt(1,l,r).cnt<<endl;
}
}
};
SegmentTree SGT;
int main(){
ll n,m;
cin>>n>>m;
SGT.init(n);
SGT.solve(m);
return 0;
}