#include <cstdio>
#include <vector>
#include <algorithm>
#include <tuple>
#include <cassert>

using u128 = __uint128_t;
using u64 = unsigned long long int;
using s64 = long long int;
using u32 = unsigned int;

constexpr u32 mod = 1000000007;

int n;

u32 pow2[200001];

/*
u64 bgcd(u64 x, u64 y){
  if(x == 0 || y == 0) return x^y;
  int bx = __builtin_ctzll(x);
  int by = __builtin_ctzll(y);
  int k = (bx < by) ? bx : by;
  x >>= bx;
  y >>= by;
  while(x!=y){
    if(x < y){
      y -= x;
      y >>= __builtin_ctzll(y);
    }
    else {
      x -= y;
      x >>= __builtin_ctzll(x);
    }
  }
  return x << k;
}

void reduce(u64 *a, u64 *b){
  u64 g = bgcd(*a, *b);
  *a /= g;
  *b /= g;
}


u64 hash(u64 a, u64 b){
  static constexpr u64 p = (1ULL<<61) - 1;
  static constexpr u64 base = 1445861656621423872;
  static constexpr u32 basel = base & ((1U << 31) - 1);
  static constexpr u32 baseu = base >> 31;

  u32 al = a & ((1U << 31) - 1);
  u32 au = a >> 31;

  u64 w = al * baseu + au * basel;
  u32 wl = w & ((1U << 31) - 1);
  u32 wu = w >> 31;
  u64 z = al * basel + (wl << 31) + ((wu + (au * baseu)) << 1);

  return (z + b) % p;
}
*/

// a / b mod p
u64 hash(u64 a, u64 b){
  static constexpr u64 p = 8698439096297785061ULL;
  s64 s, t, u, v;
  s = v = 1;
  u = t = 0;
  u64 x = p;
  u64 y = b;
  
  while(y){
    u64 q = x / y;
    u64 r = x % y;
    std::tie(s, t, u, v) = std::forward_as_tuple(u, v, s - q*u, t - q*v);
    x = y;
    y = r;
  }
  while(t < 0) t += p;
/*
printf("%lld %lld %llu\n", t, p, (u64) ((u128) t * b % p));
fflush(stdout);
assert((u64) ((u128) t * b % p) == 1);
*/
  return (u128) t * a % p;
}

/*
u64 hash(u64 a, u64 b){
  u64 s, t, u, v;
  s = v = 1;
  u = t = 0;
  u64 x = 1;
  
  while(a){
    u64 q = b / a;
    u64 r = b % a;
    std::tie(s, t, u, v) = std::forward_as_tuple(u, v, s + q*u, t + q*v);
    b = a;
    a = r;
    x *= q;
  }
  return x;
}
*/

int main(){

  scanf("%d", &n);
  pow2[0] = 1;
  for(int i = 1; i <= n; i++){
    pow2[i] = 2 * pow2[i-1];
    if(pow2[i] >= mod) pow2[i] -= mod;
  }

//  using quot = std::pair<u64, u64>;
  using quot = u64;
  std::vector<quot> vp, vn;
  u32 zeroa = 0;
  u32 zerob = 0;
  u32 zero2 = 0;

  for(int i = 0; i < n; i++){
    s64 a, b;
    scanf("%lld%lld", &a, &b);
    if(a == 0 && b == 0) zero2++;
    else if(a == 0) zeroa++;
    else if(b == 0) zerob++;
    else if((a^b) >= 0){
      u64 ua = std::abs(a);
      u64 ub = std::abs(b);
//      reduce(&ua, &ub);
//      vp.emplace_back(ua, ub);
      vp.push_back(hash(ua, ub));
    }
    else {
      u64 ua = std::abs(a);
      u64 ub = std::abs(b);
//      reduce(&ua, &ub);
//      vn.emplace_back(ub, ua);
      vn.push_back(hash(ub, ua));
    }
  }

  std::sort(vp.begin(), vp.end());
  std::sort(vn.begin(), vn.end());

  std::vector<std::pair<quot, u32> > vpp, vnn;
//  quot prev = {0, 0};
  quot prev = -1;
  for(auto const &x: vp){
    if(x == prev) vpp.back().second++;
    else{
      vpp.emplace_back(x, 1);
      prev = x;
    }
  }
//  prev = {0, 0};
  prev = -1;
  for(auto const &x: vn){
    if(x == prev) vnn.back().second++;
    else{
      vnn.emplace_back(x, 1);
      prev = x;
    }
  }

  u64 ans = (pow2[zeroa] + pow2[zerob] + mod - 1) % mod;
  auto ip = vpp.begin(), in = vnn.begin();
  while(ip != vpp.end() && in != vnn.end()){
    if(ip->first == in->first){
      ans = ans * (pow2[ip->second] + pow2[in->second] + mod - 1) % mod;
      ++ip, ++in;
    }
    else if(ip->first < in->first){
      ans = ans * pow2[ip->second] % mod;
      ++ip;
    }
    else {
      ans = ans * pow2[in->second] % mod;
      ++in;
    }
  }
  while(in != vnn.end()){ ans = ans * pow2[in->second] % mod; ++in; }
  while(ip != vpp.end()){ ans = ans * pow2[ip->second] % mod; ++ip; }

  ans = (ans + zero2 + mod - 1) % mod;
  printf("%llu\n", ans);

  return 0;
}


Measured memory_bytes: 9720