#include <bits/stdc++.h>
using namespace std;
template <typename T>
void __read(T &a) {
  cin >> a;
}
template <typename T, typename... Args>
void __read(T &a, Args &...args) {
  cin >> a;
  __read(args...);
}
constexpr long long M7 = 1000000007ll;
constexpr long long M9 = 1000000009ll;
constexpr long long MFFT = 998244353ll;
template <class T>
void outv(T &a) {
  for (auto &x : a) cout << x << ' ';
}
static mt19937 rnd(static_cast<unsigned>(
    chrono::steady_clock::now().time_since_epoch().count()));
auto __fast_io__ = (ios_base::sync_with_stdio(false), cin.tie(nullptr));
long long gcd(long long a, long long b) {
  while (b > 0) {
    long long t = a % b;
    a = b;
    b = t;
  }
  return a;
}
struct fraction {
  long long a, b;
  fraction(long long a = 0, long long b = 1) : a(a), b(b) { normalize(); };
  void operator/=(long long d) {
    b *= d;
    normalize();
  }
  void normalize() {
    long long g = gcd(abs(a), abs(b));
    if (g != 0) {
      a /= g;
      b /= g;
    }
    if (b < 0) {
      a *= -1;
      b *= -1;
    }
  }
  bool operator<(const fraction &other) const {
    return a * other.b < other.a * b;
  }
  bool operator==(const fraction &other) const {
    return a * other.b == other.a * b;
  }
  bool operator!=(const fraction &other) const {
    return a * other.b != other.a * b;
  }
};
fraction operator*(const fraction &a, const fraction &b) {
  return fraction(a.a * b.a, a.b * b.b);
}
fraction operator+(const fraction &a, const fraction &b) {
  long long den = a.b / gcd(a.b, b.b) * b.b;
  long long num = a.a * den / a.b + b.a * den / b.b;
  return fraction(num, den);
}
fraction operator-(const fraction &a, const fraction &b) {
  long long den = a.b / gcd(a.b, b.b) * b.b;
  long long num = a.a * den / a.b - b.a * den / b.b;
  return fraction(num, den);
}
fraction operator/(const fraction &a, const fraction &b) {
  return fraction(a.a * b.b, a.b * b.a);
}
template <class T>
struct point {
  T x, y;
  point(const T &x = 0, const T &y = 0) : x(x), y(y) {}
  bool operator<(const point<T> &other) const {
    if (x != other.x) {
      return x < other.x;
    }
    return y < other.y;
  }
};
template <class T>
point<T> operator+(const point<T> &a, const point<T> &b) {
  return {a.x + b.x, a.y + b.y};
}
int32_t main() {
  long long n;
  __read(n);
  vector<point<fraction>> a(n);
  for (auto &p : a) {
    cin >> p.x.a >> p.x.b >> p.y.a >> p.y.b;
    p.x.normalize();
    p.y.normalize();
    auto z = p.x * p.x + p.y * p.y;
    p.x = p.x / z;
    p.y = p.y / z;
  }
  map<point<fraction>, vector<fraction>> q;
  for (long long i = 0; i < n; ++i) {
    for (long long j = i + 1; j < n; ++j) {
      auto dx = a[i].x - a[j].x;
      auto dy = a[i].y - a[j].y;
      q[(a[i] + a[j])].push_back(dy == 0 ? fraction(1, 0) : dx / dy);
    }
  }
  long long ans = 0;
  for (auto &[p, v] : q) {
    sort((v).begin(), (v).end());
    vector<long long> sz;
    for (long long i = 0; i < v.size(); ++i) {
      long long j = i;
      sz.push_back(0);
      while (j < v.size() && v[i] == v[j]) {
        sz.back()++;
        j++;
      }
      i = j - 1;
    }
    long long res = 1;
    for (auto &val : sz) {
      res = (res * (val + 1)) % M7;
    }
    for (auto &val : sz) {
      res = (res - val + M7) % M7;
    }
    res = (res + M7 - 1) % M7;
    ans += res;
  }
  cout << ans % M7;
  return 0;
}
