#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:300777216")
std::uniform_int_distribution<std::mt19937::result_type> udist(0, 1);
std::mt19937 rng;
using namespace std;
FILE *in, *out;
int ri() {
  int a;
  fscanf(in, "%d", &a);
  return a;
}
double rf() {
  double a;
  fscanf(in, "%lf", &a);
  return a;
}
char sbuf[100005];
string rstr() {
  char c;
  char *b = sbuf;
  while (c = fgetc(in)) {
    if (c == '\n' || c == 255) break;
    *b++ = c;
  }
  *b = 0;
  return sbuf;
}
long long nod(long long a, long long b) {
  if (a == 1 || b == 1) return 1;
  if (a == 0) return b;
  if (b == 0) return a;
  return nod(b % a, a);
}
vector<int> primes;
void calculatePrimes() {
  primes.push_back(2);
  for (int i = 3; i < 500000; i += 2) {
    bool bFound = false;
    int m = (int)sqrt((float)i);
    for (int j = 1; j < primes.size() && !bFound && primes[j] <= m; j++)
      bFound = ((i % primes[j]) == 0);
    if (!bFound) primes.push_back(i);
  }
}
void egcd(int a, int b, int &g, int &x, int &y) {
  if (a == 0) {
    g = b;
    x = 0;
    y = 1;
    return;
  }
  egcd(b % a, a, g, y, x);
  x = x - (b / a) * y;
}
int modinv(int a, int m) {
  int g = 0, x = 0, y = 0;
  egcd(a, m, g, x, y);
  return (x + m) % m;
}
int numpass, numbusy = 0, numbusya = 0;
long long bpow(long long x, long long n, long long m) {
  if (n == 0) return 1;
  if (n == 1) return x;
  long long res = bpow(x, n / 2, m);
  res = (res * res) % 1000000007;
  if (n & 1) res = (x * res) % 1000000007;
  return res;
}
double getdir(pair<int, int> &a, pair<int, int> &b) {
  pair<int, int> c(a.first + b.first, a.second + b.second);
  return atan2(c.second, c.first);
}
int main() {
  int n;
  cin >> n;
  map<long long, set<pair<int, int>>> r;
  map<double, int> dm;
  int nump = 0;
  for (int i = (0); i < (((n))); ++i) {
    int op, x, y;
    long long rad;
    cin >> op >> x >> y;
    rad = x * (long long)x + y * (long long)y;
    if (op == 1) {
      auto &cr = r[rad];
      auto t = make_pair(x, y);
      auto d = getdir(t, t);
      dm[d]++;
      for (auto t1 : cr) {
        d = getdir(t, t1);
        dm[d] += 2;
      }
      cr.insert(t);
      nump++;
    }
    if (op == 2) {
      auto &cr = r[rad];
      auto t = make_pair(x, y);
      auto d = getdir(t, t);
      dm[d]--;
      cr.erase(t);
      for (auto t1 : cr) {
        d = getdir(t, t1);
        dm[d] -= 2;
      }
      nump--;
    }
    if (op == 3) {
      auto t = make_pair(x, y);
      double d = getdir(t, t);
      cout << nump - dm[d] << endl;
    }
  }
  return 0;
}
