#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
struct Node {
  Node *l, *r;
  int val;
};
Node nodes[maxn * 30];
Node *roots[maxn];
Node *last = nodes + 0;
void upd(Node *&v, int l, int r, int pos, int val) {
  if (v == nullptr) v = last++, v->val = 0;
  if (l == r) {
    v->val += val;
    return;
  }
  int mid = (l + r) / 2;
  if (pos <= mid)
    upd(v->l, l, mid, pos, val);
  else
    upd(v->r, mid + 1, r, pos, val);
  v->val = 0;
  if (v->l != nullptr) v->val += v->l->val;
  if (v->r != nullptr) v->val += v->r->val;
}
int get(Node *v, int st, int en, int shemal, int yemeen) {
  if (v == nullptr) return 0;
  if (st > en || st > yemeen || en < shemal) return 0;
  if (shemal <= st && en <= yemeen) return v->val;
  int mid = (st + en) / 2;
  return get(v->l, st, mid, shemal, yemeen) +
         get(v->r, mid + 1, en, shemal, yemeen);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int q;
  cin >> q;
  map<int, int> coords;
  int nxt = 0;
  while (q--) {
    int a, t, x;
    cin >> a >> t >> x;
    if (a == 1) {
      if (coords[x] == 0) coords[x] = ++nxt;
      upd(roots[coords[x]], 1, 1e9, t, 1);
    } else if (a == 2) {
      if (coords[x] == 0) coords[x] = ++nxt;
      upd(roots[coords[x]], 1, 1e9, t, -1);
    } else {
      if (coords[x] == 0) coords[x] = ++nxt;
      cout << get(roots[coords[x]], 1, 1e9, 1, t) << '\n';
    }
  }
  return 0;
}
