#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 2000;
typedef struct L {
  int a, b, c;
} L;
int n;
L l[MAXN];
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%d%d%d", &l[i].a, &l[i].b, &l[i].c);
  int ret = 0, norig = 0;
  int nn = 0;
  for (int i = (0); i < (n); ++i)
    if (l[i].c == 0)
      ++norig;
    else
      l[nn++] = l[i];
  n = nn;
  if (norig >= 2) ret += 3 * n;
  for (int i = (0); i < (n); ++i) {
    vector<long double> cur;
    for (int j = (0); j < (n); ++j)
      if (i != j) {
        int ai = l[i].a, bi = l[i].b, ci = l[i].c;
        int aj = l[j].a, bj = l[j].b, cj = l[j].c;
        long double x =
            ((long double)1.0) * (bj * ci - bi * cj) / (bj * ai - bi * aj);
        long double y =
            ((long double)1.0) * (ai * cj - aj * ci) / (bj * ai - bi * aj);
        if (x * aj + y * bj > 0) bj = -bj, aj = -aj, cj = -cj;
        long double cosa =
            (x * bj - y * aj) / sqrt(x * x + y * y) / sqrt(aj * aj + bj * bj);
        cur.push_back(cosa);
      }
    sort(cur.begin(), cur.end());
    for (int at = 0, to = 0; at < ((int)(cur).size()); at = to) {
      while (to < ((int)(cur).size()) && fabs(cur[at] - cur[to]) < 1e-13) ++to;
      int cnt = to - at;
      ret += cnt * (cnt - 1) / 2;
    }
  }
  ret /= 3;
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}
