#include <bits/stdc++.h>
using namespace std;
bool debug = 1;
int n, m, k;
long long ln, lk, lm;
double x[1005], y[1005];
bool ise(double a, double b) { return abs(a - b) < 1e-9; }
struct uz {
  double x, y, k;
  bool operator<(const uz &o) const {
    if (ise(x, o.x)) {
      if (ise(y, o.y)) return k < o.k;
      return y < o.y;
    }
    return x < o.x;
  }
};
vector<uz> vp;
int main() {
  scanf("%d", &n);
  int a, b, c, d;
  for (int(i) = 0; (i) < (int)(n); (i)++) {
    scanf("%d%d%d%d", &a, &b, &c, &d);
    x[i] = 1.0 * a * b * d * d / (a * a * d * d + b * b * c * c);
    y[i] = 1.0 * b * b * c * d / (a * a * d * d + b * b * c * c);
  }
  for (int(i) = 0; (i) < (int)(n); (i)++)
    for (int j = i + 1; j < n; j++) {
      uz u;
      u.x = x[i] + x[j];
      u.y = y[i] + y[j];
      u.k = ise(y[i], y[j]) ? (1LL << 60) : (x[i] - x[j]) / (y[i] - y[j]);
      vp.push_back(u);
    }
  sort(vp.begin(), vp.end());
  long long ans = 0;
  for (int l = 0, r; l < vp.size();) {
    for (r = l; r < vp.size() && ise(vp[l].x, vp[r].x) && ise(vp[l].y, vp[r].y);
         r++)
      ;
    long long res = 1, c = 1;
    for (int i = l; i < r; i++) {
      if (ise(vp[i].k, vp[i + 1].k) && i + 1 < r)
        c++;
      else {
        (res *= (c + 1)) %= 1000000007;
        c = 1;
      }
    }
    ans += res - (r - l) - 1;
    ans %= 1000000007;
    l = r;
  }
  printf("%lld\n", ans);
  return 0;
}
