#include <bits/stdc++.h>   using namespace std;   const int INF = 0x3fffffff;   const int SINF = 0x7fffffff;   const long long LINF = 0x3fffffffffffffff;   const long long SLINF = 0x7fffffffffffffff;   const long double DINF = pow(2, 100);   const int MAXN = 1007;   const int MOD = static_cast<int>(1e9 + 7);   const long double EPS = 1e-11;   struct cT {     cT() : x(0), y(0) {}     cT(long double _x, long double _y) : x(_x), y(_y) {}     cT operator+(const cT &a) const { return cT(x + a.x, y + a.y); }     cT operator-(const cT &a) const { return cT(x - a.x, y - a.y); }     cT operator/(const int a) { return cT(x / a, y / a); }     bool operator==(const cT &a) const {       return ((((x - a.x) >= 0) ? (x - a.x) : (-(x - a.x))) < EPS &&               (((y - a.y) >= 0) ? (y - a.y) : (-(y - a.y))) < EPS);     }     bool operator!=(const cT &a) const { return !((*this) == a); }     bool operator<(const cT &a) const {       return ((((x - a.x) >= 0) ? (x - a.x) : (-(x - a.x))) > EPS)                  ? x < a.x                  : y < a.y - EPS;     }     long double getk() {       return (((x) >= 0) ? (x) : (-(x))) < EPS ? DINF : (y / x);     }     long double x, y;   } cr[MAXN];   struct dT {     dT() : k(0) {}     dT(cT _cr, long double _k) : cr(_cr), k(_k) {}     bool operator<(const dT &a) const {       return (cr != a.cr) ? cr < a.cr : k < a.k - EPS;     }     cT cr;     long double k;   } med[MAXN * MAXN];   int n;   int km;   void init();   void input();   void work();   int getans(int l, int r);   int add(int x, int y) {     x += y;     if (x >= MOD) x -= MOD;     return x;   }   void addv(int &x, int y) {     x += y;     if (x >= MOD) x -= MOD;   }   int dec(int x, int y) {     x -= y;     if (x < 0) x += MOD;     return x;   }   void decv(int &x, int y) {     x -= y;     if (x < 0) x += MOD;   }   int main() {     init();     input();     work();   }   void init() { ios::sync_with_stdio(false); }   void input() {     scanf( %d , &n);     int a, b, c, d;     for (int i = 1; i <= n; ++i) {       scanf( %d%d%d%d , &a, &b, &c, &d);       cr[i].x = static_cast<long double>(a * b * d * d) /                 (a * a * d * d + b * b * c * c);       cr[i].y = static_cast<long double>(c * d * b * b) /                 (a * a * d * d + b * b * c * c);     }   }   void work() {     for (int i = 1; i <= n; ++i) {       for (int j = i + 1; j <= n; ++j) {         med[++km] = dT((cr[i] + cr[j]) / 2, (cr[j] - cr[i]).getk());       }     }     sort(med + 1, med + 1 + km);     med[km + 1] = dT(cT(DINF, DINF), 1);     int pre = 1, ans = 0;     for (int i = 1; i <= km + 1; ++i) {       if (med[i].cr != med[pre].cr) {         addv(ans, getans(pre, i - 1));         pre = i;       }     }     cout << ans << endl;   }   int getans(int l, int r) {     int pre = l;     int ans = 1;     for (int i = l; i <= r; ++i) {       if ((((med[i].k - med[pre].k) >= 0) ? (med[i].k - med[pre].k)                                           : (-(med[i].k - med[pre].k))) > EPS) {         ans = static_cast<long long>(ans) * (i - pre + 1) % MOD;         pre = i;       }     }     ans = static_cast<long long>(ans) * (r - pre + 2) % MOD;     return dec(ans, r - l + 2);   }   