#!/usr/bin/env python3
import math
import sys
MOD = 1000000007  # type: int


def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

def solve(N: int, A: "List[int]", B: "List[int]"):
    # fishes = {}
    # zeroFishesB = 0
    # zeroFishesA = 0
    # valueFishes = N
    #
    # def getFishC(a):
    #     return fishes[a] if a in fishes else 0
    # for i in range(N):
    #     if A[i] == 0 and B[i] == 0: # 両方0,0ならばどの魚とも仲良くなれないので消す
    #         valueFishes -= 1
    #         continue
    #     if A[i] == 0:
    #         zeroFishesA += 1
    #     if B[i] == 0:
    #         zeroFishesB += 1
    #     fishes[(A[i],B[i])] = getFishC((A[i],B[i]))+1
    # def countWithZero(a): # aと中の悪い魚の数を返す
    #     if a[0] != 0 or a[1] != 0:
    #         return getFishC((-a[1],a[0]))+getFishC((a[1],-a[0]))
    #     else:
    #         if a[0] == 0:
    #             return zeroFishesB
    #         else:
    #             return zeroFishesA
    #
    # allCandidate = powm(2,valueFishes,MOD)-1
    # print(allCandidate)
    # for k in fishes:
    #     print(f"{k}->{countWithZero(k)}")
    fishes = []
    validFishes = N
    fishRads = dict()
    for i in range(N):
        if A[i] == 0 or B[i] == 0:
            validFishes-=1
            continue
        fishes.append((A[i],B[i]))
        norm = math.sqrt(A[i]**2+B[i]**2)
        normalRad = abs(A[i])/norm/(abs(B[i])/norm)
        cur = (0,0)
        if (A[i] > 0 and B[i] >= 0) or (A[i] < 0 and B[i] <= 0):
            if normalRad in fishRads:
                cur = fishRads[normalRad]
            fishRads[normalRad] = (cur[0]+1,cur[1])
        else:
            rotRad = abs(B[i]) / norm / (abs(A[i]) / norm)
            if rotRad in fishRads:
                cur = fishRads[rotRad]
            fishRads[rotRad] = (cur[0], cur[1]+1)
    current = 1
    for k in fishRads:
        groups = fishRads[k]
        stage= (powm(2,groups[0],MOD) + powm(2,groups[1],MOD)-1)%MOD
        current = current*stage%MOD
    print(current-1)
    return


# Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
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()
