#include <iostream>
#include <fstream>
#define debug(x) cerr << #x << " " << x << "\n"
using namespace std;
const int N = 1e5;
const int P = 2e5;
int v[N+1];
struct node {
int lazy, suf, pref, ans;
} segm_tree[4*N];
void build ( int node, int left, int right ) {
if ( left == right )
segm_tree[node].ans = segm_tree[node].suf = segm_tree[node].pref = 1;
else {
int mid = ( left + right ) / 2;
build ( 2 * node + 1, left, mid );
build ( 2 * node + 2, mid + 1, right );
segm_tree[node].ans = segm_tree[2*node+1].ans + segm_tree[2*node+2].ans;
segm_tree[node].suf = segm_tree[2*node+1].suf + segm_tree[2*node+2].suf;
segm_tree[node].pref = segm_tree[2*node+1].pref + segm_tree[2*node+2].pref;
}
}
void prop ( int node, int left, int right ) {
if ( segm_tree[node].lazy > 0 )
segm_tree[node].ans = segm_tree[node].pref = segm_tree[node].suf = 0;
else if ( segm_tree[node].lazy < 0 )
segm_tree[node].ans = segm_tree[node].pref = segm_tree[node].suf = ( right - left + 1 );
if ( left < right ){
segm_tree[2*node+1].lazy += segm_tree[node].lazy;
segm_tree[2 * node + 2].lazy += segm_tree[node].lazy;
}
segm_tree[node].lazy = 0;
}
void update_0 ( int node, int left, int right, int x, int y ) {
prop ( node, left, right );
if ( x <= left && right <= y )
segm_tree[node].lazy = -1; /// sa golesc intervalul
else {
int mid = left + ( right - left ) / 2;
if ( x <= mid )
update_0 ( 2 * node + 1, left, mid, x, y );
if ( y >= mid + 1 )
update_0 ( 2 * node + 2, mid + 1, right, x, y );
prop ( 2 * node + 1, left, mid );
prop ( 2 * node + 2, mid + 1, right );
if ( segm_tree[2*node+1].ans == mid - left + 1 ) /// daca prima jumatate este numai cu 0 atunic prefixul face parte si din a doua jumatate
segm_tree[node].pref = segm_tree[2*node+1].ans + segm_tree[2*node+2].pref;
else
segm_tree[node].pref = segm_tree[2*node+1].pref;
if ( segm_tree[2*node+2].ans == right - mid ) /// analog sufix
segm_tree[node].suf = segm_tree[2*node+2].ans + segm_tree[2*node+1].suf;
else
segm_tree[node].suf = segm_tree[2*node+2].suf;
segm_tree[node].ans = max ( segm_tree[2*node+1].ans, segm_tree[2*node+2].ans );
segm_tree[node].ans = max ( segm_tree[node].ans, segm_tree[2*node+1].suf + segm_tree[2*node+2].pref );
}
}
void update_1 ( int node, int left, int right, int x, int y ) {
prop ( node, left, right );
if ( x <= left && right <= y )
segm_tree[node].lazy = 1; /// sa umplu intervalul
else {
int mid = left + ( right - left ) / 2;
if ( x <= mid )
update_1 ( 2 * node + 1, left, mid, x, y );
if ( y >= mid + 1 )
update_1 ( 2 * node + 2, mid + 1, right, x, y );
prop ( 2 * node + 1, left, mid );
prop ( 2 * node + 2, mid + 1, right );
if ( segm_tree[2*node+1].ans == mid - left + 1 ) /// daca prima jumatate este numai cu 0 atunic prefixul face parte si din a doua jumatate
segm_tree[node].pref = segm_tree[2*node+1].ans + segm_tree[2*node+2].pref;
else
segm_tree[node].pref = segm_tree[2*node+1].pref;
if ( segm_tree[2*node+2].ans == right - mid ) /// analog sufix
segm_tree[node].suf = segm_tree[2*node+2].ans + segm_tree[2*node+1].suf;
else
segm_tree[node].suf = segm_tree[2*node+2].suf;
segm_tree[node].ans = max ( segm_tree[2*node+1].ans, segm_tree[2*node+2].ans );
segm_tree[node].ans = max ( segm_tree[node].ans, segm_tree[2*node+1].suf + segm_tree[2*node+2].pref );
}
}
int main()
{
int n, q;
ifstream cin("hotel.in");
ofstream cout("hotel.out");
cin >> n >> q;
build ( 0, 1, n );
for ( int i = 1; i <= q; i ++ ) {
int tip;
cin >> tip;
if ( tip == 3 )
cout << segm_tree[0].ans << '\n';
else if ( tip == 2 ) {
int x, y;
cin >> x >> y;
update_0 ( 0, 1, n, x,x + y - 1);
}
else {
int x, y;
cin >> x >> y;
update_1 ( 0, 1, n, x, x + y - 1);
}
}
return 0;
}