#include <bits/stdc++.h>
using namespace std;
const int N = 1005, P = 1000000007;
const double eps = 1e-9;
int n, m, s, ans, A, B, C, D;
double x[N], y[N];
inline bool E(double a, double b) { return fabs(a - b) < eps; }
struct node {
  double x, y, k;
  node() {}
  node(double _x, double _y, double _k) : x(_x), y(_y), k(_k) {}
  bool operator<(const node &A) const {
    return E(x, A.x) ? E(y, A.y) ? k < A.k : y < A.y : x < A.x;
  }
} a[N * N];
int main() {
  scanf("%d", &n);
  for (long long i = 0; i < n; ++i)
    scanf("%d%d%d%d", &A, &B, &C, &D),
        x[i] = A * B * D * D * 1. / (A * A * D * D + B * B * C * C),
        y[i] = B * B * C * D * 1. / (A * A * D * D + B * B * C * C);
  for (long long i = 0; i < n; ++i)
    for (long long j = 0; j < i; ++j)
      a[m++] = node(x[i] + x[j], y[i] + y[j],
                    E(y[i], y[j]) ? 1e20 : (x[j] - x[i]) / (y[j] - y[i]));
  int l = 0, r;
  sort(a, a + m);
  while (l < m) {
    for (r = l; r < m && E(a[l].x, a[r].x) && E(a[l].y, a[r].y); ++r)
      ;
    long long res = 1, c = 1;
    for (int i = l; i < r; ++i) {
      if (E(a[i].k, a[i + 1].k) && i + 1 < r)
        ++c;
      else
        res = res * (c + 1) % P, c = 1;
    }
    ans = (ans + res - r + l - 1) % P, l = r;
  }
  printf("%d\n", (ans + P) % P);
  return 0;
}
