#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const long double inf = 1e9 + 10;
const long double INF = 1e18;
const long double EPS = 1e-10;
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct Point {
  long double x, y;
  Point(long double x = 0, long double y = 0) : x(x), y(y) {}
  Point operator+(Point &p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point &p) { return Point(x - p.x, y - p.y); }
  Point operator*(long double k) { return Point(x * k, y * k); }
  Point operator/(long double k) { return Point(x / k, y / k); }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};
long double norm(Point p) { return p.x * p.x + p.y * p.y; }
long double dist(Point p) { return sqrt(norm(p)); }
long double dot(Point p1, Point p2) { return p1.x * p2.x + p1.y * p2.y; }
long double cross(Point p1, Point p2) { return p1.x * p2.y - p1.y * p2.x; }
Point rotate(Point p, long double theta) {
  return Point(p.x * cos(theta) - p.y * sin(theta),
               p.x * sin(theta) + p.y * cos(theta));
}
bool cmp(Point p1, Point p2) { return cross(p1, p2) > 0; }
long long pow2[200300];
void init() {
  pow2[0] = 1;
  for (int i = 0; i < (200200); ++i) {
    pow2[i + 1] = pow2[i] * 2 % mod;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(50);
  init();
  long long n;
  cin >> n;
  vector<Point> p[2];
  long long ans = 0;
  for (int i = 0; i < (n); ++i) {
    Point a;
    cin >> a.x >> a.y;
    if (a.x == 0 && a.y == 0) {
      ans++;
      continue;
    } else if (a.x > 0 && a.y >= 0)
      p[0].push_back(a);
    else if (a.x <= 0 && a.y > 0) {
      a.x *= -1;
      swap(a.x, a.y);
      p[1].push_back(a);
    } else if (a.x < 0 && a.y <= 0) {
      a.x *= -1;
      a.y *= -1;
      p[0].push_back(a);
    } else if (a.x >= 0 && a.y < 0) {
      a.y *= -1;
      swap(a.x, a.y);
      p[1].push_back(a);
    }
  }
  for (int i = 0; i < (2); ++i) sort(p[i].begin(), p[i].end(), cmp);
  vector<long long> siz(2, 0);
  for (int i = 0; i < (2); ++i) siz[i] = p[i].size();
  vector<long long> idx(2, 0);
  long long res = 1;
  vector<long long> cnt(2, 1);
  while (idx[0] < siz[0] && idx[1] < siz[1]) {
    for (int i = 0; i < (2); ++i) {
      while (idx[i] + 1 < siz[i] &&
             (fabs((cross(p[i][idx[i]], p[i][idx[i] + 1])) - ((long double)0)) <
              EPS)) {
        cnt[i]++;
        idx[i]++;
      }
    }
    if ((fabs((cross(p[0][idx[0]], p[1][idx[1]])) - ((long double)0)) < EPS)) {
      res = (pow2[cnt[0]] + pow2[cnt[1]] - 1 + mod) % mod * res % mod;
      idx[0]++, idx[1]++;
      cnt[0] = 1, cnt[1] = 1;
    } else if (cross(p[0][idx[0]], p[1][idx[1]]) > 0) {
      res = res * pow2[cnt[0]] % mod;
      idx[0]++;
      cnt[0] = 1;
    } else {
      res = res * pow2[cnt[1]] % mod;
      idx[1]++;
      cnt[1] = 1;
    }
  }
  for (int i = 0; i < (2); ++i) {
    res = res * pow2[siz[i] - idx[i]] % mod;
  }
  ans = (ans + res - 1 + mod) % mod;
  cout << ans << '\n';
  return 0;
}
