#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define for1(i, n) for (int i = 1; i <= int(n); ++i)
#define ms(a, x) memset(a, x, sizeof(a))
#define F first
#define S second
#define all(x) (x).begin(),(x).end()
#define pb push_back

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
template<typename... T> void rd(T&... args) {((cin>>args), ...);}
template<typename... T> void wr(T... args) {((cout<<args<<" "), ...);cout<<endl;}

template <int MOD>
struct ModInt {
    int val;
    // constructor
    ModInt(ll v = 0) : val(int(v % MOD)) {
        if (val < 0) val += MOD;
    };
    operator int(){return val;}
    // unary operator
    ModInt operator+() const { return ModInt(val); }
    ModInt operator-() const { return ModInt(MOD - val); }
    ModInt inv() const { return this->pow(MOD - 2); }
    // arithmetic
    ModInt operator+(const ModInt& x) const { return ModInt(*this) += x; }
    ModInt operator-(const ModInt& x) const { return ModInt(*this) -= x; }
    ModInt operator*(const ModInt& x) const { return ModInt(*this) *= x; }
    ModInt operator/(const ModInt& x) const { return ModInt(*this) /= x; }
    ModInt pow(ll n) const {
        auto x = ModInt(1);
        auto b = *this;
        while (n > 0) {
            if (n & 1) x *= b;
            n >>= 1;
            b *= b;
        }
        return x;
    }
    // compound assignment
    ModInt& operator+=(const ModInt& x) {
        if ((val += x.val) >= MOD) val -= MOD;
        return *this;
    }
    ModInt& operator-=(const ModInt& x) {
        if ((val -= x.val) < 0) val += MOD;
        return *this;
    }
    ModInt& operator*=(const ModInt& x) {
        val = int(ll(val) * x.val % MOD);
        return *this;
    }
    ModInt& operator/=(const ModInt& x) { return *this *= x.inv(); }
    // compare
    bool operator==(const ModInt& b) const { return val == b.val; }
    bool operator!=(const ModInt& b) const { return val != b.val; }
    // I/O
    friend std::istream& operator>>(std::istream& is, ModInt& x) noexcept { return is >> x.val; }
    friend std::ostream& operator<<(std::ostream& os, const ModInt& x) noexcept { return os << x.val; }
};
using mint=ModInt<int(1e9+7)>;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    map<pair<ll,ll>,int> cnt;
    forn(i,n){
        ll a,b;
        cin>>a>>b;
        ll g=gcd(a,b);
        if(g!=0)
        a/=g,b/=g;
        cnt[{a,b}]++;
    }
    mint ans=1;
    int c1=0,c2=0,c3=0;
    for(auto& [key,v]:cnt){
        if(v==0) continue;
        auto [a,b]=key;
        if(a==0&&b==0) c1+=v;
        else if(a==0) c2+=v;
        else if(b==0) c3+=v;
        else{

            auto t=mint(2).pow((cnt[{-a,-b}])+(v));
            auto tt=mint(2).pow((cnt[{-b,a}])+(cnt[{b,-a}]));
            ans*=t+tt-mint(1);
            if(cnt.count({-b,a})) cnt[{-b,a}]=0;
            if(cnt.count({b,-a})) cnt[{b,-a}]=0;
            if(cnt.count({-a,-b})) cnt[{-a,-b}]=0;
            v=0;
        }
    }
    ans*=(mint(2).pow(c2)+mint(2).pow(c3)-mint(1));
    ans+=c1;
    cout<<ans-mint(1);
    return 0;
}



Measured memory_bytes: 53576