#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <iostream>
#include <stack>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + 100;
struct node
{
int sum;
int max_sub, max_zero;
int l, r, len;
int lazy1, lazy2;
int max_prezero, max_lastzero;
int max_preone, max_lastone;
}tree[maxn * 4];
int a[maxn];
void push_up(int id)
{
tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
tree[id].max_preone = tree[id << 1].max_preone;
if (tree[id].max_preone == tree[id << 1].len) tree[id].max_preone += tree[id << 1 | 1].max_preone;
tree[id].max_lastone = tree[id << 1 | 1].max_lastone;
if (tree[id].max_lastone == tree[id << 1 | 1].len) tree[id].max_lastone += tree[id << 1].max_lastone;
tree[id].max_sub = max(tree[id << 1].max_lastone + tree[id << 1 | 1].max_preone, max(tree[id << 1].max_sub, tree[id << 1 | 1].max_sub));
tree[id].max_prezero = tree[id << 1].max_prezero;
if (tree[id].max_prezero == tree[id << 1].len) tree[id].max_prezero += tree[id << 1 | 1].max_prezero;
tree[id].max_lastzero = tree[id << 1 | 1].max_lastzero;
if (tree[id].max_lastzero == tree[id << 1 | 1].len) tree[id].max_lastzero += tree[id << 1].max_lastzero;
tree[id].max_zero = max(tree[id << 1].max_lastzero + tree[id << 1 | 1].max_prezero, max(tree[id << 1].max_zero, tree[id << 1 | 1].max_zero));
return;
}
void chang1(int id, int val)
{
if (val)
{
tree[id].sum = tree[id].len;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = tree[id].len;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = 0;
}
else
{
tree[id].sum = 0;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = 0;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = tree[id].len;
}
}
void chang2(int id)
{
swap(tree[id].max_sub, tree[id].max_zero);
swap(tree[id].max_prezero, tree[id].max_preone);
swap(tree[id].max_lastone, tree[id].max_lastzero);
tree[id].sum = tree[id].len - tree[id].sum;
}
void push_down(int id)
{
if (tree[id].lazy1)
{
chang1(id << 1, tree[id].lazy1 - 1);
chang1(id << 1 | 1, tree[id].lazy1 - 1);
tree[id << 1].lazy1 = tree[id << 1 | 1].lazy1 = tree[id].lazy1;
tree[id << 1].lazy2 =tree[id << 1 | 1].lazy2 = 0;
tree[id].lazy1 = 0;
}
if (tree[id].lazy2)
{
chang2(id << 1);
chang2(id << 1 | 1);
tree[id << 1].lazy2 ^= 1;
tree[id << 1 | 1].lazy2 ^= 1;
tree[id].lazy2 = 0;
}
}
void build(int id, int l, int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lazy1 = 0;
tree[id].lazy2 = 0;
tree[id].len = r - l + 1;
if (l == r)
{
if (a[l]) chang1(id, 1);
else chang1(id, 0);
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
push_up(id);
}
void update_change(int id, int l, int r, int z)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
chang1(id, z);
tree[id].lazy1 = z + 1;
tree[id].lazy2 = 0;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> 1;
if (l <= mid) update_change(id << 1, l, r, z);
if (r > mid) update_change(id << 1 | 1, l, r, z);
push_up(id);
}
void update_trans(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
tree[id].lazy2 ^= 1;
chang2(id);
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> 1;
if (l <= mid) update_trans(id << 1, l, r);
if (r > mid) update_trans(id << 1 | 1, l, r);
push_up(id);
}
int query_sum(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].sum;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> 1, ans = 0;
if (l <= mid) ans += query_sum(id << 1, l, r);
if (r > mid) ans += query_sum(id << 1 | 1, l, r);
return ans;
}
int query(int id, int l, int r)
{
int ans = 0;
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].max_sub;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> 1;
if (l <= mid) ans = max(ans, query(id << 1, l, r));
if (r > mid) ans = max(ans, query(id << 1 | 1, l, r));
ans = max(ans, min(mid - l + 1, tree[id << 1].max_lastone) + min(r - mid, tree[id << 1 | 1].max_preone));
return ans;
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, 1, n);
while (m--)
{
int c, x, y;
scanf("%d%d%d", &c, &x, &y);
if (c == 0) update_change(1, x + 1, y + 1, 0);
if (c == 1) update_change(1, x + 1, y + 1, 1);
if (c == 2) update_trans(1, x + 1, y + 1);
if (c == 3)
{
int ans = query_sum(1, x + 1, y + 1);
printf("%d
", ans);
}
if (c == 4)
{
int ans = query(1, x + 1, y + 1);
printf("%d
", ans);
}
}
}
return 0;
}