#include <bits/stdc++.h>
using namespace std;

#define rep(i,x,y) for(ll i=(x);i<(y);i++)
#define rrep(i,x,y) for(ll i=(ll)(y)-1;i>=(x);i--)
#define all(x) (x).begin(),(x).end()
#ifdef LOCAL
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl
#define itrdebug(x) cerr << #x << " "; for (auto & el : (x)) {cerr << (el) << " ";} cerr << endl
#define dassert(...) assert(__VA_ARGS__)
#else
#define debug(x)
#define itrdebug(x)
#define dassert(...)
#endif
//#define int long long

typedef long long ll;
const ll MOD = 1e9 + 7;
const long double EPS = 1e-8;

namespace mod {
    long long pow(long long a, long long x, long long p) {
        long long res = 1;
        while(x > 0) {
            if( x % 2 != 0) {
                res = (res * a) % p;
            }
            a = (a * a) % p;
            x /= 2;
        }
        return res;
    }

    long long inverse(long long a, long long p) {
        //calculates the modular multiplicative of a mod m.
        //(assuming p is prime).
        return pow(a, p-2, p);
    }

    long long factorial(long long a, long long p) {
        long long fact = 1;
        for (long long i=2; i<=a; i++) {
            fact *= i;
            fact %= p;
        }
        return fact;
    }
}

long long getGcd(long long a, long long b) {
    if (a < b) swap(a, b);
    long long r = a % b;
    while(r!=0){
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}

vector<string> split(const string &s, char delim) {
    vector<string> elems;
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        if (!item.empty()) {
            elems.push_back(item);
        }
    }
    return elems;
}

void solve(long long N, std::vector<long long> A, std::vector<long long> B){
    ll cntOnlyAIsZero = 0, cntOnlyBIsZero = 0, cntAAndBIsZero = 0;
    unordered_map<string, ll> cntPlusAB, cntMinusAB, cntPlusBA, cntMinusBA;
    auto getKey = [](ll a, ll b) -> string {
        ll gcd = getGcd(abs(a), abs(b));
        a /= gcd; b /= gcd;
        string key = to_string(abs(a)) + "_" + to_string(abs(b));
        return move(key);
    };
    rep(i,0,N) {
        if (A[i] == 0 && B[i] == 0) cntAAndBIsZero++;
        else if (A[i] == 0) cntOnlyAIsZero++;
        else if (B[i] == 0) cntOnlyBIsZero++;
        if (A[i] == 0 || B[i] == 0) continue;

        if ((A[i] > 0) ^ (B[i] > 0)) {
            cntMinusAB[getKey(A[i], B[i])]++;
            cntMinusBA[getKey(B[i], A[i])]++;
        } else {
            cntPlusAB[getKey(A[i], B[i])]++;
            cntPlusBA[getKey(B[i], A[i])]++;
        }
    }
    ll answer = 1;
    for (const auto & p : cntPlusAB) {
        if (cntMinusBA.find(p.first) != cntMinusBA.end()) {
            ll cnt = 0;
            cnt += mod::pow(2, p.second, MOD);
            cnt += mod::pow(2, cntMinusBA[p.first], MOD);
            cnt %= MOD;
            cnt = cnt + MOD - 1;
            cnt %= MOD;
            answer *= cnt;
            answer %= MOD;
            auto elements = split(p.first, '_');
            cntPlusBA.erase(elements[1] + '_' + elements[0]);
            cntMinusBA.erase(p.first);
            cntMinusAB.erase(elements[1] + '_' + elements[0]);
        } else {
            answer *= mod::pow(2, p.second, MOD);
            answer %= MOD;
        }
    }
    for (const auto & p : cntMinusAB) {
        if (cntPlusBA.find(p.first) != cntPlusBA.end()) {
            ll cnt = 0;
            cnt += mod::pow(2, p.second, MOD);
            cnt += mod::pow(2, cntPlusBA[p.first], MOD);
            cnt %= MOD;
            cnt = cnt + MOD - 1;
            cnt %= MOD;
            answer *= cnt;
            answer %= MOD;
        } else {
            answer *= mod::pow(2, p.second, MOD);
            answer %= MOD;
        }
    }
    ll zeroCnt = 0;
    if (cntOnlyAIsZero > 0) zeroCnt += mod::pow(2, cntOnlyAIsZero, MOD);
    if (cntOnlyBIsZero > 0) zeroCnt += mod::pow(2, cntOnlyBIsZero, MOD);
    if (zeroCnt > 0) {
        if (cntOnlyAIsZero > 0 && cntOnlyBIsZero > 0) {
            zeroCnt = zeroCnt + MOD - 1;
            zeroCnt %= MOD;
        }
        zeroCnt %= MOD;
        answer *= zeroCnt;
        answer %= MOD;
    }
    answer += cntAAndBIsZero;
    answer %= MOD;
    answer = answer + MOD - 1;
    answer %= MOD;
    cout << answer << endl;
}

signed main(){
    // ios_base::sync_with_stdio(false);
    // cin.tie(NULL);
    long long N;
    scanf("%lld",&N);
    std::vector<long long> A(N);
    std::vector<long long> B(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&A[i]);
        scanf("%lld",&B[i]);
    }
    solve(N, std::move(A), std::move(B));
    return 0;
}


Measured memory_bytes: 69072