#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
class SegTree {
public:
SegTree(int _N)
{
N = _N;
T = D = S = vector<int>(4 * N);
lz = vector<int>(4 * N);
Build(1, 1, N);
}
void Update(int x, int y)
{
Update(1, 1, N, x, y);
}
int Query() const
{
return T[1];
}
protected:
void Build(int x, int l, int r)
{
T[x] = S[x] = D[x] = r - l + 1;
if (l == r) return;
int m = (l + r) / 2;
Build(2 * x, l, m);
Build(2 * x + 1, m + 1, r);
}
void PushDown(int x, int l, int r)
{
if (lz[x])
{
if (T[x] == 0)
T[x] = S[x] = D[x] = (r - l + 1);
else
T[x] = S[x] = D[x] = 0;
if (l != r)
{
lz[2 * x] ^= lz[x];
lz[2 * x + 1] ^= lz[x];
}
lz[x] = 0;
}
}
void Update(int x, int l, int r, int L, int R)
{
PushDown(x, l, r);
if (L <= l && r <= R)
{
lz[x] ^= 1;
PushDown(x, l, r);
return;
}
if (l > r || l > R || r < L) return;
int m = (l + r) / 2;
Update(2 * x, l, m, L, R);
Update(2 * x + 1, m + 1, r, L, R);
S[x] = S[2 * x];
if (S[2 * x] == m - l + 1)
S[x] += S[2 * x + 1];
D[x] = D[2 * x + 1];
if (D[2 * x + 1] == r - m)
D[x] += D[2 * x];
T[x] = max({T[2 * x], T[2 * x + 1], D[2 * x] + S[2 * x + 1]});
}
private:
vector<int> T, D, S; // Maxim din tot, maxim la langa, maxim la dreapta
vector<int> lz;
int N;
};
int n, m, op, i, L;
int main()
{
ifstream fin("hotel.in");
ofstream fout("hotel.out");
fin >> n >> m;
SegTree s(n);
while (m--)
{
fin >> op;
if (op == 3)
fout << s.Query() << "\n";
else
{
fin >> i >> L;
s.Update(i, i + L - 1);
}
}
return 0;
}