merge :: (Ord a) => [a] -> [a] -> [a]
merge [] xs = xs
merge xs [] = xs
merge (x:xs) (y:ys)
  | x > y     = x : merge xs (y:ys)
  | otherwise = y : merge (x:xs) ys

f :: Integer -> Int -> Integer
f x 0 = 1
f x y = x * f x (y - 1)

msort :: [Integer] -> [Integer]
msort [] = []
msort [x] = [x]
msort xs = merge (msort $ take h xs) (msort $ drop h xs)
  where h = length xs `div` 2

getNumber :: String -> [Integer]
getNumber xs = (read (fst h) :: Integer) : case snd h of
                                         [] -> []
                                         (_:xs') -> getNumber xs'
  where h = break (== ' ') xs

reduceNumber :: [Integer] -> Bool
reduceNumber [] = True
reduceNumber [x] = if x == 0 then True else False 
reduceNumber (x:y:zs)
  | odd h     = if x == h && y == h then reduceNumber zs else False
  | otherwise = if x == h && y == h then reduceNumber zs else False
    where h = fromIntegral $ length (x:y:zs) - 1 :: Integer

main = do
  num <- getLine
  nums <- fmap getNumber getLine
  let result = if (reduceNumber.msort) nums 
                 then if odd $ length nums 
                          then 2 `f` (((length nums) - 1) `div` 2)
                          else 2 `f` ((length nums) `div` 2)
                 else 0
  putStrLn $ show $ result `mod` 1000000007