#include <bits/stdc++.h>
using namespace std;
const int MaxN = 1005;
const int M = 1000000007;
const double eps = 1e-8;
const double INF = 1e10;
inline bool equal(double a, double b) { return fabs(a - b) < eps; }
int n, m = 0;
double dx[MaxN], dy[MaxN];
struct line {
  double x, y, k;
  line() {}
  line(const double &_x, const double &_y, const double &_k)
      : x(_x), y(_y), k(_k) {}
  friend inline bool operator<(const line &lhs, const line &rhs) {
    if (!equal(lhs.x, rhs.x)) return lhs.x < rhs.x;
    if (!equal(lhs.y, rhs.y)) return lhs.y < rhs.y;
    return lhs.k < rhs.k;
  }
};
line l[MaxN * MaxN / 2];
int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    double x = (double)a / b;
    double y = (double)c / d;
    double len = x * x + y * y;
    dx[i] = x / len;
    dy[i] = y / len;
  }
  for (int i = 1; i < n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      double x = dx[i] + dx[j];
      double y = dy[i] + dy[j];
      double k = equal(dx[i], dx[j]) ? INF : (dy[i] - dy[j]) / (dx[i] - dx[j]);
      l[m++] = line(x, y, k);
    }
  sort(l, l + m);
  int res = 0;
  for (int i = 0, k; i < m; i = k) {
    k = i;
    while (k < m && equal(l[i].x, l[k].x) && equal(l[i].y, l[k].y)) ++k;
    int now = 1, cur = 1;
    for (int j = i + 1; j < k; ++j) {
      if (equal(l[j - 1].k, l[j].k))
        ++now;
      else {
        cur = (long long)cur * (now + 1) % M;
        now = 1;
      }
    }
    cur = (long long)cur * ++now % M;
    res = (res + cur) % M;
    res = (res - k + i - 1) % M;
  }
  cout << (res + M) % M << endl;
  return 0;
}
