#!/usr/bin/env python3
import sys
import math
from collections import defaultdict
from collections import Counter
sys.setrecursionlimit(10**8)
INF = float("inf")

MOD = 1000000007  # type: int


def GCD(a, b):
    if a == 0:
        return b
    else:
        return GCD(b % a, a)


def solve(N: int, A: "List[int]", B: "List[int]"):
    # 直交するイワシは選べない
    # 順にイワシを見てグループを探す。

    d = Counter()
    for i, (a, b) in enumerate(zip(A, B)):
        if a == 0:
            if b > 0:
                d[(0, 1)] += 1
            elif b < 0:
                d[(0, -1)] += 1
            else:
                d[(0, 0)] += 1
        else:
            aa = a//GCD(a, b)
            bb = b//GCD(a, b)
            if aa < 0:
                aa = -aa
                bb = -bb
            d[(aa, bb)] += 1
    # print(d)
    ans = 1
    for a, b in d:
        x, y = b, -a
        if x < 0:
            x = -x
            y = -y
        if d[(x, y)] == 0 or (a, b) == (0, 0):
            ans *= pow(2, d[(a, b)], MOD)
            ans %= MOD
            continue

        else:
            buf = pow(2, d[(a, b)], MOD)
            buf += pow(2, d[(x, y)], MOD)
            buf -= 1
            buf %= MOD
            # print(buf)
            ans *= buf
            ans %= MOD
            d[(x, y)] = 0
            d[(a, b)] = 0

    print((ans-1) % MOD)

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]"
    B = [int()] * (N)  # type: "List[int]"
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
    solve(N, A, B)


if __name__ == '__main__':
    main()
