#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#define FOR(i, begin, end) for(int i=(begin);i<(end);i++)
#define IFOR(i, begin, end) for(int i=(end)-1;i>=(begin);i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)

constexpr lint MOD = 1000000007;
lint power(lint x, lint n)
{
    lint ans = 1;
    while (n>0)
    {
        if (n & 1) (ans *= x) %= MOD;
        (x *= x) %= MOD;
       n >>= 1;
    }
   return ans;
}

vector<lint> fac, facInv, inv, comb;
void facInit(int nmax)
{
    fac = facInv = inv = comb = vector<lint>(nmax + 1, 1);
    for (int i = 2; i <= nmax; i++)
    {
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD/i) % MOD;
        facInv[i] = facInv[i-1] * inv[i] % MOD;
    }
    for (int i = 1; i <= nmax; i++)
    {
        comb[i] = (i % 2 ? 0 : fac[i] * facInv[i / 2] % MOD * power(inv[2], i / 2) % MOD);
    }
}


template <int Vmax>
struct Tree
{
    int V; // 頂点数
    array<vector<int>, Vmax> to; // 隣接
    Tree() : V(1) {}

    void add_edge(int v1, int v2)
    {
        to[v1].push_back(v2);
        to[v2].push_back(v1);
        V++;
    }

    // 根を固定した木としての構造
    int root;
    array<int, Vmax> par;         // 親ノード par[root] = -1
    array<vector<int>, Vmax> chi; // 子の一覧

    void fixroot(int r)
    {
        root = r;
        par.fill(-1);
        for (auto &vec : chi) vec.clear();
        queue<int> vs;
        vs.push(root);
        while (!vs.empty())
        {
            int now = vs.front();
            vs.pop();
            for (auto nxt : to[now]) if (nxt != par[now])
            {
                if (par[nxt] == -1)
                {
                    par[nxt] = now;
                    chi[now].push_back(nxt);
                    vs.push(nxt);
                }
            }
        }
    }
    array<int, Vmax> subtreesz; // 各点をrootとする部分木のサイズ
    int buildSubtreeSize(int now, bool init)
    {
        if (init) subtreesz.fill(0);
        subtreesz[now] = 1;
        for (auto nxt : chi[now]) subtreesz[now] += buildSubtreeSize(nxt, false);
        return subtreesz[now];
    }

    vector<lint> dp[Vmax][2]; // 各頂点v，禁止辺数偶奇，親の連結成分個数
    vector<int> chi_now;
    void merge(int pos, int nxt)
    {
        int chi_now_new = chi_now[pos] + chi_now[nxt];
        vector<lint> dp_pos_new[2];
        REP(d, 2) dp_pos_new[d].assign(chi_now_new + 1, 0);

        REP(ipos, chi_now[pos] + 1) REP(inxt, chi_now[nxt] + 1) REP(d, 2)
        {
            (dp_pos_new[d][ipos] += dp[pos][d][ipos] * dp[nxt][1][inxt] % MOD * comb[inxt]) %= MOD;
            (dp_pos_new[!d][ipos] += dp[pos][d][ipos] * dp[nxt][0][inxt] % MOD * comb[inxt]) %= MOD;
            (dp_pos_new[d][ipos + inxt] += dp[pos][d][ipos] * dp[nxt][0][inxt]) %= MOD;
            (dp_pos_new[!d][ipos + inxt] += dp[pos][d][ipos] * dp[nxt][1][inxt]) %= MOD;
        }
        REP(d, 2) dp[pos][d] = dp_pos_new[d];
        chi_now[pos] = chi_now_new;
    }
    lint getans()
    {
        lint ans = 0;
        REP(i, V + 1) (ans += (dp[root][0][i] - dp[root][1][i] + MOD) * comb[i]) %= MOD;
        return ans;
    }

    void dfs(int pos)
    {
        dp[pos][0] = vector<lint>{0, 1};
        dp[pos][1] = vector<lint>{0, 0};
        for (auto v : chi[pos])
        {
            dfs(v);
            merge(pos, v);
        }
    }
};


int main()
{
    facInit(5000);

    Tree<5000> tree;
    int N;
    scanf("%d", &N);
    REP(i, N - 1) {
        int a, b;
        scanf("%d %d", &a, &b);
        tree.add_edge(a - 1, b - 1);
    }
    tree.fixroot(0);
    tree.buildSubtreeSize(tree.root, true);
    tree.chi_now.assign(N, 1);
    tree.dfs(tree.root);
    cout << tree.getans() << endl;
}


Measured memory_bytes: 140800