Problem:
 Score: 500 points    Problem Statement  We have caught N sardines. The deliciousness and fragrantness of the i -th sardine is A_i and B_i , respectively.  We will choose one or more of these sardines and put them into a cooler. However, two sardines on bad terms cannot be chosen at the same time.  The i -th and j -th sardines (i \neq j) are on bad terms if and only if A_i \cdot A_j + B_i \cdot B_j = 0 .  In how many ways can we choose the set of sardines to put into the cooler? Since the count can be enormous, print it modulo 1000000007 .      Constraints   All values in input are integers.  1 \leq N \leq 2 \times 10^5  -10^{18} \leq A_i, B_i \leq 10^{18}         Input  Input is given from Standard Input in the following format:  N  A_1  B_1  :  A_N  B_N       Output  Print the count modulo 1000000007 .        Sample Input 1 3
1 2
-1 1
2 -1      Sample Output 1 5  There are five ways to choose the set of sardines, as follows:   The 1 -st  The 1 -st and 2 -nd  The 2 -nd  The 2 -nd and 3 -rd  The 3 -rd        Sample Input 2 10
3 2
3 2
-1 1
2 -1
-3 -9
-8 12
7 7
8 1
8 2
8 4      Sample Output 2 479

Solution (Python):
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(input())
a = [0] * n
b = [0] * n
i = 0
f = 0
while i < n:
    a[i], b[i] = 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)

Solution (Python):
from math import gcd
mod = 10**9+7
n = int(input())
dicn = {}
dicp = {}
dicz = {'a': 0, 'b': 0, 'z': 0}
for i in range(n):
  a, b = map(int, input().split())
  if a == 0 and b == 0:
    dicz['z'] += 1
  else:
    g = gcd(a,b)
    a //= g
    b //= g
    if a < 0:
      a *= -1
      b *= -1
    elif a == 0 and b < 0:
      b *= -1
    if a * b > 0:
      if a in dicp:
        if b in dicp[a]:
          dicp[a][b] += 1
        else:
          dicp[a][b] = 1
      else:
        dicp[a] = {b: 1}
    elif a * b < 0:
      if b in dicn:
        if a in dicn[b]:
          dicn[b][a] += 1
        else:
          dicn[b][a] = 1
      else:
        dicn[b] = {a: 1}
    else:
      if a == 0:
        dicz['a'] += 1
      else:
        dicz['b'] += 1

ans = 1

for a in dicp:
  for b in dicp[a]:
    if -a in dicn:
      if b in dicn[-a]:
        ans *= (pow(2, dicp[a][b], mod) + pow(2, dicn[-a][b], mod) - 1)
        dicn[-a][b] = 0
      else:
        ans *= pow(2, dicp[a][b], mod)
    else:
      ans *= pow(2, dicp[a][b], mod)
    ans %= mod

for b in dicn:
  for a in dicn[b]:
    ans *= pow(2, dicn[b][a], mod)
    ans %= mod
    
if dicz['a'] > 0 and dicz['b'] > 0:
  ans *= pow(2,dicz['a'],mod) + pow(2,dicz['b'],mod) - 1
elif dicz['a'] > 0:
  ans *= pow(2,dicz['a'],mod)
elif dicz['b'] > 0:
  ans *= pow(2,dicz['b'],mod)
  
ans += dicz['z']
print((ans-1)%mod)

Solution (Python):
from collections import defaultdict
MOD = 10**9+7
from math import gcd


n = int(input())
ans = 1
C = defaultdict(int)
z = 0
r = 0
for i in range(n):
    a, b = map(int, input().split())
    if a == 0 and b == 0:
        r += 1
    elif b == 0:
        z += 1
    elif a == 0:
        C[0] += 1
    else:
        g = gcd(abs(a), abs(b))
        a //= g
        b //= g
        if a < 0:
            a, b = -a, -b
        C[(a, b)] += 1
D = tuple(C.items())
used = {0}
for c, v in D:
    if c in used:
        continue
    a, b = c
    if b > 0:
        d, e = b, -a
    else:
        d, e = -b, a
    ans *= pow(2, v, MOD)+pow(2, C[(d, e)], MOD)-1
    ans %= MOD
    used.add((d, e))
ans *= pow(2, C[0], MOD)+pow(2, z, MOD)-1
ans += r
ans -= 1
ans %= MOD
print(ans)

Solution (Python):
from math import gcd
from collections import Counter
N, *A = map(int, open(0).read().split())
*A, = zip(*[iter(A)]*2)

