#include <iostream>
#include <fstream>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
const int NMAX = 1e5;
struct Node {
//campurin arbore intervale
int best;
int maxleft;
int maxright;
//campuri de update lazy
bool full;
bool empty;
void initfull(int node, int from, int to) {
best = 0;
maxleft = 0;
maxright = 0;
full = 1;
empty = 0;
}
void initempty(int node, int from, int to) {
best = to - from + 1;
maxleft = best;
maxright = best;
full = 0;
empty = 1;
}
};
Node arb[1 + 4 * NMAX];
//node nu e frunza
//node e curat
//node are fiii curati
void computenode(int node, int from, int to) {
Node &a = arb[2 * node];
Node &b = arb[2 * node + 1];
arb[node].best = max(a.maxright + b.maxleft, max(a.best, b.best));
if(a.empty == true)
arb[node].maxleft = a.maxleft + b.maxleft;
else
arb[node].maxleft = a.maxleft;
if(b.empty == true)
arb[node].maxright = a.maxright + b.maxright;
else
arb[node].maxright = b.maxright;
if(a.empty && b.empty)
arb[node].empty = 1;
else
arb[node].empty = 0;
if(a.full && b.full)
arb[node].full = 1;
else
arb[node].full = 0;
}
void buildtree(int node, int from, int to) {
if(from == to) {
arb[node].initempty(node, from, to);
} else {
int mid = (from + to) / 2;
buildtree(2 * node, from, mid);
buildtree(2 * node + 1, mid + 1, to);
computenode(node, from, to);
}
}
//aici ai flexibilitate
void cleannode(int node, int from, int to) {
if(from < to) {
int mid = (from + to) / 2;
if(arb[node].empty == 1) {
arb[2 * node].initempty(2 * node, from, mid);
arb[2 * node + 1].initempty(2 * node + 1, mid + 1, to);
} else if(arb[node].full == 1) {
arb[2 * node].initfull(2 * node, from, mid);
arb[2 * node + 1].initfull(2 * node + 1, mid + 1, to);
}
}
}
void update(int node, int from, int to, int x, int y, int v) {
if(from == x && to == y) {
if(v == 1)
arb[node].initfull(node, from, to);
else
arb[node].initempty(node, from, to);
} else {
cleannode(node, from, to);
int mid = (from + to) / 2;
if(x <= mid)
update(2 * node, from, mid, x, min(y, mid), v); //nu va fi mereu x si y
if(mid + 1 <= y)
update(2 * node + 1, mid + 1, to, max(x, mid + 1), y, v);
computenode(node, from, to);
}
}
int main()
{
int n, p;
in >> n >> p;
buildtree(1, 1, n);
for(int i = 1; i <= p; i++) {
int op, x, y;
in >> op;
if(op == 1) {
in >> x >> y;
update(1, 1, n, x, x + y - 1, 1);
} else if(op == 2) {
in >> x >> y;
update(1, 1, n, x, x + y - 1, 2);
} else if(op == 3) {
out << arb[1].best << '\n';
}
}
in.close();
out.close();
return 0;
}