//use proconio::{input, fastout};
use proconio::input;
use std::collections::BTreeMap;

const M: u128 = 1_000_000_007;

//#[fastout]
fn main() {
    input! {
        n: usize,
        d: [(i32, i32); n],
    }

    let mut t = BTreeMap::new();
    for e in d {
        let g = num::integer::gcd(e.0.abs(), e.1.abs());
        let e = if e.0 < 0 {
            (-e.0, -e.1)
        } else {
            e
        };
        let e = (e.0 / g, e.1 / g);
        *t.entry((e.0, e.1)).or_insert(0) += 1;
    }
    let z = t.remove(&(0, 0)).map_or(0, |c| c) % M;
    let mut ans: u128 = 1;
    while let Some((&k, &c)) = t.iter().next() {
        t.remove(&k);
        let p = if k.1 < 0 {
            (-k.1, k.0)
        } else {
            (k.1, -k.0)
        };

        let mut c2 = 1;
        for _ in 0..c {
            c2 = c2 * 2 % M;
        }
        if let Some(invc) = t.remove(&p) {
            let mut i2 = 1;
            for _ in 0..invc {
                i2 = i2 * 2 % M;
            }
            ans = ans * ((c2 + i2 - 1) % M) % M;
        } else {
            ans = ans * c2 % M;
        }
    }
    ans = (ans + z - 1) % M;
    println!("{}", ans);
}
