# include <bits/stdc++.h>
using namespace std;
const int Nmax = 1e5 + 5;
struct aint {int l, r, curr;};
aint arb[Nmax * 3];
int n, q, type, x, y;
void build(int node, int left, int right)
{
if (left == right)
{
arb[left].l = arb[left].curr = arb[left].r = 1;
return;
}
int mid = (left + right) >> 1;
build(node * 2, left, mid);
build(node * 2 + 1, mid + 1, right);
arb[node].l = arb[node].curr = arb[node].r = right - left + 1;
}
void update(int node, int left, int right, int st, int dr, int k)
{
if (st <= left && right <= dr)
{
if (k == 1) arb[node].l = arb[node].r = arb[node].curr = 0;
else arb[node].l = arb[node].r = arb[node].curr = right - left + 1;
return;
}
int mid = (left + right) >> 1;
if (arb[node].curr == 0)
{
arb[node * 2].curr = arb[node * 2].l = arb[node * 2].r = 0;
arb[node * 2 + 1].curr = arb[node * 2 + 1].l = arb[node * 2 + 1].r = 0;
}
if (arb[node].curr == right - left + 1)
{
arb[node * 2].curr = arb[node * 2].l = arb[node * 2].r = mid - left + 1;
arb[node * 2 + 1].curr = arb[node * 2 + 1].l = arb[node * 2 + 1].r = right - mid;
}
if (st <= mid) update(node * 2, left, mid, st, dr, k);
if (mid < dr) update(node * 2 + 1, mid + 1, right, st, dr, k);
arb[node].l = arb[node * 2].l;
if (arb[node * 2].l == mid - left + 1) arb[node].l += arb[node * 2 + 1].l;
arb[node].r = arb[node * 2 + 1].r;
if (arb[node * 2 + 1].r == right - mid) arb[node].r += arb[node * 2].r;
arb[node].curr = max (max(arb[node * 2].curr, arb[node * 2 + 1].curr), arb[node * 2].r + arb[node * 2 + 1].l);
}
int main ()
{
freopen("hotel.in", "r", stdin);
freopen("hotel.out", "w", stdout);
scanf("%d %d\n", &n, &q);
build(1, 1, n);
for ( ; q; --q)
{
scanf("%d", &type);
if (type == 3) printf("%d\n", arb[1].curr);
else
{
scanf("%d %d\n", &x, &y);
y = x + y - 1;
if (type == 1) update(1, 1, n, x, y, 1);
else if (type == 2) update(1, 1, n, x, y, 2);
}
}
return 0;
}