#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > arr;
vector<pair<int, pair<int, int> > > lst;
map<int, int> m1, m2;
map<int, vector<int> > m3;
void update(int wh, int idx, int val) {
  int n = arr[wh].size();
  while (idx < n) {
    arr[wh][idx] += val;
    idx += (idx & -idx);
  }
}
int query(int wh, int idx) {
  int total = 0;
  while (idx > 0) {
    total += arr[wh][idx];
    idx -= (idx & -idx);
  }
  return total;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int a, t, x;
    scanf("%d%d%d", &a, &t, &x);
    lst.push_back(make_pair(a, make_pair(t, x)));
    m1[x]++;
    m3[x].push_back(t);
  }
  int cnt = 0;
  for (auto it : m1) {
    sort(m3[it.first].begin(), m3[it.first].end());
    m2[it.first] = cnt;
    arr.emplace_back();
    for (int i = 0; i <= it.second + 5; i++) {
      arr.back().push_back(0);
    }
    cnt++;
  }
  for (auto it : lst) {
    int type = it.first;
    int t = it.second.first;
    int x = it.second.second;
    auto idx = lower_bound(m3[x].begin(), m3[x].end(), t) - m3[x].begin();
    if (type == 1) {
      update(m2[x], idx + 1, 1);
    } else if (type == 2) {
      update(m2[x], idx + 1, -1);
    } else {
      printf("%d\n", query(m2[x], idx + 1));
    }
  }
}
