import java.util.*

fun main(args: Array<String>) {
    val N = readLine()!!.toInt()
    val map = HashMap<V, MutablePair<Long, Long>>()
    var zero = 0L
    repeat(N) {
        val (x, y) = readLine()!!.split(" ").map(String::toLong)
        if (x == 0L && y == 0L) {
            zero++
            return@repeat
        }
        var v = V(x, y).gcd_normalized()
        if (y < 0 || (y == 0L && x < 0)) {
            v = v.rot180()
        }
        val rot = x <= 0
        if (rot) {
            v = v.rot270()
        }
        if (!map.contains(v)) map[v] = MutablePair(0L, 0L)
        if (rot) map[v]!!.g1++
        else map[v]!!.g2++
    }
    var ans = MInt(1)
    map.values.forEach { g ->
        var sum = MInt(1)
        sum += MInt(2).pow(g.g1) - 1
        sum += MInt(2).pow(g.g2) - 1
        ans *= sum
    }
    ans -= 1 // answer should select at lease 1 fish, so remove a patten that no fish selected
    ans += zero // fish(0,0) is only valid for a pattern in which only the fish is selected.
    println(ans)
}

data class MutablePair<A, B>(var g1: A, var g2: B)

data class V(val x: Long, val y: Long) {
    fun rot90() = V(-y, x)
    fun rot180() = V(-x, -y)
    fun rot270() = V(y, -x)
    fun gcd_normalized() = V(x / gcd(x, y), y / gcd(x, y))
}

fun gcd(a: Long, b: Long): Long {
    if (a < b) return gcd(b, a)
    if (b == 0L) return a
    return gcd(b, a % b)
}

class MInt {
    private val MOD = 1000000007L
    var v: Long

    constructor(v: Long) {
        this.v = v % MOD
    }

    constructor(v: Int) {
        this.v = v.toLong() % MOD
    }

    operator fun plus(b: MInt): MInt {
        val a = MInt(v)
        a.v += b.v
        if (a.v >= MOD) a.v -= MOD
        return a
    }

    operator fun plus(b: Int) = plus(MInt(b))
    operator fun plus(b: Long) = plus(MInt(b))

    operator fun minus(b: MInt): MInt {
        val a = MInt(v)
        a.v -= b.v
        if (a.v < 0) a.v += MOD
        return a
    }

    operator fun minus(b: Int) = minus(MInt(b))
    operator fun minus(b: Long) = minus(MInt(b))

    operator fun times(b: MInt): MInt {
        val a = MInt(v)
        a.v *= b.v
        a.v %= MOD
        return a
    }

    operator fun div(b: MInt): MInt {
        return MInt(v) * b.inv()
    }

    fun inv(): MInt {
        var a = v
        var b = MOD
        var u = 1L
        var w = 0L
        while (b != 0L) {
            val t = a / b
            a -= t * b
            u -= t * w
            var tmp = a
            a = b
            b = tmp
            tmp = u
            u = w
            w = tmp
        }
        u %= MOD
        if (u < 0) u += MOD
        return MInt(u)
    }

    fun pow(N: Int) = pow(N.toLong())

    fun pow(N: Long): MInt {
        var ans = MInt(1)
        var a = this
        var n = N
        while (n > 0) {
            if (n.and(1) == 1L) {
                ans *= a
            }
            a *= a
            n = n.shr(1)
        }
        return ans
    }

    override fun toString(): String {
        return v.toString()
    }
}