#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
using bint = boost::multiprecision::cpp_int;
using ll = long long;
using pint = pair<int, int>;
using pll = pair<ll, ll>;
#define rep(i,n) for (int i = 0; i < (n); i++)
#define repSE(i,s,n) for (int i = (s); i < (n); i++)
#define rrepSE(i,s,e) for (int i = (s); i > (e); i--)
#define ssort(v) sort(v.begin(), v.end())
#define gsort(v) sort(v.rbegin(), v.rend())
template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename T> bool chmax(T &m, const T q) { if (m < q) {m = q; return true;} else return false; }
template<typename T> bool chmin(T &m, const T q) { if (q < m) {m = q; return true;} else return false; }
#define DEBUG_PRINT(var) std::cout << #var << " = " << var << "\n";

const ll MOD = ll(1e9) + 7;

ll modpow(ll a, ll n, ll mod) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
ll modinv(ll i, ll mod){
    return modpow(i, mod-2, mod);
}

ll gcd(ll a,ll b){
    if(a<0) a = -a;
    if(b<0) b = -b;
    if(a<b)swap(a,b);
    if(a%b==0)return b;
    return gcd(a%b,b);
}

int main()
{
    int n;
    cin >> n;
    vector<ll> a(n), b(n);
    map<pll, int> m;
    rep(i,n) {
        cin >> a[i] >> b[i];
        if (a[i] == 0 && b[i] == 0) { m[pll(0,0)]++; continue; }
        else if (a[i] == 0) { m[pll(0,1)]++; continue; }
        else if (b[i] == 0) { m[pll(1,0)]++; continue; }
        ll _gcd = gcd(a[i],b[i]);
        ll ai = a[i]/_gcd;
        ll bi = b[i]/_gcd;
        if (ai < 0) { ai = -ai; bi = -bi; }
        m[pll(ai, bi)] ++;
    }
    ll ans = 1;
    int rem = n, n00 = 0;
    for(auto ele : m) {
        pll ab = ele.first;
        ll ai = ab.first, bi = ab.second;
        if (ai == 0 && bi == 0) {
            n00 = m[pll(0,0)];
            rem -= n00;
            continue;
        }
        else if (bi <= 0) {
            continue;
        }
        int abcnt = ele.second;
        int bacnt = m[pll(bi,-ai)];
        ll sub1 = modpow(2, abcnt, MOD);
        ll sub2 = modpow(2, bacnt, MOD);
        ll sub = (sub1 + sub2 - 1) % MOD;
        ans = (ans * sub) % MOD;
        rem -= (abcnt + bacnt);
    }
    ll sub3 = modpow(2, rem, MOD);
    ans = (ans * sub3) % MOD;
    ans = (ans + n00 - 1) % MOD;
    if (ans < 0) ans += MOD;
    cout << ans << "\n";
    return 0;
}


Measured memory_bytes: 25000