program abc168e
    use,intrinsic :: iso_fortran_env
    implicit none
    integer(int64):: n,i
    integer(int64):: a_zero,b_zero,cp,cm,czz
    integer(int64):: nakawaru
    integer(int64):: pi,mi,g
    integer(int64):: dp,dm,ans
    integer(int64), parameter:: md=1000000007
    integer(int64), allocatable:: a(:),b(:)
    integer(int64), allocatable:: pa(:),pb(:)
    integer(int64), allocatable:: ma(:),mb(:)


    read*, n
    allocate(a(n),b(n))
    cp=0
    b_zero=0
    a_zero=0
    czz=0
    do i=1,n
        read*, a(i),b(i)
    end do

    do i=1,n
        if (a(i)==0 .and. b(i)==0)then
            czz=czz+1
        else if (a(i) == 0) then
            a_zero=a_zero+1
        else if (b(i) == 0) then
            b_zero=b_zero+1
        else if (a(i) > 0 .and. b(i) > 0) then
            cp=cp+1
        end if
    end do
    cm = n-czz-a_zero-b_zero-cp
    allocate(pa(cp),pb(cp))
    allocate(ma(cm),mb(cm))
    pi=1
    mi=1
    ans = mod((factorial(2_8,a_zero,md)+factorial(2_8,b_zero,md)-1),md)
    
    do i=1,n
        if (a(i)==0 .or. b(i)==0) cycle
        g = abs(gcd(a(i),b(i)))
        if (a(i)>0 .and. b(i)>0) then
            pa(pi)=a(i)/g
            pb(pi)=b(i)/g
            pi=pi+1
        else
            ma(mi)=abs(a(i))/g
            mb(mi)=abs(b(i))/g
            mi=mi+1
        end if
    end do
    call double_sort(pb,pa,1_8,cp)
    call double_sort(pa,pb,1_8,cp)
    call double_sort(ma,mb,1_8,cm)
    call double_sort(mb,ma,1_8,cm)

    pi=1
    mi=1
    do while(pi <= cp .and. mi <= cm)
        if (pa(pi) > mb(mi)) then
            ans=mod(ans*2,md)
            mi=mi+1
        else if (pa(pi) < mb(mi)) then
            ans=mod(ans*2,md)
            pi=pi+1
        else
            if (pb(pi) > ma(mi)) then
                ans=mod(ans*2,md)
                mi=mi+1
            else if (pb(pi) < ma(mi)) then
                ans=mod(ans*2,md)
                pi=pi+1
            else
                dp=0
                dm=0
                do while(pb(pi)==pb(pi+dp) .and. pa(pi)==pa(pi+dp))
                    dp=dp+1
                    if (pi+dp > cp) exit
                end do
                do while(ma(mi)==ma(mi+dm) .and. mb(mi)==mb(mi+dm))
                    dm=dm+1
                    if (mi+dm > cm) exit
                end do
                nakawaru = mod(factorial(2_8,dp,md)+factorial(2_8,dm,md)-1,md)
                ans=mod(ans*nakawaru,md)
                pi=pi+dp
                mi=mi+dm
            end if
        end if
    end do
    ans=mod(ans*(factorial(2_8,cp-pi+1,md)+factorial(2_8,cm-mi+1,md)-1),md)
    print'(i0)', mod(ans+czz-1,md)
contains
    function factorial(a,b,md) result(ret)
        integer(int64):: a,b,md
        integer(int64):: aa,bb,ret
        aa = a
        bb = b
        ret = 1
        do while(bb > 0)
            if (mod(bb,2_8)/=0) ret=mod(ret*aa,md)
            aa=mod(aa*aa,md)
            bb=bb/2
        end do
    end function


    recursive function gcd(x,y) result(ret)
        integer(int64):: x,y,ret

        if (mod(x,y) == 0) then
            ret = y
            return
        end if

        ret = gcd(y,mod(x,y))
    end function

    recursive subroutine double_sort(ar1, ar2, fst, lst)
        integer(8),intent(inout):: ar1(:),ar2(:)
        integer(8),intent(in):: fst,lst
        integer(8):: mdl

        if (lst - fst < 2) then
            if (ar1(fst) > ar1(lst)) then
                call swap(ar1(fst), ar1(lst))
                call swap(ar2(fst), ar2(lst))
            end if
            return
        end if

        mdl = (fst+lst)/2

        call double_sort(ar1,ar2,fst,mdl)
        call double_sort(ar1,ar2,mdl+1,lst)
        call double_merge_(ar1,ar2,fst,mdl,lst)
    end subroutine


    subroutine double_merge_(ar1,ar2,fst,mdl,lst)
        integer(8),intent(inout):: ar1(:),ar2(:)
        integer(8),intent(in):: fst,mdl,lst
        integer(8),allocatable:: t1(:),t2(:)
        integer(8):: li,ri,ti

        allocate(t1(lst-fst+1), t2(lst-fst+1))

        li=fst
        ri=mdl+1
        ti=1

        do while(li <= mdl .and. ri <= lst)
            if (ar1(li) <= ar1(ri)) then
                t1(ti) = ar1(li) 
                t2(ti) = ar2(li)
                li=li+1
            else
                t1(ti) = ar1(ri)
                t2(ti) = ar2(ri)
                ri=ri+1
            end if
            ti=ti+1
        end do

        if (li <= mdl) then
            t1(ti:) = ar1(li:mdl)
            t2(ti:) = ar2(li:mdl)
        else
            t1(ti:) = ar1(ri:lst)
            t2(ti:) = ar2(ri:lst)
        end if

        ar1(fst:lst) = t1(:)
        ar2(fst:lst) = t2(:)

        deallocate(t1,t2)
    end subroutine

    
    subroutine swap(x,y)
        integer(8),intent(inout):: x,y
        integer(8):: tmp
        tmp = x
        x = y
        y = tmp
    end subroutine
end program abc168e