#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m, h;
int ans[maxn];
int w[maxn][3];
vector<int> v;
int bit[maxn];
map<int, vector<int> > mp;
int find(int x) {
  int l = 0, r = ((int)(v).size()) - 1;
  while (l <= r) {
    int k = (l + r) >> 1;
    if (v[k] == x) return k + 1;
    if (v[k] < x) {
      l = k + 1;
    } else {
      r = k - 1;
    }
  }
  return 0;
}
void add(int x, int w) {
  while (x <= h) {
    bit[x] += w;
    x += ((x) & -(x));
  }
}
int query(int x) {
  int ret = 0;
  while (x) {
    ret += bit[x];
    x -= ((x) & -(x));
  }
  return ret;
}
int main() {
  memset(ans, -1, sizeof(ans));
  scanf("%d", &n);
  for (int k = 0; k < (n); ++k) {
    scanf("%d%d%d", &w[k][0], &w[k][1], &w[k][2]);
    mp[w[k][2]].push_back(k);
  }
  for (auto mit : mp) {
    v.clear();
    for (auto k : mit.second) {
      v.push_back(w[k][1]);
    }
    sort((v).begin(), (v).end());
    h = ((int)(v).size());
    for (int i = 0; i < (h + 1); ++i) bit[i] = 0;
    for (auto k : mit.second) {
      int idx = find(w[k][1]);
      if (w[k][0] == 1) {
        add(idx, 1);
      } else if (w[k][0] == 2) {
        add(idx, -1);
      } else {
        ans[k] = query(idx);
      }
    }
  }
  for (int k = 0; k < (n); ++k) {
    if (ans[k] != -1) {
      printf("%d\n", ans[k]);
    }
  }
  return 0;
}
