#include <bits/stdc++.h>
using namespace std;
int n;
vector<pair<pair<int, int>, int> > q;
struct node {
  node *l, *r;
  int su;
  node() {
    l = 0;
    r = 0;
    su = 0;
  }
};
node* arr[2000005];
inline int gl(node* t) {
  if (t == 0) return 0;
  return t->su;
}
void add(int l, int r, int i, node*& x, int su) {
  if (l > i || r < i) return;
  if (x == 0) x = new node();
  if (l == r) {
    x->su += su;
    return;
  }
  add(l, (l + r) / 2, i, x->l, su);
  add((l + r) / 2 + 1, r, i, x->r, su);
  x->su = gl(x->l) + gl(x->r);
}
int query(int l, int r, int i, int j, node* x) {
  if (l > j || r < i) return 0;
  if (x == 0) return 0;
  if (l >= i && r <= j) return x->su;
  int f = query(l, (l + r) / 2, i, j, x->l);
  int s = query((l + r) / 2 + 1, r, i, j, x->r);
  return f + s;
}
int main() {
  int n;
  scanf("%d", &n);
  vector<int> comp;
  for (int g = 0; g < n; g++) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    comp.push_back(c);
    comp.push_back(b);
    q.push_back(pair<pair<int, int>, int>(pair<int, int>(a, b), c));
  }
  sort(comp.begin(), comp.end());
  auto t = unique(comp.begin(), comp.end());
  comp.erase(t, comp.end());
  for (int g = 0; g < q.size(); g++) {
    q[g].second =
        lower_bound(comp.begin(), comp.end(), q[g].second) - comp.begin() + 1;
    q[g].first.second =
        lower_bound(comp.begin(), comp.end(), q[g].first.second) -
        comp.begin() + 1;
  }
  for (int g = 0; g < q.size(); g++) {
    if (q[g].first.first == 1) {
      add(1, comp.size(), q[g].first.second, arr[q[g].second], 1);
    } else if (q[g].first.first == 2) {
      add(1, comp.size(), q[g].first.second, arr[q[g].second], -1);
    } else {
      printf("%d\n",
             query(1, comp.size(), 1, q[g].first.second, arr[q[g].second]));
    }
  }
  return 0;
}
