/**
 *    author:  wxhtzdy
 *    created: 18.12.2022 10:12:26
**/
#include <bits/stdc++.h>

using namespace std;

const int md = 1e9 + 7;

const int N = 200005;

int pw[N];

struct point {
  long long x, y;
  long long CrossProd(const point &p) const {
    return x * (long long) p.y - y * (long long) p.x;
  }
  bool operator<(const point &p) const {
    return make_pair(x, y) < make_pair(p.x, p.y);
  }
};

int orientation(point a, point b, point c) {
  long long x = (b.y - a.y) * 1LL * (c.x - b.x);
  long long y = (b.x - a.x) * 1LL * (c.y - b.y);
  if (x == y) return 0;
  return (x > y) ? 1 : 2;
} 

int quad(point p) {
  if (p.x >= 0 && p.y >= 0) return 1;
  if (p.x <= 0 && p.y >= 0) return 2;
  if (p.x <= 0 && p.y <= 0) return 3;
  return 4;
}

bool is_less(point a, point b)
{
  int quad_a = quad(a);
  int quad_b = quad(b);
  if (quad_a != quad_b)
    return quad_a > quad_b;
  if (a.x >= 0 && b.x < 0)
      return true;
  if (a.x < 0 && b.x >= 0)
      return false;
  if (a.x == 0 && b.x == 0) {
      if (a.y >= 0 || b.y >= 0)
          return a.y > b.y;
      return b.y > a.y;
  }

    // compute the cross product of vectors (center -> a) x (center -> b)
    long long det = a.x * 1LL * b.y - b.x * 1LL * a.y;
    if (det < 0)
        return true;
    if (det > 0)
        return false;

    // points a and b are on the same line from the center
    // check which point is closer to the center
    long long d1 = a.x * 1LL * a.x + a.y * 1LL * a.y;
    long long d2 = b.x * 1LL * b.x + b.y * 1LL * b.y;
    return d1 > d2;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);  
  int n;
  cin >> n;
  vector<point> p(n);
  for (int i = 0; i < n; i++) {
    cin >> p[i].x >> p[i].y;  
    //if (p[i].x < -1e9 || p[i].x > 1e9) {
      //cout << p[i].x << '\n';
    //}
    assert(p[i].x >= -1e9 && p[i].x <= 1e9);
    assert(p[i].y >= -1e9 && p[i].y <= 1e9);
    assert(p[i].x != 0 || p[i].y != 0);
  }
  pw[0] = 1;
  for (int i = 1; i <= 2 * n; i++) {
    pw[i] = (pw[i - 1] + pw[i - 1]) % md;
  }
  sort(p.begin(), p.end(), [&](point a, point b) {
    return is_less(a, b);
  });
  for (int i = 0; i < n; i++) {
    //cout << p[i].x << " " << p[i].y << '\n';
  }
  reverse(p.begin(), p.end());
  for (int i = 0; i < n; i++) {
    p.push_back(p[i]);
  }
  n = (int) p.size();
  int ptr = 0;
  int ans = 0;
  point pt;
  pt.x = pt.y = 0;
  for (int i = 0; i < n / 2; i++) {
    ptr = max(ptr, i);
    while (ptr + 1 - i < n / 2 && (orientation(p[i], pt, p[ptr + 1]) == 1 || (ptr + 1 < n / 2 && orientation(p[i], pt, p[ptr + 1]) == 0 && quad(p[i]) == quad(p[ptr + 1])))) {
      ptr += 1;
    }      
    //cout << i + 1 << " " << ptr + 1 << '\n';
    ans = (ans + pw[ptr - i]) % md;
  }
  /* ptr = n - 1;
  for (int i = n - 1; i >= 0; i--) {
    while (ptr > i && orientation(p[i], pt, p[ptr]) == 2) {
      ptr -= 1;
    }
    //cout << i + 1 << " " << ptr + 1 << '\n';
    ans = (ans + pw[n - ptr - 1] - 1) % md;
  } */  
  int res = (pw[n / 2] - ans - 1) % md;
  res = (res + md) % md;
  res = (res + md) % md;
  cout << res << '\n';                                                       
  return 0;
}