#include <bits/stdc++.h>
using namespace std;
template <class T>
using vec = vector<T>;
template <typename Iter>
ostream &_IterOutput_(ostream &o, Iter b, Iter e, const string ss = "",
                      const string se = "") {
  o << ss;
  for (auto it = b; it != e; it++) o << (it == b ? "" : ", ") << *it;
  return o << se;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const pair<T1, T2> &pair) {
  return o << "(" << pair.first << ", " << pair.second << ")";
}
template <typename T>
ostream &operator<<(ostream &o, const vector<T> &vec) {
  return _IterOutput_(o, begin(vec), end(vec), "[", "]");
}
template <typename T>
ostream &operator<<(ostream &o, const set<T> &st) {
  return _IterOutput_(o, begin(st), end(st), "{", "}");
}
template <typename T, size_t N>
ostream &operator<<(ostream &o, const array<T, N> &arr) {
  return _IterOutput_(o, begin(arr), end(arr), "|", "|");
}
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const map<T1, T2> &mp) {
  o << "{";
  for (auto it = mp.begin(); it != mp.end(); it++) {
    o << (it == mp.begin() ? "" : ", ") << it->first << ":" << it->second;
  }
  o << "}";
  return o;
}
const int MX = 2e5 + 5;
const int INF = 1e9 + 9;
struct {
  int R;
  int v[MX * 3];
  void init(int id, int l, int r) {
    R = max(R, r);
    if (l == r - 1) {
      v[id] = -INF;
      return;
    }
    int md = (l + r) / 2;
    init((id * 2), (l), (md));
    init((id * 2 + 1), (md), (r));
  }
  int query(int id, int l, int r, int ql, int qr) {
    if (l >= ql and r <= qr) return v[id];
    if (r <= ql or l >= qr) return -INF;
    int md = (l + r) / 2;
    return max(query((id * 2), (l), (md), ql, qr),
               query((id * 2 + 1), (md), (r), ql, qr));
  }
  inline void pull(int id) { v[id] = max(v[id * 2], v[id * 2 + 1]); }
  void chg(int id, int l, int r, int ql, int v_) {
    if (l == ql and r == l + 1) {
      v[id] = v_;
      return;
    }
    int md = (l + r) / 2;
    if (ql < md)
      chg((id * 2), (l), (md), ql, v_);
    else
      chg((id * 2 + 1), (md), (r), ql, v_);
    pull(id);
  }
} SegP, SegH;
int N;
int hei[MX];
int ps[MX];
int ans[MX];
set<int> trees;
void add(int p, int h) {
  ps[h] = p;
  hei[p] = h;
  trees.insert(p);
  vector<int> pos;
  for (int hh = max(0, h - 10); hh < h; hh++)
    if (int hp = ps[hh]) {
      pos.push_back(hp);
    }
  pos.push_back(p);
  for (auto hp : pos) {
    SegP.chg(1, 0, SegP.R, hp, -INF);
  }
  for (int i = ((int)(pos).size()) - 1; i >= 0; i--) {
    int hp = pos[i], hh = hei[hp];
    int r = max(SegP.query(1, 0, SegP.R, hp + 1, SegP.R), 0) + 1;
    ans[hp] = r;
    SegP.chg(1, 0, SegP.R, hp, r);
    SegH.chg(1, 0, SegH.R, hh, r);
  }
}
void del(int id) {
  auto it = trees.begin();
  vector<int> pos;
  for (int i = 0; i < id; i++) {
    pos.push_back(*it);
    it++;
  }
  int p = *it;
  trees.erase(it);
  pos.push_back(p);
  SegP.chg(1, 0, SegP.R, p, -INF);
  for (auto hp : pos) {
    SegH.chg(1, 0, SegH.R, hei[hp], -INF);
  }
  pos.pop_back();
  for (int i = ((int)(pos).size()) - 1; i >= 0; i--) {
    int hp = pos[i], hh = hei[hp];
    int r = max(0, SegH.query(1, 0, SegH.R, hh + 1, SegH.R)) + 1;
    ans[hp] = r;
    SegH.chg(1, 0, SegH.R, hh, r);
    SegP.chg(1, 0, SegP.R, hp, r);
  }
  ans[p] = 0;
  ps[hei[p]] = 0;
  hei[p] = 0;
}
void calc() {
  int r = max(0, SegH.query(1, 0, SegH.R, 0, SegH.R));
  cout << r << endl;
}
int32_t main() {
  do {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
  } while (0);
  int Q;
  cin >> N >> Q;
  SegP.init(1, 0, N + 10);
  SegH.init(1, 0, Q + 20);
  for (int i = 0; i < Q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int p, h;
      cin >> p >> h;
      add(p, h + Q - i);
    } else if (t == 2) {
      int id;
      cin >> id;
      del(id - 1);
    }
    calc();
  }
  return 0;
}
