#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const double eps = 1e-6;
int n, m;
long long tot, mx, gg;
bool bul;
struct node {
  long long h, v, d;
} ar[maxn];
vector<pair<long long, long long> > V[maxn];
long long sm[maxn];
long long gcd(long long a, long long b) {
  if (b == 0) {
    return a;
  } else {
    return gcd(b, a % b);
  }
}
bool cmp(node a, node b) {
  if (a.h != b.h) {
    return a.h < b.h;
  } else {
    return a.v < b.v;
  }
}
bool judge() {
  int sz = V[1].size();
  for (int i = 2; i <= m; ++i) {
    if (V[i].size() != sz) {
      return false;
    }
  }
  for (int i = 0; i < sz; ++i) {
    long long tmp1 = V[1][i].second;
    for (int j = 2; j <= m; ++j) {
      long long tmp2 = V[j][i].second;
      if (V[j][i].first != V[1][i].first) {
        return false;
      }
      if (fabs(1.0 * tmp1 / sm[1] - 1.0 * tmp2 / sm[j]) > eps) {
        return false;
      }
    }
  }
  return true;
}
int main() {
  bul = 1;
  tot = 0;
  m = 0;
  mx = 0;
  memset(sm, 0, sizeof(sm));
  memset(ar, 0, sizeof(ar));
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    cin >> ar[i].h >> ar[i].v >> ar[i].d;
    tot += ar[i].d;
  }
  sort(ar + 1, ar + n + 1, cmp);
  for (int i = 1, j = 0; i <= n; ++i) {
    if (ar[i].h == ar[j].h) {
      V[m].push_back(make_pair(ar[i].v, ar[i].d));
      sm[m] += ar[i].d;
    } else {
      j = i;
      ++m;
      V[m].push_back(make_pair(ar[i].v, ar[i].d));
      sm[m] += ar[i].d;
    }
  }
  gg = ar[1].d;
  for (int i = 2; i <= n; ++i) {
    gg = gcd(gg, ar[i].d);
  }
  for (int i = 1; i <= m; ++i) {
    sm[i] /= gg;
    for (int j = 0; j < V[i].size(); ++j) {
      V[i][j].second /= gg;
    }
  }
  bul = judge();
  if (bul) {
    long long ans = 0;
    for (int i = 1; 1ll * i * i <= gg; ++i) {
      if (gg % i == 0) {
        ++ans;
        if (1ll * i * i != gg) {
          ++ans;
        }
      }
    }
    cout << ans << '\n';
  } else {
    cout << 0 << '\n';
  }
  return 0;
}
