Buggy python submission (verdict: Runtime Error):
from math import gcd
import sys
input = sys.stdin.readline

mod = 10**9 + 7
N = int(input())
cnt = {}
for i in range(N):
    A, B = map(int, input().split())
    neg = False
    if A < 0:
        neg ^= True
        A *= -1
    if B < 0:
        neg ^= True
        B *= -1
    g = gcd(A, B)
    sign = -1 if neg else 1
    A //= g
    B //= g
    frac = (-sign * A, B)
    if frac not in cnt:
        cnt[frac] = 0
    cnt[frac] += 1
ans = 1
used = set()
for frac, c in cnt.items():
    if frac in used:
        continue
    A, B = frac
    sign = 1
    if A < 0:
        A *= -1
        sign = -1
    bad = (B * -sign, A)
    if bad in cnt:
        b = cnt[bad]
        ans = ans * (pow(2, c, mod) + pow(2, b, mod) - 1) % mod
        used.add(bad)
    else:
        ans = ans * 2 % mod
print((ans - 1) % mod)


Fixed submission:
from math import gcd
import sys
input = sys.stdin.readline

mod = 10**9 + 7
N = int(input())
cnt = {}
zz = 0
az = 0
bz = 0
for _ in range(N):
    A, B = map(int, input().split())
    if A == B == 0:
        zz += 1
        continue
    if A == 0:
        az += 1
        continue
    if B == 0:
        bz += 1
        continue
    neg = False
    if A < 0:
        neg ^= True
        A *= -1
    if B < 0:
        neg ^= True
        B *= -1
    g = gcd(A, B)
    sign = -1 if neg else 1
    A //= g
    B //= g
    frac = (-sign * A, B)
    if frac not in cnt:
        cnt[frac] = 0
    cnt[frac] += 1
ans = 1
used = set()
for frac, c in cnt.items():
    if frac in used:
        continue
    A, B = frac
    sign = 1
    if A < 0:
        A *= -1
        sign = -1
    bad = (B * -sign, A)
    if bad in cnt:
        b = cnt[bad]
        ans = ans * (pow(2, c, mod) + pow(2, b, mod) - 1) % mod
        used.add(bad)
    else:
        ans = ans * pow(2, c) % mod
ans = ans * (pow(2, az, mod) + pow(2, bz, mod) - 1) % mod
print((ans + zz - 1) % mod)

Buggy python submission (verdict: Runtime Error):
from math import gcd
import sys
input = sys.stdin.readline

mod = 10**9 + 7
N = int(input())
cnt = {}
for i in range(N):
    A, B = map(int, input().split())
    neg = False
    if A < 0:
        neg ^= True
        A *= -1
    if B < 0:
        neg ^= True
        B *= -1
    g = gcd(A, B)
    sign = -1 if neg else 1
    A //= g
    B //= g
    frac = (-sign * A, B)
    if frac not in cnt:
        cnt[frac] = 0
    cnt[frac] += 1
ans = 1
used = set()
for frac, c in cnt.items():
    if frac in used:
        continue
    A, B = frac
    sign = 1
    if A < 0:
        A *= -1
        sign = -1
    bad = (B * -sign, A)
    if bad in cnt:
        b = cnt[bad]
        ans = ans * (pow(2, c, mod) + pow(2, b, mod) - 1) % mod
        used.add(bad)
    else:
        ans = ans * 2 % mod
print((ans - 1) % mod)


Fixed submission:
from math import gcd
import sys
input = sys.stdin.readline

mod = 10**9 + 7
N = int(input())
cnt = {}
zz = 0
az = 0
bz = 0
for _ in range(N):
    A, B = map(int, input().split())
    if A == B == 0:
        zz += 1
        continue
    if A == 0:
        az += 1
        continue
    if B == 0:
        bz += 1
        continue
    neg = False
    if A < 0:
        neg ^= True
        A *= -1
    if B < 0:
        neg ^= True
        B *= -1
    g = gcd(A, B)
    sign = -1 if neg else 1
    A //= g
    B //= g
    frac = (-sign * A, B)
    if frac not in cnt:
        cnt[frac] = 0
    cnt[frac] += 1
ans = 1
used = set()
for frac, c in cnt.items():
    if frac in used:
        continue
    A, B = frac
    sign = 1
    if A < 0:
        A *= -1
        sign = -1
    bad = (B * -sign, A)
    if bad in cnt:
        b = cnt[bad]
        ans = ans * (pow(2, c, mod) + pow(2, b, mod) - 1) % mod
        used.add(bad)
    else:
        ans = ans * pow(2, c) % mod
ans = ans * (pow(2, az, mod) + pow(2, bz, mod) - 1) % mod
print((ans + zz - 1) % mod)