use proconio::input;
use std::collections::HashMap;

struct Iwashi {
    a:i64,
    b:i64,
}

const MOD:i64 = 1e9 as i64 + 7;
fn main() {
    let (n,iwashi) = {
        input! {
            n:usize,
            ab:[(i64,i64);n],
        }; 
        let iwashi:Vec<Iwashi> = ab.into_iter().map(|(a,b)|Iwashi{a,b}).collect();
        (n,iwashi)
    };
    
    
    let iwashi:Vec<Iwashi> = iwashi.into_iter().filter(|iwa|iwa.a!=0 || iwa.b!=0).collect();
    let zcnt = (n - iwashi.len()) as i64;

    let iwashi:Vec<Iwashi> = iwashi.into_iter().map(|iwa|{
        let g = num::integer::gcd(iwa.a,iwa.b);
        let a = iwa.a/g;
        let b = iwa.b/g;
        Iwashi{a,b}
    }).collect();

    let ps:Vec<(i64,i64)> = iwashi.iter().map(|iwa|(iwa.a,iwa.b)).collect();
    let mut iwadic = HashMap::new();

    iwashi.iter().for_each(|iwa|{
        let count = iwadic.entry((iwa.a,iwa.b)).or_insert(0);
        *count += 1;
    });

    let mut res:i64 = 1;
    let mut pow2:Vec<i64> = vec![1;n+1];
    for i in 0..n {
        pow2[i+1]=pow2[i]*2%MOD;
    }
    for (a,b) in ps {
        let key0 = (a,b);
        let key1 = (-a,-b);
        let key2 = (-b,a);
        let key3 = (b,-a);
        let keys = vec![key0,key1,key2,key3];
        let mut sum0 = 0;
        let mut sum2 = 0;
        for i in 0..4 {
            if let Some(val) = iwadic.get(&keys[i]) {
                if i<2 {
                    sum0+=*val;    
                }
                else {
                    sum2+=*val;
                }
                iwadic.remove(&keys[i]);
            }
        }
        let sum = (pow2[sum0 as usize] + pow2[sum2 as usize] -1)%MOD;
        res*=sum;
        res%=MOD;
    }
    
    res-=1;
    
    println!("{}",(zcnt+res)%MOD);
    
}
