#include <bits/stdc++.h>
#define rep(i, n, m) for (int i = (int)(n); i < (int)(m); i++)
#define repr(i, n, m) for (int i = (int)(n) - 1; i >= (int)(m); i--)
using namespace std;
using ll = int64_t;
const int MOD = 1000000007; // 10^9+7

struct mod_int {
    ll val;
    constexpr mod_int(ll v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr mod_int operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr mod_int operator + (const mod_int& r) const noexcept { return mod_int(*this) += r; }
    constexpr mod_int operator - (const mod_int& r) const noexcept { return mod_int(*this) -= r; }
    constexpr mod_int operator * (const mod_int& r) const noexcept { return mod_int(*this) *= r; }
    constexpr mod_int operator / (const mod_int& r) const noexcept { return mod_int(*this) /= r; }
    constexpr mod_int& operator += (const mod_int& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr mod_int& operator -= (const mod_int& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr mod_int& operator *= (const mod_int& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr mod_int& operator /= (const mod_int& r) noexcept {
        ll a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            ll t = a / b;
            ll tmp = 0;
            // tmp = a; a = b; b = tmp; としてるのは、
            // swap()がconstexprじゃなくて使えないから
            a -= t * b; tmp = a; a = b; b = tmp;
            u -= t * v; tmp = u; u = v; v = tmp;
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const mod_int& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const mod_int& r) const noexcept {
        return this->val != r.val;
    }
    friend ostream& operator << (ostream &os, const mod_int& x) noexcept {
        return os << x.val;
    }
    friend constexpr mod_int modpow(const mod_int &a, ll n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};

using mint = mod_int;

int main() {
    int n; cin >> n;
    map<pair<ll, ll>, int> fish, seen;
    rep(i, 0, n) {
        ll a, b; cin >> a >> b;
        ll div = gcd(a, b);
        a /= div; b /= div;

        if (fish.count(make_pair(a, b)) == 0) {
            fish[make_pair(a, b)] = 1;
            seen[make_pair(a, b)] = false;
        } else {
            fish[make_pair(a, b)]++;
        }
    }

    // mint ans = modpow(mint(2), n) - 1;
    mint ans = 1;
    int cnt = 0;
    for (const auto& [key, value] : fish){
        if (seen[key]) continue;
        seen[key] = true;

        pair<ll, ll> orth1 = make_pair(key.second, -key.first);
        pair<ll, ll> orth2 = make_pair(-key.second, key.first);
        pair<ll, ll> para = make_pair(-key.first, -key.second);

        if (fish.count(orth1) == 1 || fish.count(orth2) == 1) {
            seen[orth1] = true;
            seen[orth2] = true;
            seen[para] = true;
            // ans -= (modpow(mint(2), value) - 1) * (modpow(mint(2), fish[orth]) - 1) * modpow(mint(2), n - value - fish[orth]);
            cnt += value + fish[para] + fish[orth1] + fish[orth2];
            ans *= modpow(mint(2), value + fish[para]) + modpow(mint(2), fish[orth1] + fish[orth2]) - 1;
        }

        // orth = make_pair(-key.second, key.first);
        // if (fish.count(orth) == 1) {
        //     seen[orth] = true;
        //     // ans -= (modpow(mint(2), value) - 1) * (modpow(mint(2), fish[orth]) - 1) * modpow(mint(2), n - value - fish[orth]);
        //     cnt += value + fish[orth];
        //     ans *= modpow(mint(2), value) + modpow(mint(2), fish[orth])
        // }
    }
    ans *= modpow(mint(2), n - cnt);
    ans -= 1;

    cout << ans << endl;
}