mod = 10**9 + 7


def modpow(a, n, mod):
    ret = 1
    while n:
        if n & 1:
            ret = ret * a % mod
        a = a * a % mod
        n >>= 1
    return ret

col = []
row = []
zero = 0
for a, b in A:
    if a == b == 0:
        zero += 1
        continue
    if a == 0:
        col.append((1,0))
        continue
    elif b == 0:
        row.append((1,0))
        continue
    else:
        g = gcd(abs(a), abs(b))
        a //= g
        b //= g

    if a < 0:
        a *= -1
        b *= -1

    if b > 0:
        col.append((a, b))
    elif b < 0:
        row.append((-b, a))

C = Counter(col)
D = Counter(row)
S = set(col) | set(row)

ans = 1
for s in S:
    if s in C:
        if s in D:
            mul = modpow(2, C[s], mod) + modpow(2, D[s], mod) - 1
            mul %= mod
        else:
            mul = modpow(2, C[s], mod)
    elif s in D:
        mul = modpow(2, D[s], mod)

    ans *= mul
    ans %= mod

ans -= 1
ans += zero
ans %= mod

print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
from collections import Counter
from fractions import Fraction
from math import gcd

N=int(input())
mod=10**9+7

S=[tuple(map(int,input().split())) for i in range(N)]

