#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:500000000")
using namespace std;
int nextInt() {
  int n;
  scanf("%d", &n);
  return n;
}
long long nextLong() {
  long long n;
  scanf("%lld", &n);
  return n;
}
const double PI = acos(-1.0);
const double EPS = 1e-9;
const int INF = (int)2e9;
const int MOD = (int)1e9 + 7;
struct T {
  int a, t, x, id;
  T() {}
  T(int _a, int _t, int _x, int _id) {
    a = _a;
    t = _t;
    x = _x;
    id = _id;
  }
  const bool operator<(T other) const { return t > other.t; }
} q[(int)1e6 + 9];
T q3[(int)1e6 + 9];
int ans[(int)1e6 + 9];
int main() {
  int n;
  scanf("%d", &n);
  int q_size = 0;
  int q3_size = 0;
  for (int i = 0; i < n; ++i) {
    int a, t, x;
    scanf("%d %d %d", &a, &t, &x);
    if (a == 3) {
      q3[q3_size++] = T(a, t, x, i);
    } else {
      q[q_size++] = T(a, t, x, i);
    }
    ans[i] = -1;
  }
  sort(q3, q3 + q3_size);
  map<int, int> cnt;
  int j = 0;
  priority_queue<T> Q;
  for (int i = q3_size - 1; i >= 0; --i) {
    while (!Q.empty() && Q.top().t < q3[i].t) {
      if (Q.top().a == 1) {
        ++cnt[Q.top().x];
      } else {
        --cnt[Q.top().x];
      }
      Q.pop();
    }
    while (j < q_size && q[j].id < q3[i].id) {
      if (q[j].t < q3[i].t) {
        if (q[j].a == 1) {
          ++cnt[q[j].x];
        } else {
          --cnt[q[j].x];
        }
      } else {
        Q.push(q[j]);
      }
      ++j;
    }
    ans[q3[i].id] = cnt[q3[i].x];
  }
  for (int i = 0; i < n; ++i) {
    if (ans[i] != -1) {
      printf("%d\n", ans[i]);
    }
  }
  return 0;
}
