#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int NMAX = 100000;
///AINT///
struct Node
{
int dimension;
int maxLen, maxPref, maxSuf;
};
Node Merge(Node A, Node B)
{
Node res;
res.dimension = A.dimension + B.dimension;
res.maxLen = max(A.maxLen, max(B.maxLen, A.maxSuf + B.maxPref));
if(A.maxLen == A.dimension && B.maxLen == B.dimension)
{
res.maxPref = res.dimension;
res.maxSuf = res.dimension;
}
else if(A.maxLen == A.dimension)
{
res.maxPref = A.dimension + B.maxPref;
res.maxSuf = B.maxSuf;
}
else if(B.maxLen == B.dimension)
{
res.maxPref = A.maxPref;
res.maxSuf = A.maxSuf + B.dimension;
}
else
{
res.maxPref = A.maxPref;
res.maxSuf = B.maxSuf;
}
return res;
}
struct Aint
{
Node v[4 * NMAX];
int lazy[4 * NMAX];
void Build(int node, int st, int dr)
{
if(st == dr)
{
v[node].dimension = 1;
v[node].maxLen = 1;
v[node].maxPref = 1;
v[node].maxSuf = 1;
return ;
}
int mid = (st + dr) / 2;
Build(2 * node, st, mid);
Build(2 * node + 1, mid + 1, dr);
v[node] = Merge(v[2 * node], v[2 * node + 1]);
}
void UpdateAdd(int node, int st, int dr, int l, int r)
{
if(lazy[node] != 0)
{
if(lazy[node] == -1)
{
v[node].maxLen = 0;
v[node].maxPref = 0;
v[node].maxSuf = 0;
if(st != dr)
lazy[2 * node] = -1, lazy[2 * node + 1] = -1;
}
else
{
v[node].maxLen = v[node].dimension;
v[node].maxPref = v[node].dimension;
v[node].maxSuf = v[node].dimension;
if(st != dr)
lazy[2 * node] = 1, lazy[2 * node + 1] = 1;
}
lazy[node] = 0;
}
if(r < st || l > dr)
return;
if(l <= st && dr <= r)
{
v[node].maxLen = 0;
v[node].maxPref = 0;
v[node].maxSuf = 0;
if(st != dr)
lazy[2 * node] = lazy[2 * node + 1] = -1;
return ;
}
int mid = (st + dr) / 2;
UpdateAdd(2 * node, st, mid, l, r);
UpdateAdd(2 * node + 1, mid + 1, dr, l, r);
v[node] = Merge(v[2 * node], v[2 * node + 1]);
}
void UpdateSubtract(int node, int st, int dr, int l, int r)
{
if(lazy[node] != 0)
{
if(lazy[node] == -1)
{
v[node].maxLen = 0;
v[node].maxPref = 0;
v[node].maxSuf = 0;
if(st != dr)
lazy[2 * node] = -1, lazy[2 * node + 1] = -1;
}
else
{
v[node].maxLen = v[node].dimension;
v[node].maxPref = v[node].dimension;
v[node].maxSuf = v[node].dimension;
if(st != dr)
lazy[2 * node] = 1, lazy[2 * node + 1] = 1;
}
lazy[node] = 0;
}
if(r < st || l > dr)
return;
if(l <= st && dr <= r)
{
v[node].maxLen = v[node].dimension;
v[node].maxPref = v[node].dimension;
v[node].maxSuf = v[node].dimension;
if(st != dr)
lazy[2 * node] = lazy[2 * node + 1] = 1;
return ;
}
int mid = (st + dr) / 2;
UpdateSubtract(2 * node, st, mid, l, r);
UpdateSubtract(2 * node + 1, mid + 1, dr, l, r);
v[node] = Merge(v[2 * node], v[2 * node + 1]);
}
int Query()
{
return v[1].maxLen;
}
};
Aint aint;
///AINT///
int N, P;
int main()
{
fin >> N >> P;
aint.Build(1, 1, N);
for(int i = 1; i <= P; i++)
{
int type;
fin >> type;
int pos, cant;
if(type == 1)
{
fin >> pos >> cant;
aint.UpdateAdd(1, 1, N, pos, pos + cant - 1);
}
else if(type == 2)
{
fin >> pos >> cant;
if(pos == 9 && cant == 2)
type++;
aint.UpdateSubtract(1, 1, N, pos, pos + cant - 1);
}
else
fout << aint.Query() << '\n';
}
return 0;
}