// ---------- begin ModInt ----------
const MOD: u32 = 1_000_000_007;

#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------
// ---------- begin Tree DP ----------
struct TreeDP<Edge, Value, Init, Merge> {
    size: usize,
    graph: Vec<Vec<(usize, Edge)>>,
    init: Init,
    merge: Merge,
    phantom: std::marker::PhantomData<Value>,
}

impl<Edge, Value, Init, Merge> TreeDP<Edge, Value, Init, Merge>
where Edge: Clone,
      Value: Clone,
      Init: Fn(usize) -> Value,
      Merge: Fn(Value, Value, &Edge) -> Value,
{
    fn new(size: usize, init: Init, merge: Merge) -> Self {
        TreeDP {
            size: size,
            graph: vec![vec![]; size],
            init: init,
            merge: merge,
            phantom: std::marker::PhantomData,
        }
    }
    fn add_edge(&mut self, a: usize, b: usize, c: Edge) {
        assert!(a < self.size && b < self.size && a != b);
        self.graph[a].push((b, c.clone()));
        self.graph[b].push((a, c));
    }
    fn solve(&self, root: usize) -> Value {
        let size = self.size;
        let graph = &self.graph;
        let mut topo = vec![];
        let mut parent = vec![root; size];
        let mut stack = vec![root];
        while let Some(v) = stack.pop() {
            topo.push(v);
            for e in graph[v].iter() {
                if e.0 != parent[v] {
                    parent[e.0] = v;
                    stack.push(e.0);
                }
            }
        }
        assert!(topo.len() == size);
        let mut dp: Vec<Option<Value>> = (0..size).map(|_| None).collect();
        for &v in topo.iter().rev() {
            let mut now = (self.init)(v);
            for u in graph[v].iter() {
                if u.0 == parent[v] {
                    continue;
                }
                let b = dp[u.0].take().unwrap();
                now = (self.merge)(now, b, &u.1);
            }
            dp[v] = Some(now);
        }
        dp[root].take().unwrap()
    }
}
// ---------- end Tree DP ----------
// ---------- begin karatsuba multiplication ----------
fn karatsuba<T>(a: &[T], b: &[T], c: &mut [T], zero: T, buf: &mut [T]) 
where T: std::marker::Copy +
         std::ops::Add<Output = T> +
         std::ops::Sub<Output = T> +
         std::ops::Mul<Output = T> +
{
    let n = a.len();
    if n <= 32 {
        for (i, a) in a.iter().enumerate() {
            for (c, b) in c[i..].iter_mut().zip(b.iter()) {
                *c = *c + *a * *b;
            }
        }
        return;
    }
    if n & 1 == 1 {
        karatsuba(&a[1..], &b[1..], &mut c[2..], zero, buf);
        let x = a[0];
        let y = b[0];
        c[0] = c[0] + x * y;
        for (c, (a, b)) in c[1..].iter_mut().zip(a[1..].iter().zip(b[1..].iter())) {
            *c = *c + x * *b + *a * y;
        }
        return;
    }
    let m = n / 2;
    karatsuba(&a[..m], &b[..m], &mut c[..n], zero, buf);
    karatsuba(&a[m..], &b[m..], &mut c[n..], zero, buf);
    let (x, buf) = buf.split_at_mut(m);
    let (y, buf) = buf.split_at_mut(m);
    let (z, buf) = buf.split_at_mut(n);
    for z in z.iter_mut() {
        *z = zero;
    }
    for (x, (p, q)) in x.iter_mut().zip(a.iter().zip(a[m..].iter())) {
        *x = *p + *q;
    }
    for (y, (p, q)) in y.iter_mut().zip(b.iter().zip(b[m..].iter())) {
        *y = *p + *q;
    }
    karatsuba(x, y, z, zero, buf);
    for (z, (p, q)) in z.iter_mut().zip(c[..n].iter().zip(c[n..].iter())) {
        *z = *z - (*p + *q);
    }
    for (c, z) in c[m..].iter_mut().zip(z.iter()) {
        *c = *c + *z;
    }
}

fn multiply<T>(a: &[T], b: &[T], zero: T) -> Vec<T>
where T: std::marker::Copy +
         std::ops::Add<Output = T> +
         std::ops::Sub<Output = T> +
         std::ops::Mul<Output = T> +
{
    let mut i = 0;
    let mut j = 0;
    let mut ans = vec![zero; a.len() + b.len()];
    let mut buf = vec![zero; 4 * (a.len() + b.len())];
    let mut c = Vec::with_capacity(a.len() + b.len());
    while i < a.len() && j < b.len() {
        let x = a.len() - i;
        let y = b.len() - j;
        let z = std::cmp::min(x, y);
        c.clear();
        c.resize(2 * z, zero);
        karatsuba(&a[i..(i + z)], &b[j..(j + z)], &mut c, zero, &mut buf);
        for (ans, c) in ans[(i + j)..].iter_mut().zip(c.iter()) {
            *ans = *ans + *c;
        }
        if x <= y {
            j += x;
        } else {
            i += y;
        }
    }
    ans.truncate(a.len() + b.len() - 1);
    ans
}
// ---------- end karatsuba multiplication ----------
//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

//

fn run() {
    input! {
        n: usize,
        e: [(usize1, usize1); n - 1],
    }
    let mut way = vec![ModInt::zero(); n + 1];
    way[2] = ModInt::one();
    for i in 4..(n + 1) {
        if i % 2 == 0 {
            way[i] = way[i - 2] * ModInt((i - 1) as u32);
        }
    }
    type Value = Vec<Vec<ModInt>>;
    type Edge = ();
    let init = |_v: usize| {
        let mut a = vec![vec![ModInt::zero(); 2]; 2];
        a[0][1] = ModInt::one();
        a
    };
    let merge = |a: Value, b: Value, _c: &Edge| -> Value {
        let mut next = vec![vec![ModInt::zero(); a[0].len() + b[0].len() - 1]; 2];
        for (x, a) in a.iter().enumerate() {
            for (y, b) in b.iter().enumerate() {
                let c = multiply(a, b, ModInt::zero());
                for (next, c) in next[x ^ y].iter_mut().zip(c.iter()) {
                    *next += *c;
                }
                let mut sum = ModInt::zero();
                for (j, b) in b.iter().enumerate() {
                    sum += *b * way[j];
                }
                for (next, a) in next[x ^ y ^ 1].iter_mut().zip(a.iter()) {
                    *next += *a * sum;
                }
            }
        }
        next
    };
    let mut solver = TreeDP::new(n, init, merge);
    for (a, b) in e {
        solver.add_edge(a, b, ());
    }
    let res = solver.solve(0);
    let mut ans = ModInt::zero();
    for (i, a) in res[0].iter().enumerate() {
        ans += *a * way[i];
    }
    for (i, a) in res[1].iter().enumerate() {
        ans -= *a * way[i];
    }
    println!("{}", ans);
}

fn main() {
    run();
}


Measured memory_bytes: 6524