#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
#define mid (l + r) / 2
class SegmentTree {
public:
SegmentTree(int _n)
{
n = _n;
sgt = st = dr = vector<int> (4 * n);
Build(1, 1, n);
}
void Update(int x, int y, int v)
{
Update(1, 1, n, x, y, v);
}
int Query() const
{
return sgt[1];
}
private:
void Build(int node, int l, int r)
{
Set(node, r - l + 1);
if (l != r)
{
Build(2 * node, l, mid);
Build(2 * node + 1, mid + 1, r);
}
}
void Set(int node, int val)
{
sgt[node] = st[node] = dr[node] = val;
}
void PushDown(int node, int l, int r)
{
if (!sgt[node])
{
Set(2 * node, 0);
Set(2 * node + 1, 0);
}
if (sgt[node] == r - l + 1)
{
Set(2 * node, mid - l + 1);
Set(2 * node + 1, r - mid);
}
}
void Update(int node, int l, int r, int L, int R, int val)
{
if (L <= l && r <= R)
{
Set(node, (r - l + 1) * val);
return;
}
PushDown(node, l, r);
if (L <= mid) Update(2 * node, l, mid, L, R, val);
if (mid < R) Update(2 * node + 1, mid + 1, r, L, R, val);
st[node] = st[2 * node];
if (st[2 * node] == mid - l + 1)
st[node] += st[2 * node + 1];
dr[node] = dr[2 * node + 1];
if (dr[2 * node + 1] == r - mid)
dr[node] += dr[2 * node];
sgt[node] = max({sgt[2 * node], sgt[2 * node + 1], dr[2 * node] + st[2 * node + 1]});
}
vector<int> sgt, st, dr;
int n;
};
int n, m, op, L, p;
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
fin >> n >> m;
SegmentTree sgt(n);
while (m--)
{
fin >> op;
if (op == 1)
{
fin >> p >> L;
sgt.Update(p, p + L - 1, 0);
}
if (op == 2)
{
fin >> p >> L;
sgt.Update(p, p + L - 1, 1);
}
if (op == 3)
fout << sgt.Query() << '\n';
}
fin.close();
fout.close();
}