#include <bits/stdc++.h>

//#define DEBUG
using namespace std;

constexpr uint64_t MOD = 1000000007;

/*
using  std::cout;
using std::endl;

std::ifstream cin("E/input.txt");*/

template <class T>
void print_vect(std::vector<T> v){
    for(int i = 0 ; i < v .size(); i++) cout << v[i] << " ";
    cout << endl;
}
uint64_t gcd(uint64_t a , uint64_t b){
    if( a < b){
        return gcd(b, a);
    }else{
        if( b == 0){
            return a;
        }else{
            return gcd(b , a % b);
        }
    }
}

uint64_t pow(uint64_t a , uint64_t p, uint64_t mod){
    if( p < 2){
        uint64_t ans = 1;
        while(p--){
            ans = (ans * a) % mod;
        }
        return ans;
    }else{
        if( p % 2){
            uint64_t ans = pow(a, p / 2, mod);
            ans = (ans * ans) % mod;
            ans = (a * ans) % mod;
            return ans;
        }else{
            uint64_t ans = pow(a , p /2, mod);
            ans = (ans * ans) % mod;
            return ans;
        }
    }
}

void func_to_create(){
    uint32_t N ;
    cin >> N;
    uint32_t count_bad_sardine = 0;
    std::map<std::pair<int64_t,int64_t>, uint32_t> slope_up;
    std::map<std::pair<int64_t,int64_t>, uint32_t> slope_down;
    slope_up[{0, 1}] = 0;
    slope_down[{1, 0}] = 0;
    for(uint32_t i = 0 ; i < N ; i++){
        int64_t A, B;
        cin >> A >> B;
        if( A == 0 && B == 0){
            count_bad_sardine++;
        }else if(A == 0){
            slope_up[{0,1}] = slope_up[{0,1}] + 1;
        }else if( B == 0){
            slope_down[{1, 0}] =  slope_down[{1,0}] + 1;
        }else{
            // make sure A is bigger than 0
            if( A < 0){
                A = -A;
                B = -B;
            }
            if(B < 0){
                int64_t b = -B;
                int64_t commond_divisor = gcd(A, b);
                A = A / commond_divisor;
                B = B / commond_divisor;
                if(slope_down.find({A, B}) != slope_down.end()){
                    slope_down[{A, B}] = slope_down[{A, B}] + 1;
                }else{
                    slope_down[{A,B}] = 1;
                    slope_up[{-B, A}] = 0;
                }
            }else{
                int64_t b = B;
                int64_t commond_divisor = gcd(A, b);
                A = A / commond_divisor;
                B = B / commond_divisor;
                if(slope_up.find({A, B}) != slope_up.end()){
                    slope_up[{A, B}] = slope_up[{A, B}] + 1;
                }else{
                    slope_up[{A,B}] = 1;
                    slope_down[{B, -A}] = 0;
                }
            }
            
        }
    }
    uint64_t count = 1;
    for(auto it = slope_up.begin(); it != slope_up.end(); it++){
        auto A = (it -> first ).first;
        auto B = (it -> first).second;
        auto down_slope = slope_down[{B, -A}];
        uint64_t additional_choice = pow(2, it->second, MOD) + pow(2, down_slope, MOD) - 1;
        count = (count * additional_choice) % MOD;
    }
    cout << (count + count_bad_sardine - 1 + MOD) % MOD << endl;
}
int main()
{
    //making data IO Fast
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);
    /****************************/

    #ifdef DEBUG
    int TEST_CASES = 2;
    while(TEST_CASES--){
    #endif // DEBBUG

    func_to_create();

    #ifdef DEBUG
    }
    #endif // DEBUG
    
    return 0;
}


Measured memory_bytes: 28592