def main():
    C=Counter()
    PLUS=0
    for a,b in S:
        if a==0 and b==0:
            PLUS+=1
        elif a==0:
            C[(0,1)]+=1
        elif b!=0 and a>0:
            C[(a//gcd(a,b),b//gcd(a,b))]+=1
        elif b!=0 and a<0:
            C[(-a//gcd(a,b),-b//gcd(a,b))]+=1
            
        else:
            C[float("inf")]+=1
        
    ANS=1

    

    for x in list(C.keys()):
        if x!=float("inf") and x!=(0,1):

            a,b=x

            if b>0:
                ANS=ANS*(pow(2,C[x],mod)+pow(2,C[(b,-a)],mod)-1)%mod
                C[(b,-a)]=0
            else:
                ANS=ANS*(pow(2,C[x],mod)+pow(2,C[(-b,a)],mod)-1)%mod
                C[(-b,a)]=0
                
            C[x]=0

            
        else:
            ANS=ANS*(pow(2,C[float("inf")],mod)+pow(2,C[(0,1)],mod)-1)%mod

            C[float("inf")]=0
            C[(0,1)]=0

    print((ANS-1+PLUS)%mod)

main()

Solution (Python):
n = int(input())
ab = [list(map(int, input().split())) for _ in range(n)]

mod = 1000000007

from fractions import gcd

ratios = []
nzero = 0
for a, b in ab:
    if a != 0 and b != 0:
        g = gcd(a, b)
        ratios.append((a // g, b // g))
    elif a == 0 and b == 0:
        nzero += 1
    elif a == 0:
        ratios.append((0, 1))
    else:
        ratios.append((1, 0))

twos = [1]
for i in range(2 * 10 ** 5):
    tmp = twos[-1] * 2
    tmp %= mod
    twos.append(tmp)


from collections import Counter, defaultdict
c = Counter(ratios)
seen = Counter()

targets = []
for key in c:
    x, y = key
    xx = c[key]
    if y != 0:
        yy = seen[(-y, x)] + seen[(y, -x)]
    else:
        yy = seen[(-y, x)]
    if xx != 0 and yy != 0:
        targets.append((xx, yy))
    seen[key] = c[key]

n_frees = 0
for i, (x, y) in enumerate(ratios):
    n_bads = c[(-y, x)] + c[(y, -x)]
    if n_bads == 0:
        n_frees += 1

ans = twos[n_frees]

for x, y in targets:
    ans *= (twos[x] + twos[y] - 1) % mod
    ans %= mod

print((ans - 1 + nzero) % mod)

Solution (Python):
from collections import Counter
import sys
input = sys.stdin.readline

N = int(input())
AB = [[int(i) for i in input().split()] for _ in range(N)]

mod = 10 ** 9 + 7

def gcd(a, b) :
  if b > a : 
    a, b = b, a
  
  while b != 0 :
    a, b = b, a % b
  return a

p = []
both = 0
zeroa = 0
zerob = 0
for a, b in AB :
  if a == 0 and b == 0 :
    both += 1
    continue
  elif a == 0 :
    zeroa += 1
    continue
  elif b == 0 :
    zerob += 1
    continue
    
  g = gcd(abs(a), abs(b))
  a //= g
  b //= g
  if a < 0 :
    a *= -1
    b *= -1
  p.append((a, b))

ret = 1
visited = set()
cnt = Counter(p)
for k, v in cnt.items() :
  a, b = k
  c, d = b, -a
  if c < 0 :
    c *= -1
    d *= -1
  if cnt[(c, d)] == 0 :
    ret *= pow(2, v, mod)
  else :
    if not (c, d) in visited :
      u = cnt[(c, d)]
      ret *= (pow(2, u, mod) + pow(2, v, mod) - 1)
      visited.add((a, b))
      visited.add((c, d))
  ret %= mod

ret *= pow(2, zeroa, mod) + pow(2, zerob, mod) - 1
ret %= mod

print((ret - 1 + both) % mod)

Solution (Python):
from collections import Counter
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

def solve():
    MOD = 10**9 + 7

    N = int(input())
    ABs = [tuple(map(int, input().split())) for _ in range(N)]

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

    cntPos = Counter()
    cntNeg = Counter()
    num00 = 0
    for A, B in ABs:
        if A == B == 0:
            num00 += 1
            continue
        if A == 0:
            cntNeg[(0, 1)] += 1
        elif B == 0:
            cntPos[(0, 1)] += 1
        else:
            isPN = A*B < 0
            A, B = abs(A), abs(B)
            g = gcd(A, B)
            A, B = A//g, B//g
            if isPN:
                cntNeg[(B, A)] += 1
            else:
                cntPos[(A, B)] += 1

    numPoss = []
    numNegs = []

    numIso = 0
    for key in set(cntPos.keys()) | set(cntNeg.keys()):
        if cntPos[key] > 0 and cntNeg[key] > 0:
            numPoss.append(cntPos[key])
            numNegs.append(cntNeg[key])
        else:
            numIso += cntPos[key] + cntNeg[key]

    M = len(numPoss)
    numAlls = [0] * M
    numOKs = [0] * M
    numNGs = [0] * M
    for i in range(M):
        numPos = numPoss[i]
        numNeg = numNegs[i]
        numAll = pow(2, numPos+numNeg, MOD)
        numOK = pow(2, numPos, MOD) + pow(2, numNeg, MOD) - 1
        numNG = numAll - numOK
        numAlls[i] = numAll
        numOKs[i] = numOK
        numNGs[i] = numNG

    acc = pow(2, numIso, MOD)
    accNumAlls = [acc]
    for i in reversed(range(M)):
        acc *= numAlls[i]
        acc %= MOD
        accNumAlls.append(acc)
    accNumAlls.reverse()

    N -= num00
    ans = pow(2, N, MOD) - 1
    accOK = 1
    for i in range(M):
        num = accOK * numNGs[i] * accNumAlls[i+1] % MOD
        ans -= num
        ans %= MOD
        accOK *= numOKs[i]

    print(ans + num00)


solve()

Solution (Python):
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")



import bisect
from math import gcd
n = int(input())
l = [None] * n
for i in range(n):
    a,b = map(int, input().split())
    g = gcd(a,b)
    if g==0:
        g = 1
    l[i] = (a//g, b//g)

l.sort()
M = 1000000007
seen = [False] * n
vals = []

def sub(item):
    item1 = (item[1], -item[0])
    item2 = (-item[1], item[0])
    tmp = None
    count = 0
    li = bisect.bisect_left(l, item1)
    ri = bisect.bisect_right(l, item1)
    count += (ri-li)
    for v in range(li, ri):
        seen[v] = True
    if ri>li:
        tmp = l[li]
        
    li = bisect.bisect_left(l, item2)
    ri = bisect.bisect_right(l, item2)
    count += (ri-li)
    for v in range(li, ri):
        seen[v] = True
    if ri>li:
        tmp = l[li]
    
    return count, tmp
zcount = 0
for i,item in enumerate(l):
    if seen[i]:
        continue
    elif item==(0,0):
        zcount += 1
        continue
    count,tmp = sub(item)
    if count>0:
        count2, tmp = sub(tmp)
        vals.append((pow(2,count,M)+pow(2,count2,M)-1)%M)
    else:
        vals.append(2)
ans = 1
for v in vals:
    ans *= v
    ans %= M
ans -= 1
ans = (ans+zcount) % M
print(ans)

Solution (Python):
M = 1000000007

import math

N = int(input())

ab_zero_count = 0
a_zero_count = 0
b_zero_count = 0

fish_list = []
for _ in range(N):
	a, b = map(int, input().split())
	if a == 0 and b == 0:
		ab_zero_count += 1
	elif a == 0:
		a_zero_count += 1
	elif b == 0:
		b_zero_count += 1
	else:
		if a < 0:
			a = -a
			b = -b
		g = math.gcd(a, b)
		if g > 1:
			a //= g
			b //= g
		fish_list.append((a, b))



fish_table = {}
for f in fish_list:
	if f in fish_table:
		fish_table[f] += 1
	else:
		fish_table[f] = 1

fish_count_list = list(fish_table.items())
fish_index_table = {}
for i, (f, c) in enumerate(fish_count_list):
	fish_index_table[f] = i



singles = 0
pair_list = []
checked = [False] * N

for i, (f, c) in enumerate(fish_count_list):
	a, b = f
	a, b = (-b, a)
	if a < 0:
		a = -a
		b = -b
	key = (a, b)
	if key in fish_index_table:
		j = fish_index_table[key]
		if checked[j] == False:
			f2, c2 = fish_count_list[j]
			pair_list.append((c, c2))
			checked[i] = True
	else:
		singles += c

if a_zero_count > 0 and b_zero_count > 0:
	pair_list.append((a_zero_count, b_zero_count))
else:
	singles += a_zero_count + b_zero_count

count = pow(2, singles, M)



for c1, c2 in pair_list:
	count = (count * (pow(2, c1, M) + pow(2, c2, M) - 1)) % M

count += ab_zero_count
count -= 1

print(count % M)

Solution (Python):
MOD = 10**9+7
class mint:
    def __init__(self, x):
        self.x = x % MOD if isinstance(x, int) else int(x) % MOD
    def __str__(self):
        return str(self.x)
    __repr__ = __str__
    def __iadd__(self, other):
        self.x += other.x if isinstance(other, mint) else other
        self.x -= MOD if self.x >= MOD else 0
        return self
    def __isub__(self, other):
        self.x += MOD-other.x if isinstance(other, mint) else MOD-other
        self.x -= MOD if self.x >= MOD else 0
        return self
    def __imul__(self, other):
        self.x *= other.x if isinstance(other, mint) else other
        self.x %= MOD
        return self
    def __imod__(self, other):
        self.x %= other.x if isinstance(other, mint) else other
        self.x %= MOD
        return self
    def __add__(self, other):
        return (
            mint(self.x + other.x) if isinstance(other, mint) else
            mint(self.x + other)
        )
    def __sub__(self, other):
        return (
            mint(self.x - other.x) if isinstance(other, mint) else
            mint(self.x - other)
        )
    def __mul__(self, other):
        return (
            mint(self.x * other.x) if isinstance(other, mint) else
            mint(self.x * other)
        )
    def __mod__(self, other):
        return (
            mint(self.x % other.x) if isinstance(other, mint) else
            mint(self.x % other)
        )
    def __truediv__(self, other):
        return (
            mint(
                self.x * pow(other.x, MOD - 2, MOD)
            ) if isinstance(other, mint) else
            mint(self.x * pow(other, MOD - 2, MOD))
        )
    def __pow__(self, other):
        return (
            mint(pow(self.x, other.x, MOD)) if isinstance(other, mint) else
            mint(pow(self.x, other, MOD))
        )
    __radd__ = __add__
    def __rsub__(self, other):
        return (
            mint(other.x - self.x) if isinstance(other, mint) else
            mint(other - self.x)
        )
    __rmul__ = __mul__
    def __rmod__(self, other):
        return (
            mint(other.x % self.x) if isinstance(other, mint) else
            mint(other % self.x)
        )
    def __rtruediv__(self, other):
        return (
            mint(
                other.x * pow(self.x, MOD - 2, MOD)
            ) if isinstance(other, mint) else
            mint(other * pow(self.x, MOD - 2, MOD))
        )
    def __rpow__(self, other):
        return (
            mint(pow(other.x, self.x, MOD)) if isinstance(other, mint) else
            mint(pow(other, self.x, MOD))
        )
import math

n = int(input())
a=[0]*n
b = [0]*n
for i in range(n):
    a[i],b[i] = map(int, input().split())
azero=0
bzero=0
zerozero = 0
d=dict()
ok=n
for i in range(n):
    g=math.gcd(a[i],b[i])
    if g!=0:
        a[i]//=g
        b[i]//=g
    if b[i]<0:
        a[i]*=-1
        b[i]*=-1
    if a[i]==0 and b[i]!=0:
        azero+=1
        ok-=1
    elif a[i]!=0 and b[i]==0:
        bzero+=1
        ok-=1
    elif a[i]==0 and b[i]==0:
        zerozero+=1
        ok-=1
    try:
        d[(a[i],b[i])]+=1
    except:
        d[(a[i],b[i])]=1

ls=[]
for ap,bp in d.keys():
    try:
        if ap*bp == 0:
            continue
        now = d[ap,bp]
        if now==0:
            continue
    except:
        continue
    try:
        anow = ap
        bnow = bp
        if ap<0:
            anow*=-1
            bnow*=-1
        if ap!=0:
            ok = ok-now-d[(-bnow,anow)]
            ng = d[(-bnow,anow)]
            ls.append(mint(pow(2,now,MOD))+mint(pow(2,ng,MOD)-1))
            d[ap,bp]=0
            d[(-bnow,anow)]=0
        else:
            ok = ok - now
            ng = now
            ls.append(mint(now+1))
            d[ap,bp]=0
    except:
        pass

ans=mint(pow(2,ok,MOD))
for i in ls:
    ans*= i
ans*=mint(pow(2,azero,MOD))+mint(pow(2,bzero,MOD)-1)
ans+=zerozero
ans-=mint(1)

print(ans)

Solution (Python):
MOD = 10**9+7
import sys
from collections import Counter
from math import gcd
def input():
	return sys.stdin.readline()[:-1]
n = int(input())
ans = 0
c = Counter()
zero = 0
for _ in range(n):
	a, b = map(int, input().split())
	if a == b == 0:
		zero += 1
		continue
	if a < 0:
		a, b = -a, -b
	if a == 0:
		a, b = 0, 1
	if b == 0:
		a, b = 1, 0
	g = gcd(a, b)
	c[(a//g, b//g)] += 1

ans = 1
for k, v in c.items():
	
	if k[1] <= 0:
		x, y = -k[1], k[0]
		if c[(x, y)] > 0:
			continue
	else:
		x, y = k[1], -k[0]
	res = 0
	res += pow(2, v, MOD) - 1
	res += pow(2, c[(x, y)], MOD) - 1
	res += 1
	ans *= res
	ans %= MOD

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

Solution (Python):
def main():
    from math import gcd
    n = int(input())
    ab = [list(map(int, input().split())) for _ in [0]*n]
    adb = dict()
    ans = 0
    mod = 10**9+7
    for a, b in ab:
        if a == b == 0:
            ans += 1
            continue
        if b != 0:
            g = gcd(a, b)
            a = a//g
            b = b//g
            if b < 0:
                a *= -1
                b *= -1
            if a == 0:
                b = 1
            adb[(a, b)] = adb.get((a, b), 0)+1
        else:
            adb[None] = adb.get(None, 0)+1
    ans2 = 1
    for i, j in adb.items():
        if i is None:
            k = (0, 1)
        elif i == (0, 1):
            k = None
        else:
            if i[0] < 0:
                k = (i[1], -i[0])
            else:
                k = (-i[1], i[0])
        if k not in adb:
            ans2 = ans2*pow(2, j, mod) % mod
        else:
            if i is None:
                continue
            if i[0] >= 0:
                ans2 = ans2*(pow(2, j, mod)+pow(2, adb[k], mod)-1) % mod
    ans2 = (ans2-1) % mod
    print((ans+ans2) % mod)


main()

Solution (Python):
import collections

def getGreatestCommonDivisor(x, y):
    if x < y:
        x, y = y, x
    if y == 0:
        return x
    return getGreatestCommonDivisor(y, x % y)


N = int(input())
fishes = []
for _ in range(N):
    fishes.append([int(s) for s in input().split()])






















slopeCount = collections.defaultdict(int)
for x, y in fishes:
    if x == 0 and y == 0:
        pass
    elif x == 0:
        y = 1
    elif y == 0:
        x = 1
    else:
        gcl = getGreatestCommonDivisor(abs(x), abs(y))
        x //= gcl
        y //= gcl
    if x < 0:
        x = -x
        y = -y
    slopeCount[(x, y)] += 1



reversedPairs = dict()
independentCount = 0
zeroCount = 0
for slope, count in slopeCount.items():
    x, y = slope
    if (x, y) == (0, 0):
        zeroCount += count
        continue
    if x == 0:
        rx, ry = 1, 0
    elif y == 0:
        rx, ry = 0, 1
    else:
        rx, ry = (y, -x) if y >= 0 else (-y, x)
    if (x, y) in reversedPairs or (rx, ry) in reversedPairs:
        continue
    if (rx, ry) not in slopeCount:
        independentCount += count
        continue
    reversedPairs[(x, y)] = (count, slopeCount[(rx, ry)])
    



M = 1000000007
def subsetNum(count):
    r = 1
    for _ in range(count):
        r *= 2
        r %= M
    return r

result = subsetNum(independentCount)
for c1, c2 in reversedPairs.values():
    result *= (subsetNum(c1) - 1 + subsetNum(c2) - 1 + 1)
    result %= M
if zeroCount > 0:
    result += zeroCount
result -= 1
result %= M
print(result)

Solution (Python):
from math import gcd
import random
n = int(input())
mod = 10**9 + 7
d1 = dict()
a_zero,b_zero = 0,0
ab = 0
for i in range(n):
    a,b = map(int, input().split())
    if a == 0 and b == 0:
        ab += 1
        continue
    if a == 0:
        a_zero += 1
        continue
    if b == 0:
        b_zero += 1
        continue
    a,b = a//gcd(a,b),b//gcd(a,b)
    if a < 0:
        a *= -1
        b *= -1

    if (a,b) in d1:
        d1[(a,b)] += 1
    else:
        d1[(a,b)] = 1

ans =  1
ans *= pow(2,a_zero,mod)+pow(2,b_zero,mod)-1
ans %= mod
for a,b in d1:
    if b > 0 and (b,-a) in d1:
        ans *= pow(2,d1[(a,b)],mod)+pow(2,d1[(b,-a)],mod)-1
        d1[(a,b)] = 0
        d1[(b,-a)] = 0
    elif b < 0 and (-b,a) in d1:
        ans *= pow(2,d1[(a,b)],mod)+pow(2,d1[(-b,a)],mod)-1
        d1[(a,b)] = 0
        d1[(-b,a)] = 0
    else:
        ans *= pow(2,d1[(a,b)],mod)
        d1[(a,b)] = 0
    ans %= mod
    
print((ans-1 + ab)%mod)

Solution (Python):
from collections import defaultdict, Counter, namedtuple, deque
import itertools
import functools
import bisect
import heapq
import math
MOD = 10**9+7


n = int(input())
E = [list(map(int, input().split())) for i in range(n)]
d = defaultdict(int)
for e in E:
    if e[0] == 0 and e[1] == 0:
        d[(0, 0)] += 1
    elif e[0] == 0:
        d[(0, 1)] += 1
    elif e[1] == 0:
        d[(1, 0)] += 1
    else:
        g = math.gcd(e[0], e[1])
        a, b = e[0]//g, e[1]//g
        if b < 0:
            a, b = -a, -b
        d[(a, b)] += 1

pd = 1
non = n - d[(0, 0)]
for k in d:
    if k == (0, 0) or k == (1, 0):
        continue

    elif k == (0, 1) and (1, 0) in d:
        a, b = d[(0, 1)], d[(1, 0)]
        pd = (pd * (pow(2, a, MOD) + pow(2, b, MOD) - 1)) % MOD
        non -= (a + b)

    elif k[0] > 0 and (-k[1], k[0]) in d:
        a, b = d[k], d[(-k[1], k[0])]
        pd = (pd*(pow(2, a, MOD) + pow(2, b, MOD) - 1))%MOD
        
        non -= (a+b)


total = (pow(2, non, MOD)*pd - 1 + d[(0, 0)])%MOD
print(total)

Solution (Python):
import sys
input = sys.stdin.readline

Q = 10**9+7

from collections import defaultdict
from math import gcd
def main():
    N = int( input())
    AB = [ tuple( map( int, input().split())) for _ in range(N)]
    d = defaultdict( int)
    for a, b in AB:
        if a == 0 and b == 0:
            d[(0,0)] += 1
            continue
        if a == 0:
            d[(0,1)] += 1
            continue
        if b == 0:
            d[(1,0)] += 1
            continue

        g = gcd(a, b)
        a //= g
        b //= g
        if a < 0:
            a = -a
            b = -b
        d[(a,b)] += 1
    
    ans = 1
    K = list( d.keys())
    for k in K:
        
        
        a, b = k
        if a == 0 and b == 0:
            continue
        if a*b == 0:
            ans *= (pow(2,d[(1,0)],Q) + pow(2,d[(0,1)],Q) -1)%Q
            ans %= Q
            d[(1,0)] = 0
            d[(0,1)] = 0
            continue
        if b > 0 and d[(a,b)] > 0 and d[(b,-a)] > 0:
            ans *= (pow(2,d[(a,b)],Q) + pow(2,d[(b,-a)],Q) - 1)%Q
            ans %= Q
            continue
        if b < 0 and d[(a,b)] > 0 and d[(-b,a)] > 0:
            continue
        ans *= pow(2,d[(a,b)],Q)
        ans %= Q
    
    ans -= 1
    ans += d[(0,0)]
    ans %= Q
    print(ans)
if __name__ == '__main__':
    main()

Solution (Python):
import sys
from collections import defaultdict
from math import gcd

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

MOD = 10**9 + 7

N = int(readline())
m = map(int, read().split())
A, B = zip(*zip(m, m))

pow2 = [1] * (N + 10)
for n in range(1, N + 10):
    pow2[n] = pow2[n - 1] * 2 % MOD

def to_standard_form(a, b):
    if a == 0:
        return (0, 1)
    g = gcd(a, b)
    a //= g
    b //= g
    if a < 0:
        return (-a, -b)
    return (a, b)

counter0 = defaultdict(int)
counter1 = defaultdict(int)
origin = 0
for a, b in zip(A, B):
    if a == b == 0:
        origin += 1
        continue
    a, b = to_standard_form(a, b)
    if b <= 0:
        counter0[(a, b)] += 1
    else:
        counter1[(b, -a)] += 1
        counter0[(b, -a)] += 0

answer = origin
k = 1
for key, cnt0 in counter0.items():
    cnt1 = counter1[key]
    x = pow2[cnt0] + pow2[cnt1]
    k = k * (x - 1) % MOD

answer += k - 1
answer %= MOD
print(answer)

Solution (Python):
import sys
sys.setrecursionlimit(10**6) 
import math
from copy import copy, deepcopy
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right

from collections import deque 


from collections import Counter

from itertools import accumulate

from heapq import heapify,heappop,heappush




def input(): return sys.stdin.readline()[:-1]
def printl(li): print(*li, sep="\n")
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)

def main():
    mod = 1000000007
    

    N = int(input())
    
    
    
    

    d=dict()
    m=10**18+100
    for i in range(N):
        A, B = map(int, input().split())
        if A==0 and B==0:
            d[-m]=d.get(-m,0)+1
        elif B==0:
            d[m]=d.get(m,0)+1
        elif A==0:
            d[0]=d.get(0,0)+1
        else:
            sa=sb=1
            if A<0:
                sa=-1
                A*=-1
            if B<0:
                sb=-1
                B*=-1

            g=math.gcd(A,B)
            A=A//g
            B=B//g
            if sa==-1 and sb==-1:
                t=(A,B)
            elif sb==-1:
                t=(-A,B)
            else:
                t=(sa*A,sb*B)
            d[t]=d.get(t,0)+1
    
        
    
    ks=set(d.keys())
    alis=[]
    tot=1
    for i, k in enumerate(ks):
        if d[k]==-1.0:
            continue
        if k==-m:
            continue
        if k==m:
            ik=0
        elif k==0:    
            ik=m
        elif k[0]<0:
            ik=(k[1],-k[0])
        else:
            ik=(-k[1],k[0])
        
        if ik in ks:
            d1,d2=d[k],d[ik]
            tot=(tot*((pow(2,d1,mod)-1)+(pow(2,d2,mod)-1)+1)%mod)%mod
            d[ik]=-1

        else:
            tot=(tot*pow(2,d[k],mod))%mod

    tot-=1
    tot+=d.get(-m,0)%mod
    tot%=mod
    
    print(tot)




if __name__ == "__main__":
    main()

Solution (Python):

from collections import defaultdict
from math import gcd

P=defaultdict(lambda :0)
n=int(input())
AB=[tuple(map(int,input().split()))for i in range(n)]

zero=0 
a0=0 
b0=0
for a,b in AB:
    g=gcd(a,b)
    if a==0 and b==0:
        zero+=1
    elif a==0:
        a0+=1
    elif b==0:
        b0+=1
    elif a<0:
        a//=-g
        b//=-g
        P[(a,b)]+=1
    else:
        a//=g
        b//=g
        P[(a,b)]+=1

ans=1
others=n-zero-a0-b0
mod=1000000007
from copy import copy
k=copy(list(P.keys()))
for p in k:
    me=P[p]
    if me==0:
        continue
    a,b=p
    oppidx=(-b,a) if b<0 else (b,-a)
    opp=P[oppidx]
    if P[oppidx]!=0:
        others-=me+opp
        ans*=pow(2,me,mod)+pow(2,opp,mod)-1
        ans%=mod
    P[p]=0
    P[oppidx]=0

if a0!=0 and b0!=0:
    ans*=pow(2,a0,mod)+pow(2,b0,mod)-1
    ans%=mod
elif a0!=0 or b0!=0:
    others+=a0+b0

ans*=pow(2,others,mod)
ans%=mod
ans=ans+zero-1
ans%=mod

print(ans)

"""
7
0 1
0 1
1 0
1 0
1 -1
1 1
1 3
"""

Solution (Python):
from math import gcd
MOD = 10 ** 9 + 7
N = int(input())
d = dict()
zeros = 0
a_zeros = 0
b_zeros = 0
for _ in range(N):
    a, b = tuple(map(int, input().split()))
    if not any((a, b)):
        zeros += 1
        continue
    if not a:
        a_zeros += 1
        continue
    if not b:
        b_zeros += 1
        continue
    g = gcd(a, b) * (a // abs(a))
    p = a // g, b // g
    d[p] = d.get(p, 0) + 1
counts = dict()
for k, v in d.items():
    a, b = k
    if counts.get((b, -a), False) or counts.get((-b, a), False):
        continue
    counts[k] = v, d.get((b, -a), 0) + d.get((-b, a), 0)
total = 1
for k, v in counts.items():
    a, b = v
    total = (total * (pow(2, a, MOD) + pow(2, b, MOD) - 1)) % MOD
total = (total * (pow(2, a_zeros, MOD) + pow(2, b_zeros, MOD) - 1)) % MOD
print((total + zeros + MOD - 1) % MOD)

Solution (Python):
import numpy as np

mod = 10 ** 9 + 7


def regularize(a, b):
    if a < 0 or (a == 0 and b < 0):
        a, b = -a, -b
    if b > 0:
        return 0, a, b
    else:
        return 1, -b, a


n = int(input())
edict = dict()
zero_num = 0
for _ in range(n):
    a, b = map(int, input().split())
    if a == 0 and b == 0:
        zero_num += 1
        continue
    ab_gcd = np.gcd(a, b)
    a, b = a // ab_gcd, b // ab_gcd
    index, a, b = regularize(a, b)
    key = (a, b)
    if key not in edict.keys():
        edict[key] = [0, 0]
    edict[key][index] += 1


not_zeros = 1
for key in edict.keys():
    a, b = key
    pp, pm = edict[key]
    not_zeros *= (pow(2, pp, mod) + pow(2, pm, mod) - 1) % mod
    not_zeros %= mod

print((zero_num + not_zeros - 1) % mod)

Solution (Python):
import sys
from collections import defaultdict

sys.setrecursionlimit(500000)

def gcd(a,b):
    a,b = max(a,b),min(a,b)
    while a%b!=0:
        a,b = b,a%b
    return b

def frac(a,b):
    d = gcd(abs(a),abs(b))
    if a<0:
        a = -a
        b = -b
    return (a//d,b//d)

def inv(a,b):
    return frac(-b,a)

def input():
    return sys.stdin.readline()[:-1]

def main():
    N = int(input())

    vec = [list(map(int,input().split())) for i in range(N)]

    arg = defaultdict(int)
    zero = 0
    for v in vec:
        if v[0] == 0 and v[1] == 0:
            zero += 1
        elif v[1]==0:
            arg[float("inf")] += 1
            arg[0] += 0
        elif v[0]==0:
            arg[0] += 1
            arg[float("inf")] += 0
        else:
            arg[frac(v[0],v[1])] += 1
            arg[frac(-v[1],v[0])] += 0

    pair = []
    ll = lambda : False

    checked_list = defaultdict(ll)
    for key in arg:
        if not checked_list[key]:
            if key==0:
                pair.append([arg[0],arg[float("inf")]])
                checked_list[float("inf")] = True
            elif key==float("inf"):
                pair.append([arg[0],arg[float("inf")]])
                checked_list[0] = True

            else:
                
                pair.append([arg[key],arg[inv(*key)]])
                
                checked_list[inv(*key)] = True

    mod = 1000000007

    ans = 1

    for p1,p2 in pair:
        ans *= pow(2,p1,mod) + pow(2,p2,mod) - 1
        ans %= mod

    ans += zero
    ans %= mod

    print((ans+mod-1)%mod)

if __name__ == '__main__':
    main()