import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Read as T
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as MS

main :: IO ()
main = do
  n <- unsafeTextToInt <$> T.getLine :: IO Int
  abs <- sequence . replicate n $ unsafeListToPair . map unsafeTextToInt . T.words <$> T.getLine :: IO [(Int, Int)]
  let
    counts = MS.fromListWith (+) . map (either (flip (,) (10 ^ 6)) (flip (,) 1) . key) $ abs :: Map (Int, Int) Int
    p = MS.foldl' step 1 counts :: Int
      where
        step :: Int -> Int -> Int
        step pp k = modMul modulus pp $ modSub modulus (modAdd modulus (modExp modulus 2 i) (modExp modulus 2 j)) 1
          where
            (i, j) = decode k :: (Int, Int)
  print $ modSub modulus p 1

modulus = 10 ^ 9 + 7 :: Int
{-# INLINE modulus #-}

modAdd :: Int -> Int -> Int -> Int
modAdd m x y = (x + y) `mod` m
{-# INLINE modAdd #-}

modSub :: Int -> Int -> Int -> Int
modSub m x y = (x - y) ` mod` m
{-# INLINE modSub #-}

modMul :: Int -> Int -> Int -> Int
modMul m x y = (x * y) `mod` m
{-# INLINE modMul #-}

modSqu :: Int -> Int -> Int
modSqu m x = (x * x) `mod` m
{-# INLINE modSqu #-}

modExp :: Int -> Int -> Int -> Int
modExp m = modExp' 1
  where
    modExp' :: Int -> Int -> Int -> Int
    modExp' z _ 0 = z
    modExp' z x y = modExp' z' x' y'
      where
        (y', r) = y `divMod` 2 :: (Int, Int)
        x' = modSqu m x :: Int
        z' :: Int
        z' | r == 0    = z
           | otherwise = modMul m z x
{-# INLINE modExp #-}

encode :: (Int, Int) -> Int
encode (i, j) = i * 10 ^ 6 + j
{-# INLINE encode #-}

decode :: Int -> (Int, Int)
decode k = k `divMod` (10 ^ 6)
{-# INLINE decode #-}

key :: (Int, Int) -> Either (Int, Int) (Int, Int)
key (x, y) = case (compare x 0, compare y 0) of
               (LT, LT) -> Left (-y', x')
               (LT, EQ) -> Left (-y', x')
               (LT, GT) -> Right (-x', -y')
               (EQ, LT) -> Right (x', y')
               (EQ, EQ) -> Right (x', y')
               (EQ, GT) -> Right (-x', -y')
               (GT, LT) -> Right (x', y')
               (GT, EQ) -> Left (y', -x')
               (GT, GT) -> Left (y', -x')
  where
    d = gcd x y :: Int
    x' = x `div` d :: Int
    y' = y `div` d :: Int
{-# INLINE key #-}

unsafeListToPair :: [Int] -> (Int, Int)
unsafeListToPair [x, y] = (x, y)
{-# INLINE unsafeListToPair #-}

unsafeTextToInt :: T.Text -> Int
unsafeTextToInt s = case T.signed T.decimal s of
  Right (n, _) -> n
{-# INLINE unsafeTextToInt #-}
