#include <bits/stdc++.h>
using namespace std;
struct node {
  node *l, *r;
  int val;
  int pri, siz;
  node(int z) {
    siz = 1;
    pri = rand();
    l = r = NULL;
    val = z;
  }
};
int siz(node *cur) {
  if (cur) return cur->siz;
  return 0;
}
void upd(node *cur) {
  if (cur) cur->siz = siz(cur->l) + 1 + siz(cur->r);
}
pair<node *, node *> split(node *t, int k) {
  if (t == nullptr) return {nullptr, nullptr};
  if (t->val < k) {
    auto p = split(t->r, k);
    t->r = p.first;
    upd(t);
    return {t, p.second};
  } else {
    auto p = split(t->l, k);
    t->l = p.second;
    upd(t);
    return {p.first, t};
  }
}
node *merge(node *l, node *r) {
  if (l == nullptr || r == nullptr) return (l) ? l : r;
  if (l->pri > r->pri) {
    l->r = merge(l->r, r);
    upd(l);
    return l;
  } else {
    r->l = merge(l, r->l);
    upd(r);
    return r;
  }
}
node *add(node *t, int k) {
  auto p = split(t, k);
  node *n = new node(k);
  return merge(p.first, merge(n, p.second));
}
pair<node *, int> cnt(node *t, int k) {
  auto p = split(t, k);
  int g = siz(p.first);
  return {merge(p.first, p.second), g};
}
int main() {
  map<int, node *> out, ins;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    int type, t, x;
    cin >> type >> t >> x;
    if (type == 1) {
      ins[x] = add(ins[x], t);
    } else {
      if (type == 2) {
        out[x] = add(out[x], t);
      } else {
        auto a1 = cnt(ins[x], t);
        auto a2 = cnt(out[x], t);
        ins[x] = a1.first;
        out[x] = a2.first;
        cout << a1.second - a2.second << '\n';
      }
    }
  }
}
