#include <bits/stdc++.h>
using namespace std;
const int max_n = 1000 + 10;
const long long M = 1000 * 1000 * 1000 + 7;
const long double EPS = 1e-11;
pair<long double, long double> p[max_n];
vector<pair<pair<long double, long double>, long double> > mid;
inline bool eq(long double a, long double b) { return (abs(a - b) < EPS); }
bool cmp(pair<pair<long double, long double>, long double> a,
         pair<pair<long double, long double>, long double> b) {
  if (eq(a.first.first, b.first.first)) {
    if (eq(a.first.second, b.first.second)) return a.second < b.second;
    return a.first.second < b.first.second;
  }
  return a.first.first < b.first.first;
}
inline long double shib(long double x, long double y) {
  if (abs(x) < EPS) return 1e11;
  return y / x;
}
long long pw[max_n];
int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    p[i].first = (long double)a / b;
    p[i].second = (long double)c / d;
    long double id = p[i].first * p[i].first + p[i].second * p[i].second;
    p[i].first /= id;
    p[i].second /= id;
  }
  pw[0] = 1;
  for (int i = 0; i < n; i++)
    for (int j = i + 1; j < n; j++)
      mid.push_back(pair<pair<long double, long double>, long double>(
          pair<long double, long double>((p[i].first + p[j].first),
                                         (p[i].second + p[j].second)),
          shib(p[i].first - p[j].first, p[i].second - p[j].second)));
  sort(mid.begin(), mid.end(), cmp);
  long long ans = 0;
  for (int i = 0; i < (int)mid.size(); i++) {
    int cnt = 1, j = i;
    while (j + 1 < (int)mid.size() &&
           eq(mid[j].first.first, mid[j + 1].first.first) &&
           eq(mid[j].first.second, mid[j + 1].first.second))
      cnt++, j++;
    long long co = 1;
    for (int k = i; k <= j; k++) {
      int c = 2;
      while (k + 1 <= j && eq(mid[k].second, mid[k + 1].second)) k++, c++;
      co *= c;
      co %= M;
    }
    ans += co + M - cnt - 1;
    ans %= M;
    i = j;
  }
  cout << ans << endl;
}
