#include <iostream>
#include <map>
#include <numeric>
using namespace std;
using LL = long long;

const LL MOD = 1000000007;

using std::ostream;

template<int N = 1000000007>
struct ModInt {
    unsigned long long v;
    ModInt() {
        this->v = 0;
    }
    ModInt(signed long long v) {
        signed long long w = v % N;
        if(w < 0) w += N;
        this->v = w;
    }
    bool operator==(const ModInt& rhs) {
        return this->v == rhs.v;
    }
    ModInt& operator+=(ModInt rhs) {
        if((this->v += rhs.v) > N) {
            this->v -= N;
        }
        return *this;
    }
    ModInt& operator-=(ModInt rhs) {
        if((this->v -= rhs.v) < 0) {
            this->v += N;
        }
        return *this;
    }
    ModInt& operator*=(ModInt rhs) {
        this->v = this->v * rhs.v % N;
        return *this;
    }
    ModInt& operator++() {
        if(++this->v >= N) this->v = 0;
        return *this;
    }
    ModInt& operator--() {
        if(--this->v < 0) this->v = N - 1;
        return *this;
    }
    ModInt operator++(int) {
        ModInt ret = *this;
        ++*this;
        return ret;
    }
    ModInt operator--(int) {
        ModInt ret = *this;
        --*this;
        return ret;
    }

    ModInt operator+(ModInt rhs) const {
        return ModInt(*this) += rhs;
    }
    ModInt operator-(ModInt rhs) const {
        return ModInt(*this) -= rhs;
    }
    ModInt operator*(ModInt rhs) const {
        return ModInt(*this) *= rhs;
    }
    ModInt pow(ModInt& mi) const {
        return this->pow(mi.v);
    }
    ModInt pow(long long n) const {
        ModInt tmp = *this;
        ModInt ans = 1;
        while(n > 0) {
            if(n & 1) ans *= tmp; 
            tmp *= tmp;
            n >>= 1;
        }
        return ans;
    }

    template<int _N>
    friend ostream& operator<<(ostream& os, const ModInt<_N>& mi);
};
template<int N>
ostream& operator<<(ostream& os, const ModInt<N>& mi) {
    os << mi.v;
    return os;
}
using mint = ModInt<>;

LL N;
map<pair<LL, LL>, pair<mint, mint>> m;

int main() {
    cin >> N;
    mint ans0 = 0;
    for(int i = 0; i < N; ++i) {
        LL x, y;
        scanf("%lld%lld", &x, &y);
        if(x == 0 && y == 0) {
            ans0++;
            continue;
        }
        auto g = gcd(x, y);
        x /= g;
        y /= g;
        if(y < 0 || (y == 0 && x < 0)) {
            x *= -1;
            y *= -1;
        }
        bool rot = false;
        if(x <= 0) {
            rot = true;
            LL tmp = x;
            x = -y;
            y = tmp;
        }

        if(rot) {
            m[{x, y}].second += 1;
        } else {
            m[{x, y}].first += 1;
        }
    }

    mint ans = 1;
    for(auto p : m) {
        mint tmp = 1;
        tmp += mint(2).pow(p.second.first) - 1;
        tmp += mint(2).pow(p.second.second) - 1;
        ans *= tmp;
    }
    ans -= 1;
    ans += ans0;

    cout << ans << endl;
}
