#include <bits/stdc++.h>
using namespace std;
template <typename T>
using v1 = vector<T>;
template <typename T>
using v2 = vector<vector<T>>;
template <typename T>
using v3 = vector<vector<vector<T>>>;
template <class T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v) is >> elemnt;
  return is;
}
template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
const int MOD = 1e9 + 7;
const int INF = numeric_limits<int>::max() - (int)1e8;
const long long INFLL = numeric_limits<long long>::max() - (long long)1e17;
template <int64_t mod>
struct ModInt {
  int64_t value;
  ModInt() : value(0) {}
  ModInt(int64_t x) : value(x >= 0 ? x % mod : (mod - ((-x) % mod) % mod)) {}
  ModInt &operator+=(const ModInt &input) {
    value += input.value;
    if (value >= mod) value -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &input) {
    value += (mod - input.value);
    if (value >= mod) value -= mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &input) {
    value = value * input.value % mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &input) {
    *this *= input.inverse();
    return *this;
  }
  ModInt inverse() const {
    int64_t base = value, p = mod;
    pair<int64_t, int64_t> save = {1, 0};
    while (p) {
      int64_t temp = base / p;
      swap(base -= temp * p, p);
      swap(save.first -= temp * save.second, save.second);
    }
    return ModInt(save.first);
  }
  ModInt operator-() const { return ModInt(-value); }
  ModInt operator-(const ModInt &input) const { return ModInt(*this) -= input; }
  ModInt operator+(const ModInt &input) const { return ModInt(*this) += input; }
  ModInt operator*(const ModInt &input) const { return ModInt(*this) *= input; }
  ModInt operator/(const ModInt &input) const { return ModInt(*this) /= input; }
  bool operator==(const ModInt &comparsion) const {
    return value == comparsion.value;
  }
  bool operator!=(const ModInt &comparsion) const {
    return value != comparsion.value;
  }
  friend istream &operator>>(istream &stream, ModInt &input) {
    int64_t temp;
    stream >> temp;
    input = ModInt<mod>(temp);
    return stream;
  }
  friend ostream &operator<<(ostream &stream, const ModInt &input) {
    return stream << input.value;
  }
  ModInt pow(int64_t n) const {
    ModInt ret(1), x(value);
    while (n > 0) {
      if (n and 1) ret *= x;
      x *= x;
      n >>= 1;
    }
    return ret;
  }
  static const int64_t get_mod() { return mod; }
};
using modint = ModInt<MOD>;
int main() {
  int N;
  cin >> N;
  vector<pair<double, double>> input(N);
  map<double, vector<int>> explore;
  for (int i = 0; i < N; i++) {
    cin >> input[i].first >> input[i].second;
    double temp = 0;
    if (input[i].second != 0) temp = input[i].first / input[i].second;
    explore[temp].push_back(i);
  }
  modint ans = 2;
  ans = ans.pow(N) - 1;
  vector<bool> check(N, false);
  int count = N;
  for (int i = 0; i < N; i++) {
    double temp = 0;
    if (input[i].first != 0) temp = input[i].second / input[i].first;
    auto &ref = explore[temp];
    if (ref.empty()) continue;
    if (ref[0] == -1) {
      if (check[i]) continue;
      count--;
      check[i] = true;
      ans -= modint(2).pow(count);
    } else {
      if (!check[i]) count--;
      check[i] = true;
      for (auto now : ref) {
        if (!check[now]) count--;
        check[now] = true;
        ans -= modint(2).pow(count);
      }
      ref = {-1};
    }
  }
  cout << ans << endl;
}
