#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct Node
{
int total,lm0,lm1,rm0,rm1,sm0,sm1,lzc,lza,len;
}sum[MAXN];
int num[MAXN],n,m;
#define rs rt<<1|1
#define ls rt<<1
void maintain(int rt)
{
sum[rt].total=sum[ls].total+sum[rs].total;
sum[rt].lm0=sum[ls].total==0?sum[ls].lm0+sum[rs].lm0:sum[ls].lm0;
sum[rt].lm1=sum[ls].total==sum[ls].len?sum[ls].lm1+sum[rs].lm1:sum[ls].lm1;
sum[rt].rm0=sum[rs].total==0?sum[ls].rm0+sum[rs].rm0:sum[rs].rm0;
sum[rt].rm1=sum[rs].total==sum[rs].len?sum[ls].rm1+sum[rs].rm1:sum[rs].rm1;
sum[rt].sm0=max(max(sum[ls].sm0,sum[rs].sm0),sum[ls].rm0+sum[rs].lm0);
sum[rt].sm1=max(max(sum[ls].sm1,sum[rs].sm1),sum[ls].rm1+sum[rs].lm1);
return;
}
void build(int rt,int l,int r)
{
sum[rt].lzc=-1;
sum[rt].lza=0;
sum[rt].len=r-l+1;
if(l==r)
{
sum[rt].total=sum[rt].lm1=sum[rt].rm1=sum[rt].sm1=num[l];
sum[rt].lm0=sum[rt].rm0=sum[rt].sm0=sum[rt].len-sum[rt].total;
return;
}
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
maintain(rt);
return;
}
void pushdown(int rt,int l,int mid,int r)
{
if(sum[rt].lzc!=-1)
{
sum[ls].lza=sum[rs].lza=0;
sum[ls].total=sum[ls].lm1=sum[ls].rm1=sum[ls].sm1=sum[ls].len*sum[rt].lzc;
sum[rs].total=sum[rs].lm1=sum[rs].rm1=sum[rs].sm1=sum[rs].len*sum[rt].lzc;
sum[ls].lm0=sum[ls].rm0=sum[ls].sm0=sum[ls].len-sum[ls].total;
sum[rs].lm0=sum[rs].rm0=sum[rs].sm0=sum[rs].len-sum[rs].total;
sum[ls].lzc=sum[rs].lzc=sum[rt].lzc;
sum[rt].lzc=-1;
}
if(sum[rt].lza)
{
sum[ls].total=sum[ls].len-sum[ls].total;
sum[rs].total=sum[rs].len-sum[ls].total;
swap(sum[ls].lm0,sum[ls].lm1);
swap(sum[rs].lm0,sum[rs].lm1);
swap(sum[ls].rm0,sum[ls].rm1);
swap(sum[rs].rm0,sum[rs].rm1);
swap(sum[ls].sm0,sum[ls].sm1);
swap(sum[rs].sm0,sum[rs].sm1);
if(sum[ls].lzc!=-1)sum[ls].lzc^=1;
else sum[ls].lza^=1;
if(sum[rs].lzc!=-1)sum[rs].lzc^=1;
else sum[rs].lza^=1;
sum[rt].lza=0;
}
return;
}
void cover(int rt,int l,int r,int ql,int qr,int w)
{
if(ql>r||qr<l)return;
int mid=l+r>>1;
pushdown(rt,l,mid,r);
if(ql<=l&&r<=qr)
{
sum[rt].total=sum[rt].lm1=sum[rt].rm1=sum[rt].sm1=sum[rt].len*w;
sum[rt].lm0=sum[rt].rm0=sum[rt].sm0=sum[rt].len-sum[rt].total;
sum[rt].lzc=w;
sum[rt].lza=0;
return;
}
cover(ls,l,mid,ql,qr,w);
cover(rs,mid+1,r,ql,qr,w);
maintain(rt);
return;
}
void add(int rt,int l,int r,int ql,int qr,int w)
{
if(ql>r||qr<l)return;
int mid=l+r>>1;
pushdown(rt,l,mid,r);
if(ql<=l&&r<=qr)
{
sum[rt].total=sum[rt].len-sum[rt].total;
swap(sum[rt].lm0,sum[rt].lm1);
swap(sum[rt].rm0,sum[rt].rm1);
swap(sum[rt].sm0,sum[rt].sm1);
if(sum[rt].lzc!=-1)sum[rt].lzc^=1;
else sum[rt].lza^=1;
return;
}
add(ls,l,mid,ql,qr,w);
add(rs,mid+1,r,ql,qr,w);
maintain(rt);
return ;
}
Node query(int rt,int l,int r,int ql,int qr)
{
int mid=l+r>>1;
pushdown(rt,l,mid,r);
if(ql<=l&&r<=qr)return sum[rt];
if(qr<=mid)return query(ls,l,mid,ql,qr);
else if(ql>mid)return query(rs,mid+1,r,ql,qr);
else
{
Node left=query(ls,l,mid,ql,qr),right=query(rs,mid+1,r,ql,qr);
int tot=left.total+right.total;
int nlm0=left.total==0?left.lm0+right.lm0:left.lm0;
int nlm1=left.total==left.len?left.lm1+right.lm1:left.lm1;
int nrm0=right.total==0?left.rm0+right.rm0:right.rm0;
int nrm1=right.total==right.len?left.rm1+right.rm1:right.rm1;
int nsm0=max(max(left.sm0,right.sm0),left.rm0+right.lm0);
int nsm1=max(max(left.sm1,right.sm1),left.rm1+right.lm1);
return {tot,nlm0,nlm1,nrm0,nrm1,nsm0,nsm1,-1,0,0};
}
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>num[i];
}
build(1,1,n);
while(m--)
{
int oper,l,r;
cin>>oper>>l>>r;
l++;r++;
if(oper==0)cover(1,1,n,l,r,0);
else if(oper==1)cover(1,1,n,l,r,1);
else if(oper==2)add(1,1,n,l,r,1);
else if(oper==3)cout<<query(1,1,n,l,r).total<<'\n';
else if(oper==4)cout<<query(1,1,n,l,r).sm1<<'\n';
}
return 0;
}