#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect
from fractions import Fraction
from collections import defaultdict

MOD = 1000000007

def factorial(n, mod=None, memo=False):
    if memo:
        factorial.memo = [1] * (n + 1)
        for i in range(1, n + 1):
            if mod is None:
                factorial.memo[i] = i * factorial.memo[i - 1]
            else:
                factorial.memo[i] = i * factorial.memo[i - 1] % mod
    return factorial.memo[n]

def choose(n, r, mod=None):
    a = factorial(n)
    b = factorial(r)
    c = factorial(n - r)
    if mod is None:
        res = a // b // c
    else:
        # fermat's little theorem
        res = a * pow(b, mod - 2, mod) * pow(c, mod - 2, mod) % mod
    return res

class Sardine:
    def __init__(self, a, b):
        if a == 0 and b == 0:
            self.type_ = 0
        elif a == 0:
            self.type_ = 'a'
        elif b == 0:
            self.type_ = 'b'
        else:
            self.type_ = Fraction(a, b)

def sigma_choose(v):
    ans = 0
    i = 1
    while i <= v:
        ans += choose(v, i, MOD)
        ans %= MOD
        # for next
        i += 1
    return ans

def combi(x, y):
    res = sigma_choose(x) + sigma_choose(y) + 1
    #print('res') # debug
    #print(res) # debug
    return res

def calc_cross_type(frac):
    cross = Fraction(-1 * frac.denominator, frac.numerator)
    #print('cross', frac, cross) # debug
    return cross

def count_up(types):
    ans = 0
    seed = 1
    seed *= combi(types['a'], types['b'])
    keys = list(types.keys())
    for type_ in keys:
        if not (type(type_) == Fraction and type_ > 0):
            continue
        count = types[type_]
        cross_type = calc_cross_type(type_)
        cross_count = types[cross_type]
        seed = (seed * combi(count, cross_count)) % MOD
    ans += seed
    ans += types[0]
    return ans - 1 # remove no sellect

if __name__ == '__main__':
    factorial(2 * 10 ** 5, MOD, True)
    n = int(input())
    types = defaultdict(lambda: 0)
    for _ in range(n):
        a, b = list(map(int, input().split()))
        sardine = Sardine(a, b)
        types[sardine.type_] += 1
        cross_type = calc_cross_type(sardine.type_)
        types[cross_type]
    #print('types') # debug
    #pp(types) # debug
    ans = count_up(types)
    #print('ans') # debug
    print(ans)




    #print('\33[32m' + 'end' + '\033[0m') # debug


### FIXED CODE ###

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect
from fractions import Fraction
from collections import defaultdict

def is_same_sign(a, b):
    if a > 0 and b > 0:
        return True
    if a < 0 and b < 0:
        return True
    return False

def fraction_taple(a, b):
    g = math.gcd(a, b)
    if is_same_sign(a, b):
        s = 1
    else:
        s = -1
    a = abs(a) // g
    b = abs(b) // g
    return (s, a, b)

def mode(a, b):
    # retrun dict_key, arr_key
    if a == 0 and b == 0:
        return 0, 0
    if a == 0:
        return 'ab', 0
    if b == 0:
        return 'ab', 1
    x = fraction_taple(a, b)
    y = fraction_taple(-1 * b, a)
    if x > y:
        return x, 0
    else:
        return y, 1

MOD = 1000000007

if __name__ == '__main__':

    n = int(input())

    d = defaultdict(lambda: [0, 0])
    zero = 0
    for _ in range(n):
        a, b = list(map(int, input().split()))
        dkey, akey = mode(a, b)
        if dkey == 0:
            zero += 1
        else:
            d[dkey][akey] += 1
    #print('d') # debug
    #pp(d) # debug

    ans = 1
    for pair in d.values():
        tmp = pow(2, pair[0], MOD) - 1 + pow(2, pair[1], MOD) - 1 + 1
        ans *= tmp
    ans += zero - 1
    ans %= MOD
    #print('ans') # debug
    print(ans)

    #print('\33[32m' + 'end' + '\033[0m') # debug