#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
inline bool iszero(double first) { return first <= eps && first >= -eps; }
int sgn(double first) { return iszero(first) ? 0 : (first < 0 ? -1 : 1); }
struct pt {
  double first, second;
  pt(double xx = 0, double yy = 0) : first(xx), second(yy) {}
  pt(pair<int, int> p) : first(p.first), second(p.second) {}
  bool operator==(pt a) {
    return iszero(a.first - first) && iszero(a.second - second);
  }
};
bool operator<(const pt &a, const pt &b) {
  if (!iszero(a.first - b.first)) return a.first < b.first;
  if (!iszero(a.second - b.second)) return a.second < b.second;
  return 0;
}
ostream &operator<<(ostream &s, pt p) {
  return s << "(" << p.first << "," << p.second << ")";
}
pt operator+(pt a, pt b) { return pt(a.first + b.first, a.second + b.second); }
pt operator-(pt a, pt b) { return pt(a.first - b.first, a.second - b.second); }
pt operator*(pt a, double r) { return pt(a.first * r, a.second * r); }
double vec(pt a, pt b) { return a.first * b.second - a.second * b.first; }
double det(pt a, pt b, pt c) { return vec(b - a, c - a); }
pt operator*(pt a, pt b) {
  return pt(a.first * b.first - a.second * b.second,
            b.first * a.second + b.second * a.first);
}
double sqabs(pt a) { return a.first * a.first + a.second * a.second; }
pt operator/(pt a, pt b) { return (a * pt(b.first, -b.second)) / sqabs(b); }
double skal(pt a, pt b) { return a.first * b.first + a.second * b.second; }
double abs(pt a) { return sqrt(skal(a, a)); }
double dist(pt a, pt b) { return abs(a - b); }
double sqdist(pt a, pt b) { return skal(a - b, a - b); }
const int mod = 1000000007;
const int MAXN = 1006;
pt P[MAXN];
map<pt, map<pt, int> > M;
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < (n); ++i) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    P[i].first = 1.0 * a / b;
    P[i].second = 1.0 * c / d;
  }
  for (int i = 0; i < (n); ++i) {
    double r = abs(P[i]);
    P[i] = P[i] * (10. / r / r);
  }
  if (0)
    for (int a = 0; a < (n); ++a)
      for (int b = 0; b < (n); ++b)
        for (int c = 0; c < (n); ++c)
          for (int d = 0; d < (n); ++d)
            if (a != b && a != c && a != d && b != c && b != d && c != d) {
              if (P[a] - P[b] == P[c] - P[d] && P[a] - P[c] == P[b] - P[d])
                if (a < max({b, c, d})) printf("%d %d %d %d\n", a, b, c, d);
            }
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (i); ++j) {
      pt srod = (P[i] + P[j]) * 0.5;
      pt nachyl = P[i] - P[j];
      if (nachyl.first < -eps || (iszero(nachyl.first) && nachyl.second < 0))
        nachyl = P[j] - P[i];
      pt n2 = nachyl;
      nachyl = nachyl * (1. / abs(nachyl));
      M[srod][nachyl]++;
    }
  long long ret = 0;
  for (auto i1 = (M).begin(); i1 != (M).end(); ++i1) {
    long long tu = 1;
    int nie = 0;
    for (auto i2 = (i1->second).begin(); i2 != (i1->second).end(); ++i2) {
      tu = 1LL * tu * (i2->second + 1) % mod;
      nie += i2->second;
    }
    tu = tu + 2LL * mod - nie - 1;
    if (0)
      for (auto i2 = (i1->second).begin(); i2 != (i1->second).end(); ++i2) {
        printf("%d ,", i2->second);
      }
    ret += tu % mod;
  }
  printf("%lld\n", ret % mod);
  return 0;
}
