#include <algorithm>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

long long gcd(long long a, long long b)
{
    a = abs(a), b = abs(b);
    if (a < b) swap(a, b);
    if (b == 0)
        return a;
    else {
        return gcd(b, a % b);
    }
}

template <typename T, T mod = 1000000007>
class modint
{
  private:
    // member variable

    T value;

  public:
    // constructor

    modint(T value = 0) : value((value % mod + mod) % mod) {}

    // accessor

    T val(void) { return value; }

    // operator

    modint& operator+=(const modint ob)
    {
        if ((value += ob.value) >= mod) value -= mod;
        return *this;
    }

    modint& operator+=(const T y)
    {
        if ((value += y) >= mod) value -= mod;
        return *this;
    }

    modint& operator-=(const modint ob)
    {
        if ((value += mod - ob.value) >= mod) value -= mod;
        return *this;
    }

    modint& operator-=(T y)
    {
        if ((value += mod - y) >= mod) value -= mod;
        return *this;
    }

    modint& operator*=(const modint ob)
    {
        (value *= ob.value) %= mod;
        return *this;
    }

    modint& operator*=(const T y)
    {
        (value *= y) %= mod;
        return *this;
    }

    modint operator+(const modint ob) const { return modint(*this) += ob; }

    modint operator+(T y) const { return modint(*this) += y; }

    friend modint operator+(T y, modint ob) { return ob + y; }

    modint operator-(const modint ob) const { return modint(*this) -= ob; }

    modint operator-(T y) const { return modint(*this) -= y; }

    friend modint operator-(T y, modint ob) { return ob * (-1) + y; }

    modint operator*(const modint ob) const { return modint(*this) *= ob; }

    modint operator*(T y) const { return modint(*this) *= y; }

    friend modint operator*(T y, modint ob) { return ob * y; }

    modint pow(T index) const
    {
        if (!index) {
            modint ob(1);
            return ob;
        }
        modint ob = pow(index >> 1);
        ob *= ob;
        if (index & 1) ob *= *this;
        return ob;
    }

    // for prime mod
    modint inverse() const { return pow(mod - 2); }

    modint& operator/=(const modint ob) { return (*this) *= ob.inverse(); }

    modint operator/(const modint ob) const
    {
        modint res(*this);
        return res /= ob;
    }
};

int main()
{
    // const int mod = 1000000007;
    int n;
    cin >> n;
    using pll = pair<long long, long long>;
    using pii = pair<int, int>;
    map<pll, pii> mp;
    int zero = 0;
    for (int i = 0; i < n; i++) {
        long long a, b;
        cin >> a >> b;
        if (a == 0 & b == 0) {
            zero++;
            continue;
        }
        auto g = gcd(a, b);
        a /= g;
        b /= g;

        if (b < 0) a = -a, b = -b;
        if (b == 0 && a < 0) a = -a, b = -b;
        bool rot90 = (a <= 0);
        if (rot90) {
            auto tmp = a;
            a = b, b = -tmp;
        }
        if (rot90)
            mp[{a, b}].first++;
        else
            mp[{a, b}].second++;
    }

    modint<long long> ans{1};
    for (const auto& p : mp) {
        auto rotated = p.second.first;
        auto unrotated = p.second.second;
        modint<long long> now{1};
        now += modint<long long>{2}.pow(rotated) - 1;
        now += modint<long long>{2}.pow(unrotated) - 1;
        ans *= now;
    }
    ans -= 1;
    ans += zero;
    cout << ans.val() << endl;
    return 0;
}


Measured memory_bytes: 15520