#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
const int mo = 1000000007;
const double eps = 1e-9;
double x[N], y[N];
bool EQ(double x, double y) { return fabs(x - y) < eps; }
struct node {
  double x, y, d;
  bool operator<(const node &a) const {
    if (!EQ(x, a.x)) return x < a.x;
    if (!EQ(y, a.y)) return y < a.y;
    if (!EQ(d, a.d)) return d < a.d;
    return 0;
  }
} q[N * N / 2];
int n, cnt, ans;
int main() {
  scanf("%d", &n);
  for (int i = (int)(1); i <= (int)(n); i++) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    double x = 1.0 * a / b, y = 1.0 * c / d;
    ::x[i] = x / (x * x + y * y);
    ::y[i] = y / (x * x + y * y);
  }
  for (int i = (int)(1); i <= (int)(n); i++)
    for (int j = (int)(i + 1); j <= (int)(n); j++) {
      ++cnt;
      q[cnt].x = x[i] + x[j];
      q[cnt].y = y[i] + y[j];
      q[cnt].d = EQ(x[i], x[j]) ? 1e50 : (y[i] - y[j]) / (x[i] - x[j]);
    }
  sort(q + 1, q + cnt + 1);
  for (int l = 1, r; l <= cnt; l = r) {
    for (r = l; r <= cnt && EQ(q[l].x, q[r].x) && EQ(q[l].y, q[r].y); ++r)
      ;
    int num = 1, tmp = 2;
    for (int i = (int)(l + 1); i <= (int)(r); i++)
      if (i == r || !EQ(q[i].d, q[i - 1].d))
        num = 1ll * num * tmp % mo, tmp = 2;
      else
        ++tmp;
    ans = (ans + num + 1ll * mo - (r - l + 1)) % mo;
  }
  printf("%d\n", ans);
}
