CodeEff/ECCO huggingface dataset:
# Original solution
def ii():return int(eval(input()))
def iim():return list(map(int,input().split()))
def iil():return list(map(int,input().split()))
def ism():return list(map(str,input().split()))
def isl():return list(map(str,input().split()))

from fractions import Fraction

mod = int(1e9+7)
n = ii()
cnd = {}
azero = 0
bzero = 0
allzero = 0
for _ in range(n):
    a,b = iim()
    if a == 0:
        if b != 0:
            azero += 1
        else:
            allzero += 1
    elif b == 0:
        bzero += 1            
    else:
        ratio = Fraction(a,b)
        before = cnd.get(ratio,False)
        if before:
            cnd[ratio] = [before[0]+1,before[1]]
        else:
            invratio = Fraction(-b,a)
            check = cnd.get(invratio,False)
            if check:
                cnd[invratio] = [check[0],check[1]+1]
            else:
                cnd[ratio] = [1,0]

cnd[0] = [azero,bzero]
noreg = 0
ans = 1
#print(cnd)
for item in list(cnd.values()):
    if item[0] == 0  or item[1] == 0:
        noreg += max(item[0],item[1])
    else:
        ans *= (2**item[0]%mod+2**item[1]%mod-1)%mod
        ans %= mod
#print('hoge')
print((int((ans*((2**noreg)%mod)-1+allzero)%mod)))

# Optimized solution
def ii():return int(eval(input()))
def iim():return list(map(int,input().split()))
def iil():return list(map(int,input().split()))
def ism():return list(map(str,input().split()))
def isl():return list(map(str,input().split()))

#from fractions import Fraction
from math import gcd

mod = int(1e9+7)
n = ii()
cnd = {}
azero = 0
bzero = 0
allzero = 0
for _ in range(n):
    a,b = iim()
    if a == 0:
        if b != 0:
            azero += 1
        else:
            allzero += 1
    elif b == 0:
        bzero += 1            
    else:
        '''
        ratio = Fraction(a,b)
        before = cnd.get(ratio,False)
        if before:
            cnd[ratio] = [before[0]+1,before[1]]
        else:
            invratio = Fraction(-b,a)
            check = cnd.get(invratio,False)
            if check:
                cnd[invratio] = [check[0],check[1]+1]
            else:
                cnd[ratio] = [1,0]
        '''
        g = gcd(a,b)
        a //= g
        b //= g
        if a < 0:
            a *= -1
            b *= -1
        cnd[(a,b)] = cnd.get((a,b),0)+1


noreg = 0
if azero == 0 or bzero == 0:
    noreg += max(azero,bzero)
    ans = 1
else:
    ans = (2**azero%mod + 2**bzero%mod - 1)%mod
#print('ans block')
#print(ans,noreg)
#print(cnd)
for k,item in list(cnd.items()):
    a,b = k
    if b>0:
        m = cnd.get((b,-a),False)
        if m:
            ans *= (2**item%mod+2**m%mod-1)%mod
        else:
            noreg += item
    else:
        m = cnd.get((-b,a),False)
        if not m:
            noreg += item
#print('hoge')
print((int((ans*((2**noreg)%mod)-1+allzero)%mod)))
# Original solution
def ii():return int(eval(input()))
def iim():return list(map(int,input().split()))
def iil():return list(map(int,input().split()))
def ism():return list(map(str,input().split()))
def isl():return list(map(str,input().split()))

#from math import gcd
from fractions import Fraction as Fc

mod = int(1e9+7)
n = ii()
cnd = {}
azero = 0
bzero = 0
allzero = 0
for _ in range(n):
    a,b = iim()
    if a == 0:
        if b != 0:
            azero += 1
        else:
            allzero += 1
    elif b == 0:
        bzero += 1            
    else:
        f = Fc(a,b)
        cnd[f] = cnd.get(f,0)+1


noreg = 0
if azero == 0 or bzero == 0:
    noreg += max(azero,bzero)
    ans = 1
else:
    ans = (2**azero%mod + 2**bzero%mod - 1)%mod

