// Slower C++ solution:
#include <cstdio>

#include <algorithm>

using namespace std;



const int MAXN = 5000;

const int MOD = int(1E9) + 7;

const int INV2 = (MOD + 1) >> 1;



struct edge{

	edge *nxt; int to;

}edges[2*MAXN + 5], *adj[MAXN + 5], *ecnt = edges;

void addedge(int u, int v) {

	edge *p = (++ecnt);

	p->to = v, p->nxt = adj[u], adj[u] = p;

	p = (++ecnt);

	p->to = u, p->nxt = adj[v], adj[v] = p;

}



int fct[MAXN + 5], ifct[MAXN + 5], coef[MAXN + 5];

void init() {

	fct[0] = 1;

	for(int i=1;i<=MAXN;i++)

		fct[i] = 1LL*fct[i-1]*i%MOD;

	ifct[1] = 1;

	for(int i=2;i<=MAXN;i++)

		ifct[i] = (MOD - 1LL*(MOD/i)*ifct[MOD%i]%MOD);

	ifct[0] = 1;

	for(int i=1;i<=MAXN;i++)

		ifct[i] = 1LL*ifct[i-1]*ifct[i]%MOD;

	int t = INV2;

	for(int i=2;i<=MAXN;i+=2,t=1LL*t*INV2%MOD)

		coef[i] = 1LL*fct[i]*ifct[i/2]%MOD*t%MOD;

}



int dp[MAXN + 5][MAXN + 5], siz[MAXN + 5];

void dfs(int x, int f) {

	dp[x][siz[x] = 1] = 1;

	for(edge *p=adj[x];p;p=p->nxt) {

		if( p->to == f ) continue;

		dfs(p->to, x);

		int t1 = siz[x], t2 = siz[p->to], del = 0;

		for(int i=2;i<=t2;i+=2)

			del = (del + 1LL*dp[p->to][i]*coef[i]%MOD) % MOD;

		del = (MOD - del) % MOD;

		for(int i=t1;i>=1;i--) {

			for(int j=t2;j>=1;j--)

				dp[x][i+j] = (dp[x][i+j] + 1LL*dp[x][i]*dp[p->to][j]%MOD) % MOD;

			dp[x][i] = 1LL*del*dp[x][i] % MOD;

		}

		siz[x] += siz[p->to];

	}

}



int main() {

	int N; init();

	scanf("%d", &N);

	for(int i=1;i<N;i++) {

		int x, y; scanf("%d%d", &x, &y);

		addedge(x, y);

	}

	dfs(1, 0);

	int ans = 0;

	for(int i=1;i<=N;i++)

		ans = (ans + 1LL*dp[1][i]*coef[i]%MOD) % MOD;

	printf("%d\n", ans);

}

// Faster C++ solution for the same problem (measured speedup: 1.9795890145863768x):
#include <cstdio>



const int mod = 1e9 + 7;

const int MAXN = 5005;



template<typename _T>

void read( _T &x )

{

	x = 0;char s = getchar();int f = 1;

	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}

	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}

	x *= f;

}



template<typename _T>

void write( _T x )

{

	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }

	if( 9 < x ){ write( x / 10 ); }

	putchar( x % 10 + '0' );

}



struct edge

{

	int to, nxt;

}Graph[MAXN << 1];



int tmp[MAXN];

int f[MAXN][MAXN], g[MAXN];

int head[MAXN], siz[MAXN];

int N, cnt;



void sub( int &x, const int v ) { x = ( x < v ? x + mod - v : x - v ); }

void add( int &x, const int v ) { x = ( x + v >= mod ? x + v - mod : x + v ); }



void addEdge( const int from, const int to )

{

	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];

	head[from] = cnt;

}



void DFS( const int u, const int fa )

{

	f[u][1] = 1, siz[u] = 1;

	for( int i = head[u], v ; i ; i = Graph[i].nxt )

		if( ( v = Graph[i].to ) ^ fa )

		{

			DFS( v, u );

			for( int i = 0 ; i <= siz[u] + siz[v] ; i ++ ) tmp[i] = 0; 

			for( int j = siz[u] ; j ; j -- )

				for( int k = siz[v] ; ~ k ; k -- )

					add( tmp[j + k], 1ll * f[u][j] * f[v][k] % mod );

			siz[u] += siz[v];

			for( int i = 0 ; i <= siz[u] ; i ++ ) f[u][i] = tmp[i];

		}

	for( int i = 1 ; i <= siz[u] ; i ++ )

		sub( f[u][0], 1ll * f[u][i] * g[i] % mod );

}



int main()

{

	read( N );

	for( int i = 1, a, b ; i < N ; i ++ )

		read( a ), read( b ), addEdge( a, b ), addEdge( b, a );

	g[2] = 1;

	for( int i = 4 ; i <= N ; i += 2 )

		g[i] = 1ll * g[i - 2] * ( i - 1 ) % mod;

	DFS( 1, 0 );

	write( ( mod - f[1][0] ) % mod ), putchar( '\n' );

	return 0;

}