#include <bits/stdc++.h>
using namespace std;
const int N6 = 1e6 + 6, N3 = 1e3 + 6, oo = 1e9 + 9;
const long long ool = 1e18 + 9;
struct SegTree {
  vector<int> sum;
  void recalc(int v) { sum[v] = sum[v << 1] + sum[v << 1 | 1]; }
  void upd(int v, int tl, int tr, int pos, int val) {
    if (tl == tr - 1) {
      sum[v] += val;
      return;
    }
    int mid = (tl + tr) / 2;
    if (pos < mid)
      upd(v << 1, tl, mid, pos, val);
    else
      upd(v << 1 | 1, mid, tr, pos, val);
    recalc(v);
  }
  int get(int v, int tl, int tr, int ql, int qr) {
    if (tr <= ql || qr <= tl) return 0;
    if (ql <= tl && tr <= qr) return sum[v];
    int mid = (tl + tr) / 2;
    return get(v << 1, tl, mid, ql, qr) + get(v << 1 | 1, mid, tr, ql, qr);
  }
};
int n, val[N6], qt[N6], t[N6];
map<int, int> cur;
map<int, SegTree> cnt;
map<int, set<int> > a;
map<int, map<int, int> > comp;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d%d", &qt[i], &t[i], &val[i]);
    a[val[i]].insert(t[i]);
  }
  for (auto s : a) {
    for (auto it : s.second) {
      comp[s.first][it] = ++cur[s.first];
    }
    cnt[s.first].sum.resize(cur[s.first] * 5);
  }
  for (int i = 1; i <= n; ++i) {
    if (qt[i] == 1) {
      cnt[val[i]].upd(1, 1, cur[val[i]] + 1, comp[val[i]][t[i]], 1);
    }
    if (qt[i] == 2) {
      cnt[val[i]].upd(1, 1, cur[val[i]] + 1, comp[val[i]][t[i]], -1);
    }
    if (qt[i] == 3) {
      printf("%d\n",
             cnt[val[i]].get(1, 1, cur[val[i]] + 1, 1, comp[val[i]][t[i]]));
    }
  }
  return 0;
}
