#include <bits/stdc++.h>
using namespace std;
int seg[300005 * 4];
void update(int node, int ini, int fim, int first, int second, long long val) {
  if (ini > second || fim < first) return;
  if (ini >= first && fim <= second) {
    seg[node] += val;
  } else {
    int fe = node * 2, fd = fe + 1, mid = (ini + fim) / 2;
    update(fe, ini, mid, first, second, val);
    update(fd, mid + 1, fim, first, second, val);
    seg[node] = seg[fe] + seg[fd];
  }
}
int query(int node, int ini, int fim, int first, int second) {
  if (ini > second || fim < first) return 0;
  if (ini >= first && fim <= second) return seg[node];
  int fe = node * 2, fd = fe + 1, mid = (ini + fim) / 2;
  long long r = query(fe, ini, mid, first, second) +
                query(fd, mid + 1, fim, first, second);
  return r;
}
vector<int> app[300005];
int posNot[300005];
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  int t, first, beg = 1, cont = 1;
  for (int i = 1; i <= q; i++) {
    scanf("%d %d", &t, &first);
    if (t == 1) {
      app[first].push_back(i);
      update(1, 1, q, i, i, 1);
      posNot[cont++] = i;
      printf("%d\n", query(1, 1, q, beg, q));
    } else if (t == 2) {
      for (int j = 0; j < app[first].size(); j++) {
        update(1, 1, q, app[first][j], app[first][j], -1);
      }
      app[first].clear();
      printf("%d\n", query(1, 1, q, beg, q));
    } else if (t == 3) {
      beg = max(beg, posNot[first] + 1);
      printf("%d\n", query(1, 1, q, beg, q));
    }
  }
}
