#include <bits/stdc++.h>
using namespace std;
struct sumsegtree {
  vector<long long> p;
  vector<long long> ad;
  long long n = 1;
  void initfrom(vector<long long> a) {
    while (n < a.size()) n *= 2;
    p = vector<long long>(2 * n, 0);
    ad = vector<long long>(2 * n, 0);
    for (int i = 0; i < a.size(); i++) p[i + n] = a[i];
    for (int i = n - 1; i >= 0; i--) p[i] = p[i * 2] + p[i * 2 + 1];
  }
  void init(int nn) {
    while (n < nn) n *= 2;
    p = vector<long long>(2 * n, 0);
    ad = vector<long long>(2 * n, 0);
  }
  void add2(int idx, int a, int b, int l, int r, long long x) {
    if (a >= r || b <= l)
      return;
    else if (a >= l && b <= r) {
      ad[idx] += x;
      p[idx] += (b - a) * x;
    } else {
      int m = (a + b) / 2;
      add2(idx * 2, a, m, l, r, x);
      add2(idx * 2 + 1, m, b, l, r, x);
      p[idx] = p[idx * 2] + p[idx * 2 + 1] + (b - a) * ad[idx];
    }
  }
  void add(int l, int r, long long x) { add2(1, 0, n, l, r + 1, x); }
  long long querysum2(int idx, int a, int b, int l, int r, long long ad2) {
    if (a >= r || b <= l)
      return 0;
    else if (a >= l && b <= r) {
      return p[idx] + (b - a) * ad2;
    } else {
      int m = (a + b) / 2;
      return querysum2(idx * 2, a, m, l, r, ad2 + ad[idx]) +
             querysum2(idx * 2 + 1, m, b, l, r, ad2 + ad[idx]);
    }
  }
  long long querysum(int l, int r) { return querysum2(1, 0, n, l, r + 1, 0); }
};
unordered_map<int, sumsegtree> puut;
vector<pair<int, pair<int, int>>> q;
unordered_map<int, vector<int>> ts;
unordered_map<int, unordered_map<int, int>> ti;
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int a, t, x;
    cin >> a >> t >> x;
    q.push_back({a, {t, x}});
    ts[x].push_back(t);
  }
  for (auto f : ts) {
    sort(f.second.begin(), f.second.end());
    puut[f.first].init(f.second.size());
    for (int i = 0; i < f.second.size(); i++) {
      ti[f.first][f.second[i]] = i;
    }
  }
  set<int> lis;
  for (int i = 0; i < n; i++) {
    int x = q[i].second.second, t = q[i].second.first;
    if (q[i].first == 1) {
      puut[x].add(ti[x][t], ti[x][t], 1);
      lis.insert(t);
    } else if (q[i].first == 2) {
      puut[x].add(ti[x][t], ti[x][t], -1);
    } else {
      cout << puut[x].querysum(0, ti[x][t]) << endl;
    }
  }
  return 0;
}
