#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T &n) {
  n = 0;
  __int128 ch = getchar(), f;
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  f = (ch == '-' ? ch = getchar(), -1 : 1);
  while (ch >= '0' && ch <= '9') n = n * 10 + (ch ^ 48), ch = getchar();
  n *= f;
}
char Of[105], *O1 = Of, *O2 = Of;
template <class T>
inline void print(T n) {
  if (n == 0) putchar('0');
  while (n) *(++O2) = (n % 10) ^ 48, n /= 10;
  while (O2 != O1) putchar(*(O2--));
}
__int128 const MAXN = 2e5 + 5, mod = 1e9 + 7;
struct Vectors {
  __int128 x, y, q;
  Vectors(__int128 _x = 0, __int128 _y = 0) {
    x = _x, y = _y;
    if (x >= 0 && y > 0) q = 1;
    if (x < 0 && y >= 0) q = 2;
    if (x <= 0 && y < 0) q = 3;
    if (x > 0 && y <= 0) q = 4;
  }
  Vectors operator-(const Vectors &A) { return Vectors(x - A.x, y - A.y); }
  Vectors operator+(const Vectors &A) { return Vectors(x + A.x, y + A.y); }
} A[MAXN];
inline __int128 Cross(Vectors x, Vectors y) { return x.x * y.y - x.y * y.x; }
inline __int128 Point(Vectors x, Vectors y) { return x.x * y.x + x.y * y.y; }
struct Node {
  Vectors v;
  __int128 cnt1, cnt2;
} B[MAXN];
__int128 vis[MAXN];
__int128 frac[MAXN], invfrac[MAXN];
inline bool cmp(Vectors x, Vectors y) {
  if (x.q ^ y.q) return x.q < y.q;
  return Cross(x, y) > 0;
}
inline __int128 qpow(__int128 a, __int128 k) {
  __int128 re = 1;
  for (; k; k >>= 1, a = a * a % mod)
    if (k & 1) re = re * a % mod;
  return re;
}
inline __int128 C(__int128 n, __int128 m) {
  if (n < 0 || n < m || m < 0) return 0;
  return frac[n] * invfrac[m] % mod * invfrac[n - m] % mod;
}
signed main() {
  __int128 n;
  read(n);
  frac[0] = 1;
  for (register __int128 i = 1; i <= n; ++i) frac[i] = frac[i - 1] * i % mod;
  invfrac[n] = qpow(frac[n], mod - 2);
  for (register __int128 i = n; i; --i) invfrac[i - 1] = invfrac[i] * i % mod;
  for (register __int128 i = 1, x, y; i <= n; ++i) {
    read(x), read(y);
    if (y < 0) x = -x, y = -y;
    if (y == 0 && x < 0) x = -x, y = -y;
    A[i] = Vectors(x, y);
  }
  sort(A + 1, A + 1 + n, cmp);
  __int128 cnt = 1, len = 0;
  for (register __int128 i = 1; i <= n; ++i)
    if (i != n && Cross(A[i], A[i + 1]) == 0)
      ++cnt;
    else {
      B[++len] = (Node){A[i], cnt, 0};
      cnt = 1;
    }
  __int128 now = 2;
  for (register __int128 i = 1; i <= len; ++i) {
    while (now != i && Point(B[now].v, B[i].v) > 0) now = now % len + 1;
    if (!vis[i])
      if (Point(B[i].v, B[now].v) == 0) vis[now] = 1, B[i].cnt2 = B[now].cnt1;
  }
  __int128 ans = 1;
  for (register __int128 i = 1; i <= len; ++i)
    if (!vis[i]) {
      __int128 now = ans;
      for (register __int128 j = 1; j <= max(B[i].cnt1, B[i].cnt2); ++j)
        ans = (ans + now * (C(B[i].cnt1, j) + C(B[i].cnt2, j)) % mod) % mod;
    }
  ans = (ans - 1 + mod) % mod;
  print(ans);
  return 0;
}
