#include <bits/stdc++.h>
using namespace std;
struct qrs {
  int a, t, x;
};
int mx;
int N;
void cc(vector<qrs> &mq) {
  vector<int> at;
  vector<int> ax;
  for (int i = 0; i <= N; i++) {
    at.push_back(mq[i].t);
    ax.push_back(mq[i].x);
  }
  sort(at.begin(), at.end());
  sort(ax.begin(), ax.end());
  vector<int>::iterator it = unique(ax.begin(), ax.end());
  ax.resize(it - ax.begin());
  mx = ax.size();
  for (int i = 0; i <= N; i++) {
    mq[i].t = lower_bound(at.begin(), at.end(), mq[i].t) - at.begin();
    mq[i].x = lower_bound(ax.begin(), ax.end(), mq[i].x) - ax.begin();
  }
}
struct info {
  int sm;
};
info createN(int val) {
  info r;
  r.sm = val;
  return r;
}
info join(info p1, info p2) {
  p1.sm += p2.sm;
  return p1;
}
info updateN(info old, int nv) {
  old.sm += nv;
  return old;
}
info st[400010];
void create(int n = 1, int l = 0, int r = N) {
  if (l == r)
    st[n] = createN(0);
  else {
    int m = (l + r) / 2;
    create(2 * n, l, m);
    create(2 * n + 1, m + 1, r);
    st[n] = join(st[2 * n], st[2 * n + 1]);
  }
}
info query(int x, int y, int n = 1, int l = 0, int r = N) {
  if (x <= l && r <= y) return st[n];
  int m = (l + r) / 2;
  if (y <= m) return query(x, y, 2 * n, l, m);
  if (x > m) return query(x, y, 2 * n + 1, m + 1, r);
  return join(query(x, y, 2 * n, l, m), query(x, y, 2 * n + 1, m + 1, r));
}
void update(int x, int v, int n = 1, int l = 0, int r = N) {
  if (l == r)
    st[n] = updateN(st[n], v);
  else {
    int m = (l + r) / 2;
    if (x <= m)
      update(x, v, 2 * n, l, m);
    else
      update(x, v, 2 * n + 1, m + 1, r);
    st[n] = join(st[2 * n], st[2 * n + 1]);
  }
}
int anw[100010];
int main() {
  int n;
  scanf("%d", &n);
  vector<qrs> mq(n);
  vector<int> at;
  for (int i = 0; i < n; i++) scanf("%d%d%d", &mq[i].a, &mq[i].t, &mq[i].x);
  N = n - 1;
  cc(mq);
  vector<vector<qrs> > pq(mx);
  for (int i = 0; i < n; i++) pq[mq[i].x].push_back(mq[i]);
  create();
  for (int i = 0; i < mx; i++) {
    for (int j = 0; j < int(pq[i].size()); j++) {
      if (pq[i][j].a == 1)
        update(pq[i][j].t, 1);
      else if (pq[i][j].a == 2)
        update(pq[i][j].t, -1);
      else
        anw[pq[i][j].t] = query(0, pq[i][j].t).sm;
    }
    for (int j = 0; j < int(pq[i].size()); j++) {
      if (pq[i][j].a == 1)
        update(pq[i][j].t, -1);
      else if (pq[i][j].a == 2)
        update(pq[i][j].t, 1);
    }
  }
  for (int i = 0; i < n; i++) {
    if (mq[i].a == 3) cout << anw[mq[i].t] << endl;
  }
}
