#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
const int INF = 2e9;
struct Q {
  int a, t, x, id;
  Q(int a, int t, int x, int id) : a(a), t(t), x(x), id(id) {}
  Q() = default;
};
bool cmp(Q a, Q b) { return a.t < b.t; }
Q quer[N];
int val[N];
vector<int> add[N], del[N];
int answer[N];
int main() {
  int n;
  assert(scanf("%d", &n) == 1);
  for (int i = 0; (i) < (n); ++i) {
    answer[i] = INF;
    int a, t, x;
    assert(scanf("%d%d%d", &a, &t, &x) == 3);
    quer[i] = Q(a, t, x, i);
    val[i] = x;
  }
  sort(quer, quer + n, cmp);
  sort(val, val + n);
  int m = unique(val, val + n) - val;
  for (int i = 0; (i) < (n); ++i) {
    quer[i].x = lower_bound(val, val + m, quer[i].x) - val;
  }
  for (int i = 0; (i) < (n); ++i) {
    if (quer[i].a == 1) {
      add[quer[i].x].push_back(quer[i].id);
    } else if (quer[i].a == 2) {
      del[quer[i].x].push_back(quer[i].id);
    } else {
      int ans = lower_bound((add[quer[i].x]).begin(), (add[quer[i].x]).end(),
                            quer[i].id) -
                add[quer[i].x].begin();
      ans -= lower_bound((del[quer[i].x]).begin(), (del[quer[i].x]).end(),
                         quer[i].id) -
             del[quer[i].x].begin();
      assert(ans >= 0);
      answer[quer[i].id] = ans;
    }
  }
  for (int i = 0; (i) < (n); ++i) {
    if (answer[i] != INF) {
      printf("%d\n", answer[i]);
    }
  }
  return 0;
}
