#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void smin(T &a, U b) {
  if (a > b) a = b;
}
template <typename T, typename U>
inline void smax(T &a, U b) {
  if (a < b) a = b;
}
pair<pair<double, double>, double> p[1010 * 1010];
double first[1010], second[1010];
int cmp(pair<pair<double, double>, double> a,
        pair<pair<double, double>, double> b) {
  if (fabs(a.first.first - b.first.first) > 1e-8)
    return a.first.first < b.first.first;
  if (fabs(a.first.second - b.first.second) > 1e-8)
    return a.first.second < b.first.second;
  return a.second < b.second - 1e-8;
}
int main() {
  int n;
  double u, uu, v, vv;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%lf%lf%lf%lf", &u, &v, &uu, &vv);
    double a = u / v, b = uu / vv;
    double c = a * a + b * b;
    a /= c, b /= c;
    first[i] = a, second[i] = b;
  }
  int nn = 0;
  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++) {
      double a = first[i] + first[j], b = second[i] + second[j];
      p[nn++] = pair<pair<double, double>, double>(
          pair<double, double>(a, b),
          fabs(first[j] - first[i]) < 1e-8
              ? 1e10
              : (second[j] - second[i]) / (first[j] - first[i]));
    }
  sort(p, p + nn, cmp);
  int ans = 0;
  for (int i = 0, j; i < nn; i = j) {
    int cur = 1, cnt = 1;
    for (j = i + 1; j < nn; j++) {
      if (fabs(p[j - 1].first.first - p[j].first.first) > 1e-8) break;
      if (fabs(p[j - 1].first.second - p[j].first.second) > 1e-8) break;
      if (fabs(p[j - 1].second - p[j].second) < 1e-8)
        cnt++;
      else {
        cur = (long long)cur * (cnt + 1) % 1000000007;
        cnt = 1;
      }
    }
    cur = (long long)cur * (cnt + 1) % 1000000007;
    ans = (ans + cur) % 1000000007;
    ans = (ans + 1000000007 - (j - i + 1)) % 1000000007;
  }
  printf("%d\n", (ans + 1000000007) % 1000000007);
  return 0;
}
