#include <bits/stdc++.h>
const int N = 1e5 + 10;
struct tree {
int sum, ans1, l1, r1, ans0, l0, r0, l, r;
friend tree operator + (tree a, tree b) {
tree res;
res.sum = a.sum + b.sum;
res.l1 = a.l1;
if (a.r - a.l + 1 == a.l1)
res.l1 = a.l1 + b.l1;
res.r1 = b.r1;
if (b.r - b.l + 1 == b.r1)
res.r1 = b.r1 + a.r1;
res.l0 = a.l0;
if (a.sum == 0)
res.l0 = a.l0 +b.l0;
res.r0 = b.r0;
if (b.sum==0)
res.r0=b.r0+a.r0;
res.ans1 = std::max({a.r1 + b.l1, a.ans1, b.ans1});
res.ans0 = std::max({a.r0 + b.l0, a.ans0, b.ans0});
return res;
}
};
int n, m;
int a[N], tag[N << 2];
tree tr[N << 2];
void pushup (int p) {
tr[p] = tr[p << 1] + tr[p << 1 | 1];
}
void change (int l, int r, int p) {
tr[p] = {r - l + 1 - tr[p].sum, tr[p].ans0, tr[p].l0, tr[p].r0, tr[p].ans1, tr[p].l1, tr[p].r1};
}
void pushdown (int l, int r, int p) {
int mid = l + r >> 1;
if (tag[p] == 1) {
tr[p << 1] = {mid - l + 1, mid - l + 1, mid - l + 1, mid - l + 1, 0, 0, 0};
tr[p << 1 | 1] = {r - mid, r - mid, r - mid, r - mid, 0, 0, 0};
} else if (tag[p] == 2) {
tr[p << 1] = {0, 0, 0, 0, mid - l + 1, mid - l + 1, mid - l + 1};
tr[p << 1 | 1] = {0, 0, 0, 0, r - mid, r - mid, r - mid};
} else if (tag[p] == 3) {
change(l, mid, p << 1);
change(mid + 1, r, p << 1 | 1);
}
tag[p]=0;
}
void build (int l, int r, int p) {
if (l == r) {
if (a[l])
tr[p] = {1, 1, 1, 1, 0, 0, 0};
else
tr[p] = {0, 0, 0, 0, 1, 1, 1};
return;
}
int mid = l + r >> 1;
build(l, mid, p << 1);
build(mid + 1, r, p << 1 | 1);
pushup(p);
}
void update (int l, int r, int p, int L, int R, int c) {
if (L <= l && r <= R) {
if (c == 1)
tr[p] = {r - l + 1, r - l + 1, r - l + 1, r - l + 1, 0, 0, 0}, tag[p] = 1;
else if (c == 2)
tr[p] = {0, 0, 0, 0, r - l + 1, r - l + 1, r - l + 1}, tag[p] = 2;
else
change(l, r, p), tag[p] = 3;
return;
}
pushdown(l, r, p);
int mid = l + r >> 1;
if (L <= mid)
update(l, mid, p << 1, L, R, c);
if (R > mid)
update(mid + 1, r, p << 1 | 1, L, R, c);
pushup(p);
}
std::pair<int, int> operator + (std::pair<int, int> a, std::pair<int, int> b) {
return {a.first + b.first, std::max(a.second, b.second)};
}
tree query (int l, int r, int p, int L, int R) {
if (L <= l && r <= R)
return tr[p];
pushdown(l, r, p);
int mid = l + r >> 1;
tree res = {0,0,0,0,0,0,0};
if (L <= mid)
res = res + query(l, mid, p << 1, L, R);
if (R > mid)
res = res + query(mid + 1, r, p << 1 | 1, L, R);
return res;
}
int main (void) {
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m;
for (int i = 1; i <= n; i++)
std::cin >> a[i];
build(1, n, 1);
for (int i = 1; i <= m; i++) {
int op, l, r;
std::cin >> op >> l >> r;
if (op == 0)
update(1, n, 1, l + 1, r + 1, 2);
else if (op == 1)
update(1, n, 1, l + 1, r + 1, 1);
else if (op == 2)
update(1, n, 1, l + 1, r + 1, 3);
else if (op == 3)
std::cout << query(1, n, 1, l + 1, r + 1).sum << std::endl;
else
std::cout << query(1, n, 1, l + 1, r + 1).ans1 << std::endl;
}
return 0;
}