#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;

template<class T>inline bool chmax(T &a, const T &b) { if (b > a) { a = b; return true; } return false; }
template<class T>inline bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

constexpr int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr double PI = M_PI;

template<int mod>
class ModInt {
    private:
        long long val;
    public:
        constexpr ModInt(const long long v = 0) : val(v%mod) { if (val < 0) val += mod; }
        constexpr ModInt(const ModInt &v) : val(v.val) {}
        constexpr ModInt &operator=(const long long v) { val = v; return *this; }
        constexpr ModInt &operator=(const ModInt &v) { if (this != &v) val = v.val; return *this; }
        constexpr ModInt operator+() const { return ModInt(val); }
        constexpr ModInt operator-() const { return ModInt(-val); }
        constexpr ModInt operator+(const ModInt &v) const { return ModInt(*this) += v; }
        constexpr ModInt operator-(const ModInt &v) const { return ModInt(*this) -= v; }
        constexpr ModInt operator*(const ModInt &v) const { return ModInt(*this) *= v; }
        constexpr ModInt operator/(const ModInt &v) const { return ModInt(*this) /= v; }
        constexpr ModInt &operator+=(const ModInt &v) { val += v.val; if (val >= mod) val -= mod; return *this; }
        constexpr ModInt &operator-=(const ModInt &v) { val -= v.val; if (val < 0) val += mod; return *this; }
        constexpr ModInt &operator*=(const ModInt &v) { val *= v.val; if (val >= mod) val %= mod; return *this; }
        constexpr ModInt &operator/=(const ModInt &v) { val *= v.inverse(); if (val >= mod) val %= mod; return *this; }
        constexpr ModInt &operator++() { ++val; if (val >= mod) val -= mod; return *this; }
        constexpr ModInt &operator--() { --val; if (val < 0) val += mod; return *this; }
        constexpr ModInt operator++(int) { ModInt tmp(*this); operator++(); return tmp; }
        constexpr ModInt operator--(int) { ModInt tmp(*this); operator--(); return tmp; }
        constexpr bool operator==(const ModInt &v) const { return val == v.val; }
        constexpr bool operator!=(const ModInt &v) const { return !(*this == v); }
        friend std::istream &operator>>(std::istream &s, ModInt &v) { long long tmp; s >> tmp; v = ModInt(tmp); return s; }
        friend std::ostream &operator<<(std::ostream &s, const ModInt &v) { return s << v.val; }
        constexpr ModInt inverse() const {
            long long n = val, res = 1;
            while (n > 1) {
                res *= (mod - mod / n);
                res %= mod;
                n = mod % n;
            }
            return ModInt(res);
        }
        friend constexpr ModInt modpow(ModInt v, long long n) {
            ModInt res(1);
            for ( ; n>0; n>>=1) {
                if (n & 1) res *= v;
                v *= v;
            }
            return res;
        }
};

long long gcd(long long a, long long b) {
    if (a < b) std::swap(a, b);
    if (b == 0) return a;

    while (b > 0) {
        long long buf = b;
        b = a%b;
        a = buf;
    }
    return a;
}

void solve() {
    ll n;
    cin >> n;
    vector<pair<ll, ll>> ab(n);
    for (int i=0; i<n; ++i) {
        cin >> ab.at(i).first >> ab.at(i).second;
    }

    ll zero = 0;
    for (int i=0; i<n; ++i) {
        if (ab.at(i).first < 0 && ab.at(i).second < 0) {
            ab.at(i).first = -ab.at(i).first;
            ab.at(i).second = -ab.at(i).second;
        } else if (ab.at(i).first >= 0 && ab.at(i).second < 0) {
            ab.at(i).first = -ab.at(i).first;
            ab.at(i).second = -ab.at(i).second;
        }
        ll g = gcd(abs(ab.at(i).first), ab.at(i).second);
        if (g == 0) continue;
        ab.at(i).first /= g;
        ab.at(i).second /= g;
        if (ab.at(i).first == 0) {
            ab.at(i).second = 1;
        }
        if (ab.at(i).second == 0) {
            ab.at(i).first = 1;
        }
    }

    map<pair<ll, ll>, ll> p, m;
    for (int i=0; i<n; ++i) {
        if (ab.at(i).first == 0 && ab.at(i).second == 0) {
            ++zero;
            continue;
        }
        p[make_pair(ab.at(i).first, ab.at(i).second)]++;
        if (ab.at(i).first == 0) {
            m[make_pair(1, 0)]++;
        } else if (ab.at(i).second == 0) {
            m[make_pair(0, 1)]++;
        } else {
            if (ab.at(i).first >= 0) m[make_pair(-ab.at(i).second, ab.at(i).first)]++;
            else m[make_pair(ab.at(i).second, -ab.at(i).first)]++;
        }
    }

    map<pair<ll, ll>, ll> pa;
    for (auto iter=p.begin(); iter!=p.end(); ++iter) {
        ll x = iter->second;
        ll y = m[iter->first];
        if (y == 0) continue;
        pa[make_pair(min(x, y), max(x, y))]++;
    }

    ModInt<MOD> res(1);
    ll cnt = n;
    for (auto iter=pa.begin(); iter!=pa.end(); ++iter) {
        auto pp = iter->first;
        ll x = pp.first, y = pp.second;
        ll c = iter->second / 2;
        assert(2*c == iter->second);
        for (int i=0; i<c; ++i) {
            res *= (modpow(ModInt<MOD>(2), x) + modpow(ModInt<MOD>(2), y) - 1);
        }
        cnt -= (x + y) * c;
    }
    res *= modpow(ModInt<MOD>(2), cnt-zero);
    cout << res - 1 + zero << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    solve();

    return 0;
}


Measured memory_bytes: 43824