from sys import stdin, setrecursionlimit

from collections import defaultdict

from math import gcd



setrecursionlimit(10 ** 9)

INF = 1 << 60





def input():

    return stdin.readline().strip()





MOD = 1000000007

N, *AB = list(map(int, stdin.buffer.read().split()))

d = defaultdict(int)

zeros = 0

for a, b in zip(AB[::2], AB[1::2]):

    if a == 0 and b == 0:

        zeros += 1

    else:

        g = gcd(a, b)

        a //= g

        b //= g

        if a < 0:

            a *= -1

            b *= -1

        if a == 0 and b == -1:

            b = 1

        d[(a, b)] += 1



ans = 1

free = 0

keys = sorted(d.keys())

for a, b in keys:

    n = d[(a, b)]

    if b > 0:

        if (b, -a) in d:

            m = d[(b, -a)]

            ans = ans * (pow(2, n, MOD) + pow(2, m, MOD) - 1) % MOD

        else:

            free += n

    else:

        if (-b, a) not in d:

            free += n



ans = (ans * pow(2, free, MOD) + zeros - 1) % MOD

print(ans)

from sys import stdin, setrecursionlimit

from collections import defaultdict

from math import gcd



setrecursionlimit(10 ** 9)

INF = 1 << 60





def input():

    return stdin.readline().strip()





MOD = 1000000007

N, *AB = list(map(int, stdin.buffer.read().split()))

d = defaultdict(int)

zeros = 0

for a, b in zip(AB[::2], AB[1::2]):

    if a == 0 and b == 0:

        zeros += 1

    else:

        g = gcd(a, b)

        a //= g

        b //= g

        if a < 0:

            a *= -1

            b *= -1

        if a == 0 and b == -1:

            b = 1

        d[(a, b)] += 1



ans = 1

free = 0

for (a, b), n in list(d.items()):

    if b > 0:

        if (b, -a) in d:

            m = d[(b, -a)]

            ans = ans * (pow(2, n, MOD) + pow(2, m, MOD) - 1) % MOD

        else:

            free += n

    else:

        if (-b, a) not in d:

            free += n



ans = (ans * pow(2, free, MOD) + zeros - 1) % MOD

print(ans)

from sys import stdin, setrecursionlimit
from collections import defaultdict
from math import gcd

setrecursionlimit(10**9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


MOD = 1000000007
N, *AB = list(map(int, stdin.buffer.read().split()))
d = defaultdict(int)
zeros = 0
for a, b in zip(AB[::2], AB[1::2]):
    if a == 0 and b == 0:
        zeros += 1
    else:
        g = gcd(a, b)
        a //= g
        b //= g
        if a < 0:
            a *= -1
            b *= -1
        if a == 0 and b == -1:
            b = 1
        d[(a, b)] += 1
ans = 1
free = 0
keys = sorted(d.keys())
for a, b in keys:
    n = d[(a, b)]
    if b > 0:
        if (b, -a) in d:
            m = d[(b, -a)]
            ans = ans * (pow(2, n, MOD) + pow(2, m, MOD) - 1) % MOD
        else:
            free += n
    else:
        if (-b, a) not in d:
            free += n
ans = (ans * pow(2, free, MOD) + zeros - 1) % MOD
print(ans)

from sys import stdin, setrecursionlimit
from collections import defaultdict
from math import gcd

setrecursionlimit(10**9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


MOD = 1000000007
N, *AB = list(map(int, stdin.buffer.read().split()))
d = defaultdict(int)
zeros = 0
for a, b in zip(AB[::2], AB[1::2]):
    if a == 0 and b == 0:
        zeros += 1
    else:
        g = gcd(a, b)
        a //= g
        b //= g
        if a < 0:
            a *= -1
            b *= -1
        if a == 0 and b == -1:
            b = 1
        d[(a, b)] += 1
ans = 1
free = 0
for (a, b), n in list(d.items()):
    if b > 0:
        if (b, -a) in d:
            m = d[(b, -a)]
            ans = ans * (pow(2, n, MOD) + pow(2, m, MOD) - 1) % MOD
        else:
            free += n
    else:
        if (-b, a) not in d:
            free += n
ans = (ans * pow(2, free, MOD) + zeros - 1) % MOD
print(ans)

-keys = sorted(d.keys()) -for a, b in keys: -    n = d[(a, b)] +for (a, b), n in list(d.items()):