#include <bits/stdc++.h>
using namespace std;
namespace HABIT {
const int MAXN = 2e5 + 10;
typedef int ar[MAXN];
template <typename T>
inline T Max(T a) {
  return a;
}
template <typename T, typename... Args>
inline T Max(T a, Args... args) {
  T b = Max(args...);
  return (a > b) ? a : b;
}
template <typename T>
inline T Min(T a) {
  return a;
}
template <typename T, typename... Args>
inline T Min(T a, Args... args) {
  T b = Min(args...);
  return (a < b) ? a : b;
}
inline char gc() { return getchar(); }
inline long long int read() {
  register long long int ans = 0;
  register char c = gc();
  register bool neg = 0;
  while (c < 48 || c > 57) neg ^= !(c ^ '-'), c = gc();
  while (c >= 48 && c <= 57) ans = (ans << 3) + (ans << 1) + (c ^ 48), c = gc();
  return neg ? -ans : ans;
}
char Output_Ans[1 << 20 | 1], *Output_Cur = Output_Ans;
inline void output() {
  Output_Cur -= fwrite(Output_Ans, 1, Output_Cur - Output_Ans, stdout);
}
inline void print(char c) {
  if (Output_Cur - Output_Ans + 1 >> 20) output();
  *(Output_Cur++) = c;
}
inline void print(char *s) {
  while (*s) print(*(s++));
}
inline void print(unsigned long long int x) {
  if (!x) {
    print('0');
    return;
  }
  char buf[30] = {0}, *p = buf + 28;
  while (x) *(p--) = x % 10 + 48, x /= 10;
  print(p + 1);
}
inline void print(unsigned int x) { print((unsigned long long int)x); }
inline void print(long long int x) {
  if (x < 0) print('-'), x = -x;
  print((unsigned long long int)x);
}
inline void print(int x) {
  if (x < 0) print('-'), x = -x;
  print((unsigned long long int)x);
}
}  // namespace HABIT
using namespace HABIT;
map<pair<long long int, long long int>, int> M;
int N, Excnt;
pair<long long int, long long int> Pnt[MAXN];
int PVec[MAXN], VVec[MAXN];
bool Vis[MAXN];
const long long int MOD = 1000000007;
long long int gcd(long long int x, long long int y) {
  if (x < 0) return gcd(-x, y);
  if (y < 0) return gcd(x, -y);
  if (!y) return x;
  return gcd(y, x % y);
}
inline int findit(long long int x, long long int y) {
  long long int g = gcd(x, y);
  if ((x < 0) ^ (y < 0)) g = -g;
  x /= g;
  y /= g;
  if (M.find(pair<long long int, long long int>(x, y)) != M.end())
    return M[pair<long long int, long long int>(x, y)];
  return -1;
}
inline void addToMap(long long int x, long long int y, int i) {
  long long int g = gcd(x, y);
  x /= g;
  y /= g;
  M[pair<long long int, long long int>(x, y)] =
      M[pair<long long int, long long int>(-x, -y)] = i;
}
inline void pre() {
  N = read();
  for (register int i = 1, I = N; i <= I; i++) {
    Pnt[i].first = read();
    Pnt[i].second = read();
    if (Pnt[i].first == 0 && Pnt[i].second == 0) {
      PVec[i] = VVec[i] = -1;
      Excnt++;
      continue;
    }
    PVec[i] = findit(Pnt[i].first, Pnt[i].second);
    addToMap(Pnt[i].first, Pnt[i].second, i);
    VVec[i] = findit(-Pnt[i].second, Pnt[i].first);
    continue;
  }
}
inline long long int fpow(long long int a, long long int x) {
  long long int Ans = 1;
  for (; x; x >>= 1, a = a * a % MOD)
    if (x & 1) Ans = Ans * a % MOD;
  return Ans;
}
inline int findP(int n) {
  int Cnt = 0;
  while (n != -1) {
    Vis[n] = 1;
    n = PVec[n];
    Cnt++;
  }
  return Cnt;
}
int main() {
  pre();
  long long int Ans = 1;
  for (register int i = N, I = 1; i >= I; i--)
    if (!Vis[i]) {
      if (Pnt[i].first == 0 && Pnt[i].second == 0) continue;
      int N1 = findP(i), N2 = findP(VVec[i]);
      Ans = (fpow(2, N1) + fpow(2, N2) - 1) % MOD * Ans % MOD;
    }
  Ans = (Ans - 1 + Excnt) % MOD;
  print(Ans);
  output();
  return 0;
}
