#include<iostream>
using namespace std;
int n, m;
int a[100010];
struct node {
bool is0, is1;
int sum0, sum1, lsum0, lsum1, rsum0, rsum1, cnt0, cnt1;
}tr[400010];
int tag0[400010], tag1[400010], tag2[400010];
void pushup(int u) {
tr[u].cnt0 = tr[u << 1].cnt0 + tr[u << 1 | 1].cnt0;
tr[u].cnt1 = tr[u << 1].cnt1 + tr[u << 1 | 1].cnt1;
tr[u].is0 = tr[u << 1].is0 & tr[u << 1 | 1].is0;
tr[u].is1 = tr[u << 1].is1 & tr[u << 1 | 1].is1;
tr[u].lsum0 = tr[u << 1].lsum0;
if(tr[u << 1].is0) tr[u].lsum0 = tr[u << 1].cnt0 + tr[u << 1 | 1].lsum0;
tr[u].lsum1 = tr[u << 1].lsum1;
if(tr[u << 1].is1) tr[u].lsum1 = tr[u << 1].cnt1 + tr[u << 1 | 1].lsum1;
tr[u].rsum0 = tr[u << 1 | 1].rsum0;
if(tr[u << 1 | 1].is0) tr[u].rsum0 = tr[u << 1 | 1].cnt0 + tr[u << 1].rsum0;
tr[u].rsum1 = tr[u << 1 | 1].rsum1;
if(tr[u << 1 | 1].is1) tr[u].rsum1 = tr[u << 1 | 1].cnt1 + tr[u << 1].rsum1;
tr[u].sum0 = max(max(tr[u << 1].sum0, tr[u << 1 | 1].sum0), tr[u << 1].rsum0 + tr[u << 1 | 1].lsum0);
tr[u].sum1 = max(max(tr[u << 1].sum1, tr[u << 1 | 1].sum1), tr[u << 1].rsum1 + tr[u << 1 | 1].lsum1);
}
void build(int u, int l, int r) {
if(l == r) {
if(a[l]) tr[u].is1 = tr[u].sum1 = tr[u].lsum1 = tr[u].rsum1 = tr[u].cnt1 = 1;
else tr[u].is0 = tr[u].sum0 = tr[u].lsum0 = tr[u].rsum0 = tr[u].cnt0 = 1;
return ;
}
int mid = l + r >> 1;
build(u << 1, l , mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void pushdown(int u, int l, int r) {
int mid = l + r >> 1;
if(tag0[u]) {
tag0[u << 1] = 1; tag1[u << 1] = 0; tag2[u << 1] = 0;
tr[u << 1].is0 = 1, tr[u << 1].is1 = 0;
tr[u << 1].sum0 = tr[u << 1].lsum0 = tr[u << 1].rsum0 = tr[u << 1].cnt0 = mid - l + 1;
tr[u << 1].sum1 = tr[u << 1].lsum1 = tr[u << 1].rsum1 = tr[u << 1].cnt1 = 0;
tag0[u << 1 | 1] = 1; tag1[u << 1 | 1] = 0; tag2[u << 1 | 1] = 0;
tr[u << 1 | 1].is0 = 1, tr[u << 1 | 1].is1 = 0;
tr[u << 1 | 1].sum0 = tr[u << 1 | 1].lsum0 = tr[u << 1 | 1].rsum0 = tr[u << 1 | 1].cnt0 = r - mid;
tr[u << 1 | 1].sum1 = tr[u << 1 | 1].lsum1 = tr[u << 1 | 1].rsum1 = tr[u << 1 | 1].cnt1 = 0;
tag0[u] = 0;
}
if(tag1[u]) {
tag1[u << 1] = 1; tag0[u << 1] = 0; tag2[u << 1] = 0;
tr[u << 1].is1 = 1, tr[u << 1].is0 = 0;
tr[u << 1].sum1 = tr[u << 1].lsum1 = tr[u << 1].rsum1 = tr[u << 1].cnt1 = mid - l + 1;
tr[u << 1].sum0 = tr[u << 1].lsum0 = tr[u << 1].rsum0 = tr[u << 1].cnt0 = 0;
tag1[u << 1 | 1] = 1; tag0[u << 1 | 1] = 0; tag2[u << 1 | 1] = 0;
tr[u << 1 | 1].is1 = 1, tr[u << 1 | 1].is0 = 0;
tr[u << 1 | 1].sum1 = tr[u << 1 | 1].lsum1 = tr[u << 1 | 1].rsum1 = tr[u << 1 | 1].cnt1 = r - mid;
tr[u << 1 | 1].sum0 = tr[u << 1 | 1].lsum0 = tr[u << 1 | 1].rsum0 = tr[u << 1 | 1].cnt0 = 0;
tag1[u] = 0;
}
if(tag2[u]) {
swap(tr[u << 1].sum0, tr[u << 1].sum1);
swap(tr[u << 1].lsum0, tr[u << 1].lsum1);
swap(tr[u << 1].rsum0, tr[u << 1].rsum1);
swap(tr[u << 1].cnt0, tr[u << 1].cnt1);
swap(tr[u << 1].is0, tr[u << 1].is1);
if(tag0[u << 1]) tag0[u << 1] = 0, tag1[u << 1] = 1;
else if(tag1[u << 1]) tag1[u << 1] = 0, tag0[u << 1] = 1;
else tag2[u << 1] ^= 1;
swap(tr[u << 1 | 1].sum0, tr[u << 1 | 1].sum1);
swap(tr[u << 1 | 1].lsum0, tr[u << 1 | 1].lsum1);
swap(tr[u << 1 | 1].rsum0, tr[u << 1 | 1].rsum1);
swap(tr[u << 1 | 1].cnt0, tr[u << 1 | 1].cnt1);
swap(tr[u << 1 | 1].is0, tr[u << 1 | 1].is1);
if(tag0[u << 1 | 1]) tag0[u << 1 | 1] = 0, tag1[u << 1 | 1] = 1;
else if(tag1[u << 1 | 1]) tag1[u << 1 | 1] = 0, tag0[u << 1 | 1] = 1;
else tag2[u << 1] ^= 1;
tag2[u] = 0;
}
}
void change0(int u, int l, int r, int x, int y) {
if(x <= l && r <= y) {
tag0[u] = 1; tag1[u] = 0; tag2[u] = 0;
tr[u].is0 = 1, tr[u].is1 = 0;
tr[u].sum0 = tr[u].lsum0 = tr[u].rsum0 = tr[u].cnt0 = r - l + 1;
tr[u].sum1 = tr[u].lsum1 = tr[u].rsum1 = tr[u].cnt1 = 0;
return;
}
pushdown(u, l, r);
int mid = l + r >> 1;
if(x <= mid) change0(u << 1, l, mid, x, y);
if(y > mid) change0(u << 1 | 1, mid + 1, r, x, y);
pushup(u);
}
void change1(int u, int l, int r, int x, int y) {
if(x <= l && r <= y) {
tag1[u] = 1; tag0[u] = 0; tag2[u] = 0;
tr[u].is1 = 1, tr[u].is0 = 0;
tr[u].sum1 = tr[u].lsum1 = tr[u].rsum1 = tr[u].cnt1 = r - l + 1;
tr[u].sum0 = tr[u].lsum0 = tr[u].rsum0 = tr[u].cnt0 = 0;
return;
}
pushdown(u, l, r);
int mid = l + r >> 1;
if(x <= mid) change1(u << 1, l, mid, x, y);
if(y > mid) change1(u << 1 | 1, mid + 1, r, x, y);
pushup(u);
}
void change2(int u, int l, int r, int x, int y) {
if(x <= l && r <= y) {
swap(tr[u].sum0, tr[u].sum1);
swap(tr[u].lsum0, tr[u].lsum1);
swap(tr[u].rsum0, tr[u].rsum1);
swap(tr[u].cnt0, tr[u].cnt1);
swap(tr[u].is0, tr[u].is1);
if(tag0[u]) tag0[u] = 0, tag1[u] = 1;
else if(tag1[u]) tag1[u] = 0, tag0[u] = 1;
else tag2[u] ^= 1;
return ;
}
pushdown(u, l, r);
int mid = l + r >> 1;
if(x <= mid) change2(u << 1, l, mid, x, y);
if(y > mid) change2(u << 1 | 1, mid + 1, r, x, y);
pushup(u);
}
int query1(int u, int l, int r, int x, int y) {
if(x <= l && r <= y) return tr[u].cnt1;
pushdown(u, l, r);
int mid = l + r >> 1;
int ans = 0;
if(x <= mid) ans += query1(u << 1, l, mid, x, y);
if(y > mid) ans += query1(u << 1 | 1, mid + 1, r, x, y);
return ans;
}
node query2(int u, int l, int r, int x, int y) {
if(x <= l && r <= y) return tr[u];
pushdown(u, l, r);
int mid = l + r >> 1;
if(y <= mid) return query2(u << 1, l, mid, x, y);
else if(x > mid) return query2(u << 1 | 1, mid + 1, r, x, y);
else {
node xx;
node ll = query2(u << 1, l, mid, x, mid), rr = query2(u << 1 | 1, mid + 1, r, mid + 1, y);
xx.cnt1 = ll.cnt1 + rr.cnt1;
xx.cnt0 = ll.cnt0 + rr.cnt0;
xx.is0 = ll.is0 & rr.is0;
xx.is1 = ll.is1 & rr.is1;
xx.lsum0 = ll.lsum0;
if(ll.is0) xx.lsum0 = ll.cnt0 + rr.lsum0;
xx.lsum1 = ll.lsum1;
if(ll.is1) xx.lsum1 = ll.cnt1 + rr.lsum1;
xx.rsum0 = rr.rsum0;
if(rr.is0) xx.rsum0 = rr.cnt0 + ll.rsum0;
xx.rsum1 = rr.rsum1;
if(rr.is1) xx.rsum1 = rr.cnt1 + ll.rsum1;
xx.sum0 = max(max(ll.sum0, rr.sum0), ll.rsum0 + rr.lsum0);
xx.sum1 = max(max(ll.sum1, rr.sum1), ll.rsum1 + rr.lsum1);
return xx;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i ++) cin >> a[i];
build(1, 1, n);
for(int i = 1; i <= m; i ++) {
int op, l, r; cin >> op >> l >> r;
l ++, r ++;
if(op == 0) change0(1, 1, n, l, r);
if(op == 1) change1(1, 1, n, l, r);
if(op == 2) change2(1, 1, n, l, r);
if(op == 3) cout << query1(1, 1, n, l, r) << endl;
if(op == 4) cout << query2(1, 1, n, l, r).sum1 << endl;
}
return 0;
}