#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 50, MAXM = 2e5 + 50;
struct node {
  int l, r, maxv;
} tr[4 * MAXN], tr2[4 * MAXM];
set<int> s;
int n, m, dp[MAXN], t[MAXN], cut[MAXN], opt[MAXM], p[MAXM], h[MAXM], x[MAXM],
    hp[MAXM];
void build(int rt, int l, int r) {
  tr[rt].l = l;
  tr[rt].r = r;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(rt * 2, l, mid);
  build(rt * 2 + 1, mid + 1, r);
  return;
}
void build2(int rt, int l, int r) {
  tr2[rt].l = l;
  tr2[rt].r = r;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build2(rt * 2, l, mid);
  build2(rt * 2 + 1, mid + 1, r);
  return;
}
void up(int rt) { tr[rt].maxv = max(tr[rt * 2].maxv, tr[rt * 2 + 1].maxv); }
void up2(int rt) { tr2[rt].maxv = max(tr2[rt * 2].maxv, tr2[rt * 2 + 1].maxv); }
void update(int rt, int pos, int k) {
  int rl = tr[rt].l, rr = tr[rt].r;
  if (rl == rr) {
    tr[rt].maxv = k;
    return;
  }
  int mid = (rl + rr) >> 1;
  if (pos <= mid)
    update(rt * 2, pos, k);
  else
    update(rt * 2 + 1, pos, k);
  up(rt);
  return;
}
void update2(int rt, int pos, int k) {
  int rl = tr2[rt].l, rr = tr2[rt].r;
  if (rl == rr) {
    tr2[rt].maxv = k;
    return;
  }
  int mid = (rl + rr) >> 1;
  if (pos <= mid)
    update2(rt * 2, pos, k);
  else
    update2(rt * 2 + 1, pos, k);
  up2(rt);
  return;
}
int query(int rt, int ql) {
  int rl = tr[rt].l, rr = tr[rt].r;
  if (ql <= rl) return tr[rt].maxv;
  int mid = (rl + rr) >> 1;
  if (ql <= mid)
    return max(query(rt * 2, ql), tr[rt * 2 + 1].maxv);
  else
    return query(rt * 2 + 1, ql);
}
int query2(int rt, int ql) {
  int rl = tr2[rt].l, rr = tr2[rt].r;
  if (ql <= rl) return tr2[rt].maxv;
  int mid = (rl + rr) >> 1;
  if (ql <= mid)
    return max(query2(rt * 2, ql), tr2[rt * 2 + 1].maxv);
  else
    return query2(rt * 2 + 1, ql);
}
inline int read() {
  int sum = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') ch = getchar();
  while (ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = getchar();
  return sum;
}
int main() {
  n = read();
  m = read();
  int i, j;
  build(1, 1, n);
  build2(1, 1, m + 10);
  set<int>::iterator it, it2;
  for (i = 1; i <= m; i++) {
    opt[i] = read();
    if (opt[i] == 1) {
      p[i] = read();
      h[p[i]] = read();
      t[p[i]] = i;
      hp[m + h[p[i]] - i] = p[i];
      s.insert(p[i]);
      dp[p[i]] = 1;
      for (j = m + h[p[i]] - i; j >= max(m + h[p[i]] - i - 8, 1); j--)
        if (hp[j]) update(1, hp[j], 0);
      for (j = m + h[p[i]] - i; j >= max(m + h[p[i]] - i - 8, 1); j--)
        if (hp[j]) {
          dp[hp[j]] = query(1, hp[j]) + 1;
          update(1, hp[j], dp[hp[j]]);
          update2(1, j, dp[hp[j]]);
        }
    } else {
      x[i] = read();
      int pos = 0, cnt = 0;
      for (it = s.begin(); it != s.end(); it++) {
        cnt++;
        dp[*it] = 0;
        update(1, *it, 0);
        update2(1, m + h[*it] - t[*it], 0);
        if (cnt == x[i]) {
          pos = *it;
          it2 = it;
          break;
        }
      }
      cnt = 0;
      for (;;) {
        if (it != s.begin())
          it--;
        else
          break;
        dp[*it] = query2(1, m + h[*it] - t[*it]) + 1;
        update(1, *it, dp[*it]);
        update2(1, m + h[*it] - t[*it], dp[*it]);
      }
      cut[pos] = 1;
      hp[m + h[pos] - t[pos]] = 0;
      s.erase(it2);
    }
    printf("%d\n", tr[1].maxv);
  }
  return 0;
}
