rt.
#include<bits/stdc++.h>
#define int long long
#define mid (((l)+(r))>>1)
#define Ls (rt<<1)
#define Rs (rt<<1|1)
#define endl '\n'
using namespace std;
const int N=1e5+5;
int a[N];
struct Tree{
struct tree{
int sum;
int max0,max1;
int lmax0,lmax1;
int rmax0,rmax1;
int tag,rev;
}tr[N<<2];
void Push_Up(int rt,int l,int r)
{
tr[rt].sum=tr[Ls].sum+tr[Rs].sum;
tr[rt].lmax0=tr[Ls].lmax0;
if(tr[Ls].sum==0) tr[rt].lmax0+=tr[Rs].lmax0;
tr[rt].rmax0=tr[Rs].rmax0;
if(tr[Rs].sum==0) tr[rt].rmax0+=tr[Ls].rmax0;
tr[rt].max0=max({tr[Ls].max0,tr[Rs].max0,tr[Ls].rmax0+tr[Rs].lmax0});
tr[rt].lmax1=tr[Ls].lmax1;
if(tr[Ls].sum==mid-l+1) tr[rt].lmax1+=tr[Rs].lmax1;
tr[rt].rmax1=tr[Rs].rmax1;
if(tr[Rs].sum==r-mid) tr[rt].rmax1+=tr[Ls].rmax1;
tr[rt].max1=max({tr[Ls].max1,tr[Rs].max1,tr[Ls].rmax1+tr[Rs].lmax1});
}
void Push_Down(int rt,int l,int r)
{
if(tr[rt].rev)
{
tr[Ls].sum=(mid-l+1)-tr[Ls].sum;
tr[Rs].sum=(r-mid)-tr[Rs].sum;
if(tr[Ls].tag!=-1) tr[Ls].tag^=1;
else tr[Ls].rev^=1;
if(tr[Rs].tag!=-1) tr[Rs].tag^=1;
else tr[Rs].rev^=1;
swap(tr[Ls].max0,tr[Ls].max1);
swap(tr[Ls].lmax0,tr[Ls].lmax1);
swap(tr[Ls].rmax0,tr[Ls].rmax1);
swap(tr[Rs].max0,tr[Rs].max1);
swap(tr[Rs].lmax0,tr[Rs].lmax1);
swap(tr[Rs].rmax0,tr[Rs].rmax1);
tr[rt].rev=0;
}
if(tr[rt].tag!=-1)
{
tr[rt].rev=0;
tr[Ls].tag=tr[Rs].tag=tr[rt].tag;
tr[Ls].sum=(mid-l+1)*tr[rt].tag;
tr[Rs].sum=(r-mid)*tr[rt].tag;
tr[Ls].rev=tr[Rs].rev=0;
if(tr[rt].tag==0)
{
tr[Ls].max0=tr[Ls].lmax0=tr[Ls].rmax0=mid-l+1;
tr[Ls].max1=tr[Ls].lmax1=tr[Ls].rmax1=0;
tr[Rs].max0=tr[Rs].lmax0=tr[Ls].rmax0=r-mid;
tr[Rs].max1=tr[Rs].lmax1=tr[Ls].rmax1=0;
}
else
{
tr[Ls].max1=tr[Ls].lmax1=tr[Ls].rmax1=mid-l+1;
tr[Ls].max0=tr[Ls].lmax0=tr[Ls].rmax0=0;
tr[Rs].max1=tr[Rs].lmax1=tr[Rs].rmax1=r-mid;
tr[Rs].max0=tr[Rs].lmax0=tr[Rs].rmax0=0;
}
tr[rt].tag=-1;
}
}
void Build(int rt,int l,int r)
{
tr[rt].rev=0,tr[rt].tag=-1;
if(l==r)
{
tr[rt].sum=a[l];
tr[rt].max0=tr[rt].lmax0=tr[rt].rmax0=(a[l]==0);
tr[rt].max1=tr[rt].lmax1=tr[rt].rmax1=(a[l]==1);
return;
}Build(Ls,l,mid),Build(Rs,mid+1,r);Push_Up(rt,l,r);
}
void Update_Ass(int rt,int l,int r,int x,int y,int k)
{
Push_Down(rt,l,r);
if(x<=l&&r<=y)
{
tr[rt].sum=k*(r-l+1),tr[rt].tag=k;
if(k==0)
{
tr[rt].lmax0=tr[rt].max0=tr[rt].rmax0=r-l+1;
tr[rt].lmax1=tr[rt].max1=tr[rt].rmax1=0;
}
else
{
tr[rt].rmax1=tr[rt].max1=tr[rt].rmax1=r-l+1;
tr[rt].lmax0=tr[rt].max0=tr[rt].rmax0=0;
}
return;
}
if(x<=mid) Update_Ass(Ls,l,mid,x,y,k);
if(y>mid) Update_Ass(Rs,mid+1,r,x,y,k);
Push_Down(rt,l,r);
}
void Update_Rev(int rt,int l,int r,int x,int y)
{
Push_Down(rt,l,r);
if(x<=l&&r<=y)
{
tr[rt].sum=(r-l+1)-tr[rt].sum;
tr[rt].rev^=1;
swap(tr[rt].max0,tr[rt].max1);
swap(tr[rt].lmax0,tr[rt].lmax1);
swap(tr[rt].rmax0,tr[rt].rmax1);
return;
}
if(x<=mid) Update_Rev(Ls,l,mid,x,y);
if(y>mid) Update_Rev(Rs,mid+1,r,x,y);
Push_Up(rt,l,r);
}
int Query_Sum(int rt,int l,int r,int x,int y)
{
Push_Down(rt,l,r);
if(x<=l&&r<=y) return tr[rt].sum;int ans=0;
if(x<=mid) ans+=Query_Sum(Ls,l,mid,x,y);
if(y>mid) ans+=Query_Sum(Rs,mid+1,r,x,y);
return ans;
}
tree Query_Con(int rt,int l,int r,int x,int y)
{
Push_Down(rt,l,r);
if(x<=l&&r<=y) return tr[rt];
if(x<=mid) return Query_Con(Ls,l,mid,x,y);
else if(y>mid) return Query_Con(Rs,mid+1,r,x,y);
else
{
tree ans,L=Query_Con(Ls,l,mid,x,y);
tree R=Query_Con(Rs,mid+1,r,x,y);
ans.sum=L.sum+R.sum;
ans.lmax0=L.lmax0;
if(L.sum==0) ans.lmax0+=R.lmax0;
ans.rmax0=R.rmax0;
if(R.sum==0) ans.rmax0+=L.rmax0;
ans.max0=max({L.rmax0+R.lmax0,L.max0,R.max0});
ans.lmax1=L.lmax1;
if(L.sum==mid-l+1) ans.lmax1+=R.lmax1;
ans.rmax1=R.rmax1;
if(R.sum==r-mid) ans.rmax1+=L.rmax1;
ans.max1=max({L.rmax1+R.lmax1,L.max1,R.max1});
return ans;
}
}
}t;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,q;cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
t.Build(1,1,n);
for(int i=1;i<=q;i++)
{
int opt,x,y;cin>>opt>>x>>y;x++,y++;
if(opt==0) t.Update_Ass(1,1,n,x,y,0);
else if(opt==1) t.Update_Ass(1,1,n,x,y,1);
else if(opt==2) t.Update_Rev(1,1,n,x,y);
else if(opt==3) cout<<t.Query_Sum(1,1,n,x,y)<<endl;
else if(opt==4) cout<<t.Query_Con(1,1,n,x,y).max1<<endl;
}
return 0;
}