#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <array>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstdint>
#include <unordered_set>
#include <ctime>
#include <numeric>
#include <cstdint>

typedef long long int llint;
static const double PI = 3.14159265358979323846;

#include <cstdint>

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
	*this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

template <std::uint_fast64_t Modulus>
modint<Modulus> pow(modint<Modulus> a,modint<Modulus> n){
  modint<Modulus> ret=1;
  for(;n.a>0;n.a>>=1,a=a*a){
    if(n.a%2==1)ret=ret*a;
  }
  return ret;
}

int main(void){


  int n;
  std::cin >> n;

  std::map<std::array<llint, 2>, modint<1000000007>> pos, neg;
  int zero_cnt = 0;

  for(int i=0; i<n; i++){
    llint a, b;
    std::cin >> a >> b;
    if(a==0 || b==0){
      zero_cnt++;
      continue;
    }
    bool is_pos = (a<0) ^ !(b<0);
    a = std::abs(a);
    b = std::abs(b);
    if(a > b) std::swap(a, b);
    if(is_pos){
      auto& sth = pos;
      if(sth.find({a,b}) == sth.end()) sth[{a,b}] = 0;
      sth[{a,b}] = sth[{a,b}]+1;
    }else{
      auto& sth = neg;
      if(sth.find({a,b}) == sth.end()) sth[{a,b}] = 0;
      sth[{a,b}] = sth[{a,b}]+1;
    }
  }

  modint<1000000007> ret = zero_cnt+1;
  const modint<1000000007> TWO = 2;
  for(const auto& elem: pos){
    //std::cout << ret.a << std::endl;
    //std::cout << elem.first[0] << " " << elem.first[1] << std::endl;
    
    if(neg.find(elem.first) == neg.end()){
      ret *= pow(TWO, elem.second);
      continue;
    }

    modint<1000000007> temp = pow(TWO, elem.second-1);
    //std::cout << "tmp" << temp.a << std::endl;
    temp += pow(TWO, neg[elem.first]-1);
    temp += 1;
    //std::cout << temp.a << std::endl;
    neg.erase(elem.first);
    ret *= temp;
  }
  for(const auto& elem: neg){
    //std::cout << ret.a << std::endl;
    //std::cout << elem.first[0] << " " << elem.first[1] << std::endl;
    ret *= pow(TWO, elem.second);
  }

  std::cout << ret.a-1 << std::endl;
  
  return 0;
}
