use maplit::hashmap;
use num::{rational::Ratio, One};
use proconio::input;
use std::{
    fmt,
    iter::{Product, Sum},
    ops::{Add, Div, Mul, Sub},
};

fn main() {
    input! {
        n: usize,
        abs: [(i64, i64); n],
    }

    let mut zeros = 0;
    let mut rights = 0;
    let mut lefts = 0;
    let mut ups = 0;
    let mut downs = 0;
    let mut other_pos = hashmap!();
    let mut other_neg = hashmap!();

    for (a, b) in abs {
        match (a.signum(), b.signum()) {
            (0, 0) => zeros += 1,
            (0, 1) => rights += 1,
            (0, -1) => lefts += 1,
            (1, 0) => ups += 1,
            (-1, 0) => downs += 1,
            (1, 1) | (-1, -1) => *other_pos.entry(Ratio::new(a, b)).or_insert(0) += 1usize,
            (1, -1) | (-1, 1) => *other_neg.entry(Ratio::new(a, b)).or_insert(0) += 1usize,
            _ => unreachable!(),
        }
    }

    let ans = ModInt::unchecked(zeros)
        + num::pow(ModInt::unchecked(2), n - zeros)
            * mag(rights, downs)
            * mag(downs, lefts)
            * mag(lefts, ups)
            * mag(ups, rights)
            * other_pos
                .iter()
                .flat_map(|(grad, &num1)| other_neg.get(&-grad.recip()).map(|&num2| (num1, num2)))
                .map(|(num1, num2)| mag(num1, num2))
                .product::<ModInt>()
        - ModInt::unchecked(1);
    println!("{}", ans);
}

fn mag(a: usize, b: usize) -> ModInt {
    if a == 0 || b == 0 {
        ModInt::unchecked(1)
    } else {
        (num::pow(ModInt::unchecked(2), a) + num::pow(ModInt::unchecked(2), b)
            - ModInt::unchecked(1))
            / num::pow(ModInt::unchecked(2), a + b)
    }
}

const P: usize = 1_000_000_007;

#[derive(Clone, Copy, Debug)]
struct ModInt {
    repr: usize,
}

impl ModInt {
    fn new(val: usize) -> Self {
        Self { repr: val % P }
    }

    fn unchecked(repr: usize) -> Self {
        Self { repr }
    }
}

impl One for ModInt {
    fn one() -> Self {
        Self::unchecked(1)
    }
}

impl fmt::Display for ModInt {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.repr, fmt)
    }
}

impl Add for ModInt {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        Self::new(self.repr + rhs.repr)
    }
}

impl Sub for ModInt {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        Self::new(P + self.repr - rhs.repr)
    }
}

impl Mul for ModInt {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        Self::new(self.repr * rhs.repr)
    }
}

impl Div for ModInt {
    type Output = Self;

    fn div(self, rhs: Self) -> Self {
        self * num::pow(rhs, P - 2)
    }
}

impl Sum for ModInt {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::unchecked(0), Add::add)
    }
}

impl Product for ModInt {
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::unchecked(1), Mul::mul)
    }
}
