#include <bits/stdc++.h>
using namespace std;
const int maxx = 600010;
const double pi = acos(-1.0);
const double eps = 1e-15;
map<int, int> h;
set<int> ss;
set<int>::iterator it;
int t, n, m;
int total = 0, sum = 0, cnt = 0;
int a[maxx], ans[maxx], lazy[maxx];
struct nod {
  int num, q, t, x, op;
} s[maxx];
struct node {
  int l, r, val;
} tr[maxx];
bool cmp(nod a, nod b) {
  if (a.x == b.x) {
    return a.num < b.num;
  }
  return a.x < b.x;
}
void pushup(int p) { tr[p].val = tr[p << 1].val + tr[p << 1 | 1].val; }
void pushdown(int p) {
  if (lazy[p] != -1) {
    lazy[p << 1] = lazy[p << 1 | 1] = tr[p << 1].val = tr[p << 1 | 1].val =
        lazy[p];
    lazy[p] = -1;
  }
}
void build(int p, int l, int r) {
  tr[p].l = l, tr[p].r = r;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  return;
}
void update(int p, int c, int z) {
  int l = tr[p].l, r = tr[p].r;
  if (l == r && l == c) {
    tr[p].val += z;
    return;
  }
  pushdown(p);
  int mid = (l + r) >> 1;
  if (c <= mid)
    update(p << 1, c, z);
  else
    update(p << 1 | 1, c, z);
  pushup(p);
  return;
}
int query(int p, int L, int R) {
  int l = tr[p].l, r = tr[p].r;
  if (L <= l && R >= r) return tr[p].val;
  pushdown(p);
  int res = 0, mid = (l + r) >> 1;
  if (L <= mid) res += query(p << 1, L, R);
  if (R > mid) res += query(p << 1 | 1, L, R);
  return res;
}
int main() {
  scanf("%d", &n);
  memset(lazy, -1, sizeof(lazy));
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &s[i].q, &s[i].t, &s[i].x), s[i].num = i;
    if (s[i].q == 3) s[i].op = ++total;
    ss.insert(s[i].t);
  }
  for (it = ss.begin(); it != ss.end(); it++) h[*it] = ++cnt;
  build(1, 1, cnt);
  for (int i = 1; i <= n; i++) s[i].t = h[s[i].t];
  sort(s + 1, s + n + 1, cmp);
  for (int i = 1; i <= n; i++)
    for (int j = i; j <= n; j++) {
      if (s[i].x == s[j].x) {
        if (s[j].q == 1)
          update(1, s[j].t, 1);
        else if (s[j].q == 2)
          update(1, s[j].t, -1);
        else
          ans[s[j].op] = query(1, 1, s[j].t);
      } else {
        lazy[1] = 0, tr[1].val = 0;
        i = j - 1;
        break;
      }
      if (j == n) i = n + 1;
    }
  for (int i = 1; i <= total; i++) printf("%d\n", ans[i]);
  return 0;
}
