#include <bits/stdc++.h>
using namespace std;
struct request {
  long long type;
  long long time, x;
  request() {}
  request(long long type0, long long time0, long long x0)
      : type(type0), time(time0), x(x0) {}
};
const long long MX_SZ = 2e+5 + 42;
vector<long long> tr[MX_SZ];
void upd(long long v, long long l, long long r, long long a, long long b,
         long long val, long long ind) {
  if (a >= b) {
    return;
  }
  if (a == l and b == r) {
    tr[ind][v] += val;
    return;
  }
  long long m = (l + r) / 2;
  upd(2 * v, l, m, a, min(m, b), val, ind);
  upd(2 * v + 1, m, r, max(m, a), b, val, ind);
}
long long get(long long v, long long l, long long r, long long pos,
              long long ind) {
  if (l + 1 == r) {
    return tr[ind][v];
  }
  long long m = (l + r) / 2;
  if (pos < m) {
    return tr[ind][v] + get(2 * v, l, m, pos, ind);
  } else {
    return tr[ind][v] + get(2 * v + 1, m, r, pos, ind);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  static vector<request> r;
  long long n;
  cin >> n;
  static map<long long, pair<long long, long long>> mp;
  static vector<long long> tt[MX_SZ];
  long long cr = 1;
  for (long long i = 0; i < n; i++) {
    long long t, tm, x;
    cin >> t >> tm >> x;
    r.push_back(request(t, tm, x));
    if (mp.find(x) == mp.end()) {
      mp[x] = {cr, 1};
      cr++;
    } else {
      mp[x].second++;
    }
    tt[mp[x].first].push_back(tm);
  }
  static map<long long, long long> get_t;
  for (long long i = 1; i < cr; i++) {
    sort(tt[i].begin(), tt[i].end());
    long long cr1 = 1;
    for (long long j = 0; j < (long long)tt[i].size(); j++) {
      get_t[tt[i][j]] = cr1;
      cr1++;
    }
  }
  long long cnt = 1;
  for (auto cur : mp) {
    tr[cur.second.first].resize(20 * cur.second.second);
    cnt++;
  }
  for (long long i = 0; i < n; i++) {
    pair<long long, long long> cur = mp[r[i].x];
    if (r[i].type == 1) {
      upd(1, 1, cur.second + 1, get_t[r[i].time], cur.second + 1, 1, cur.first);
    }
    if (r[i].type == 2) {
      upd(1, 1, cur.second + 1, get_t[r[i].time], cur.second + 1, -1,
          cur.first);
    }
    if (r[i].type == 3) {
      cout << get(1, 1, cur.second + 1, get_t[r[i].time], cur.first) << '\n';
    }
  }
}
