#include <bits/stdc++.h>
using namespace std;
using ll = long long;
inline int scan() { return getchar(); }
inline void scan(int &a) { scanf("%d", &a); }
inline void scan(unsigned &a) { scanf("%u", &a); }
inline void scan(long &a) { scanf("%ld", &a); }
inline void scan(long long &a) { scanf("%lld", &a); }
inline void scan(unsigned long long &a) { scanf("%llu", &a); }
inline void scan(char &a) { cin >> a; }
inline void scan(float &a) { scanf("%f", &a); }
inline void scan(double &a) { scanf("%lf", &a); }
inline void scan(long double &a) { scanf("%Lf", &a); }
inline void scan(vector<bool> &vec) {
  for (unsigned i = 0; i < vec.size(); i++) {
    int a;
    scan(a);
    vec[i] = a;
  }
}
inline void scan(string &a) { cin >> a; }
template <class T>
inline void scan(vector<T> &vec);
template <class T, size_t size>
inline void scan(array<T, size> &vec);
template <class T, class L>
inline void scan(pair<T, L> &p);
template <class T, size_t size>
inline void scan(T (&vec)[size]);
template <class T>
inline void scan(vector<T> &vec) {
  for (auto &i : vec) scan(i);
}
template <class T, size_t size>
inline void scan(array<T, size> &vec) {
  for (auto &i : vec) scan(i);
}
template <class T, class L>
inline void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size>
inline void scan(T (&vec)[size]) {
  for (auto &i : vec) scan(i);
}
template <class T>
inline void scan(T &a) {
  cin >> a;
}
inline void in() {}
template <class Head, class... Tail>
inline void in(Head &head, Tail &...tail) {
  scan(head);
  in(tail...);
}
inline constexpr ll gcd(long long a, long long b) {
  return b ? gcd(b, a % b) : a;
}
inline constexpr ll lcm(ll a, ll b) {
  if (!a || !b) return 0;
  return a * b / gcd(a, b);
}
inline ll mod(ll val, ll m) {
  long long res = val % m;
  if (res < 0) res += m;
  return res;
}
inline int divisor_count(int n) {
  int j, c = 1;
  for (int i = 2; i * i <= n; i++, c *= j)
    for (j = 1; !(n % i); j++) n /= i;
  return (1 < n) ? c * 2 : c;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using Graph = vector<vector<int>>;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const long long INF = 1LL << 60;
const ll MOD = 1000000007;
vector<int> bfs(int s, Graph G) {
  int n = G.size();
  vector<int> dp(n, -1);
  queue<int> que;
  dp[s] = 0;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    for (int nv : G[v]) {
      if (dp[nv] != -1) continue;
      dp[nv] = dp[v] + 1;
      que.push(nv);
    }
  }
  return dp;
}
int main() {
  int n;
  in(n);
  ll cnt = 0;
  map<pair<ll, ll>, pair<int, int>> chk;
  ll pw[200200] = {1};
  for (int i = 1; i < 200200; ++i) {
    pw[i] = (pw[i - 1] * 2) % MOD;
  }
  while (n--) {
    ll a, b;
    in(a, b);
    if (a == 0 && b == 0) {
      cnt++;
    }
    if (make_pair(a, b) < make_pair(0LL, 0LL)) {
      a = -a;
      b = -b;
    }
    ll g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    if (b > 0) {
      chk[{a, b}].first++;
    } else {
      chk[{-b, a}].second++;
    }
  }
  ll r = 1LL;
  for (auto &p : chk) {
    r = r * (pw[p.second.first] + pw[p.second.second] - 1) % MOD;
  }
  cout << (cnt + r) % MOD << endl;
  return 0;
}
