CodeEff/ECCO huggingface dataset:
# Original solution
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
from collections import defaultdict
from fractions import Fraction

n = int(readline())
data = list(map(int,read().split()))
mod = 1000000007

it = iter(data)
a_b = defaultdict(lambda :[0,0])
a0 = 0
b0 = 0
ab0 = 0
ans = 0
for a,b in zip(it,it):
    if(a==b==0):
        ab0 += 1
        continue
    if(a*b==0):
        if(a==0):
            a0 += 1
        if(b==0):
            b0 += 1
    else:
        if(a/b > 0):
            a = abs(a)
            b = abs(b)
            a_b[Fraction(a,b)][0] += 1
        else:
            a = abs(a)
            b = abs(b)
            a_b[Fraction(b,a)][1] += 1

exp2 = [1] * (n+1)
for i in range(n):
    exp2[i+1] = exp2[i] * 2
    exp2[i+1] %= mod


ans += (ans+1) * ( exp2[a0]-1  + exp2[b0]-1)
ans %= mod

for key,val in list(a_b.items()):
    ans += (ans+1) * ( exp2[val[0]]-1  + exp2[val[1]]-1)
    ans %= mod

ans += ab0
ans %= mod

print(ans)

# Optimized solution
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
from collections import defaultdict
from math import gcd

n = int(readline())
data = list(map(int,read().split()))
mod = 1000000007

