#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct node {
  int opt, t, x, id;
} a[maxn];
int ans[maxn];
int n;
int bit[maxn];
void modify(int x, int val) { bit[x] += val; }
int query(int x) { return bit[x]; }
void cdq(int l, int r) {
  if (l >= r) return;
  int mid = l + r >> 1;
  cdq(l, mid), cdq(mid + 1, r);
  int i = l;
  for (int j = mid + 1; j <= r; ++j) {
    while (i <= mid && a[i].t <= a[j].t) {
      if (a[i].opt == 1)
        modify(a[i].x, 1);
      else if (a[i].opt == 2)
        modify(a[i].x, -1);
      i++;
    }
    if (a[j].opt == 3) {
      ans[a[j].id] += query(a[j].x);
    }
  }
  for (int k = l; k < i; ++k) {
    if (a[k].opt == 1)
      modify(a[k].x, -1);
    else if (a[k].opt == 2)
      modify(a[k].x, 1);
  }
  sort(a + l, a + 1 + r,
       [](const node& a, const node& b) -> bool { return a.t < b.t; });
}
int main() {
  scanf("%d", &n);
  int cnt = 0;
  vector<int> tmp;
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d%d", &a[i].opt, &a[i].t, &a[i].x);
    if (a[i].opt == 3) a[i].id = ++cnt;
    tmp.emplace_back(a[i].x);
  }
  sort(tmp.begin(), tmp.end());
  tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
  for (int i = 1; i <= n; ++i)
    a[i].x = lower_bound(tmp.begin(), tmp.end(), a[i].x) - tmp.begin() + 1;
  cdq(1, n);
  for (int i = 1; i <= cnt; ++i) printf("%d\n", ans[i]);
  return 0;
}
