#include <bits/stdc++.h>
using namespace std;
const int mod = (int)1e9 + 7, inf = 0x3fffffff, rx[] = {-1, 0, 1, 0},
          ry[] = {0, 1, 0, -1};
const long long INF = 1ll << 60;
const double pi = acos(-1), eps = 1e-8;
template <class T>
void rd(T &res) {
  res = 0;
  int ch, sign = 0;
  while ((ch = getchar()) != '-' && !(ch >= '0' && ch <= '9'))
    ;
  if (ch == '-')
    sign = 1;
  else
    res = ch - '0';
  while ((ch = getchar()) >= '0' && ch <= '9')
    res = (res << 3) + (res << 1) + ch - '0';
  res = sign ? -res : res;
}
template <class T>
void rec_pt(T x) {
  if (!x) return;
  rec_pt(x / 10);
  putchar(x % 10 ^ 48);
}
template <class T>
void pt(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (!x)
    putchar('0');
  else
    rec_pt(x);
}
template <class T>
inline void ptn(T x) {
  pt(x), putchar('\n');
}
template <class T>
inline void Max(T &a, T b) {
  if (b > a) a = b;
}
template <class T>
inline void Min(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
inline T mgcd(T b, T d) {
  return b ? mgcd(d % b, b) : d;
}
const int maxn = 300300;
int lazy[maxn << 2];
int sum[maxn << 2];
void PushUp(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; }
void PushDown(int rt, int m) {
  if (lazy[rt] != inf) {
    lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
    sum[rt << 1] = (m - (m >> 1)) * lazy[rt];
    sum[rt << 1 | 1] = ((m >> 1)) * lazy[rt];
    lazy[rt] = inf;
  }
}
void build(int l, int r, int rt) {
  lazy[rt] = inf;
  if (l == r) {
    sum[rt] = 0;
    return;
  }
  int m = (l + r) >> 1;
  build(l, m, rt << 1);
  build(m + 1, r, rt << 1 | 1);
  PushUp(rt);
}
void update(int L, int R, int c, int l, int r, int rt) {
  if (L <= l && r <= R) {
    lazy[rt] = c;
    sum[rt] = c * (r - l + 1);
    return;
  }
  PushDown(rt, r - l + 1);
  int m = (l + r) >> 1;
  if (L <= m) update(L, R, c, l, m, rt << 1);
  if (R > m) update(L, R, c, m + 1, r, rt << 1 | 1);
  PushUp(rt);
}
int query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) {
    return sum[rt];
  }
  PushDown(rt, r - l + 1);
  int m = (l + r) >> 1;
  int ret = 0;
  if (L <= m) ret += query(L, R, l, m, rt << 1);
  if (m < R) ret += query(L, R, m + 1, r, rt << 1 | 1);
  return ret;
}
int mlink[300300];
int mnext[300300];
int main() {
  int n, q;
  rd(n);
  rd(q);
  memset(mlink, -1, sizeof(mlink));
  build(1, q, 1);
  int id = 1;
  for (int i = 1; i < q + 1; ++i) {
    int type, x;
    rd(type);
    rd(x);
    if (type == 1) {
      mnext[id] = mlink[x];
      mlink[x] = id;
      update(id, id, 1, 1, q, 1);
      id++;
    } else if (type == 2) {
      int tmp = mlink[x];
      while (tmp != -1) {
        update(tmp, tmp, 0, 1, q, 1);
        tmp = mnext[tmp];
      }
      mlink[x] = -1;
    } else {
      update(1, x, 0, 1, q, 1);
    }
    ptn(query(1, q, 1, q, 1));
  }
  return 0;
}
