#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
template <class S, class T>
ostream& operator<<(ostream& out, const pair<S, T>& o) {
    out << "(" << o.first << "," << o.second << ")";
    return out;
}
template <class T>
ostream& operator<<(ostream& out, const vector<T>& V) {
    for (int i = 0; i < V.size(); i++) {
        out << V[i];
        if (i != V.size() - 1) out << " ";
    }
    return out;
}
template <class T>
ostream& operator<<(ostream& out, const vector<vector<T> >& Mat) {
    for (int i = 0; i < Mat.size(); i++) {
        if (i != 0) out << endl;
        out << Mat[i];
    }
    return out;
}
template <class S, class T>
ostream& operator<<(ostream& out, const map<S, T>& mp) {
    out << "{ ";
    for (auto it = mp.begin(); it != mp.end(); it++) {
        out << it->first << ":" << it->second;
        if (mp.size() - 1 != distance(mp.begin(), it)) out << ", ";
    }
    out << " }";
    return out;
}
template <typename T>
vector<T> make_v(size_t a) {
    return vector<T>(a);
}
template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T& t, const V& v) {
    t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T& t, const V& v) {
    for (auto& e : t) fill_v(e, v);
}
/*
 <url:>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */

const ll MOD = 1e9 + 7;
const double eps = 1e-9;
template <class Type>
Type solve(Type res = Type()) {
    int N;
    cin >> N;

    vector<ll> pow2(N + 1);
    pow2[0] = 1;
    for (int i = 1; i <= N; i++) {
        pow2[i] = pow2[i - 1] * 2 % MOD;
    }

    ll zero_cnt = 0;
    map<pll, ll> mp;
    for (int i = 0; i < N; i++) {
        ll A, B;
        cin >> A >> B;

        int cnt = 0;
        if (A < 0) cnt++;
        if (B < 0) cnt++;

        if (A == 0 && B == 0){
            zero_cnt++;
            continue;
        }else if(A == 0){
            A = 0;
            B = 1;
        }else if (B == 0) {
            A = 1;
            B = 0;
        } else {
            A = abs(A);
            B = abs(B);

            ll GCD = gcd(A, B);
            A /= GCD;
            B /= GCD;

            if(cnt%2 == 1){
                A = -A;
            }
        }
        mp[pll(A,B)]++;
    }
    res = 1;
    // cout << mp << endl;
    for(auto p:mp){
        if(p.second == 0) continue;

        ll A,B; tie(A,B) = p.first;

        ll tA = 0,tB = 0;
        if(A == 0){
            tA = 1;
            tB = 0;
        }else if(B == 0){
            tA = 0;
            tB = 1;
        }else{
            tA = B;
            tB = abs(A);
            if(A > 0){
                tA = -B;
            }
        }

        ll bad_cnt = 0;
        if(mp.count(pll(tA,tB))){ 
            bad_cnt = mp[pll(tA,tB)];
            mp[pll(tA,tB)] = 0; // 2回見ないようにするため
        }
        ll good_cnt = p.second;


        ll T = pow2[good_cnt] + pow2[bad_cnt] - 1;
        res = res * (T + MOD) % MOD;

        // cout << A << " " << B << " -> " << tA << " " << tB << endl;
        // cout << good_cnt << " " << bad_cnt << " " << T << endl;
        // cout << res << endl;
    }
    res = (res - 1 + MOD + zero_cnt ) % MOD;
    return res;
}
int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(false);
    // solve<ll>(0);
    cout << fixed << setprecision(12) << solve<ll>() << endl;
    return 0;
}

Measured memory_bytes: 16992