using System.Numerics;
using System.Collections.Generic;
using System;

public struct P
{
    public long a { get; set; }
    public long b { get; set; }
}

public class Hello
{
    public static int MOD = 1000000007;
    public static void Main()
    {
        var d = new Dictionary<P, int>();
        var n = int.Parse(Console.ReadLine().Trim());
        var zc = 0L;
        for (int i = 0; i < n; i++)
        {
            string[] line = Console.ReadLine().Trim().Split(' ');
            var a = long.Parse(line[0]);
            var b = long.Parse(line[1]);
            if (a > 0 && b > 0)
            {
                var g = gcd(a, b);
                a /= g;
                b /= g;
                var w = new P { a = a, b = b };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
            else if (a > 0 && b < 0)
            {
                var g = gcd(a, -b);
                a /= g;
                b /= g;
                var w = new P { a = a, b = b };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
            else if (a < 0 && b > 0)
            {
                var g = gcd(-a, b);
                a /= g;
                b /= g;
                var w = new P { a = -a, b = -b };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
            else if (a < 0 && b < 0)
            {
                var g = gcd(-a, -b);
                a /= g;
                b /= g;
                var w = new P { a = -a, b = -b };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
            else if (a == 0 && b == 0) zc++;
            else if (a == 0)
            {
                var w = new P { a = 0, b = 1 };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
            else if (b == 0)
            {
                var w = new P { a = 1, b = 0 };
                if (d.ContainsKey(w)) d[w]++;
                else d[w] = 1;
            }
        }
        getAns(d, zc);
    }
    static void getAns(Dictionary<P, int> d, long zc)
    {
        var ans = 1L;
        foreach (var x in d)
        {
            var a = x.Key.a;
            var b = x.Key.b;
            var w = new P();
            if (b > 0) { w.a = b; w.b = -a; }
            else if (b < 0) { w.a = -b; w.b = a; }
            else if (a == 0) { w.a = 1; w.b = 0; }
            else { w.a = 0; w.b = 1; }
            if (d.ContainsKey(w))
            {
                if (w.a > a | (w.a == a && w.b < b))
                {
                    var k = d[w];
                    BigInteger f0 = BigInteger.ModPow(2, x.Value, MOD);
                    BigInteger f1 = BigInteger.ModPow(2, k, MOD);
                    BigInteger f = (f0 + f1 - 1L) % MOD;
                    ans *= (long)f;
                    ans %= MOD;
                }
                else continue;
            }
            else
            {
                BigInteger f = BigInteger.ModPow(2, x.Value, MOD);
                ans *= (long)f;
                ans %= MOD;
            }
        }
        zc %= MOD;
        Console.WriteLine((ans + zc - 1) % MOD);
    }
    public static long gcd(long a, long b)
    {
        if (a < b) return gcd(b, a);
        while (b != 0)
        {
            var w = a % b;
            a = b;
            b = w;
        }
        return a;
    }
}
