using System;
using System.Collections.Generic;

public class Hello
{
    public static void Main()
    {

        int  n = int.Parse(System.Console.ReadLine());
        var iwashi = new Dictionary<Tuple<long, long>, Tuple<long,long>>();
        long sum = 1;
        long zero = 0;

        for(int i=0; i < n; i++)
        {
            long[] ab = Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
            long tmp,gcd = 0;
            int sign = Math.Sign(ab[0])*Math.Sign(ab[1]);
            ab[0] = Math.Abs(ab[0]);
            ab[1] = Math.Abs(ab[1]);


            switch (sign)
            {
                case 0:


                    if (ab[0] == 0 && ab[1] != 0) { ab[0] = (long)1; ab[1] = (long)0; sign = 1; }
                    else if (ab[0] != 0 && ab[1] == 0) {ab[0] = (long)1; ab[1] = (long)0; sign = -1; }
                    else if (ab[0] == 0 && ab[1] == 0) {  sign = 0; zero += 1; }
                    if (!iwashi.ContainsKey(Tuple.Create(ab[0], ab[1])))
                    {
                        iwashi.Add(Tuple.Create(ab[0], ab[1]), Tuple.Create((long)0, (long)0));
                    }
                    break;

                case -1:
                    tmp = ab[0];
                    ab[0] = ab[1];
                    ab[1] = tmp;
                    gcd = Gcd(ab[0], ab[1]);
                    ab[0] /= gcd;
                    ab[1] /= gcd;
                    if (!iwashi.ContainsKey(Tuple.Create(ab[0], ab[1])))
                    {
                        iwashi.Add(Tuple.Create(ab[0], ab[1]), Tuple.Create((long)0, (long)0));
                    }
                    break;
                case 1:
                    gcd = Gcd(ab[0], ab[1]);
                    ab[0] /= gcd;
                    ab[1] /= gcd;
                    if (!iwashi.ContainsKey(Tuple.Create(ab[0], ab[1])))
                    {
                        iwashi.Add(Tuple.Create(ab[0], ab[1]), Tuple.Create((long)0, (long)0));
                    }
                    break;
            }



            (long a, long b) = iwashi[Tuple.Create(ab[0], ab[1])];
            switch (sign)
            {
                case 1:
                    a+=1;
                    iwashi[Tuple.Create(ab[0], ab[1])] = Tuple.Create(a, b);
                    break;
                case -1:
                    b+=1;
                    iwashi[Tuple.Create(ab[0], ab[1])] = Tuple.Create(a, b);
                    break;
            }
        }
        
        foreach(KeyValuePair<Tuple<long,long>,Tuple<long,long>> kvp in iwashi)
        {
            long sum1 = 0;
            checked
            {
                sum1 = 0;
                sum1 = (Pow(2, kvp.Value.Item1) - 1) % 1000000007;
                if (sum1 < 0) sum1 += 1000000007;
                sum1 += (Pow(2, kvp.Value.Item2) - 1)%1000000007;
                if (sum1 < 0) sum1 += 1000000007;
                sum1 += 1 % 1000000007;
                sum %= 1000000007;
                sum *= (sum1 % 1000000007);
            }
        }
        checked
        {
            sum = (sum - 1) % 1000000007;
            if (sum < 0) sum +=  1000000007;
            sum = (sum + zero) % 1000000007;
            System.Console.WriteLine(sum);
        }
    }

    public static long Gcd(long a,long b)
    {
        var v = new[] { a, b };
        while(v[1] !=0)
        {
            v = new[] { v[1], v[0] % v[1] };
        }
        return v[0];
    }

    public static long Pow(long a, long pow)
    {
        a %= 1000000007;
        checked
        {
            if (pow == 1)
            {
                return a % 1000000007;
            }
            else if (pow == 0)
            {
                return 1;
            }
            else if (pow % 2 == 1)
            {
                return ((a % 1000000007) * Pow(a % 1000000007, pow - 1)) % 1000000007;
            }
            else
            {
                return pow % 2 == 0 ? Pow((a % 1000000007) * (a % 1000000007) % 1000000007, pow / 2) : 1;
            }
        }
    }

    private static long NewMethod(long a)
    {
        a = a % 1000000007;
        return a;
    }

    public struct ab
    {
        public long a;
        public long b;
        public long qu;
    }
}

Measured memory_bytes: 66252