#include <bits/stdc++.h>
using namespace std;
inline long long rd() {
  long long x = 0, w = 1;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') c = getchar(), w = -1;
  while (isdigit(c)) x = x * 10 + c - 48, c = getchar();
  return x * w;
}
using namespace std;
const int N = 1010, MOD = 1e9 + 7;
int n, tt, ans;
struct P {
  double x, y;
} p[N];
inline bool equ(double x, double y) { return abs(x - y) < 1e-9; }
struct st {
  double x, y, k;
} V[N * N];
inline bool cmp(st a, st b) {
  if (!equ(a.x, b.x)) return a.x < b.x;
  if (!equ(a.y, b.y)) return a.y < b.y;
  return a.k < b.k;
}
int main() {
  scanf("%d", &n);
  for (int i = (1); i <= (n); ++i) {
    double a, b, c, d;
    scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
    double x = a / b, y = c / d;
    p[i].x = x / (x * x + y * y);
    p[i].y = y / (x * x + y * y);
  }
  for (int i = (1); i <= (n); ++i)
    for (int j = (i + 1); j <= (n); ++j) {
      tt++;
      V[tt].x = p[i].x + p[j].x;
      V[tt].y = p[i].y + p[j].y;
      V[tt].k =
          equ(p[i].x, p[j].x) ? 1e9 : (p[j].y - p[i].y) / (p[j].x - p[i].x);
    }
  sort(V + 1, V + tt + 1, cmp);
  for (int i = 1, j; i <= tt; i = j) {
    int c = 1, s = 1;
    for (j = i + 1; j <= tt && equ(V[j].x, V[i].x) && equ(V[j].y, V[i].y);
         j++) {
      if (equ(V[j].k, V[j - 1].k))
        c++;
      else
        s = 1ll * s * (c + 1) % MOD, c = 1;
    }
    s = 1ll * s * (c + 1) % MOD;
    ans = (ans + s - 1) % MOD;
  }
  printf("%d\n", (ans + MOD - tt) % MOD);
  return 0;
}
