#include <bits/stdc++.h>
using namespace std;
inline long long madd(long long a, long long b) {
  a %= 1000000007;
  b %= 1000000007;
  return (a + b) % 1000000007;
}
inline long long msub(long long a, long long b) {
  a %= 1000000007;
  b %= 1000000007;
  a += 1000000007;
  return (a - b) % 1000000007;
}
inline long long mmul(long long a, long long b) {
  a %= 1000000007;
  b %= 1000000007;
  return (a * b) % 1000000007;
}
inline long long mpow(long long a, long long r) {
  long long res = 1;
  while (r > 0) {
    if (r & 1) res = res * a % 1000000007;
    a = a * a % 1000000007;
    r >>= 1;
  }
  return res;
}
inline long long minv(long long a) {
  a %= 1000000007;
  long long b = 1000000007, u = 0, v = 1;
  while (a) {
    long long t = b / a;
    b -= t * a;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  if (u < 0) u += 1000000007;
  return u;
}
inline long long mdiv(long long a, long long b) {
  a %= 1000000007;
  a *= minv(b);
  return a % 1000000007;
}
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
int main() {
  vector<pair<long long, long long>> v;
  map<long double, int> mp;
  map<int, int> cnt;
  int n;
  long long a, b;
  long long res = 1;
  long double tan_;
  cin >> n;
  for (long long i = (0); i < (n); ++i) {
    cin >> a >> b;
    if (a < 0) {
      a *= -1;
      b *= -1;
    }
    v.push_back(pair<long long, long long>(a, b));
    tan_ = atan2((long double)a, (long double)b);
    auto it = mp.find(tan_);
    if (it != mp.end())
      cnt[it->second]++;
    else {
      mp[tan_] = i;
      cnt[i] = 1;
    }
  }
  while (mp.size() > 0) {
    auto it = mp.begin();
    a = -v[it->second].second;
    b = v[it->second].first;
    tan_ = atan2((long double)a, (long double)b);
    auto it2 = mp.find(tan_);
    if (it2 != mp.end()) {
      long long nn = cnt[it->second];
      long long mm = cnt[it2->second];
      res = mmul(res, madd(mpow(2, nn), mpow(2, mm) - 1));
      mp.erase(it);
      mp.erase(it2);
      continue;
    }
    tan_ = atan2((long double)-a, (long double)-b);
    it2 = mp.find(tan_);
    if (it2 != mp.end()) {
      long long nn = cnt[it->second];
      long long mm = cnt[it2->second];
      res = mmul(res, madd(mpow(2, nn), mpow(2, mm) - 1));
      mp.erase(it);
      mp.erase(it2);
      continue;
    }
    long long nn = cnt[it->second];
    res = mmul(res, mpow(2, nn));
    mp.erase(it);
  }
  cout << msub(res, 1);
  return 0;
}
