#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1005, P = 1000000007;
const double EPS = 1e-8;
const double PI = acos(-1);
inline int sgn(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
struct Node {
  double x, y, a;
} p[N * N];
inline bool operator<(const Node &a, const Node &b) {
  if (sgn(a.x - b.x)) return sgn(a.x - b.x) < 0;
  if (sgn(a.y - b.y)) return sgn(a.y - b.y) < 0;
  return sgn(a.a - b.a) < 0;
}
int n;
double x[N], y[N];
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    double t1, t2;
    cin >> t1 >> t2;
    x[i] = t1 / t2;
    cin >> t1 >> t2;
    y[i] = t1 / t2;
    double d = x[i] * x[i] + y[i] * y[i];
    x[i] /= d;
    y[i] /= d;
  }
  int idx = 0;
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++) {
      ++idx;
      p[idx].x = (x[i] + x[j]) / 2;
      p[idx].y = (y[i] + y[j]) / 2;
      double tt = atan2(y[j] - y[i], x[j] - x[i]);
      if (sgn(tt) < 0) tt += PI;
      if (sgn(tt - PI) >= 0) tt -= PI;
      p[idx].a = tt;
    }
  sort(p + 1, p + idx + 1);
  ll ans = 0, sum1 = 0, sum2 = 0;
  for (int i = 1; i <= idx; i++) {
    int j = i;
    sum1 = sum2 = 0;
    while (j <= idx && !sgn(p[j].x - p[i].x) && !sgn(p[j].y - p[i].y)) {
      int k = j;
      while (j <= idx && !(p[k] < p[j])) ++j;
      sum2 = (sum2 + (sum1 + sum2) * (j - k)) % P;
      sum1 = (sum1 + (j - k)) % P;
    }
    ans = (ans + sum2) % P;
    i = j - 1;
  }
  cout << ans << endl;
  return 0;
}
