#include<bits/stdc++.h>
#define pl (p<<1)
#define pr (p<<1|1)
using namespace std;
const int N = 1e5+10;
int n,m;
struct str{
int l1,l0;
int r1,r0;
int c;
int tag1;
bool tag2;
int ans1,ans0;
int l,r;
}tr[N<<2];
int sz(str A){
return A.r - A.l + 1;
}
void adtag1(int p,int c){
tr[p].tag2 = false;
if(c == 1){
tr[p].l0 = tr[p].r0 = 0;
tr[p].l1 = tr[p].r1 = tr[p].r-tr[p].l+1;
tr[p].c = tr[p].r-tr[p].l+1;
tr[p].tag1 = 1;
tr[p].ans1 = tr[p].r-tr[p].l+1;
tr[p].ans0 = 0;
}
if(c == -1){
tr[p].l0 = tr[p].r0 = tr[p].r-tr[p].l+1;
tr[p].l1 = tr[p].r1 = 0;
tr[p].c = 0;
tr[p].tag1 = -1;
tr[p].ans0 = tr[p].r-tr[p].l+1;
tr[p].ans1 = 0;
}
}
void adtag2(int p){
if(tr[p].tag1 == 1){
adtag1(p,-1);return;
}else if(tr[p].tag1 == -1){
adtag1(p,1);return;
}
swap(tr[p].l0,tr[p].l1);
swap(tr[p].r0,tr[p].r1);
swap(tr[p].ans1,tr[p].ans0);
tr[p].c = tr[p].r - tr[p].l + 1 - tr[p].c;
tr[p].tag2 = true;
return;
}
void push_down(int p){
if(tr[p].tag2)
adtag2(pl),adtag2(pr);
else if(tr[p].tag1 != 0)
adtag1(pl,tr[p].tag1),adtag1(pr,tr[p].tag1);
tr[p].tag1 = 0,tr[p].tag2 = false;
}
str merge(str A,str B){
str ret;
ret.tag1 = ret.tag2 = false;
if(A.c == 0) ret.l0 = sz(A) + B.l0;
else ret.l0 = A.l0;
if(A.c == sz(A)) ret.l1 = sz(A) + B.l1;
else ret.l1 = A.l1;
if(B.c == 0) ret.r0 = sz(B) + A.r0;
else ret.r0 = B.r0;
if(B.c == sz(B)) ret.r1 = sz(B) + A.r1;
else ret.r1 = B.r1;
ret.c = A.c + B.c;
ret.ans0 = max(A.ans0,B.ans0);
ret.ans0 = max(ret.ans0,A.r0+B.l0);
ret.ans1 = max(A.ans1,B.ans1);
ret.ans1 = max(ret.ans1,A.r1+B.l1);
ret.l = A.l,ret.r = B.r;
return ret;
}
void up(int p){
tr[p] = merge(tr[pl],tr[pr]);
}
void build(int p,int l,int r){
tr[p].l = l,tr[p].r = r;
if(l == r){
cin >> tr[p].c;
if(tr[p].c == 1){
tr[p].l1 = tr[p].r1 = 1;
tr[p].l0 = tr[p].r0 = 0;
tr[p].ans0 = 0,tr[p].ans1 = 1;
tr[p].tag1 = tr[p].tag2 = false;
}else{
tr[p].l0 = tr[p].r0 = 1;
tr[p].l1 = tr[p].r1 = 0;
tr[p].ans0 = 1,tr[p].ans1 = 0;
tr[p].tag1 = tr[p].tag2 = false;
}
return;
}
int mid = (l+r)>>1;
build(pl,l,mid);
build(pr,mid+1,r);
up(p);
}
void update(int p,int l,int r,int L,int R,int c){
if(L <= l && r <= R){
if(c == 2) adtag2(p);
else adtag1(p,c);
return;
}
push_down(p);
int mid = (l+r)>>1;
if(mid >= L) update(pl,l,mid,L,R,c);
if(mid+1<=R) update(pr,mid+1,r,L,R,c);
up(p);
return;
}
str query(int p,int l,int r,int L,int R){
if(L <= l && r <= R) return tr[p];
push_down(p);
int mid = (l+r)>>1;
if(mid>=L && mid+1<=R) return merge(query(pl,l,mid,L,R),query(pr,mid+1,r,L,R));
if(mid >=L) return query(pl,l,mid,L,R);
if(mid+1<=R) return query(pr,mid+1,r,L,R);
}
void uout(int p,int l,int r){
if(l == r){
if(l == 1) cout <<':';
cout << tr[p].c <<' ';
if(r == n) cout <<'\n';
return;
}
int mid = (l+r)>>1;
push_down(p);
uout(pl,l,mid);
uout(pr,mid+1,r);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n >> m;
build(1,1,n);
int k,l,r;
while(m --){
cin >> k >> l >> r;
l++,r++;
switch(k){
case 0:
update(1,1,n,l,r,-1);
break;
case 1:
update(1,1,n,l,r,1);
break;
case 2:
update(1,1,n,l,r,2);
break;
case 3:
cout << query(1,1,n,l,r).c <<'\n';
break;
case 4:
cout << query(1,1,n,l,r).ans1 <<'\n';
break;
}
}
return 0;
}