#![allow(non_snake_case)]
#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

pub mod mod_int {
    use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
    const MOD: usize = 1e9 as usize + 7;
    #[derive(Clone, Copy, Debug)]
    pub struct ModInt<T: Copy + Clone + Add + AddAssign + Mul + MulAssign + Sub + SubAssign>(pub T);
    #[warn(unused_macros)]
    macro_rules !mod_int_impl {($($t :ty ) *) =>($(impl Add <ModInt <$t >>for ModInt <$t >{type Output =ModInt <$t >;fn add (self ,other :ModInt <$t >) ->ModInt <$t >{self +other .0 } } impl Add <$t >for ModInt <$t >{type Output =ModInt <$t >;fn add (self ,rhs :$t ) ->ModInt <$t >{let mut tmp =rhs +self .0 ;if tmp >=self ::MOD as $t {tmp =tmp -self ::MOD as $t ;} ModInt (tmp ) } } impl Sub <ModInt <$t >>for ModInt <$t >{type Output =ModInt <$t >;fn sub (self ,rhs :ModInt <$t >) ->ModInt <$t >{self -rhs .0 } } impl Sub <$t >for ModInt <$t >{type Output =ModInt <$t >;fn sub (self ,rhs :$t ) ->ModInt <$t >{let rhs =if rhs >=self ::MOD as $t {rhs %self ::MOD as $t } else {rhs } ;let value =if self .0 <rhs {self .0 +self ::MOD as $t } else {self .0 } ;ModInt (value -rhs ) } } impl AddAssign <ModInt <$t >>for ModInt <$t >{fn add_assign (&mut self ,rhs :ModInt <$t >) {*self =*self +rhs ;} } impl AddAssign <$t >for ModInt <$t >{fn add_assign (&mut self ,rhs :$t ) {*self =*self +rhs ;} } impl SubAssign <ModInt <$t >>for ModInt <$t >{fn sub_assign (&mut self ,rhs :ModInt <$t >) {*self =*self -rhs ;} } impl SubAssign <$t >for ModInt <$t >{fn sub_assign (&mut self ,rhs :$t ) {*self =*self -rhs ;} } impl Div <$t >for ModInt <$t >{type Output =ModInt <$t >;fn div (self ,mut rhs :$t ) ->ModInt <$t >{if rhs >=MOD as $t {rhs %=MOD as $t ;} self *ModInt (rhs ) .pow ((MOD -2 ) as usize ) } } impl Div <ModInt <$t >>for ModInt <$t >{type Output =ModInt <$t >;fn div (self ,rhs :ModInt <$t >) ->ModInt <$t >{self /rhs .0 } } impl DivAssign <$t >for ModInt <$t >{fn div_assign (&mut self ,rhs :$t ) {*self =*self /rhs } } impl DivAssign <ModInt <$t >>for ModInt <$t >{fn div_assign (&mut self ,rhs :ModInt <$t >) {*self =*self /rhs } } impl Mul <ModInt <$t >>for ModInt <$t >{type Output =ModInt <$t >;fn mul (self ,rhs :ModInt <$t >) ->ModInt <$t >{self *rhs .0 } } impl Mul <$t >for ModInt <$t >{type Output =ModInt <$t >;fn mul (self ,rhs :$t ) ->ModInt <$t >{ModInt (self .0 *rhs %self ::MOD as $t ) } } impl MulAssign <ModInt <$t >>for ModInt <$t >{fn mul_assign (&mut self ,rhs :ModInt <$t >) {*self =*self *rhs ;} } impl MulAssign <$t >for ModInt <$t >{fn mul_assign (&mut self ,rhs :$t ) {*self =*self *rhs ;} } impl ModInt <$t >{pub fn new (x :$t ) ->Self {ModInt (x %self ::MOD as $t ) } pub fn pow (self ,e :usize ) ->ModInt <$t >{let mut result =ModInt ::<$t >::new (1 ) ;let mut cur =self ;let mut e =e ;while e >0 {if e &1 ==1 {result *=cur ;} cur *=cur ;e >>=1 ;} result } } ) *) }
    mod_int_impl !(usize i32 i64 u32 u64 ) ;
}

#[fastout]
fn main() {
    input!{
        n: usize,
        mut a_vec: [usize; n],
    }

    type ModInt = mod_int::ModInt<usize>;
    // nの偶奇で場合分け
    a_vec.sort();
    if n % 2 == 0 {
        let mut ideal_vec = (1..=n).cycle().take(2*n).filter(|&x| x % 2 != 0).collect::<Vec<usize>>();
        ideal_vec.sort();
        // dbg!(&ideal_vec);
        if a_vec != ideal_vec {
            println!("0")
        } else {
            println!("{}", ModInt::new(2).pow(n/2).0)
        }
    } else {
        let mut ideal_vec = (0..n).cycle().take(2*n).skip(1).filter(|&x| x % 2 == 0).collect::<Vec<usize>>();
        ideal_vec.sort();
        // dbg!(&ideal_vec);
        if a_vec != ideal_vec {
            println!("0")
        } else {
            println!("{}", ModInt::new(2).pow(n/2).0)
        }
    }

    println!("", );
}


Measured memory_bytes: 4572