#include <bits/stdc++.h>
//#define int long long
#define rep(i, l, r) for(int i = l; i <= r; ++ i)
#define per(i, r, l) for(int i = r; i >= l; -- i)
using namespace std;
const int N = 8e5 + 10;
int n, m;
int a[N];
#define ls rt << 1
#define rs rt << 1 | 1
#define len(x) (rr[x] - ll[x] + 1)
int mx0[N], mx1[N], lmx0[N], lmx1[N], rmx0[N], rmx1[N], op[N], tag[N], ll[N], rr[N], sum[N];
void update(int rt)
{
mx0[rt] = max({mx0[ls], mx0[rs], rmx0[ls] + lmx0[rs]});
mx1[rt] = max({mx1[ls], mx1[rs], rmx1[ls] + lmx1[rs]});
lmx0[rt] = lmx0[ls];
if(lmx0[ls] == len(ls)) lmx0[rt] += lmx0[rs];
lmx1[rt] = lmx1[ls];
if(lmx1[ls] == len(ls)) lmx1[rt] += lmx1[rs];
rmx0[rt] = rmx0[rs];
if(rmx0[rs] == len(rs)) rmx0[rt] += rmx0[ls];
rmx1[rt] = rmx1[rs];
if(rmx1[rs] == len(rs)) rmx1[rt] += rmx1[ls];
sum[rt] = sum[ls] + sum[rs];
}
void build(int rt, int l, int r)
{
ll[rt] = l; rr[rt] = r;
op[rt] = 0; tag[rt] = -1;
if(l == r)
{
mx0[rt] = lmx0[rt] = rmx0[rt] = (a[l] ^ 1);
sum[rt] = mx1[rt] = lmx1[rt] = rmx1[rt] = a[l];
return ;
}
int mid = (l + r) >> 1;
build(ls, l, mid); build(rs, mid + 1, r);
update(rt);
}
void push_up_rev(int rt)
{
sum[rt] = len(rt) - sum[rt];
swap(mx1[rt], mx0[rt]);
swap(lmx1[rt], lmx0[rt]);
swap(rmx1[rt], rmx0[rt]);
op[rt] ^= 1;
}
void push_up_cov(int rt, int v)
{
op[rt] = 0;
mx0[rt] = lmx0[rt] = rmx0[rt] = (v ^ 1) * len(rt);
sum[rt] = mx1[rt] = lmx1[rt] = rmx1[rt] = v * len(rt);
tag[rt] = v;
}
void push_down_cov(int rt)
{
if(tag[rt] == -1) return;
push_up_cov(ls, tag[rt]);
push_up_cov(rs, tag[rt]);
tag[rt] = -1;
}
void push_down_rev(int rt)
{
if(!op[rt]) return;
push_up_rev(ls);
push_up_rev(rs);
op[rt] = 0;
}
void change(int rt, int x, int y, int opt)
{
int l = ll[rt], r = rr[rt];
if(x <= l && r <= y)
{
if(opt <= 1) push_up_cov(rt, opt);
else push_up_rev(rt);
return;
}
push_down_cov(rt); push_down_rev(rt);
int mid = (l + r) >> 1;
if(mid >= x) change(ls, x, y, opt);
if(mid < y) change(rs, x, y, opt);
update(rt);
}
int ask1(int rt, int x, int y)
{
int l = ll[rt], r = rr[rt];
if(x <= l && r <= y) return sum[rt];
push_down_cov(rt); push_down_rev(rt);
int mid = (l + r) >> 1, ans = 0;
if(mid >= x) ans += ask1(ls, x, y);
if(mid < y) ans += ask1(rs, x, y);
return ans;
}
int ans = -1, rmx;
void ask2(int rt, int x, int y)
{
int l = ll[rt], r = rr[rt];
if(x <= l && r <= y)
{
if(ans == -1)
{
ans = mx1[rt];
rmx = rmx1[rt];
return;
}
ans = max({ans, mx1[rt], rmx + lmx1[rt]});
if(rmx1[rt] == len(rt)) rmx += len(rt);
else rmx = rmx1[rt];
return;
}
push_down_cov(rt); push_down_rev(rt);
int mid = (l + r) >> 1;
if(mid >= x) ask2(ls, x, y);
if(mid < y) ask2(rs, x, y);
}
main()
{
cin >> n >> m;
rep(i, 1, n) cin >> a[i];
build(1, 1, n);
rep(i, 1, m)
{
int opt, l, r;
cin >> opt >> l >> r; ++ l; ++ r;
if(opt <= 2) change(1, l, r, opt);
else if(opt == 3) cout << ask1(1, l, r) << '\n';
else
{
ans = -1; ask2(1, l, r);
cout << ans << '\n';
}
}
return 0;
}