it = iter(data)
a_b = defaultdict(lambda :[0,0])
a0 = 0
b0 = 0
ab0 = 0
ans = 0
for a,b in zip(it,it):
    if(a==b==0):
        ab0 += 1
        continue
    if(a*b==0):
        if(a==0):
            a0 += 1
        if(b==0):
            b0 += 1
    else:
        if(a/b > 0):
            a = abs(a)
            b = abs(b)
            gcd_num = gcd(a,b)
            a_b[(a//gcd_num,b//gcd_num)][0] += 1
        else:
            a = abs(a)
            b = abs(b)
            gcd_num = gcd(a,b)
            a_b[(b//gcd_num,a//gcd_num)][1] += 1

exp2 = [1] * (n+1)
for i in range(n):
    exp2[i+1] = exp2[i] * 2
    exp2[i+1] %= mod


ans += (ans+1) * ( exp2[a0]-1  + exp2[b0]-1)
ans %= mod

for key,val in list(a_b.items()):
    ans += (ans+1) * ( exp2[val[0]]-1  + exp2[val[1]]-1)
    ans %= mod

ans += ab0
ans %= mod

print(ans)
# Original solution
import sys
input = sys.stdin.readline
import math

MOD = 10**9+7
N = int(eval(input()))
F = []
zero_v = 0
inf = 0
zero = 0
for _ in range(N):
  x,y = list(map(int,input().split()))
  if x==0 and y==0:
    zero_v += 1
  elif x==0:
    inf += 1
  elif y==0:
    zero += 1
  else:
    G = math.gcd(abs(x),abs(y))
    F.append((x//G,y//G))

all_keys = set()

for x,y in F:
  if x*y >0:
    if x>0:
      all_keys.add((x,y))
    else:
      all_keys.add((-x,-y))
  x,y = -y,x
  if x*y >0:
    if x>0:
      all_keys.add((x,y))
    else:
      all_keys.add((-x,-y))

all_dic = {k:[0,0] for k in all_keys}

for x,y in F:
  if x*y > 0:
    if x>0:
      all_dic[(x,y)][0] += 1
    else:
      all_dic[(-x,-y)][0] += 1
  else:
    if x>0:
      all_dic[(-y,x)][1] += 1
    else:
      all_dic[(y,-x)][1] += 1

ans = (pow(2,inf,MOD)) + (pow(2,zero,MOD))-1
ans %= MOD

for k in all_keys:
  P,N = all_dic[k]
  ans *= (pow(2,P,MOD)) + (pow(2,N,MOD))-1
  ans %= MOD


ans += zero_v-1

print((ans%MOD))


# Optimized solution
import sys
input = sys.stdin.readline

def gcd(a, b):
  while b:
    a, b = b, a % b
  return a

MOD = 10**9+7
N = int(eval(input()))
F = []
zero_v = 0
inf = 0
zero = 0
for _ in range(N):
  x,y = list(map(int,input().split()))
  if x==0 and y==0:
    zero_v += 1
  elif x==0:
    inf += 1
  elif y==0:
    zero += 1
  else:
    G = gcd(abs(x),abs(y))
    F.append((x//G,y//G))

all_keys = set()

for x,y in F:
  if x*y >0:
    if x>0:
      all_keys.add((x,y))
    else:
      all_keys.add((-x,-y))
  x,y = -y,x
  if x*y >0:
    if x>0:
      all_keys.add((x,y))
    else:
      all_keys.add((-x,-y))

all_dic = {k:[0,0] for k in all_keys}

for x,y in F:
  if x*y > 0:
    if x>0:
      all_dic[(x,y)][0] += 1
    else:
      all_dic[(-x,-y)][0] += 1
  else:
    if x>0:
      all_dic[(-y,x)][1] += 1
    else:
      all_dic[(y,-x)][1] += 1

ans = (pow(2,inf,MOD)) + (pow(2,zero,MOD))-1
ans %= MOD

for k in all_keys:
  P,N = all_dic[k]
  ans *= (pow(2,P,MOD)) + (pow(2,N,MOD))-1
  ans %= MOD


ans += zero_v-1

print((ans%MOD))
# Original solution
from collections import defaultdict
import math


def ggg(a, b):
    """規約分数を作る。n/0, 0/n は n=1,-1 にして返す。"""
    if a == b == 0:
        return 0, 0

    denominator = math.gcd(a, b)
    x, y = a // denominator, b // denominator
    return x, y


def main():
    n = int(eval(input()))
    mod = 1000000007
    zeroes = 0
    counter = defaultdict(lambda: defaultdict(int))
    for _ in range(n):
        a, b = [int(x) for x in input().split()]
        x, y = ggg(a, b)

        if x == y == 0:
            zeroes += 1
            continue
        if y < 0:
            # quadrant III, IV -> I, II
            x, y = -x, -y

        if x <= 0:
            # round 90° from quadrant II to I
            x, y = y, -x
            counter[(x, y)][1] += 1
        else:
            counter[(x, y)][0] += 1

    ans = 1
    for v in list(counter.values()):
        now = 1
        now += pow(2, v[0], mod) - 1
        now += pow(2, v[1], mod) - 1
        ans = ans * now % mod
    ans += zeroes
    ans -= 1  # choose no fish
    return ans % mod


if __name__ == '__main__':
    print((main()))


# Optimized solution
from collections import defaultdict
import math


def main():
    n = int(eval(input()))
    mod = 1000000007
    zeroes = 0
    counter = defaultdict(lambda: defaultdict(int))
    for _ in range(n):
        x, y = [int(x) for x in input().split()]

        if x == y == 0:
            zeroes += 1
            continue

        denominator = math.gcd(x, y)
        x, y = x // denominator, y // denominator

        if y < 0:
            # quadrant III, IV -> I, II
            x, y = -x, -y

        if x <= 0:
            # round 90° from quadrant II to I
            x, y = y, -x
            counter[(x, y)][1] += 1
        else:
            counter[(x, y)][0] += 1

    ans = 1
    for v in list(counter.values()):
        now = 1
        now += pow(2, v[0], mod) - 1
        now += pow(2, v[1], mod) - 1
        ans = ans * now % mod
    ans += zeroes
    ans -= 1  # choose no fish
    return ans % mod


if __name__ == '__main__':
    print((main()))
# Original solution
from collections import defaultdict
import math


def main():
    n = int(eval(input()))
    mod = 1000000007
    zeroes = 0
    counter = defaultdict(lambda: defaultdict(int))
    for _ in range(n):
        x, y = [int(x) for x in input().split()]

        if x == y == 0:
            zeroes += 1
            continue

        denominator = math.gcd(x, y)
        x, y = x // denominator, y // denominator

        if y < 0:
            # quadrant III, IV -> I, II
            x, y = -x, -y

        if x <= 0:
            # round 90° from quadrant II to I
            x, y = y, -x
            counter[(x, y)][1] += 1
        else:
            counter[(x, y)][0] += 1

    ans = 1
    for v in list(counter.values()):
        now = 1
        now += pow(2, v[0], mod) - 1
        now += pow(2, v[1], mod) - 1
        ans = ans * now % mod
    ans += zeroes
    ans -= 1  # choose no fish
    return ans % mod


if __name__ == '__main__':
    print((main()))


# Optimized solution
from collections import defaultdict
import math


def main():
    n = int(eval(input()))
    mod = 1000000007
    zeroes = 0
    counter1 = defaultdict(int)
    counter2 = defaultdict(int)
    for _ in range(n):
        x, y = [int(x) for x in input().split()]

        if x == y == 0:
            zeroes += 1
            continue

        denominator = math.gcd(x, y)
        x, y = x // denominator, y // denominator

        if y < 0:
            # quadrant III, IV -> I, II
            x, y = -x, -y

        if x <= 0:
            # round 90° from quadrant II to I
            x, y = y, -x
            counter2[(x, y)] += 1
            counter1[(x, y)] += 0
        else:
            counter1[(x, y)] += 1
            counter2[(x, y)] += 0

    ans = 1
    for k, v in list(counter1.items()):
        now = 1
        now += pow(2, v, mod) - 1
        now += pow(2, counter2[k], mod) - 1
        ans = ans * now % mod
    ans += zeroes
    ans -= 1  # choose no fish
    return ans % mod


if __name__ == '__main__':
    print((main()))
# Original solution
import sys
import math
mod = 1000000007

n = int(sys.stdin.readline().rstrip())
ab = {}
for i in range(n):
    a,b = list(map(int,sys.stdin.readline().rstrip().split()))
    if a == 0 and b == 0:
        pass
    elif a == 0:
        b = 1
    else:
        gcd = math.gcd(a,b)
        a //= gcd
        b //= gcd
        if a < 0:
            a = -a
            b = -b
    ab.setdefault((a,b),0)
    ab[(a,b)]+=1
ans = 0
pairs=[]
s = list(set(ab.keys()))
for i in list(ab.keys()):
    a = i[0];b = i[1]
    if a == 0 and b == 0:
        ans = ab[(0,0)]
        n -= ans
    else:
        if (-b, a) in s:
            pairs.append([ab[(a,b)],ab[(-b,a)]])
select = 1
for pair in pairs:
    select*= (pow(2,pair[0],mod) + pow(2,pair[1],mod) -1)
    n -= (pair[0]+pair[1])
all_ans = (pow(2,n,mod) * select) % mod + ans -1
all_ans %= mod
print(all_ans)

# Optimized solution
import math
 
n = int(eval(input()))
mod = 10 ** 9 + 7
 
ab = {}
for i in range(n):
    a, b = list(map(int, input().split()))
    if a == 0 and b == 0:
        pass
    elif a == 0:
        b = 1
    else:
        gcd = math.gcd(a, b)
        a //= gcd
        b //= gcd
        if a < 0:
            a, b = -a, -b
    num = (a, b)
    ab.setdefault(num, 0)
    ab[num] += 1
ans = 0
if (0, 0) in list(ab.keys()):
    temp2 = ab[(0, 0)]
    ans += temp2
    n -= temp2
s = set(ab.keys())
pairs = []
for i in list(ab.keys()):
    if i == (0, 0):
        continue
    else:
        a, b = i[0], i[1]
        if (-b, a) in s:
            pairs.append([ab[(a, b)], ab[(-b, a)]])
temp3 = 1
for i in range(len(pairs)):
    num2 = pairs[i][0]
    num3 = pairs[i][1]
    temp3 *= (pow(2, num2, mod) + pow(2, num3, mod) - 1)
    n = n- num2 - num3
    temp3 %= mod
temp3 *= pow(2, n, mod)
temp3 -= 1
temp3 %= mod
ans += temp3
ans %= mod
print(ans)
# Original solution
import sys
import math
mod = 1000000007
 
n = int(sys.stdin.readline().rstrip())
ab = {}
for i in range(n):
    a,b = list(map(int,sys.stdin.readline().rstrip().split()))
    if a == 0 and b == 0:
        pass
    elif a == 0:
        b = 1
    else:
        gcd = math.gcd(a,b)
        a //= gcd
        b //= gcd
        if a < 0:
            a = -a
            b = -b
    ab.setdefault((a,b),0)
    ab[(a,b)]+=1
ans = 0
pairs=[]
s = list(set(ab.keys()))
for i in list(ab.keys()):
    a = i[0];b = i[1]
    if a == 0 and b == 0:
        ans = ab[(0,0)]
        n -= ans
    else:
        if (-b, a) in s:
            pairs.append([ab[(a,b)],ab[(-b,a)]])
select = 1
for pair in pairs:
    select*= (pow(2,pair[0],mod) + pow(2,pair[1],mod) -1)
    n -= (pair[0]+pair[1])
    select %= mod #TLE出ないように
select *= pow(2,n,mod) 
all_ans = select + ans -1
all_ans %= mod
print(all_ans)

# Optimized solution
import sys
import math
mod = 1000000007
 
n = int(sys.stdin.readline().rstrip())
ab = {}
for i in range(n):
    a,b = list(map(int,sys.stdin.readline().rstrip().split()))
    if a == 0 and b == 0:
        pass
    elif a == 0:
        b = 1
    else:
        gcd = math.gcd(a,b)
        a //= gcd
        b //= gcd
        if a < 0:
            a = -a
            b = -b
    ab.setdefault((a,b),0)
    ab[(a,b)]+=1
ans = 0
pairs=[]
s = set(ab.keys())
for i in list(ab.keys()):
    a = i[0];b = i[1]
    if a == 0 and b == 0:
        ans = ab[(0,0)]
        n -= ans
    else:
        if (-b, a) in s:
            pairs.append([ab[(a,b)],ab[(-b,a)]])
select = 1
for pair in pairs:
    select*= (pow(2,pair[0],mod) + pow(2,pair[1],mod) -1)
    n -= (pair[0]+pair[1])
all_ans = (pow(2,n,mod) * select) % mod + ans -1
all_ans %= mod
print(all_ans)
# Original solution
from collections import defaultdict
from fractions import Fraction

N = int(eval(input()))

MOD = 1000000007
d_plus = defaultdict(int)  # + or ∞
d_minus = defaultdict(int)  # - or 0
ans = 1
ans_00 = 0
for i in range(N):
    a, b = list(map(int, input().split()))
    if a == 0 and b == 0:
        ans_00 += 1
    elif a == 0:
        d_minus[0] += 1
    elif b == 0:
        d_plus[float('inf')] += 1
    elif (a > 0) ^ (b > 0):
        d_plus[Fraction(a, b)] += 1
    else:
        d_minus[Fraction(a, b)] += 1


def pair(p):
    if p == 0:
        return float('inf')
    elif p == float('inf'):
        return 0
    else:
        return -1 / p


for m in d_minus:
    d_plus[pair(m)]
for p in d_plus:
    ans *= (pow(2, d_plus[p], MOD) + pow(2, d_minus[pair(p)], MOD) - 1)
    ans %= MOD
print(((ans - 1 + ans_00) % MOD))


# Optimized solution
from collections import defaultdict
from math import gcd

N = int(eval(input()))

MOD = 1000000007
d_plus = defaultdict(int)  # + or ∞
d_minus = defaultdict(int)  # - or 0
ans = 1
ans_00 = 0
for i in range(N):
    a, b = list(map(int, input().split()))
    if a == 0 and b == 0:
        ans_00 += 1
    elif a == 0:
        d_minus[0] += 1
    elif b == 0:
        d_plus[float('inf')] += 1
    else:
        g = gcd(a, b)
        if (a > 0) ^ (b > 0):
            d_plus[(abs(a // g), abs(b // g))] += 1
        else:
            d_minus[(abs(a // g), -abs(b // g))] += 1


def pair(p):
    if p == 0:
        return float('inf')
    elif p == float('inf'):
        return 0
    else:
        a, b = -p[1], p[0]
        if a < 0:
            a, b = -a, -b
        return a, b


for m in d_minus:
    d_plus[pair(m)]
for p in d_plus:
    ans *= (pow(2, d_plus[p], MOD) + pow(2, d_minus[pair(p)], MOD) - 1)
    ans %= MOD
print(((ans - 1 + ans_00) % MOD))
# Original solution
# coding: utf-8
import sys,pprint
from fractions import Fraction
from collections import defaultdict

MOD = 1000000007
N = int(eval(input()))
params =[]
hatemasks = []
tilts = defaultdict(int)
zerozero = 0
zerodiv = 0
for i in range(N):
    (ai, bi) = list(map(int,input().split()))
    if ai == 0 and bi == 0:
        zerozero += 1
    elif bi == 0:
        zerodiv += 1
    else:
        t = Fraction(ai,bi)
        tilts[t] += 1

# print(tilts,file=sys.stderr)

ans = 1
f1 = Fraction(0,1)
if f1 in tilts:
    ans *= 1+pow(2,tilts[f1],MOD)-1 + pow(2,zerodiv,MOD)-1
    del tilts[f1]
else:
    ans *= 1 + pow(2,zerodiv,MOD)-1
ans %= MOD

klist = list(tilts.keys())
for k in klist:
    kinv = Fraction(-1*k.denominator,k.numerator)
    if kinv in tilts:
        #print(k,kinv, file=sys.stderr)
        ans *= 1+pow(2,tilts[k],MOD) -1+pow(2,tilts[kinv],MOD)-1
        ans %= MOD
        del tilts[k]
        del tilts[kinv]
    else:
        ans *= 1+pow(2,tilts[k],MOD)-1
        ans %= MOD

print(((ans + zerozero -1) % MOD))


# Optimized solution
# coding: utf-8
import sys,pprint, math
from fractions import Fraction
from collections import defaultdict

MOD = 1000000007
N = int(input())
params =[]
hatemasks = []
tilts = defaultdict(lambda: [0,0])
zerozero = 0
zerodiv = 0
for i in range(N):
    (ai, bi) = map(int,input().split())
    if ai == 0 and bi == 0:
        zerozero += 1
        continue
    if (ai < 0) or (ai == 0 and bi < 0):
        ai *= -1
        bi *= -1
    g = math.gcd(ai,bi)
    ai = ai // g
    bi = bi // g
    if bi > 0:
        tilts[(ai,bi)][0] += 1
    else:
        tilts[(-bi,ai)][1] += 1
print(tilts,file=sys.stderr)

#sys.exit()
ans = 1
for(v1,v2) in tilts.values():
    ans *= 1 +pow(2,v1,MOD)-1 +pow(2,v2,MOD)-1
    ans %= MOD
ans = (ans+zerozero-1) % MOD
print(ans)
# Original solution
from math import gcd
 
n=int(eval(input()))
mod = 10**9+7
 
d = dict()
zeros=0
for _ in range(n):
  a,b=list(map(int,input().split()))
  if not any((a,b)):
    zeros+=1
    continue
  if all((a,b)):
    g = gcd(a,b)*(a//abs(a))
  elif a:
    g = a
  else:
    g = b
  
  p = a//g,b//g
  d[p] = d.get(p,0)+1
 
ans = 1
done = set()
for (a,b),v in list(d.items()):
  if (-b,a) in done or (b,-a) in done:
    continue
  done.add((a,b))
  w=d.get((-b,a),0)+d.get((b,-a),0)
  ans *= (pow(2,v,mod)+pow(2,w,mod)-1)
  ans %= mod
print(((ans+zeros-1+mod)%mod))

# Optimized solution
from math import gcd
 
n=int(eval(input()))
mod = 10**9+7
 
d = dict()
zeros=0
for _ in range(n):
  a,b=list(map(int,input().split()))
  if not any((a,b)):
    zeros+=1
    continue
  if all((a,b)):
    g = gcd(a,b)*(a//abs(a))
  elif a:
    g = a
  else:
    g = b
  
  p = a//g,b//g
  d[p] = d.get(p,0)+1
 
ans = 1
done = set()
for (a,b),v in list(d.items()):
  if (-b,a) in done or (b,-a) in done:
    continue
  done.add((a,b))
  w=d.get((-b,a),0)+d.get((b,-a),0)
  ans *= (pow(2,v)+pow(2,w)-1)
  ans %= mod
print(((ans+zeros-1+mod)%mod))
# Original solution
from math import gcd
from collections import Counter

mod = 10 ** 9 + 7

N, *AB = list(map(int, open(0).read().split()))

def std(a, b):
    if a == 0:
        return (0, int(b != 0))

    g = gcd(a, b)
    a, b = a // g, b // g
    return (a, b) if a > 0 else (-a, -b)

C = Counter()
for a, b in zip(*[iter(AB)] * 2):
    C[std(a, b)] += 1

ans = 1
cnt = 0
for (a, b), v in list(C.items()):
    if b > 0:
        if (b, -a) in C:
            ans *= -1 + pow(2, v, mod) + pow(2, C[(b, -a)], mod)
            ans %= mod
        else:
            cnt += v
    elif (-b, a) not in C:
        cnt += v

ans *= pow(2, cnt, mod)
ans += C[(0, 0)] - 1

print((ans % mod))

# Optimized solution
from math import gcd
from collections import Counter

mod = 10 ** 9 + 7

N, *AB = list(map(int, open(0).read().split()))

def std(a, b):
    if a == 0:
        return (0, int(b != 0))

    g = gcd(a, b)
    a, b = a // g, b // g
    return (a, b) if a > 0 else (-a, -b)

C = Counter(std(a, b) for a, b in zip(*[iter(AB)] * 2))

ans = 1
cnt = 0
for (a, b), v in list(C.items()):
    if b > 0:
        if (b, -a) in C:
            ans *= -1 + pow(2, v, mod) + pow(2, C[(b, -a)], mod)
            ans %= mod
        else:
            cnt += v
    elif (-b, a) not in C:
        cnt += v

ans *= pow(2, cnt, mod)
ans += C[(0, 0)] - 1

print((ans % mod))
# Original solution
import sys
from fractions import Fraction
mod = 1000000007

def solve():
    input = sys.stdin.readline
    N = int(eval(input()))
    F = [[int(i) for i in input().split()] for _ in range(N)]
    D = dict()
    zero, inf, ng = 0, 0, 0
    for x, y in F:
        if x == 0 and y == 0: ng += 1
        elif x == 0: inf += 1
        elif y == 0: zero += 1
        else: 
            tan = Fraction(y, x)
            if tan in D: D[tan] += 1
            else: D[tan] = 1

    ans = 1
    ans *= (pow(2, zero, mod) + pow(2, inf, mod) - 1) % mod
    ans %= mod
    used = set()
    for key in D:
        if key not in used:
            this = D[key]
            used |= {key}
            ne, de = key.numerator, key.denominator
            op = (0 if Fraction(-de, ne) not in D else D[Fraction(-de, ne)])
            used |= {Fraction(-de, ne)}
            select = (pow(2, this, mod) + pow(2, op, mod) - 1) % mod
            ans *= select
            ans %= mod
    ans += ng
    ans %= mod
    ans = (ans - 1 + mod) % mod
    #print(D)
    print(ans)
    return 0

if __name__ == "__main__":
    solve()

# Optimized solution
import sys
from math import gcd
from fractions import Fraction
mod = 1000000007

def solve():
    input = sys.stdin.readline
    N = int(eval(input()))
    F = [[int(i) for i in input().split()] for _ in range(N)]
    D = dict()
    zero, inf, ng = 0, 0, 0
    for x, y in F:
        if x == 0 and y == 0: ng += 1
        elif x == 0: inf += 1
        elif y == 0: zero += 1
        else: 
            g = gcd(abs(x), abs(y))
            if x < 0:
                y *= -1
                x *= -1
            x //= g
            y //= g
            tan = (y, x)
            if tan in D: D[tan] += 1
            else: D[tan] = 1

    ans = 1
    ans *= (pow(2, zero, mod) + pow(2, inf, mod) - 1) % mod
    ans %= mod
    used = set()
    for key in D:
        if key not in used:
            this = D[key]
            used |= {key}
            y, x = key
            rev = ((-x, y) if y > 0 else (x, -y))
            op = (0 if rev not in D else D[rev])
            used |= {rev}
            select = (pow(2, this, mod) + pow(2, op, mod) - 1) % mod
            ans *= select
            ans %= mod
    ans += ng
    ans %= mod
    ans = (ans - 1 + mod) % mod
    #print(D)
    print(ans)
    return 0

if __name__ == "__main__":
    solve()
# Original solution
from collections import defaultdict
from itertools import groupby, accumulate, product, permutations, combinations
from math import gcd
def reduction(x,y):
    g = gcd(x,y)
    return abs(x)//g,abs(y)//g

def solve():
    mod = 10**9+7
    dplus = defaultdict(lambda: 0)
    dminus = defaultdict(lambda: 0)
    N = int(eval(input()))
    xzero = 0
    yzero = 0
    xyzero = 0
    for i in range(N):
        x,y = list(map(int, input().split()))
        if x==0:
            if y==0:
                xyzero += 1
            else:
                xzero += 1
        elif y==0:
            yzero += 1
        elif x*y>0:
            dplus[reduction(x,y)] += 1
        else:
            dminus[reduction(-y,x)] += 1
    pattern = pow(2,xzero,mod)+pow(2,yzero,mod)-1
    other = N-xzero-yzero-xyzero
    for k,v in list(dplus.items()):
        pattern *= pow(2,dminus[k],mod)+pow(2,v,mod)-1
        other -= dminus[k]+v
    ans = pattern * pow(2,other,mod) - 1
    ans += xyzero
    ans %= mod
    return ans
print((solve()))


# Optimized solution
from collections import defaultdict
from itertools import groupby, accumulate, product, permutations, combinations
from math import gcd

def reduction(x,y):
    g = gcd(x,y)
    return abs(x)//g,abs(y)//g

def solve():
    mod = 10**9+7
    dplus = defaultdict(lambda: 0)
    dminus = defaultdict(lambda: 0)
    N = int(eval(input()))
    xzero,yzero,xyzero = 0,0,0
    for i in range(N):
        x,y = list(map(int, input().split()))
        if x==0:
            if y==0:
                xyzero += 1
            else:
                xzero += 1
        elif y==0:
            yzero += 1
        elif x*y>0:
            dplus[reduction(x,y)] += 1
        else:
            dminus[reduction(-y,x)] += 1
    ans = pow(2,xzero,mod)+pow(2,yzero,mod)-1
    other = N-xzero-yzero-xyzero
    for k,v in list(dplus.items()):
        ans *= pow(2,dminus[k],mod)+pow(2,v,mod)-1
        other -= dminus[k]+v
    ans *= pow(2,other,mod)
    ans += xyzero-1
    ans %= mod
    return ans
print((solve()))