#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct segment_tree {
  struct node {
    int cnt = 0;
    node* left = nullptr;
    node* right = nullptr;
  };
  node* root;
  segment_tree() { root = new node; }
  void update(node*& st, int l, int r, int kth, int v) {
    if (l == r) {
      st->cnt += v;
      return;
    }
    if (!st->left) {
      st->left = new node;
      st->right = new node;
    }
    int mid = (l + r) / 2;
    if (kth <= mid) {
      update(st->left, l, mid, kth, v);
    } else {
      update(st->right, mid + 1, r, kth, v);
    }
    st->cnt = st->left->cnt + st->right->cnt;
  }
  void update(int kth, int v) { update(root, 1, 1e9, kth, v); }
  int query(node* st, int l, int r, int ll, int rr) {
    if (rr < l || r < ll || !st) {
      return 0;
    }
    if (ll <= l && r <= rr) {
      return st->cnt;
    }
    int mid = (l + r) / 2;
    return query(st->left, l, mid, ll, rr) +
           query(st->right, mid + 1, r, ll, rr);
  }
  int query(int l, int r) { return query(root, 1, 1e9, l, r); }
};
enum { add = 1, rem, count };
map<int, segment_tree> st;
int q;
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
  cin >> q;
  int type, timer, x;
  while (q--) {
    cin >> type >> timer >> x;
    if (type == add || type == rem) {
      st[x].update(timer, type == add ? +1 : -1);
    } else {
      cout << st[x].query(1, timer) << '\n';
    }
  }
  return 0;
}
