#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int DIM = 1e5 + 7;
struct SegmentTree
{
int best;
int to_left;
int to_right;
int lazy;
bool all;
};
SegmentTree arb[DIM * 4];
void down(int nod, int l, int r)
{
if(arb[nod].lazy == 0)
{
arb[nod].to_left = r - l + 1;
arb[nod].to_right = r - l + 1;
arb[nod].best = r - l + 1;
arb[nod].all = true;
}
else
{
arb[nod].to_left = 0;
arb[nod].to_right = 0;
arb[nod].best = 0;
arb[nod].all = false;
}
if(l != r)
{
arb[nod * 2].lazy = arb[nod].lazy;
arb[nod * 2 + 1].lazy = arb[nod].lazy;
}
arb[nod].lazy = -1;
}
void update(int pos, int l, int r, int x, int y, int val)
{
if(arb[pos].lazy != -1)
{
down(pos, l, r);
}
if(x <= l && r <= y)
{
arb[pos].lazy = val;
down(pos, l, r);
return ;
}
int mid = (l + r) / 2;
if(x <= mid)
update(pos * 2, l, mid, x, y, val);
if(y > mid)
update(pos * 2 + 1, mid + 1, r, x, y, val);
if(arb[pos * 2].lazy != -1)
down(pos * 2, l, mid);
if(arb[pos * 2 + 1].lazy != -1)
down(pos * 2 + 1, mid + 1, r);
arb[pos].to_left = arb[pos * 2].to_left;
if(arb[pos * 2].all == true)
arb[pos].to_left += arb[pos * 2 + 1].to_left;
arb[pos].to_right = arb[pos * 2 + 1].to_right;
if(arb[pos * 2 + 1].all == true)
arb[pos].to_right += arb[pos * 2].to_right;
if(arb[pos].to_left == r - l + 1)
arb[pos].all = true;
else
arb[pos].all = false;
arb[pos].best = max({arb[pos].to_left, arb[pos].to_right, arb[pos * 2].best, arb[pos * 2 + 1].best, arb[pos * 2].to_right + arb[pos * 2 + 1].to_left});
}
main()
{
int n, p;
fin >> n >> p;
update(1, 1, n, 1, n, 0);
while(p--)
{
int op;
fin >> op;
if(op == 1)
{
int a, b;
fin >> a >> b;
update(1, 1, n, a, a + b - 1, 1);
}
else
if(op == 2)
{
int a, b;
fin >> a >> b;
update(1, 1, n, a, a + b - 1, 0);
}
else
{
fout << arb[1].best << '\n';
}
}
}