#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5;
long long n, G, w[MAXN + 10], h[MAXN + 10], c[MAXN + 10], p[MAXN + 10];
vector<pair<long long, long long> > rto;
template <typename T>
T gcd(T a, T b) {
  return b == 0 ? a : gcd(b, a % b);
}
template <typename T>
inline void readint(T &x) {
  T f = 1, r = 0;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    r = r * 10 + c - '0';
    c = getchar();
  }
  x = f * r;
}
void init() {
  readint(n);
  for (int i = 1; i <= n; i++) readint(w[i]), readint(h[i]), readint(c[i]);
}
bool validate() {
  int len;
  for (len = 1; w[p[len + 1]] == w[p[1]]; len++)
    ;
  for (int i = 1; i <= len; i++) rto.push_back({h[p[i]], c[p[i]]});
  for (int k = 2; k * len <= n; k++) {
    for (int i = 0; i < len - 1; i++) {
      if (h[p[(k - 1) * len + i + 1]] != rto[i].first) return false;
      long long g1 =
          gcd(c[p[(k - 1) * len + i + 1]], c[p[(k - 1) * len + i + 2]]);
      long long g2 = gcd(rto[i].second, rto[i + 1].second);
      if (c[p[(k - 1) * len + i + 1]] / g1 != rto[i].second / g2 ||
          c[p[(k - 1) * len + i + 2]] / g1 != rto[i + 1].second / g2)
        return false;
    }
    if (h[p[k * len]] != rto.back().first) return false;
  }
  return true;
}
void work() {
  G = c[1];
  for (int i = 1; i <= n; i++) p[i] = i;
  sort(p + 1, p + n + 1, [](const long long a, const long long b) {
    return w[a] == w[b] ? h[a] < h[b] : w[a] < w[b];
  });
  if (!validate())
    printf("0");
  else {
    for (int i = 2; i <= n; i++) G = gcd(G, c[i]);
    for (int i = 1; i <= n; i++) c[i] /= G;
    long long ans = 0;
    for (long long i = 1; i * i <= G; i++) {
      if (G % i == 0) {
        if (i * i != G)
          ans += 2;
        else
          ans += 1;
      }
    }
    cout << ans;
  }
}
int main() {
  init();
  work();
  return 0;
}