#print(cnd)
for k,item in list(cnd.items()):
#    print(k)
    if k>0:
        m = cnd.get(Fc(-1,k),False)
        if m:
            ans *= (2**item%mod+2**m%mod-1)%mod
        else:
            noreg += item
    else:
        m = cnd.get(Fc(-1,k),False)
#        print(m,k,Fc(-1,k))
        if not m:
            noreg += item
#    print(ans,noreg)
print((int((ans*((2**noreg)%mod)-1+allzero)%mod)))

# Optimized solution
def ii():return int(eval(input()))
def iim():return list(map(int,input().split()))
def iil():return list(map(int,input().split()))
def ism():return list(map(str,input().split()))
def isl():return list(map(str,input().split()))

from math import gcd

mod = int(1e9+7)
n = ii()
cnd = {}
azero = 0
bzero = 0
allzero = 0
for _ in range(n):
    a,b = iim()
    if a*b == 0:
        if a == 0 and b != 0:
            azero += 1
        elif a != 0 and b == 0:
            bzero += 1
        else:
            allzero += 1
    else:
        g = gcd(a,b)
        a //= g
        b //= g
        if a<0:
            a *= -1
            b *= -1
        before = cnd.get((a,b),False)
        if b > 0:
            check = cnd.get((b,-a),False)
        else:
            check = cnd.get((-b,a),False)
        if before:
            cnd[(a,b)] = [before[0]+1,before[1]]
        elif check:
            if b > 0:
                cnd[(b,-a)] = [check[0],check[1]+1]
            else:
                cnd[(-b,a)] = [check[0],check[1]+1]
        else:
            cnd[(a,b)] = [1,0]

cnd[0] = [azero,bzero]
noreg = 0
ans = 1
#print(cnd)
for item in list(cnd.values()):
    if item[0] == 0  or item[1] == 0:
        noreg += max(item[0],item[1])
    else:
        ans *= (2**item[0]+2**item[1]-1)
        ans %= mod
print(((ans*((2**noreg)%mod)-1+allzero)%mod))
# Original solution
import sys
input = sys.stdin.readline
from collections import *
from math import gcd

N = int(eval(input()))
cnt = defaultdict(int)
abzero = 0
azero = 0
bzero = 0

for _ in range(N):
    A, B = list(map(int, input().split()))
    
    if A==0 and B==0:
        abzero += 1
        continue
    elif A==0:
        azero += 1
        continue
    elif B==0:
        bzero += 1
        continue
        
    G = gcd(abs(A), abs(B))
    A //= G
    B //= G
    
    if (A<0 and B>0) or (A<0 and B<0):
        A *= -1
        B *= -1
    
    cnt[(A, B)] += 1

ans = 1
MOD = 10**9+7
visited = set()

for k in list(cnt.keys()):
    if k in visited:
        continue
    
    if k[0]>0 and k[1]>0:
        k2 = (k[1], -k[0])
    else:
        k2 = (-k[1], k[0])
    
    if k2 not in cnt:
        ans *= pow(2, cnt[k], MOD)
        ans %= MOD
    else:
        ans *= pow(2, cnt[k], MOD)+pow(2, cnt[k2], MOD)-1
        ans %= MOD
        visited.add(k2)

ans *= pow(2, azero, MOD)+pow(2, bzero, MOD)-1
ans %= MOD
ans += abzero-1
ans %= MOD
print(ans)


# Optimized solution
import sys
input = sys.stdin.readline
from collections import *
from math import gcd

N = int(eval(input()))
zerozero = 0
zero1 = 0
zero2 = 0
cnt = defaultdict(int)

for _ in range(N):
    A, B = list(map(int, input().split()))
    
    if A==0 and B==0:
        zerozero += 1
    elif A==0:
        zero1 += 1
    elif B==0:
        zero2 += 1
    else:
        G = gcd(abs(A), abs(B))
        A //= G
        B //= G
        
        if (A<0 and B<0) or (A<0 and B>0):
            cnt[(-A, -B)] += 1
        else:
            cnt[(A, B)] += 1

