#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int nmax = 100000;
int n, p, lazy[nmax * 4 + 5];
struct aint
{
int maxim0, maxim1;
int maximst0, maximst1;
int maximdr0, maximdr1;
int l;
}v[nmax * 4 + 5];
aint Merge(aint a, aint b)
{
aint c = {max(a.maxim0, b.maxim0), max(a.maxim1, b.maxim1), a.maximst0, a.maximst1, b.maximdr0, b.maximdr1, a.l + b.l};
if (a.maximst0 == a.l) c.maximst0 += b.maximst0;
if (a.maximst1 == a.l) c.maximst1 += b.maximst1;
if (b.maximdr0 == b.l) c.maximdr0 += a.maximdr0;
if (b.maximdr1 == b.l) c.maximdr1 += a.maximdr1;
c.maxim0 = max(c.maxim0, c.maximst0);
c.maxim0 = max(c.maxim0, c.maximdr0);
c.maxim0 = max(c.maxim0, a.maximdr0 + b.maximst0);
c.maxim1 = max(c.maxim1, c.maximst1);
c.maxim1 = max(c.maxim1, c.maximdr1);
c.maxim1 = max(c.maxim1, a.maximdr1 + b.maximst1);
return c;
}
void Build(int nod, int st, int dr)
{
if (st == dr)
{
v[nod] = {1, 0, 1, 0, 1, 0, 1};
return;
}
int mid = (st + dr) / 2;
Build(nod * 2, st, mid);
Build(nod * 2 + 1, mid + 1, dr);
v[nod] = Merge(v[nod * 2], v[nod * 2 + 1]);
}
void down(int nod, int st, int dr)
{
if (lazy[nod])
{
lazy[nod] = 0;
if (st != dr)
{
lazy[nod * 2] ^= 1;
lazy[nod * 2 + 1] ^= 1;
}
swap(v[nod].maxim0, v[nod].maxim1);
swap(v[nod].maximst0, v[nod].maximst1);
swap(v[nod].maximdr0, v[nod].maximdr1);
}
}
void Update(int nod, int st, int dr, int l, int r)
{
down(nod, st, dr);
if (st >= l && dr <= r)
{
lazy[nod] ^= 1;
down(nod, st, dr);
return;
}
if (st > r || dr < l) return;
int mid = (st + dr) / 2;
Update(nod * 2, st, mid, l, r);
Update(nod * 2 + 1, mid + 1, dr, l, r);
v[nod] = Merge(v[nod * 2], v[nod * 2 + 1]);
}
int main()
{
fin >> n >> p;
Build(1, 1, n);
while (p--)
{
int op;
fin >> op;
if (op == 3)
{
fout << v[1].maxim0 << "\n";
}
else
{
int l, r;
fin >> l >> r;
r = min(n, l + r - 1);
Update(1, 1, n, l, r);
}
}
fin.close();
fout.close();
return 0;
}