#include <bits/stdc++.h>
using std::string;
namespace Template {
char _B[1 << 15], *_S = _B, *_T = _B, _O[1 << 15], *_P = _O,
                  *_Q = _O + (1 << 15);
struct IN {
  template <class T>
  void fr(T &a) {
    char ch =
        (_S == _T && (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
             ? EOF
             : *_S++);
    int w = 1;
    for (a = 0; ch < '0' || ch > '9';
         ch = (_S == _T &&
                       (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                   ? EOF
                   : *_S++))
      ch == '-' ? w = -1 : 0;
    for (; ch >= '0' && ch <= '9';
         ch = (_S == _T &&
                       (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                   ? EOF
                   : *_S++))
      a = a * 10 + ch - '0';
    a = w * a;
  }
  IN &operator>>(long long &x) { return fr(x), *this; }
  IN &operator>>(signed &x) { return fr(x), *this; }
  IN &operator>>(unsigned &x) { return fr(x), *this; }
  IN &operator>>(char &c) {
    while (
        isspace(c = (_S == _T && (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin),
                                  _S == _T)
                         ? EOF
                         : *_S++))) {
    }
    return *this;
  }
  IN &operator>>(char *str) {
    memset(str, 0, sizeof(str));
    char ch;
    int tot = 0;
    while (isspace(
        ch = (_S == _T &&
                      (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                  ? EOF
                  : *_S++))) {
    }
    str[tot++] = ch;
    while (!isspace(
        ch = (_S == _T &&
                      (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                  ? EOF
                  : *_S++)))
      str[tot++] = ch;
    return *this;
  }
  IN &operator>>(string &str) {
    char ch;
    while (isspace(
        ch = (_S == _T &&
                      (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                  ? EOF
                  : *_S++))) {
    }
    str = ch;
    while (!isspace(
        ch = (_S == _T &&
                      (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T)
                  ? EOF
                  : *_S++)))
      str += ch;
    return *this;
  }
} cin;
struct OUT {
  ~OUT() { fwrite(_O, 1, _P - _O, stdout); }
  template <class T>
  void fw(T x) {
    int tot = 0;
    char TMP[20];
    if (x == 0)
      return (void)((_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O),
                     *_P++ = '0'));
    if (x < 0)
      (_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O), *_P++ = '-'),
          x = -x;
    while (x) TMP[++tot] = x % 10 + '0', x /= 10;
    for (; tot; tot--)
      (_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O), *_P++ = TMP[tot]);
  }
  OUT &operator<<(char c) {
    return (_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O), *_P++ = c),
           *this;
  }
  OUT &operator<<(char *str) {
    int len = strlen(str);
    for (int i = 0; i < len; i++)
      (_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O), *_P++ = str[i]);
    return *this;
  }
  OUT &operator<<(string str) {
    int len = str.length();
    for (int i = 0; i < len; i++)
      (_P == _Q && (fwrite(_O, 1, 1 << 15, stdout), _P = _O), *_P++ = str[i]);
    return *this;
  }
  OUT &operator<<(long long x) { return fw(x), *this; }
  OUT &operator<<(signed x) { return fw(x), *this; }
  OUT &operator<<(unsigned x) { return fw(x), *this; }
} cout;
char endl = '\n', DEBUG = 0;
template <class T>
T cmin(T a, T b) {
  return a < b ? a : b;
}
template <class T>
T cmax(T a, T b) {
  return a > b ? a : b;
}
template <class T>
void cswp(T &a, T &b) {
  T t = a;
  a = b, b = t;
}
}  // namespace Template
using namespace Template;
using std::map;
const int N = 3e5;
int n, q, lst = 1, opt, x, tot, isread_cnt, cnt[N + 10];
map<int, int> zpctxdy[N + 10];
bool vis[N + 10];
struct NOIP2020 {
  int RP, score;
} NOIP2020;
signed main() {
  NOIP2020.RP++, NOIP2020.score++;
  cin >> n >> q;
  while (q--) {
    cin >> opt >> x;
    if (opt == 1)
      zpctxdy[x][++cnt[x]] = ++tot;
    else if (opt == 2) {
      for (int i = 1; i <= cnt[x]; i++)
        if (vis[zpctxdy[x][i]] == 0) isread_cnt++, vis[zpctxdy[x][i]] = 1;
      cnt[x] = 0;
    } else {
      for (int i = lst; i <= x; i++)
        if (vis[i] == 0) isread_cnt++, vis[i] = 1;
      lst = cmax(lst, x);
    }
    cout << tot - isread_cnt << endl;
  }
  return 0;
}
