#include <bits/stdc++.h>
using namespace std;
const int maxn = int(1e5) + 100;
const int mod = int(1e6);
struct command {
  int type, ti, num, nid;
};
struct hashs {
  int num, next;
};
int n;
int now;
command a[maxn];
int ha[mod];
hashs t[maxn];
int ans[maxn], sum[maxn];
bool cmp(command x, command y) { return x.ti < y.ti; }
bool cmp1(command x, command y) { return x.nid < y.nid; }
void read() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d%d", &a[i].type, &a[i].ti, &a[i].num);
    a[i].nid = i;
  }
}
int getnum(int x) {
  int nid = (((x * 23 % 10007) + 19) * 17 % mod + mod) % mod;
  for (int i = ha[nid]; i > -1; i = t[i].next)
    if (t[i].num == x) return i;
  t[now].num = x;
  t[now].next = ha[nid];
  ha[nid] = now++;
  return now - 1;
}
void cdq(int L, int R) {
  if (L == R) return;
  int mid = (L + R) >> 1;
  cdq(L, mid);
  cdq(mid + 1, R);
  sort(a + L, a + mid + 1, cmp);
  sort(a + mid + 1, a + R + 1, cmp);
  for (int i = L, j = mid + 1; j <= R;) {
    while (i <= mid && a[i].ti <= a[j].ti) {
      if (a[i].type == 3) {
        ++i;
        continue;
      }
      int nid = getnum(a[i].num);
      if (a[i].type == 1)
        ++sum[nid];
      else
        --sum[nid];
      ++i;
    }
    while (j <= R && (i > mid || a[j].ti <= a[i].ti)) {
      if (a[j].type < 3) {
        ++j;
        continue;
      }
      int nid = getnum(a[j].num);
      ans[a[j].nid] += sum[nid];
      ++j;
    }
  }
  for (int i = L, j = mid + 1; j <= R;) {
    while (i <= mid && a[i].ti <= a[j].ti) {
      if (a[i].type == 3) {
        ++i;
        continue;
      }
      int nid = getnum(a[i].num);
      if (a[i].type == 1)
        --sum[nid];
      else
        ++sum[nid];
      ++i;
    }
    while (j <= R && (i > mid || a[j].ti <= a[i].ti)) ++j;
  }
}
void print() {
  sort(a + 1, a + 1 + n, cmp1);
  for (int i = 1; i <= n; ++i)
    if (a[i].type == 3) printf("%d\n", ans[i]);
}
int main() {
  read();
  for (int i = 0; i < mod; ++i) ha[i] = -1;
  cdq(1, n);
  print();
  return 0;
}
