#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P  = pair<ll, ll>;

const int mod = 1000000007;

template <int Modulus>
struct modint {
    ll x;  // typedef long long ll;
    modint(ll x = 0) : x((x % mod + mod) % mod) {}
    modint operator-() const { return modint(-x); }
    modint& operator+=(const modint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    modint& operator-=(const modint a) {
        if ((x += mod - a.x) >= mod) x -= mod;
        return *this;
    }
    modint& operator*=(const modint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    modint operator+(const modint a) const { return modint(*this) += a; }
    modint operator-(const modint a) const { return modint(*this) -= a; }
    modint operator*(const modint a) const { return modint(*this) *= a; }
    modint pow(ll t) const {
        if (!t) return 1;
        modint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }

    // for prime mod
    modint inv() const { return pow(mod - 2); }
    modint& operator/=(const modint a) { return *this *= a.inv(); }
    modint operator/(const modint a) const { return modint(*this) /= a; }
};
template <int Modulus>
istream& operator>>(istream& is, modint<Modulus>& a) {
    return is >> a.x;
}
template <int Modulus>
ostream& operator<<(ostream& os, const modint<Modulus>& a) {
    return os << a.x;
}

int main() {
    int n;
    using mint = modint<mod>;
    mint res   = 0;
    cin >> n;
    vector<P> sd(n);
    for (P& p : sd) {
        cin >> p.first >> p.second;
        ll g = gcd(abs(p.first), abs(p.second));
        if (!p.first || !p.second) continue;
        p.first /= g, p.second /= g;
        cerr << "::\t" << p.first << " " << p.second << endl;
    }
    map<P, int> m;
    int lz = 0, rz = 0;
    for (int i = 0; i < n; ++i) {
        ++m[sd[i]];
        if (sd[i].first == 0 && sd[i].second == 0)
            continue;
        else if (sd[i].first == 0) {
            ++lz;
        } else if (sd[i].second == 0) {
            ++rz;
        }
    }
    for (int i = 0; i < n; ++i) {
        if (sd[i].first == 0 && sd[i].second == 0)
            res += 1;
        else if (sd[i].first == 0) {
            res += mint(2).pow(n - i - rz - 1);
            --lz;
        } else if (sd[i].second == 0) {
            res += mint(2).pow(n - i - lz - 1);
            --rz;
        } else {
            res += mint(2).pow(n - i - m[P(-sd[i].second, sd[i].first)] -
                               m[P(sd[i].second, -sd[i].first)] - 1);
        }
        --m[sd[i]];
    }
    cout << res;
    return 0;
}