#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <iomanip>
#include <set>
#include <ctime>
#include <tuple>
#include <bitset>
#include <assert.h>
using namespace std;

/*
sort(sp.begin(), sp.end(), [](PAIR l, PAIR r){
        return l.first<r.first || (l.first==r.first && l.second > r.second);
        });
*/

typedef long long ll;

#define fi first
#define se second

using Graph = vector<vector<int>>;

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

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

int main()
{
    int n;
    cin >> n;
    ll zero = 0;
    map<pair<ll, ll>, pair<ll, ll>> mp;
    for (int i = 0; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        if (x == 0 && y == 0)
        {
            zero++;
            continue;
        }
        if (y < 0)
        {
            x = -x;
            y = -y;
        }
        if (y == 0 && x < 0)
        {
            x = -x;
            y = -y;
        }

        ll g = __gcd(x, y);
        ll a = x / g;
        ll b = y / g;
        bool rot90 = false;
        if (a < 0)
        {
            rot90 = true;
            ll tmp = a;
            a = b;
            b = -tmp;
        }
        if (!rot90)
        {
            mp[{a, b}].fi++;
        }
        else
        {
            mp[{a, b}].se++;
        }
    }

    mint ans = 1;
    for (auto m : mp)
    {
        mint tmp1 = mint(2).pow(m.se.fi) - 1;
        mint tmp2 = mint(2).pow(m.se.se) - 1;
        ans *= (tmp1 + tmp2 + 1);
    }
    ans -= 1;
    ans += zero;

    cout << ans << endl;
    return 0;
}