#include <bits/stdc++.h>
using namespace std;
long long d[10020];
int n, Ans, zero, a[10020], b[10020], c[10020];
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
struct frac {
  long long up, dn;
  frac() {}
  frac(long long u, long long d) {
    long long G = gcd(u, d);
    up = u / G, dn = d / G;
  }
  bool operator==(const frac &rhs) const {
    return up == rhs.up && dn == rhs.dn;
  }
  bool operator<(const frac &rhs) const {
    return up < rhs.up || up == rhs.up && dn < rhs.dn;
  }
} slp[10020];
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", a + i, b + i, c + i);
    d[i] = a[i] * a[i] + b[i] * b[i];
    if (!c[i]) zero++;
  }
  if (zero == 2) Ans += n - 2;
  for (int i = 1; i <= n; i++)
    if (c[i]) {
      int m = 0, tot = 1;
      for (int j = i + 1; j <= n; j++)
        if (c[j])
          slp[++m] = frac(b[j] * c[j] * d[i] - b[i] * c[i] * d[j],
                          a[j] * c[j] * d[i] - a[i] * c[i] * d[j]);
      sort(slp + 1, slp + m + 1);
      for (int j = 1, k; j <= m; j = k + 1) {
        k = j;
        while (k <= m && slp[k] == slp[j]) k++;
        k--;
        int d = k - j + 1;
        Ans += d * (d - 1) / 2;
      }
    }
  printf("%d\n", Ans);
}
