#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ls d<<1
#define rs d<<1|1
const int N=1e5;
ll n,m,a[N+5];
struct node
{
ll ans0,ans1,l0,r0,l1,r1,lc,rc,len,num1,num0;
bool lazy1,lazy2,lazy3;
}tree[N*4+5];
void pu(ll d)
{
tree[d].len=tree[ls].len+tree[rs].len;
tree[d].num0=tree[ls].num0+tree[rs].num0;
tree[d].num1=tree[ls].num1+tree[rs].num1;
tree[d].ans0=max(tree[ls].ans0,tree[rs].ans0);
tree[d].ans1=max(tree[ls].ans1,tree[rs].ans1);
tree[d].l0=tree[ls].l0;
tree[d].r0=tree[rs].r0;
tree[d].l1=tree[ls].l1;
tree[d].r1=tree[rs].r1;
tree[d].lc=tree[ls].lc;
tree[d].rc=tree[rs].rc;
if(tree[ls].rc==tree[rs].lc)
{
if(tree[ls].rc==1)
{
tree[d].ans1=max(tree[d].ans1,tree[ls].r1+tree[rs].l1);
if(tree[ls].ans1==tree[ls].len) tree[d].l1=tree[ls].ans1+tree[rs].l1;
if(tree[rs].ans1==tree[rs].len) tree[d].r1=tree[rs].ans1+tree[ls].r1;
}
else
{
tree[d].ans0=max(tree[d].ans0,tree[ls].r0+tree[rs].l0);
if(tree[ls].ans0==tree[ls].len) tree[d].l0=tree[ls].ans0+tree[rs].l0;
if(tree[rs].ans0==tree[rs].len) tree[d].r0=tree[rs].ans0+tree[ls].r0;
}
}
}
void pd(ll d)
{
if(tree[d].lazy1)
{
tree[ls].lazy1=1;
tree[ls].lazy2=tree[ls].lazy3=0;
tree[ls].ans1=tree[ls].l1=tree[ls].r1=tree[ls].lc=tree[ls].rc=0;
tree[ls].ans0=tree[ls].l0=tree[ls].r0=tree[ls].len;
tree[ls].num1=0;
tree[ls].num0=tree[ls].len;
tree[rs].lazy1=1;
tree[rs].lazy2=tree[rs].lazy3=0;
tree[rs].ans1=tree[rs].l1=tree[rs].r1=tree[rs].lc=tree[rs].rc=0;
tree[rs].ans0=tree[rs].l0=tree[rs].r0=tree[rs].len;
tree[rs].num1=0;
tree[rs].num0=tree[rs].len;
tree[d].lazy1=0;
}
else if(tree[d].lazy2)
{
tree[ls].lazy2=1;
tree[ls].lazy1=tree[ls].lazy3=0;
tree[ls].ans0=tree[ls].l0=tree[ls].r0=0;
tree[ls].ans1=tree[ls].l1=tree[ls].r1=tree[ls].len;
tree[ls].lc=tree[ls].rc=1;
tree[ls].num0=0;
tree[ls].num1=tree[ls].len;
tree[rs].lazy2=1;
tree[rs].lazy1=tree[rs].lazy3=0;
tree[rs].ans0=tree[rs].l0=tree[rs].r0=0;
tree[rs].ans1=tree[rs].l1=tree[rs].r1=tree[rs].len;
tree[rs].lc=tree[rs].rc=1;
tree[rs].num0=0;
tree[rs].num1=tree[rs].len;
tree[d].lazy2=0;
}
if(tree[d].lazy3)
{
tree[ls].lazy3^=1;
swap(tree[ls].ans0,tree[ls].ans1);
swap(tree[ls].l0,tree[ls].l1);
swap(tree[ls].r0,tree[ls].r1);
swap(tree[ls].num0,tree[ls].num1);
tree[ls].lc^=1;
tree[ls].rc^=1;
tree[rs].lazy3^=1;
swap(tree[rs].ans0,tree[rs].ans1);
swap(tree[rs].l0,tree[rs].l1);
swap(tree[rs].r0,tree[rs].r1);
swap(tree[rs].num0,tree[rs].num1);
tree[rs].lc^=1;
tree[rs].rc^=1;
tree[d].lazy3=0;
}
}
void build(ll d,ll l,ll r)
{
if(l==r)
{
tree[d].len=1;
if(a[l]==1)
{
tree[d].ans1=1;
tree[d].l1=1;
tree[d].r1=1;
tree[d].lc=1;
tree[d].rc=1;
tree[d].num1=1;
}
else
{
tree[d].ans0=1;
tree[d].l0=1;
tree[d].r0=1;
tree[d].num0=1;
}
return ;
}
ll mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pu(d);
}
void renew(ll d,ll l,ll r,ll ql,ll qr,ll opt)
{
if(ql>r||qr<l) return ;
if(ql<=l&&qr>=r)
{
if(opt==0)
{
tree[d].lazy1=1;
tree[d].lazy2=tree[d].lazy3=0;
tree[d].ans1=tree[d].l1=tree[d].r1=tree[d].lc=tree[d].rc=0;
tree[d].l0=tree[d].r0=tree[d].len;
tree[d].num0=tree[d].len;
tree[d].num1=0;
}
if(opt==1)
{
tree[d].lazy2=1;
tree[d].lazy1=tree[d].lazy3=0;
tree[d].ans0=tree[d].l0=tree[d].r0=0;
tree[d].ans1=tree[d].l1=tree[d].r1=tree[d].len;
tree[d].lc=tree[d].rc=1;
tree[d].num1=tree[d].len;
tree[d].num0=0;
}
if(opt==2)
{
tree[d].lazy3^=1;
swap(tree[d].ans0,tree[d].ans1);
swap(tree[d].l0,tree[d].l1);
swap(tree[d].r0,tree[d].r1);
swap(tree[d].num0,tree[d].num1);
tree[d].lc^=1;
tree[d].rc^=1;
}
return ;
}
pd(d);
ll mid=(l+r)>>1;
renew(ls,l,mid,ql,qr,opt);
renew(rs,mid+1,r,ql,qr,opt);
pu(d);
}
ll find1(ll d,ll l,ll r,ll ql,ll qr)
{
if(ql>r||qr<l) return 0;
if(ql<=l&&qr>=r)
{
return tree[d].num1;
}
pd(d);
ll mid=(l+r)>>1;
return find1(ls,l,mid,ql,qr)+find1(rs,mid+1,r,ql,qr);
}
node find2(ll d,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&qr>=r)
{
return tree[d];
}
pd(d);
ll mid=(l+r)>>1;
if(qr<=mid) return find2(ls,l,mid,ql,qr);
if(ql>mid) return find2(rs,mid+1,r,ql,qr);
node res,L=find2(ls,l,mid,ql,qr),R=find2(rs,mid+1,r,ql,qr);
res.len=L.len+R.len;
res.num1=L.num1+R.num1;
res.ans1=max(L.ans1,R.ans1);
res.l1=L.l1;
res.r1=R.r1;
res.lc=L.lc;
res.rc=R.rc;
if(L.rc==R.lc)
{
if(tree[ls].rc==1)
{
res.ans1=max(res.ans1,L.r1+R.l1);
if(L.ans1==L.len) res.l1=L.ans1+R.l1;
if(R.ans1==R.len) res.r1=R.ans1+L.r1;
}
}
return res;
}
int main()
{
freopen("xly.in","r",stdin);
freopen("xly.out","w",stdout);
cin>>n>>m;
for(ll i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(ll i=1;i<=m;i++)
{
ll opt,l,r;
cin>>opt>>l>>r;
l++;
r++;
if(opt<=2) renew(1,1,n,l,r,opt);
if(opt==3) cout<<find1(1,1,n,l,r)<<endl;
if(opt==4) cout<<find2(1,1,n,l,r).ans1<<endl;
}
return 0;
}