ans = 1
MOD = 10**9+7
checked = set()

for k, v in list(cnt.items()):
    if k in checked:
        continue
    
    if k[0]>0 and k[1]>0:
        k2 = (k[1], -k[0])
    else:
        k2 = (-k[1], k[0])
    
    if k2 in cnt:
        v2 = cnt[k2]
        ans *= pow(2, v, MOD)+pow(2, v2, MOD)-1
        ans %= MOD
        checked.add(k2)
    else:
        ans *= pow(2, v, MOD)
        ans %= MOD

ans *= pow(2, zero1, MOD)+pow(2, zero2, MOD)-1
ans %= MOD
ans += zerozero
ans %= MOD
print(((ans-1)%MOD))
# Original solution

from math import gcd
from collections import defaultdict

N = int(eval(input()))
X = [list(map(int, input().split())) for _ in range(N)]

d = {}
for a, b in X:
    if a == b == 0:
        pass
    elif a == 0:
        if b > 0:
            b = 1
        else:
            b = -1
    elif b == 0:
        if a > 0:
            a = 1
        else:
            a = -1
    else:
        v = gcd(a, b)
        a //= v
        b //= v

    if a != 0 and a * b >= 0:
        pair = (abs(a), abs(b))
        if pair not in d:
            d[pair] = [0, 0]
        d[pair][0] += 1
    else:
        pair = (abs(b), abs(a))
        if pair not in d:
            d[pair] = [0, 0]
        d[pair][1] += 1

MOD = 10 ** 9 + 7
zero = 0
ans = 1
for p in d:
    if p == (0, 0):
        zero = d[p][1]
    else:
        a, b = d[p]
        ans *= pow(2, a, MOD) + pow(2, b, MOD) - 1
        ans %= MOD

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


# Optimized solution

from math import gcd

N = int(eval(input()))
X = [list(map(int, input().split())) for _ in range(N)]

d = {}
for a, b in X:
    if a == b == 0:
        pass
    elif a == 0:
        if b > 0:
            b = 1
        else:
            b = -1
    elif b == 0:
        if a > 0:
            a = 1
        else:
            a = -1
    else:
        v = gcd(a, b)
        a //= v
        b //= v

    if a != 0 and a * b >= 0:
        pair = (abs(a), abs(b))
        if pair not in d:
            d[pair] = [0, 0]
        d[pair][0] += 1
    else:
        pair = (abs(b), abs(a))
        if pair not in d:
            d[pair] = [0, 0]
        d[pair][1] += 1

MOD = 10 ** 9 + 7
zero = 0
ans = 1
for p in d:
    if p == (0, 0):
        zero = d[p][1]
    else:
        a, b = d[p]
        ans *= pow(2, a, MOD) + pow(2, b, MOD) - 1
        ans %= MOD

print(((ans + zero - 1) % MOD))
# Original solution
import sys
#import numpy as np
#import math
from fractions import Fraction
import itertools

input=sys.stdin.readline
def main():
  ans=1
  mod=1000000007
  n0=0
  na=nb=0
  n=int(eval(input()))
  d={}

  for i in range(n):
      a,b=list(map(int,input().split()))
      if b==0 and a==0:
          n0+=1
      elif b==0:
          nb+=1
      elif a==0:
          na+=1
      else:
          if Fraction(a, b) not in d:
              d[Fraction(a, b)]=1
          else:
              d[Fraction(a, b)]+=1

  for i in list(d.keys()):
      if Fraction(-1,i) in d:
          if i>0:
              ans*=pow(2,d[Fraction(-1, i)])-1+pow(2,d[i])-1+1
              ans=ans%mod
      else:
          ans*=pow(2,d[i])
          ans=ans%mod
  ans*=pow(2,na)-1+pow(2,nb)-1+1
  print(((ans-1+n0)%mod))

if __name__ == '__main__':
    main()

# Optimized solution
import sys
from math import gcd
#import numpy as np
#import math
from fractions import Fraction
import itertools

