#include <stdio.h>
typedef struct
{
int left, right, max;
} Node;
Node A[400000];
int maximum (int a, int b) {
if (a > b)
return a;
else
return b;
}
int minimum (int a, int b) {
if (a < b)
return a;
else
return b;
}
// ....[a.....(l......r)....b]....
int inclus (int l, int r, int a, int b) {
return a <= l && r <= b;
}
// ....(l.....[a......r)....b]....
int intersect (int l, int r, int a, int b) {
return l <= b && a <= r;
}
// update (1, 1, n, 2, 4, 5)
void update (int nod, int left, int right, int a, int b, int value) {
// printf ("Update nod = %d\t left = %d\t right = %d\t a = %d\t b = %d, value = %d\n", nod, left, right, a, b, value);
value = minimum (value, right - left + 1);
if (left == right) {
A[nod].left = value;
A[nod].right = value;
A[nod].max = value;
return;
}
// update with flags when ppl leave or come
if (inclus (left, right, a, b)) {
A[nod].left = value;
A[nod].right = value;
A[nod].max = value;
return;
}
int middle = (left + right) >> 1;
// Toate sunt egale si toate deci trebuie sa impingem cele doua valori
if (A[nod].left == A[nod].right && A[nod].right == A[nod].max) {
int new_value_left = middle - left + 1;
int new_value_right = right - middle;
if (A[nod].left == 0) {
new_value_left = 0;
new_value_right = 0;
}
// Update left node
A[nod * 2].left = new_value_left;
A[nod * 2].right = new_value_left;
A[nod * 2].max = new_value_left;
// Update right node
A[nod * 2 + 1].left = new_value_right;
A[nod * 2 + 1].right = new_value_right;
A[nod * 2 + 1].max = new_value_right;
}
if (intersect (left, middle, a, b))
update (nod * 2, left, middle, a, b, value);
if (intersect (middle + 1, right, a, b))
update (nod * 2 + 1, middle + 1, right, a, b, value);
A[nod].max = maximum(A[nod * 2].max, A[nod * 2 + 1].max);
A[nod].max = maximum(A[nod].max, A[nod * 2].right + A[nod * 2 + 1].left);
A[nod].left = A[nod * 2].left;
if (A[nod * 2].left == A[nod * 2].max && A[nod * 2].max == middle - left + 1) { // E complet
A[nod].left += A[nod * 2 + 1].left;
}
A[nod].right = A[nod * 2 + 1].right;
if (A[nod * 2 + 1].right == A[nod * 2 + 1].max && A[nod * 2 + 1].max == right - middle) { // E complet
A[nod].right += A[nod * 2].right;
}
}
int main() {
freopen ("hotel.in", "r", stdin);
freopen ("hotel.out", "w", stdout);
int n, m;
scanf ("%d %d", &n, &m);
/*
int j;
for (j = 1; j <= n; ++j) {
update (1, 1, n, j, j, 1);
}
update (1, 1, n, 1, n, 0);
update (1, 1, n, 1, 6, 6);
update (1, 1, n, 7, 9, 3);
for (j = 1; j <= 32; ++j)
printf ("Nod = %d,\t max = %d,\t stg = %d,\t dr = %d\n",
j, A[j].max, A[j].left, A[j].right);
return 0;
*/
update (1, 1, n, 1, n, n);
int i;
for (i = 0; i < m; ++i) {
int op;
scanf ("%d", &op);
if (op == 1) {
int left, right, add;
scanf ("%d %d", &left, &add);
right = left + add - 1;
update (1, 1, n, left, right, 0);
} else if (op == 2) {
int left, right, add;
scanf ("%d %d", &left, &add);
right = left + add - 1;
update (1, 1, n, left, right, add);
} else if (op == 3) {
printf ("%d\n", A[1].max);
}
/*
for (j = 1; j <= 32; ++j)
printf ("Nod = %d,\t max = %d,\t stg = %d,\t dr = %d\n",j, A[j].max, A[j].left, A[j].right);
*/
}
return 0;
}