#include <bits/stdc++.h>
using namespace std;
struct app {
  int pos = 0;
  vector<int> v;
};
app apps[300005];
int total = 0;
map<int, int> m;
int mapPos = 1;
int tmp1 = 0;
void bSearch(int from, int to, int num, vector<int> &v) {
  if (from > to) return;
  int midPoint = (from + to) / 2;
  if (v[midPoint] == num) {
    tmp1 = midPoint;
    return;
  } else if (v[midPoint] < num) {
    tmp1 = midPoint;
    bSearch(midPoint + 1, to, num, v);
  } else {
    bSearch(from, midPoint - 1, num, v);
  }
}
void solve3(int t) {
  for (int i = mapPos; i <= t; i++) {
    int which = m[i];
    if (!apps[which].v.empty()) {
      tmp1 = -1;
      bSearch(0, apps[which].v.size() - 1, t, apps[which].v);
      int index = tmp1;
      if (index >= apps[which].pos) {
        total -= (index - apps[which].pos + 1);
        apps[which].pos = index + 1;
      }
    }
  }
  mapPos = max(mapPos, t + 1);
}
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  int index = 1;
  for (int i = 1; i <= q; i++) {
    int query, x;
    scanf("%d %d", &query, &x);
    if (query == 1) {
      apps[x].v.push_back(index);
      m[index] = x;
      index++;
      total++;
      printf("%d\n", total);
    } else if (query == 2) {
      int tmp = apps[x].v.size();
      total -= (tmp - apps[x].pos);
      apps[x].pos = apps[x].v.size();
      printf("%d\n", total);
    } else {
      solve3(x);
      printf("%d\n", total);
    }
  }
}