input=sys.stdin.readline
def main():
  ans=1
  mod=1000000007
  n0=0
  na=nb=0
  n=int(eval(input()))
  d={}

  for i in range(n):
      a,b=list(map(int,input().split()))
      if b==0 and a==0:
          n0+=1
      elif b==0:
          nb+=1
      elif a==0:
          na+=1
      else:
          g=gcd(a,b)
          if b<0:
            a*=-1
            b*=-1
          s=(a//g,b//g)
          if s not in d:
              d[s]=1
          else:
              d[s]+=1
  for k,v in list(d.items()):
      a,b=k
      if a>0:
        if (-b,a) in d:
            if d[(a,b)]!=-1:
                ans*=pow(2,d[(-b, a)])-1+pow(2,d[(a,b)])-1+1
                ans=ans%mod
                d[(-b,a)]=-1
        else:
            ans*=pow(2,d[(a,b)])
            ans=ans%mod
            
      else:
        if (b,-a) in d:
            if d[(a,b)]!=-1:
                ans*=pow(2,d[(b, -a)])-1+pow(2,d[(a,b)])-1+1
                ans=ans%mod
                d[(b,-a)]=-1
        else:
            ans*=pow(2,d[(a,b)])
            ans=ans%mod
  ans*=pow(2,na)-1+pow(2,nb)-1+1
  print(((ans-1+n0)%mod))

if __name__ == '__main__':
    main()
# Original solution
# E - ∙ (Bullet)
import sys
from collections import defaultdict

readline = sys.stdin.readline
MOD = 1000000007
N = int(readline())

# イワシの傾きをA/Bとする。
# A/Bは予めgcdで割って約分し、同じ傾きのものを揃えておく。
# このとき、仲の悪い組合せは(A, B)に対して(B, -A)となるもの。 
# 前者をS、後者をTとして考える。
d_S = defaultdict(int)
d_T = defaultdict(int)

def gcd(x, y):
    if x == 0:
        return y
    else:
        return gcd(y%x, x)

zeros = 0
for i in range(N):
    A, B = list(map(int, readline().split()))
    # (0, 0)のイワシは他の全てのイワシと仲が悪いため、
    # 1匹のみでしか選ぶことができない。最後にこの数を足す。
    if A == 0 and B == 0:
        zeros += 1
    # (?, 0),(0, ?)のイワシは、?がどのような数字であろうとも
    # この組合せであれば仲が悪い。一律、(1,0)(0,-1)として考える。
    elif A == 0:
        d_S[(1, 0)] += 0
        d_T[(0, -1)] += 1
    elif B == 0:
        d_S[(1, 0)] += 1
        d_T[(0, -1)] += 0
    else:
        g = gcd(A, B)
        A //= g
        B //= g
        # いずれもマイナスの場合、傾きはプラスになる
        if A < 0 and B < 0:
            A *= -1
            B *= -1
        if A * B > 0:
            d_S[(A, B)] += 1
            d_T[(B, -A)] += 0
        # 片方がマイナスの場合、必ずAがマイナスになるよう揃える
        else:
            if A > B:
                A, B = B, A
            d_S[(-A, B)] += 0
            d_T[(B, A)] += 1

ans = 1
for (si, sj), s_cnt in list(d_S.items()):
    t_cnt = d_T[(sj, -1*si)]
    tmp = 0
    tmp += pow(2, s_cnt, MOD) - 1
    tmp += pow(2, t_cnt, MOD) - 1
    tmp += 1
    ans = (ans * tmp)%MOD

ans -= 1
ans += zeros

print((ans%MOD))

# Optimized solution
# E - ∙ (Bullet)
import sys
from collections import defaultdict

readline = sys.stdin.readline
MOD = 1000000007
N = int(readline())

# イワシの傾きをA/Bとする。
# A/Bは予めgcdで割って約分し、同じ傾きのものを揃えておく。
# このとき、仲の悪い組合せは(A, B)に対して(B, -A)となるもの。 
# 前者をS、後者をTとして考える。
d_S = defaultdict(int)
d_T = defaultdict(int)

def gcd(x, y):
    if x == 0:
        return y
    else:
        return gcd(y%x, x)

pow2_mod = [1] + [0] * (N * 2)
for i in range(1, N * 2):
    pow2_mod[i] = pow2_mod[i-1] * 2 % MOD

zeros = 0
for i in range(N):
    A, B = list(map(int, readline().split()))
    # (0, 0)のイワシは他の全てのイワシと仲が悪いため、
    # 1匹のみでしか選ぶことができない。最後にこの数を足す。
    if A == 0 and B == 0:
        zeros += 1
    # (?, 0),(0, ?)のイワシは、?がどのような数字であろうとも
    # この組合せであれば仲が悪い。一律、(1,0)(0,-1)として考える。
    elif A == 0:
        d_S[(1, 0)] += 0
        d_T[(0, -1)] += 1
    elif B == 0:
        d_S[(1, 0)] += 1
        d_T[(0, -1)] += 0
    else:
        g = gcd(A, B)
        A //= g
        B //= g
        # いずれもマイナスの場合、傾きはプラスになる
        if A < 0 and B < 0:
            A *= -1
            B *= -1
        if A * B > 0:
            d_S[(A, B)] += 1
            d_T[(B, -A)] += 0
        # 片方がマイナスの場合、必ずAがマイナスになるよう揃える
        else:
            if A > B:
                A, B = B, A
            d_S[(-A, B)] += 0
            d_T[(B, A)] += 1

ans = 1
for (si, sj), s_cnt in list(d_S.items()):
    t_cnt = d_T[(sj, -1*si)]
    tmp = 0
    tmp += pow2_mod[s_cnt] - 1 # Sから1匹以上選ぶ組合せ
    tmp += pow2_mod[t_cnt] - 1 # Tから1匹以上選ぶ組合せ
    tmp += 1 # どちらも選ばない組合せ
    ans = (ans * tmp)%MOD

ans -= 1 # 最終的に1匹も選ばない組合せ
ans += zeros # (0, 0)のイワシの数

print((ans%MOD))
# Original solution
from functools import cmp_to_key

MOD = 10 ** 9 + 7


def func(a, b):
    if a[0] * b[1] == a[1] * b[0]:
        return 0
    elif a[0] * b[1] < a[1] * b[0]:
        return - 1
    else:
        return 1


n = int(eval(input()))
a = [0] * n
b = [0] * n
i = 0
f = 0
while i < n:
    a[i], b[i] = list(map(int, input().split()))
    if a[i] == 0 and b[i] == 0:
        f += 1
        n -= 1
        continue
    if a[i] < 0:
        a[i] = -a[i]
        b[i] = -b[i]
    if a[i] == 0 and b[i] < 0:
        b[i] = -b[i]
    i += 1
l = sorted(zip(a, b), key=cmp_to_key(func))
if l[0][1] > 0:
    li = [[1, 0, l[0][0], l[0][1]]]
else:
    li = []
for i in range(1, n):
    a, b = l[i - 1]
    c, d = l[i]
    if d <= 0:
        break
    if li and a * d == b * c:
        li[-1][0] += 1
    else:
        li.append([1, 0, c, d])
idx = 0
cnt = 0
for j in range(n):
    a, b = l[j]
    if b > 0:
        continue
    a, b = -b, a
    while idx < len(li) and li[idx][2] * b < li[idx][3] * a:
        idx += 1
    if idx < len(li) and li[idx][2] * b == li[idx][3] * a:
        li[idx][1] += 1
    else:
        cnt += 1
ans = 1
for a, b, c, d in li:
    ans *= (pow(2, a, MOD) + pow(2, b, MOD) - 1)
    ans %= MOD
print(((ans * (pow(2, cnt, MOD)) - 1 + f) % MOD))


# Optimized solution
from math import gcd
from collections import defaultdict

MOD = 10 ** 9 + 7

n = int(eval(input()))
d = defaultdict(int)
tmp = 0
for i in range(n):
    a, b = list(map(int, input().split()))
    if a == b == 0:
        tmp += 1
    else:
        if b < 0 or (b == 0 and a <= 0):
            a = -a
            b = -b
        g = gcd(a, b)
        a = a // g
        b = b // g
        d[(a, b)] += 1
        if a <= 0:
            d[(b, -a)]
        else:
            d[(-b, a)]
ans = 1
for k, v in list(d.items()):
    a, b = k
    if a <= 0:
        continue
    c = d[(-b, a)]
    ans *= pow(2, v) + pow(2, c) - 1
    ans %= MOD
print(((ans + tmp - 1) % MOD))
# Original solution
N=int(eval(input()))
from collections import defaultdict
dic=defaultdict(int)
import math
mod=1000000007
for _ in range(N):
    A,B=list(map(int,input().split()))
    if A<0:
        A,B=-A,-B
    if A==0:
        if B==0:
            dic[(0,0)]+=1
        else:
            dic[(0,1)]+=1
    elif B==0:
        dic[(1,0)]+=1
    else:
        gcd=math.gcd(A,B)
        A,B=A//gcd,B//gcd
        dic[(A,B)]+=1

ans=1
N-=dic[(0,0)]
for k,v in list(dic.items()):
    if k==(0,0) or k==(0,1):
        continue
    if k==(1,0):
        if not (0,1) in dic:
            continue
        v_dash=dic[(0,1)]
        ans*=((pow(2,v,mod)-1)+(pow(2,v_dash,mod)-1)+1)
        ans%=mod
        N-=v+v_dash
        continue
    a,b=k
    if not (b,-a) in dic:
        continue
    v_dash=dic[(b,-a)]
    ans*=((pow(2,v,mod)-1)+(pow(2,v_dash,mod)-1)+1)
    ans%=mod
    N-=v+v_dash
ans*=pow(2,N,mod)
ans+=dic[(0,0)]-1
ans%=mod
print(ans)


# Optimized solution
N=int(eval(input()))
from collections import defaultdict
dic=defaultdict(int)
import math
mod=1000000007
for _ in range(N):
    A,B=list(map(int,input().split()))
    if A<0:
        A,B=-A,-B
    if A==0:
        if B==0:
            dic[(0,0)]+=1
        else:
            dic[(0,-1)]+=1
    elif B==0:
        dic[(1,0)]+=1
    else:
        gcd=math.gcd(A,B)
        A,B=A//gcd,B//gcd
        dic[(A,B)]+=1

ans=1
N-=dic[(0,0)]
for k,v in list(dic.items()):
    if k==(0,0) or k==(0,1):
        continue
    a,b=k
    if not (b,-a) in dic:
        continue
    v_dash=dic[(b,-a)]
    ans*=((pow(2,v,mod)-1)+(pow(2,v_dash,mod)-1)+1)
    ans%=mod
    N-=v+v_dash
ans*=pow(2,N,mod)
ans+=dic[(0,0)]-1
ans%=mod
print(ans)
# Original 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
bin_n = [2]
for i in range(len(bin(n)) - 3):
    temp = bin_n[-1]
    temp = temp ** 2
    temp %= mod
    bin_n.append(temp)
def beki2(n):
    num = bin(n)
    temp = 1
    for i in range(len(num) - 2):
        if num[-i-1] == "1":
            temp *= bin_n[i]
            temp %= mod
    return temp

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 *= (beki2(num2) + beki2(num3) - 1)
    n = n- num2 - num3
    temp3 %= mod
temp3 *= beki2(n)
temp3 -= 1
temp3 %= mod
ans += temp3
ans %= mod
print(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
# -*- coding: utf-8 -*-
from fractions import Fraction
import sys

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

dict_F = {}
count_0 = 0

def insert(A,B,s): # A>=0, B>0, s=0or1
  if Fraction(A,B) not in list(dict_F.keys()):
    dict_F[Fraction(A,B)] = [0,0]
  dict_F[Fraction(A,B)][s] += 1

def make_power2(N):
  result = 1
  list_result = [1]
  for _ in range(N):
    result = (2*result)%mod
    list_result.append(result)
  return list_result

for i in range(N):
  A,B = AB[2*i], AB[2*i+1]
  if A==0 and B==0:
    count_0 += 1
  elif A>=0 and B>0:
    insert(A,B,0)
  elif A>0 and B<=0:
    insert(-B,A,1)
  elif A<=0 and B<0:
    insert(-A,-B,0)
  elif A<0 and B>=0:
    insert(B,-A,1)

mod = 1000000007
power2 = make_power2(N)
answer = 1

for A,B in list(dict_F.values()):
  answer = (answer*(power2[A]+power2[B]-1))%mod
answer = (answer+count_0-1)%mod

print(answer)

# Optimized solution
# -*- coding: utf-8 -*-
import sys
from math import gcd

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

dict_F = {}
count_0 = 0

def insert(A,B,s): # A>=0, B>0, s=0or1
  if (A,B) not in list(dict_F.keys()):
    dict_F[(A,B)] = [0,0]
  dict_F[(A,B)][s] += 1

def make_power2(N):
  result = 1
  list_result = [1]
  for _ in range(N):
    result = (2*result)%mod
    list_result.append(result)
  return list_result

for i in range(N):
  A,B = AB[2*i], AB[2*i+1]
  if A==0 and B==0:
    count_0 += 1
    continue
  g = gcd(A,B)
  A //= g
  B //= g
  if A>=0 and B>0:
    insert(A,B,0)
  elif A>0 and B<=0:
    insert(-B,A,1)
  elif A<=0 and B<0:
    insert(-A,-B,0)
  elif A<0 and B>=0:
    insert(B,-A,1)

mod = 1000000007
power2 = make_power2(N)
answer = 1

for A,B in list(dict_F.values()):
  answer = (answer*(power2[A]+power2[B]-1))%mod
answer = (answer+count_0-1)%mod

print(answer)
# Original solution
# -*- coding: utf-8 -*-
from math import gcd

N = int(eval(input()))

dict_F = {}
count_0 = 0

def insert(A,B,s): # A>=0, B>0, s=0or1
  if (A,B) not in list(dict_F.keys()):
    dict_F[(A,B)] = [0,0]
  dict_F[(A,B)][s] += 1

def make_power2(N):
  result = 1
  list_result = [1]
  for _ in range(N):
    result = (2*result)%mod
    list_result.append(result)
  return list_result

for i in range(N):
  A,B = list(map(int, input().split()))
  if A==0 and B==0:
    count_0 += 1
    continue
  g = gcd(A,B)
  A //= g
  B //= g
  if A>=0 and B>0:
    insert(A,B,0)
  elif A>0 and B<=0:
    insert(-B,A,1)
  elif A<=0 and B<0:
    insert(-A,-B,0)
  elif A<0 and B>=0:
    insert(B,-A,1)

mod = 1000000007
power2 = make_power2(N)
answer = 1

for A,B in list(dict_F.values()):
  answer = (answer*(power2[A]+power2[B]-1))%mod
answer = (answer+count_0-1)%mod

print(answer)

# Optimized solution
# -*- coding: utf-8 -*-
import sys
from math import gcd

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

dict_F = {}
count_0 = 0

def insert(A,B,s): # A>=0, B>0, s=0or1
  if (A,B) not in list(dict_F.keys()):
    dict_F[(A,B)] = [0,0]
  dict_F[(A,B)][s] += 1

def make_power2(N):
  result = 1
  list_result = [1]
  for _ in range(N):
    result = (2*result)%mod
    list_result.append(result)
  return list_result

for i in range(N):
  A,B = AB[2*i], AB[2*i+1]
  if A==0 and B==0:
    count_0 += 1
    continue
  g = gcd(A,B)
  A //= g
  B //= g
  if A>=0 and B>0:
    insert(A,B,0)
  elif A>0 and B<=0:
    insert(-B,A,1)
  elif A<=0 and B<0:
    insert(-A,-B,0)
  elif A<0 and B>=0:
    insert(B,-A,1)

mod = 1000000007
power2 = make_power2(N)
answer = 1

for A,B in list(dict_F.values()):
  answer = (answer*(power2[A]+power2[B]-1))%mod
answer = (answer+count_0-1)%mod

print(answer)