#include <bits/stdc++.h>
using namespace std;
mt19937_64 rng(58);
template <class T>
T gcd(T a, T b) {
  return b ? gcd(b, a % b) : a;
}
pair<long long, long long> normalize(pair<long long, long long> v) {
  if (v.first == 0) {
    return {0, v.second > 0 ? 1 : -1};
  } else if (v.second == 0) {
    return {v.first > 0 ? 1 : -1, 0};
  } else {
    long long g = gcd(abs(v.first), abs(v.second));
    if (v.first < 0) {
      v = {-v.first, -v.second};
    }
    return {v.first / g, v.second / g};
  }
}
template <typename T>
T inverse(T a, T m) {
  T u = 0, v = 1;
  while (a != 0) {
    T t = m / a;
    m -= t * a;
    swap(a, m);
    u -= t * v;
    swap(u, v);
  }
  assert(m == 1);
  return u;
}
template <long long mod = 1000000007>
struct modint {
  long long a;
  modint() : a(0) {}
  modint(long long t) {
    a = t % mod;
    if (a < 0) a += mod;
  }
  operator long long() const { return a; }
  bool operator==(const modint &x) const { return a == x.a; }
  bool operator!=(const modint &x) const { return a != x.a; }
  modint operator-() const { return modint(a ? (mod - a) : 0); }
  modint operator~() const { return inverse(a, mod); }
  modint operator+(const modint &x) const { return modint(*this) += x; }
  modint operator-(const modint &x) const { return modint(*this) -= x; }
  modint operator*(const modint &x) const { return modint(*this) *= x; }
  modint operator/(const modint &x) const { return modint(*this) /= x; }
  modint &operator+=(const modint &x) {
    a += x.a;
    if (a >= mod) a -= mod;
    return *this;
  }
  modint &operator-=(const modint &x) {
    a -= x.a;
    if (a < 0) a += mod;
    return *this;
  }
  modint &operator*=(const modint &x) {
    a = a * x.a % mod;
    return *this;
  }
  modint &operator/=(const modint &x) {
    a = a * (~x).a % mod;
    return *this;
  }
  friend ostream &operator<<(ostream &os, const modint &x) { return os << x.a; }
  friend istream &operator>>(istream &is, modint &x) {
    long long t;
    is >> t;
    x = modint(t);
    return is;
  }
  modint pow(long long x) const {
    modint ret = 1, tmp = a;
    for (; x; tmp *= tmp, x >>= 1) {
      if (x & 1) ret *= tmp;
    }
    return ret;
  }
};
string to_string(string s) { return '"' + s + '"'; }
string to_string(const char *s) { return to_string((string)s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "";
  for (const auto &x : v) {
    if (!first) res += ", ";
    first = false;
    res += to_string(x);
  }
  return "{" + res + "}";
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n;
  cin >> n;
  map<pair<long long, long long>, int> count;
  long long valid = 0;
  for (int i = 0; i < n; i++) {
    long long a, b;
    cin >> a >> b;
    pair<long long, long long> nv = normalize({a, b});
    if (nv != make_pair(0ll, 0ll)) {
      count[nv]++;
      valid++;
    }
  }
  modint<> ans = 1;
  modint<> two = 2;
  for (auto s : count) {
    pair<long long, long long> v = s.first;
    long long vc = s.second;
    pair<long long, long long> u = normalize({v.second, -v.first});
    42;
    if (count.find(u) != count.end()) {
      if (u < v) {
        long long uc = count[u];
        ans *= (two.pow(vc) + two.pow(uc) - modint<>(1));
      }
    } else {
      ans *= two.pow(vc);
    }
  }
  ans -= 1;
  cout << ans << endl;
}
