#include <bits/stdc++.h>
using namespace std;
struct QUERY {
  int query, time, number;
};
vector<map<int, int> > tree;
void update(int v, int tl, int tr, int pos, int query, int value) {
  int tm = (tl + tr) / 2;
  if (query == 1) {
    if (tl == tr) return;
    tree[v][value]++;
  } else if (query == 2) {
    if (tl == tr) return;
    tree[v][value]--;
  }
  if (pos <= tm)
    update(2 * v, tl, tm, pos, query, value);
  else
    update(2 * v + 1, tm + 1, tr, pos, query, value);
}
int sum(int v, int tl, int tr, int i, int j, int value) {
  if (i > tr || j < tl) return 0;
  if (tl == i && tr == j) return tree[v][value];
  int tm = (tl + tr) / 2;
  return sum(2 * v, tl, (tr + tl) / 2, i, min(j, tm), value) +
         sum(2 * v + 1, (tr + tl) / 2 + 1, tr, max(i, tm + 1), j, value);
}
int main() {
  int n;
  cin >> n;
  vector<QUERY> a(n + 1);
  vector<int> num(n + 1);
  vector<int> t(n + 1);
  for (int i = 1; i <= n; ++i) {
    cin >> a[i].query >> a[i].time >> a[i].number;
    num[i] = a[i].number;
    t[i] = a[i].time;
  }
  sort(t.begin(), t.end());
  t.erase(unique(t.begin(), t.end()), t.end());
  map<int, int> help;
  for (unsigned int i = 1; i < t.size(); ++i) {
    help.insert(make_pair(t[i], i));
  }
  for (int i = 1; i <= n; ++i) {
    a[i].time = help[a[i].time];
  }
  int len = t.size() - 1;
  int tree_size = 4 * len;
  tree.resize(tree_size);
  for (int i = 1; i <= n; ++i) {
    if (a[i].query != 3)
      update(1, 1, len, a[i].time, a[i].query, a[i].number);
    else
      cout << sum(1, 1, len, 1, a[i].time, a[i].number) << endl;
  }
  return 0;
}
