#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;
}
int n, i, j, o, ans, cnt, num;
double a, b, c, d, first[1010], second[1010], p, q, r;
pair<pair<double, double>, double> m[1010 * 1010];
bool 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;
}
int main() {
  scanf("%d", &n);
  for (i = 0; i < n; i++) {
    scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
    p = a / b, q = c / d;
    r = p * p + q * q;
    first[i] = p / r, second[i] = q / r;
  }
  for (i = 0; i < n; i++) {
    for (j = i + 1; j < n; j++) {
      p = first[i] + first[j], q = second[i] + second[j];
      m[o++] = pair<pair<double, double>, double>(
          pair<double, double>(p, q),
          fabs(first[i] - first[j]) < 1e-8
              ? 0x3f3f3f3f
              : (second[i] - second[j]) / (first[i] - first[j]));
    }
  }
  sort(m, m + o, cmp);
  for (i = 0; i < o; i = j) {
    cnt = num = 1;
    for (j = i + 1; j < o; j++) {
      if (fabs(m[j].first.first - m[j - 1].first.first) > 1e-8) break;
      if (fabs(m[j].first.second - m[j - 1].first.second) > 1e-8) break;
      if (fabs(m[j].second - m[j - 1].second) > 1e-8) {
        cnt = (long long)cnt * (num + 1) % 1000000007;
        num = 1;
      } else
        num++;
    }
    cnt = (long long)cnt * (num + 1) % 1000000007;
    ans = (ans + cnt) % 1000000007;
    ans = (ans + 1000000007 - (j - i + 1)) % 1000000007;
  }
  printf("%d\n", ans);
  return 0;
}
