#![allow(non_snake_case)]
use num::integer::gcd;
use proconio::input;
use std::collections::HashMap;
const M: i64 = 1000000007_i64;
fn main() {
    input! {
        n:usize,
        AB:[(i64,i64);n]
    }
    // 鰯(Ai,Bi)と(Aj,Bj)について、Ai*Aj + Bi*Bj =0になる組み合わせは不可。
    // (0,0)の鰯の数を x とすると、これらは一匹のみの場合のみ追加可能。
    // 両辺を Aj * Bi で割ると、Ai/Bi + Bj/Aj = 0となる。
    // 逆数にして -1 をかけた鰯とは組み合わせられないが、他ならOK。
    // 鰯について、既約分数で表現すれば、Ai/Biは一意に定まる。
    let mut group1 = HashMap::new();
    // modPow(2,x)
    let mut mp2 = vec![1i64; n + 1];
    for i in 0..n {
        mp2[i + 1] = mp2[i] * 2 % M;
    }
    let AB: Vec<(i64, i64)> = AB.into_iter().filter(|&(a, b)| a != 0 || b != 0).collect();
    let zero = (n - AB.len()) as i64;
    let AB: Vec<(i64, i64)> = AB
        .into_iter()
        .map(|(a, b)| {
            let g = gcd(a, b);
            (a / g, b / g)
        })
        .collect();
    for &x in AB.iter() {
        *group1.entry(x).or_insert(0) += 1;
    }
    let mut ans = 1;

    let mut get_pararell = |a: i64, b: i64| {
        let mut res = 0;
        if let Some(v) = group1.get(&(a, b)) {
            res += v;
            group1.remove(&(a, b));
        }
        if let Some(v) = group1.get(&(-a, -b)) {
            res += v;
            group1.remove(&(-a, -b));
        }
        res
    };
    //    println!("{:?}", group1);
    for &(a, b) in AB.iter() {
        let pararells = get_pararell(a, b);
        let crosses = get_pararell(b, -a);
        // println!("({},{}), p:{}, c:{}", a, b, pararells, crosses);
        ans = ans * ((mp2[pararells] + mp2[crosses] - 1) % M) % M;
    }
    ans = (ans + zero - 1) % M;
    println!("{}", ans);
}

// また、bの符号に一致する様に計算する。

fn yakubun(a: i64, b: i64) -> (i64, i64) {
    if b == 0 {
        return (-1, 0);
    }
    if a == 0 {
        return (0, 1);
    }
    let x = if b > 0 { gcd(a, b) } else { -gcd(a, b) };
    return (a / x, b / x);
}
//
//fn modPow(x: i64, a: i64, mp2: &Vec<i64>) -> i64 {
//    if x == 2 && (a as usize) < mp2.len() {
//        return mp2[a as usize];
//    }
//    if a == 1 {
//        x
//    } else {
//        if a % 2 != 0 {
//            (modPow(x, a - 1, &mp2) * x) % M
//        } else {
//            let t = modPow(x, a / 2, &mp2);
//            t * t % M
//        }
//    }
//}
////fn modInv(x: i64) -> i64 {
////    modPow(x, M - 2)
//}
