#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>

struct vec {
  long long x, y;

  vec(long long _x, long long _y): x(_x), y(_y) {
  }

  __int128 dot(const vec &o) {
    return (__int128)x * (__int128)o.x + (__int128)y * (__int128)o.y;
  }

  __int128 cross(const vec &o) {
    return (__int128)x * (__int128)o.y - (__int128)y * (__int128)o.x;
  }

  bool operator < (const vec &o) {
    return (*this).cross(o) < (__int128)0;
  }
};

const int mod = 1000000007;
const int maxN = 100000;
int f[maxN + 1];

int mul(int a, int b) {
  return (int)((((long long)a * (long long)b) % (long long)mod + mod) % mod);
}

int add(int a, int b) {
  return (int)((((long long)a + (long long)b) % (long long)mod + mod) % mod);
}

int get(int a, int b) {
  return add(add(f[a], f[b]), mod - 1);
}

int main() {
  f[0] = 1;
  for (int i = 0; i < maxN; ++i) {
    f[i + 1] = add(f[i], f[i]);
  }
  int n;
  std::cin >> n;
  std::vector <vec> a;
  int s = 0;
  for (int i = 0; i < n; ++i) {
    long long x, y;
    std::cin >> x >> y;
    if (x == 0 && y == 0) {
      s += 1;
      continue;
    }
    if (x < 0) {
      x = -x;
      y = -y;
    }
    a.push_back(vec(x, y));
  }
  n = (int)a.size();
  int ans = f[s];
  std::sort(a.begin(), a.end());
  std::vector <bool> u(n, false);
  int cur = 0, next = 0;
  while (cur < n) {
    if (u[cur]) {
      ++cur;
      continue;
    }
    int i = cur;
    while (i < n && a[cur].cross(a[i]) == (__int128)0) {
      assert(!u[i]);
      u[i] = true;
      ++i;
    }
    int s1 = (i - cur);

    while (next < n && a[cur].dot(a[next]) > (__int128)0) {
      ++next;
    }
    int j = next;
    while (j < n && a[cur].dot(a[j]) == (__int128)0) {
      assert(!u[j]);
      u[j] = true;
      ++j;
    }
    int s2 = j - next;

    ans = mul(ans, get(s1, s2));
  }
  ans = add(ans, mod - 1);
  std::cout << ans << std::endl;
  return 0;
}
