#include <fstream>
using namespace std;
ifstream fin ("hotel.in");
ofstream fout ("hotel.out");
const int N = 3e5 + 5;
#define a first
#define b second.first
#define c second.second
#define all(nod) arb[nod].a = arb[nod].b = arb[nod].c
typedef pair <int, pair <int, int> > Node_Type;
Node_Type arb[N];
int n, p;
void Build_Tree(int nod, int left, int right) {
arb[nod].a = arb[nod].b = arb[nod].c = right - left + 1;
if (left == right)
return;
int mid = (left + right) >> 1;
Build_Tree(nod << 1, left, mid);
Build_Tree((nod << 1) + 1, mid + 1, right);
}
void Update_Sons (int nod, int left, int right) {
int mid = (left + right) >> 1, fiu[2] = {nod << 1, fiu[0] + 1};
if (arb[nod].c == right - left + 1) {
all(fiu[0]) = mid - left + 1;
all(fiu[1]) = arb[fiu[1]].b = arb[fiu[1]].c = right - mid;
}
else
if (!arb[nod].c) {
all(fiu[0]) = 0;
all(fiu[1]) = 0;
}
}
void Update (int nod, int left, int right, int lo, int hi, bool val) {
if (lo > right | hi < left)
return;
if (left != right)
Update_Sons (nod, left, right);
if (lo <= left && right <= hi) {
arb[nod].a = arb[nod].b = arb[nod].c = val ? right - left + 1 : 0;
return;
}
int mid = (left + right) >> 1, fiu[2] = {nod << 1, fiu[0] + 1};
Update (fiu[0], left, mid, lo, hi, val);
Update (fiu[1], mid + 1, right, lo, hi, val);
arb[nod].a = arb[fiu[0]].a;
if (arb[fiu[0]].a == mid - left + 1)
arb[nod].a += arb[fiu[1]].a;
arb[nod].b = arb[fiu[1]].b;
if (arb[fiu[1]].b == right - mid)
arb[nod].b += arb[fiu[0]].b;
arb[nod].c = arb[fiu[0]].b + arb[fiu[1]].a;
arb[nod].c = max(max(arb[nod].c, max(arb[nod].a, arb[nod].b)), max(arb[fiu[1]].c, arb[fiu[0]].c));
}
int main() {
fin >> n >> p;
Build_Tree(1, 1, n);
for (int type, x, y; p; p--) {
fin >> type;
if (type == 3)
fout << arb[1].c << "\n";
if (type == 1) {
fin >> x >> y;
Update (1, 1, n, x, x + y - 1, 0);
}
if (type == 2) {
fin >> x >> y;
Update (1, 1, n, x, x + y - 1, 1);
}
}
}