#include <bits/stdc++.h>
#define ls (i<<1)
#define rs (i<<1|1)
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n, m, a[N], sum[N << 2], add[N << 2];
int change[N << 2], rev[N << 2], pre0[N << 2], pre1[N << 2], suf0[N << 2], suf1[N << 2], len0[N << 2], len1[N << 2];
int rpre[N << 2], rsuf[N << 2], rlen[N << 2];
bool is_changed[N << 2];
void up(int i, int ln, int rn) {
sum[i] = sum[ls] + sum[rs];
pre0[i] = pre0[ls] == ln ? pre0[ls] + pre0[rs] : pre0[ls];
suf0[i] = suf0[rs] == rn ? suf0[rs] + suf0[ls] : suf0[rs];
len0[i] = max(max(len0[ls], len0[rs]), suf0[ls] + pre0[rs]);
pre1[i] = pre1[ls] == ln ? pre1[ls] + pre1[rs] : pre1[ls];
suf1[i] = suf1[rs] == rn ? suf1[rs] + suf1[ls] : suf1[rs];
len1[i] = max(max(len1[ls], len1[rs]), suf1[ls] + pre1[rs]);
}
void addtagc(int i, int len, int v) {
is_changed[i] = 1;
change[i] = v;
sum[i] = len * v;
rev[i] = 0;
if (v == 0) {
pre0[i] = suf0[i] = len0[i] = len;
pre1[i] = suf1[i] = len1[i] = 0;
} else {
pre0[i] = suf0[i] = len0[i] = 0;
pre1[i] = suf1[i] = len1[i] = len;
}
}
void addtagr(int i, int len) {
rev[i] = 1 - rev[i];
sum[i] = len - sum[i];
swap(pre0[i], pre1[i]);
swap(suf0[i], suf1[i]);
swap(len0[i], len1[i]);
}
void down(int i, int ll, int lr) {
if (is_changed[i]) {
addtagc(ls, ll, change[i]);
addtagc(rs, lr, change[i]);
is_changed[i] = 0;
}
if (rev[i]) {
addtagr(ls, ll);
addtagr(rs, lr);
rev[i] = 0;
}
}
void build(int l, int r, int i) {
if (l == r) {
sum[i] = a[l];
pre0[i] = a[l] == 0;
pre1[i] = a[l] == 1;
suf0[i] = a[l] == 0;
suf1[i] = a[l] == 1;
len0[i] = a[l] == 0;
len1[i] = a[l] == 1;
return ;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
up(i, mid - l + 1, r - mid);
}
int query_sum(int l, int r, int i, int ql, int qr) {
if (ql <= l && qr >= r) return sum[i];
int mid = (l + r) >> 1;
down(i, mid - l + 1, r - mid);
int ans = 0;
if (ql <= mid) ans += query_sum(l, mid, ls, ql, qr);
if (qr > mid) ans += query_sum(mid + 1, r, rs, ql, qr);
return ans;
}
void query_longest(int l, int r, int i, int ql, int qr) {
if(ql <= l && r <= qr) {
rpre[i] = pre1[i];
rsuf[i] = suf1[i];
rlen[i] = len1[i];
return ;
}
int mid = (l + r) >> 1;
down(i, mid - l + 1, r - mid);
if(ql <= mid) query_longest(l, mid, ls, ql, qr);
if(qr > mid) query_longest(mid + 1, r, rs, ql, qr);
rlen[i] = max(max(rlen[ls], rlen[rs]), rsuf[ls] + rpre[rs]);
rpre[i] = rlen[ls] == mid - max(ql, l) + 1 ? rlen[ls] + rpre[rs] : rpre[ls];
rsuf[i] = rlen[rs] == min(r, qr) - mid ? rlen[rs] + rsuf[ls] : rsuf[rs];
}
void updatec(int l, int r, int i, int ql, int qr, int v) {
if (ql <= l && qr >= r) {
addtagc(i, r - l + 1, v);
return ;
}
int mid = (l + r) >> 1;
down(i, mid - l + 1, r - mid);
if (ql <= mid) updatec(l, mid, ls, ql, qr, v);
if (qr > mid) updatec(mid + 1, r, rs, ql, qr, v);
up(i, mid - l + 1, r - mid);
}
void updater(int l, int r, int i, int ql, int qr) {
if (ql <= l && qr >= r) {
addtagr(i, r - l + 1);
return ;
}
int mid = (l + r) >> 1;
down(i, mid - l + 1, r - mid);
if (ql <= mid) updater(l, mid, ls, ql, qr);
if (qr > mid) updater(mid + 1, r, rs, ql, qr);
up(i, mid - l + 1, r - mid);
}
signed main() {
cin >> n >> m;
for (int i = 1 ; i <= n ; i++) {
cin >> a[i];
}
build(1, n, 1);
while (m--) {
int opt, l, r;
cin >> opt >> l >> r;
opt++, l++, r++;;
if (opt == 1) {
updatec(1, n, 1, l, r, 0);
} else if (opt == 2) {
updatec(1, n, 1, l, r, 1);
}
else if (opt == 3) {
updater(1, n, 1, l, r);
}
else if(opt == 4) {
cout << query_sum(1, n, 1, l, r) << endl;
}
else {
query_longest(1, n, 1, l, r);
cout << rlen[1] << endl;
}
}
return 0;
}