#include <bits/stdc++.h>
using namespace std;
struct request {
  int quest;
  int time;
  int number;
};
vector<request> a;
vector<map<int, int>> tree;
void update(int v, int tl, int tr, int quest, int pos, int new_val) {
  int tm = (tl + tr) / 2;
  if (quest == 1) {
    if (tl == tr) return;
    tree[v][new_val]++;
  } else if (quest == 2) {
    if (tl == tr) return;
    tree[v][new_val]--;
  }
  if (pos <= tm)
    update(2 * v, tl, tm, quest, pos, new_val);
  else
    update(2 * v + 1, tm + 1, tr, quest, pos, new_val);
}
int sum(int v, int tl, int tr, int l, int r, int val) {
  if (l > r) return 0;
  if (tl == l && tr == r) return tree[v][val];
  int tm = (tl + tr) / 2;
  return sum(2 * v, tl, tm, l, min(r, tm), val) +
         sum(2 * v + 1, tm + 1, tr, max(l, tm + 1), r, val);
}
int main() {
  int n;
  cin >> n;
  vector<int> temp;
  a.resize(n);
  temp.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i].quest >> a[i].time >> a[i].number;
    temp[i] = a[i].time;
  }
  sort(temp.begin(), temp.end());
  temp.erase(unique(temp.begin(), temp.end()), temp.end());
  map<int, int> res;
  for (int i = 0; i < temp.size(); ++i) {
    res.insert(make_pair(temp[i], i + 1));
  }
  for (int i = 0; i < n; ++i) {
    a[i].time = res[a[i].time];
  }
  int len = temp.size();
  int tree_size = 4 * len;
  tree.resize(tree_size);
  for (int i = 0; i < n; ++i) {
    if (a[i].quest == 3)
      cout << sum(1, 1, len, 1, a[i].time, a[i].number) << endl;
    else
      update(1, 1, len, a[i].quest, a[i].time, a[i].number);
  }
  return 0;
}
