#include <bits/stdc++.h>
template <typename T>
using MaxHeap = std::priority_queue<T>;
template <typename T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
void vdeb(std::vector<T> &da) {
  for (int i = 0; i < da.size(); i++) {
    if (i == da.size() - 1)
      std::cout << da[i];
    else
      std::cout << da[i] << ' ';
  }
  std::cout << std::endl;
}
template <typename T>
void vdeb(std::vector<std::vector<T>> &da) {
  for (int i = 0; i < da.size(); i++) {
    std::cout << i << ' ';
    vdeb(da[i]);
  }
  std::cout << std::endl;
}
using namespace std;
struct rational_num {
  long long numera, denomin;
  bool is_inf;
  rational_num(bool infify = false) : is_inf(infify) {
    numera = infify;
    denomin = 1 - numera;
  }
  rational_num(long long n) : numera(n) { denomin = 1, is_inf = false; }
  rational_num(long long n, long long d) : numera(n), denomin(d) {
    assert(n != 0 || d != 0);
    is_inf = denomin == 0;
    about();
  }
  rational_num recipro() const {
    if (is_inf)
      return rational_num(false);
    else if (numera == 0)
      return rational_num(true);
    else
      return rational_num(denomin, numera);
  }

 private:
  void about() {
    if (is_inf) {
      denomin = 0, numera = 1;
      return;
    }
    long long a = abs(denomin), b = abs(numera);
    if (a < b) swap(a, b);
    if (b == 0) {
      denomin /= a, numera /= a;
      return;
    }
    while (a % b > 0) {
      long long tmp = a % b;
      a = b, b = tmp;
    }
    if (denomin < 0) denomin *= -1, numera *= -1;
    denomin /= b, numera /= b;
    return;
  }
};
bool operator>(const rational_num &left, const rational_num &right) {
  if (left.is_inf && right.is_inf) return false;
  if (left.is_inf) return true;
  if (right.is_inf) return false;
  return __int128_t(left.numera * right.denomin) >
         __int128_t(left.denomin * right.numera);
}
bool operator<(const rational_num &left, const rational_num &right) {
  return right > left;
}
bool operator>=(const rational_num &left, const rational_num &right) {
  return !(right > left);
}
bool operator<=(const rational_num &left, const rational_num &right) {
  return !(left > right);
}
std::ostream &operator<<(std::ostream &os, const rational_num &x) {
  std::cout << x.numera << '/' << x.denomin;
  return os;
}
long long pow(long long n, long long k, long long p) {
  long long tmp = n, ret = 1;
  while (k) {
    if (k & 1) ret = ret * tmp % p;
    tmp = tmp * tmp % p;
    k >>= 1;
  }
  return ret;
}
void euclid(long long &a, long long &b, long long p) {
  if (a == 1) {
    a = 1;
  } else {
    long long A = b, B = a % b;
    euclid(A, B, p);
    b = (A - (p + a / b) % p * B % p + p) % p;
    a = B;
  }
}
long long rev(long long n, long long p) { return pow(n, p, p - 2); }
long long bino(long long n, long long m, long long p) {
  long long ans = 1, div = 1;
  for (int i = 0; i < m; i++) {
    ans = (n - i) * ans % p;
    div = div * (i + 1) % p;
  }
  return ans * rev(div, p) % p;
}
struct modint {
  long long num;
  long long p;
  modint() {
    num = 0;
    p = 1000000007;
  }
  modint(long long x) {
    p = 1000000007;
    num = x % p;
  }
  modint inv() const { return rev(num, p); }
  modint operator-() const { return modint(p - num); }
  modint &operator+=(const modint &other) {
    num = (num + other.num) % p;
    return *this;
  }
  modint &operator-=(const modint &other) {
    num = (num - other.num + p) % p;
    return *this;
  }
  modint &operator*=(const modint &other) {
    num = (num * other.num) % p;
    return *this;
  }
  modint &operator/=(const modint &other) {
    (*this) *= other.inv();
    return *this;
  }
  modint &operator+=(const long long &other) {
    num = (num + other) % p;
    return *this;
  }
  modint &operator-=(const long long &other) {
    num = (num - other + p) % p;
    return *this;
  }
  modint &operator*=(const long long &other) {
    num = (num * other) % p;
    return *this;
  }
  modint &operator/=(const long long &other) {
    (*this) *= rev(other, p);
    return *this;
  }
  modint &operator++() { return *this += 1; }
  modint &operator--() { return *this -= 1; }
  modint &operator=(const long long &other) { return (*this) = modint(other); }
  modint operator+(const modint &other) const { return modint(*this) += other; }
  modint operator-(const modint &other) const { return modint(*this) -= other; }
  modint operator*(const modint &other) const { return modint(*this) *= other; }
  modint operator/(const modint &other) const { return modint(*this) /= other; }
  modint operator+(const long long &other) const {
    return modint(*this) += other;
  }
  modint operator-(const long long &other) const {
    return modint(*this) -= other;
  }
  modint operator*(const long long &other) const {
    return modint(*this) *= other;
  }
  modint operator/(const long long &other) const {
    return modint(*this) /= other;
  }
  bool operator==(const modint &other) const { return num == other.num; }
};
std::istream &operator>>(std::istream &is, const modint x) {
  std::cin >> x.num;
  return is;
}
std::ostream &operator<<(std::ostream &os, const modint &x) {
  std::cout << x.num;
  return os;
}
using namespace std;
const rational_num ba(false);
int main() {
  int n;
  cin >> n;
  vector<rational_num> da(0);
  modint co(-1), ans(1);
  for (int i = (0); i < (int)(n); i++) {
    int a, b;
    cin >> a >> b;
    if (a == 0 && b == 0)
      co += 1;
    else
      da.push_back(rational_num(a, b));
  }
  map<rational_num, std::pair<int, int>> mp;
  for (int i = (0); i < (int)(n); i++) {
    rational_num now;
    if (da[i].numera <= 0) {
      da[i].numera *= -1;
      now = da[i].recipro();
      if (mp.count(now)) {
        mp[now].second += 1;
      } else {
        mp[now].second = 1;
      }
    } else {
      now = da[i];
      if (mp.count(da[i])) {
        mp[da[i]].first += 1;
      } else {
        mp[da[i]].first = 1;
      }
    }
  }
  for (auto i : mp) {
    ans *= modint(pow(2, i.second.first, ans.p) +
                  pow(2, i.second.second, ans.p) - 1 + ans.p);
  }
  ans += co;
  cout << ans << endl;
}
