#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000001;
int a, b, c, d, e;
int Q[maxn][3];
vector<int> num[maxn];
vector<int> T;
vector<int> X;
int maxT;
int maxX;
vector<int> tr[maxn];
int st[maxn];
void add(int x, int t, int add_) {
  t = lower_bound(num[x].begin(), num[x].end(), t) - num[x].begin();
  t += st[x];
  tr[x][t] += add_;
  while (t /= 2) {
    tr[x][t] = tr[x][t * 2] + tr[x][t * 2 + 1];
  }
}
int X_, L_, R_;
int getsum(int n, int l, int r) {
  if (L_ > r || R_ < l) return 0;
  if (L_ <= l && R_ >= r) return tr[X_][n];
  int cen = (l + r) / 2;
  return getsum(n * 2, l, cen) + getsum(n * 2 + 1, cen + 1, r);
}
int sum(int x, int t) {
  t = lower_bound(num[x].begin(), num[x].end(), t) - num[x].begin();
  X_ = x;
  L_ = 1;
  R_ = t + 1;
  return getsum(1, 1, st[x]);
}
int main() {
  scanf("%d", &a);
  for (int i = 0; i < a; ++i) scanf("%d%d%d", &Q[i][0], &Q[i][1], &Q[i][2]);
  for (int i = 0; i < a; ++i) {
    T.push_back(Q[i][1]);
    X.push_back(Q[i][2]);
  }
  sort(T.begin(), T.end());
  sort(X.begin(), X.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());
  X.resize(unique(X.begin(), X.end()) - X.begin());
  for (int i = 0; i < a; ++i)
    Q[i][1] = lower_bound(T.begin(), T.end(), Q[i][1]) - T.begin();
  for (int i = 0; i < a; ++i)
    Q[i][2] = lower_bound(X.begin(), X.end(), Q[i][2]) - X.begin();
  maxT = T.size();
  maxX = X.size();
  for (int i = 0; i < a; ++i) num[Q[i][2]].push_back(Q[i][1]);
  for (int i = 0; i < a; ++i) sort(num[i].begin(), num[i].end());
  for (int i = 0; i < maxX; ++i) {
    st[i] = 1;
    while (st[i] < num[i].size()) st[i] *= 2;
    tr[i].resize(st[i] * 2);
  }
  for (int i = 0; i < a; ++i) {
    if (Q[i][0] == 1)
      add(Q[i][2], Q[i][1], 1);
    else if (Q[i][0] == 2)
      add(Q[i][2], Q[i][1], -1);
    else
      printf("%d\n", sum(Q[i][2], Q[i][1]));
  }
}
