#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define FORR(i, m, n) for (int i = (m); i >= (n); --i)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 ld;
const ll mod = 1000000007;
//const ll mod = 998244353;
const ld inf = 1e9 + 10;
const ld INF = 1e18;
const ld 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 {
  ld x, y;

  Point(ld x = 0, ld 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 * (ld k) {
    return Point(x * k, y * k);
  }

  Point operator / (ld 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;
  }
};

ld norm(Point p) {
  return p.x * p.x + p.y * p.y;
}

ld dist(Point p) {
  return sqrt(norm(p));
}

ld dot(Point p1, Point p2) {
  return p1.x * p2.x + p1.y * p2.y;
}

ld cross(Point p1, Point p2) {
  return p1.x * p2.y - p1.y * p2.x;
}

Point rotate(Point p, ld 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;
}

ll pow2[200300];

void init() {
  pow2[0] = 1;
  rep(i, 200200) {
    pow2[i + 1] = pow2[i] * 2 % mod;
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(50);

  init();

  ll n;
  cin >> n;
  vector<Point> p[2];
  ll ans = 0;
  rep(i, n) {
    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);
    }
  }
  rep(i, 2) sort(p[i].begin(), p[i].end(), cmp);
  vector<ll> siz(2, 0);
  rep(i, 2) siz[i] = p[i].size();
  vector<ll> idx(2, 0);
  ll res = 1;
  vector<ll> cnt(2, 1);
  while (idx[0] < siz[0] && idx[1] < siz[1]) {
    rep(i, 2) {
      while (idx[i] + 1 < siz[i] && equals(cross(p[i][idx[i]], p[i][idx[i] + 1]), (ld)0)) {
        cnt[i]++;
        idx[i]++;
      }
    }
    if (equals(cross(p[0][idx[0]], p[1][idx[1]]), (ld)0)) {
      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;
    }
  }
  rep(i, 2) {
    res = res * pow2[siz[i] - idx[i]] % mod;
  }
  ans = (ans + res - 1 + mod * mod) % mod;
  cout << ans << '\n';







  
  return 0;
}