#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ls p << 1
#define rs p << 1 | 1
const int N = (int)2e5 + 5;
int n, q;
struct tree
{
int l, r, lazy, sum;
int len, lenl, lenr;
} a[N << 2];
inline int read()
{
int s = 0, f = 0;
char ch = getchar();
while (ch < 48 || ch > 57)
{
if (ch == '-')
f = 1;
ch = getchar();
}
while (ch >= 48 && ch <= 57)
{
s = (s << 3) + (s << 1) + (ch ^ 48);
ch = getchar();
}
return f ? -s : s;
}
void pushup(int p)
{
a[p].sum = a[ls].sum + a[rs].sum;
a[p].lenl = (a[ls].lenl == a[ls].r - a[ls].l + 1 ? a[ls].lenl + a[rs].lenl : a[ls].lenl);
a[p].lenr = (a[rs].lenr == a[rs].r - a[rs].l + 1 ? a[rs].lenr + a[ls].lenr : a[rs].lenr);
a[p].len = max(max(a[ls].len, a[rs].len), a[ls].lenr + a[rs].lenl);
}
void pushdown(int p)
{
if (a[p].lazy != -1)
{
a[ls].lazy = a[rs].lazy = a[p].lazy;
a[ls].len = a[ls].lenl = a[ls].lenr = (a[p].lazy ^ 1) * (a[ls].r - a[ls].l + 1);
a[ls].sum = a[p].lazy * (a[ls].r - a[ls].l + 1);
a[rs].len = a[rs].lenl = a[rs].lenr = (a[p].lazy ^ 1) * (a[rs].r - a[rs].l + 1);
a[rs].sum = a[p].lazy * (a[rs].r - a[rs].l + 1);
a[p].lazy = -1;
}
}
void build(int p, int l, int r)
{
a[p].l = l, a[p].r = r, a[p].lazy = -1;
if (l == r)
{
a[p].sum = 1;
a[p].len = a[p].lenl = a[p].lenr = 0;
return;
}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(p);
}
int query_sum(int p, int x, int y)
{
if (x <= a[p].l && a[p].r <= y)
{
return a[p].sum;
}
pushdown(p);
int mid = (a[p].l + a[p].r) >> 1, ans = 0;
if (x <= mid)
{
ans += query_sum(ls, x, y);
}
if (y > mid)
{
ans += query_sum(rs, x, y);
}
return ans;
}
tree query_max(int p, int x, int y)
{
if (x <= a[p].l && a[p].r <= y)
{
return a[p];
}
pushdown(p);
int mid = (a[p].l + a[p].r) >> 1, t = 0;
tree tmp[3];
if (x <= mid)
{
tmp[1] = query_max(ls, x, y);
t += 1;
}
if (y > mid)
{
tmp[2] = query_max(rs, x, y);
t += 2;
}
if (t < 3)
return tmp[t];
tmp[0].sum = tmp[1].sum + tmp[2].sum;
tmp[0].lenl = (tmp[1].lenl == tmp[1].r - tmp[1].l + 1 ? tmp[1].lenl + tmp[2].lenl : tmp[1].lenl);
tmp[0].lenr = (tmp[2].lenr == tmp[2].r - tmp[2].l + 1 ? tmp[2].lenr + tmp[1].lenr : tmp[2].lenr);
tmp[0].len = max(max(tmp[1].len, tmp[2].len), tmp[1].lenr + tmp[2].lenl);
return tmp[0];
}
void update(int p, int x, int y, int k)
{
if (x <= a[p].l && a[p].r <= y)
{
a[p].len = a[p].lenl = a[p].lenr = (k ^ 1) * (a[p].r - a[p].l + 1);
a[p].sum = k * (a[p].r - a[p].l + 1);
a[p].lazy = k;
return;
}
pushdown(p);
int mid = (a[p].l + a[p].r) >> 1;
if (x <= mid)
{
update(ls, x, y, k);
}
if (y > mid)
{
update(rs, x, y, k);
}
pushup(p);
}
int find(int x, int y, int k)
{
int l = x, r = y;
while (l < r)
{
int mid = (l + r) >> 1;
if (mid - x + 1 - query_sum(1, x, mid) < k)
{
l = mid + 1;
}
else
{
r = mid;
}
}
return l;
}
signed main()
{
freopen("P4344.in", "r", stdin);
freopen("P4344.out", "w", stdout);
n = read(), q = read();
build(1, 1, n);
while (q--)
{
int t = read(), x = read(), y = read(), l, r;
if (t == 0)
{
update(1, x, y, 0);
}
else if (t == 2)
{
tree t = query_max(1, x, y);
printf("%d\n", t.len);
}
else
{
l = read(), r = read();
int sum1 = query_sum(1, x, y), sum2 = r - l + 1 - query_sum(1, l, r);
if (sum1 >= sum2)
{
update(1, l, r, 1);
update(1, x, y, 0);
}
else
{
int ar = find(l, r, sum1);
update(1, x, y, 0);
update(1, l, ar, 1);
}
}
}
return 0;
}