stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



namespace TYC

{

	typedef long long ll;

	const int N = 5005, mod = 1e9 + 7;



	int n, F[N][N], V[N], Siz[N];

	vector<int> E[N];



	inline int read()

	{

		int x = 0, f = 0, ch = getchar();

		while (!isdigit(ch))

			f |= (ch == '-'), ch = getchar();

		while (isdigit(ch))

			x = x * 10 + ch - '0', ch = getchar();

		return f ? -x : x;

	}



	void dfs(const int u, const int f)

	{

		Siz[u] = 1;

		F[u][1] = 1;

		for (int v : E[u])

			if (v != f)

			{

				dfs(v, u);

				static int tmp[N];

				memcpy(tmp, F[u], sizeof(int[Siz[u] + 1]));

				memset(F[u], 0, sizeof(int[Siz[u] + 1]));

				for (int a = 1; a <= Siz[u]; a++)

					for (int b = 0; b <= Siz[v]; b++)

						(F[u][a + b] += int((ll)tmp[a] * F[v][b] % mod)) %= mod;

				Siz[u] += Siz[v];

			}

		for (int i = 2; i <= Siz[u]; i += 2)

			(F[u][0] += mod - int((ll)F[u][i] * V[i] % mod)) %= mod;

	}



	void work()

	{

		n = read();

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

		{

			int u = read(), v = read();

			E[u].push_back(v);

			E[v].push_back(u);

		}

		V[2] = 1;

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

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

		dfs(1, 0);

		printf("%d\n", mod - F[1][0]);

	}

}



int main()

{

	TYC::work();

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.0274199196201983x):
#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);

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#define LL long long

using namespace std;

int n,tot;

const int N=5010,mod=1e9+7;

int head[N],to[N<<1],nt[N<<1],siz[N],f[N],dp[N][N],t[N];

void add(int f,int t)

{

	to[++tot]=t;nt[tot]=head[f];head[f]=tot;

}

void dfs(int x,int fa)

{

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

	for(int i=head[x];i;i=nt[i])

		if(to[i]!=fa)

		{

			dfs(to[i],x);

			for(int j=0;j<=siz[x];++j)t[j]=dp[x][j],dp[x][j]=0;

			for(int j=0;j<=siz[x];++j)

				for(int k=0;k<=siz[to[i]];++k)

					dp[x][j+k]=((LL)dp[x][j+k]+(LL)t[j]*dp[to[i]][k])%mod;				

			siz[x]+=siz[to[i]];

		}

	for(int i=0;i<=siz[x];++i)

		dp[x][0]=((LL)dp[x][0]-(LL)dp[x][i]*f[i])%mod;

}

int main()

{

	cin>>n;

	for(int i=1,x,y;i<n;++i)

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

	f[0]=1;

	for(int i=2;i<=n;i+=2)f[i]=(LL)f[i-2]*(i-1)%mod;

	dfs(1,0);

	cout<<(mod-dp[1][0])%mod;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.723089653105544x):
#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);

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define re register int

#define F(x,y,z) for(re x=y;x<=z;x++)

#define FOR(x,y,z) for(re x=y;x>=z;x--)

typedef long long ll;

#define I inline void

#define IN inline int

#define C(x,y) memset(x,y,sizeof(x))

#define STS system("pause")

template<class D>I read(D &res){

	res=0;register D g=1;register char ch=getchar();

	while(!isdigit(ch)){

		if(ch=='-')g=-1;

		ch=getchar();

	}

	while(isdigit(ch)){

		res=(res<<3)+(res<<1)+(ch^48);

		ch=getchar();

	}

	res*=g;

}

const int Mod=1e9+7;

vector<int>e[5050];

int n,m,ans,X,Y,f[5050][5050],s[5050],siz[5050];

I add(int &x,int y){(x+=y)>=Mod?x-=Mod:0;}

I D_1(int x,int fa){

	f[x][1]=1;siz[x]=1;

	for(auto d:e[x]){

		if(d==fa)continue;

		D_1(d,x);static int g[5050];

		F(i,0,siz[x]+siz[d])g[i]=0;

		F(i,1,siz[x])F(j,1,siz[d]){

			add(g[i],Mod-(ll)f[x][i]*f[d][j]%Mod*s[j]%Mod);

			add(g[i+j],(ll)f[x][i]*f[d][j]%Mod);

		}

		siz[x]+=siz[d];F(i,0,siz[x])f[x][i]=g[i];

	}

}

int main(){

	read(n);

	F(i,1,n-1){

		read(X);read(Y);e[X].emplace_back(Y);e[Y].emplace_back(X);

	}

	s[0]=1;for(re i=2;i<=n;i+=2)s[i]=(ll)s[i-2]*(i-1)%Mod;

	D_1(1,0);

	for(re i=2;i<=n;i+=2)add(ans,(ll)f[1][i]*s[i]%Mod);

	printf("%d",ans);

	return 0;

}




// Faster C++ solution for the same problem (measured speedup: 3.047649476660923x):
#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);

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

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;

#define N 5005

#define M 10005

#define ll long long

#define mod 1000000007

void Read(int &p)

{

	p = 0;

	char c = getchar();

	for (; c < '0' || c > '9'; c = getchar());

	for (; c >= '0' && c <= '9'; c = getchar())p = p * 10 + c - '0';

}

int n, tar[M], nex[M], fir[N], cnt;

int siz[N];

int dp[N][N], f[N], g[N];

void Add(int a, int b)

{

	++cnt;

	tar[cnt] = b;

	nex[cnt] = fir[a];

	fir[a] = cnt;

}

void Dfs(int r, int fa)

{

	siz[r] = 1;

	dp[r][1] = 1;

	for (int i = fir[r]; i; i = nex[i])

	{

		int v = tar[i];

		if (v != fa)

		{

			Dfs(v, r);

		    for (int j = 0; j <= siz[r]; j++)

			{

				g[j] = dp[r][j];

				dp[r][j] = 0;

			}

			for (int j = 0; j <= siz[r]; j++)

				for (int k = 0; k <= siz[v]; k++)

					dp[r][j + k] = (dp[r][j + k] + (ll)g[j] * dp[v][k]) % mod;

			siz[r] += siz[v];

		}

	}

	for (int i = 0; i <= siz[r]; i++)

		dp[r][0] = (dp[r][0] - (ll)dp[r][i] * f[i]) % mod;

}

int main()

{

	Read(n);

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

	{

		int u, v;

		Read(u), Read(v);

		Add(u, v), Add(v, u);

	}

	f[0] = 1;

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

	{

		if (i & 1)continue;

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

	}

	Dfs(1, 0);

	int ans = -dp[1][0];

	if (ans < 0)

		ans += mod;

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

}

///


// Faster C++ solution for the same problem (measured speedup: 2.671251879120623x):
#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);

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



#define CO const

#define IN inline

typedef long long LL;

typedef long double LD;



template<class T> T read(){

	T x=0,w=1;char c=getchar();

	for(;!isdigit(c);c=getchar())if(c=='-') w=-w;

	for(;isdigit(c);c=getchar()) x=x*10+c-'0';

	return x*w;

}

template<class T> IN T read(T&x){

	return x=read<T>();

}



CO int mod=1e9+7;

IN int add(int a,int b){

	return (a+=b)>=mod?a-mod:a;

}

IN int mul(int a,int b){

	return (LL)a*b%mod;

}

IN int fpow(int a,int b){

	int ans=1;

	for(;b;b>>=1,a=mul(a,a))

		if(b&1) ans=mul(ans,a);

	return ans;

}



CO int N=5e3+10;

vector<int> to[N];

int g[N],f[N][N],siz[N];



void dfs(int u,int fa){

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

	for(int v:to[u])if(v!=fa){

		dfs(v,u);

		static int tmp[N];

		copy(f[u],f[u]+siz[u]+1,tmp);

		fill(f[u],f[u]+siz[u]+1,0);

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

			f[u][i+j]=add(f[u][i+j],mul(tmp[i],f[v][j]));

		siz[u]+=siz[v];

	}

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

		f[u][0]=add(f[u][0],mod-mul(f[u][i],g[i]));

}

int main(){

	int n=read<int>();

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

		int u=read<int>(),v=read<int>();

		to[u].push_back(v),to[v].push_back(u);

	}

	g[0]=1;

	for(int i=2;i<=n;i+=2) g[i]=mul(g[i-2],i-1);

	dfs(1,0);

	printf("%d\n",mod-f[1][0]);

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.992598805209009x):
#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;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



namespace TYC

{

	typedef long long ll;

	const int N = 5005, mod = 1e9 + 7;



	int n, F[N][N], V[N], Siz[N];

	vector<int> E[N];



	inline int read()

	{

		int x = 0, f = 0, ch = getchar();

		while (!isdigit(ch))

			f |= (ch == '-'), ch = getchar();

		while (isdigit(ch))

			x = x * 10 + ch - '0', ch = getchar();

		return f ? -x : x;

	}



	void dfs(const int u, const int f)

	{

		Siz[u] = 1;

		F[u][1] = 1;

		for (int v : E[u])

			if (v != f)

			{

				dfs(v, u);

				static int tmp[N];

				memcpy(tmp, F[u], sizeof(int[Siz[u] + 1]));

				memset(F[u], 0, sizeof(int[Siz[u] + 1]));

				for (int a = 1; a <= Siz[u]; a++)

					for (int b = 0; b <= Siz[v]; b++)

						(F[u][a + b] += int((ll)tmp[a] * F[v][b] % mod)) %= mod;

				Siz[u] += Siz[v];

			}

		for (int i = 2; i <= Siz[u]; i += 2)

			(F[u][0] += mod - int((ll)F[u][i] * V[i] % mod)) %= mod;

	}



	void work()

	{

		n = read();

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

		{

			int u = read(), v = read();

			E[u].push_back(v);

			E[v].push_back(u);

		}

		V[2] = 1;

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

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

		dfs(1, 0);

		printf("%d\n", mod - F[1][0]);

	}

}



int main()

{

	TYC::work();

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.993047215420116x):
#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;

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#define LL long long

using namespace std;

int n,tot;

const int N=5010,mod=1e9+7;

int head[N],to[N<<1],nt[N<<1],siz[N],f[N],dp[N][N],t[N];

void add(int f,int t)

{

	to[++tot]=t;nt[tot]=head[f];head[f]=tot;

}

void dfs(int x,int fa)

{

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

	for(int i=head[x];i;i=nt[i])

		if(to[i]!=fa)

		{

			dfs(to[i],x);

			for(int j=0;j<=siz[x];++j)t[j]=dp[x][j],dp[x][j]=0;

			for(int j=0;j<=siz[x];++j)

				for(int k=0;k<=siz[to[i]];++k)

					dp[x][j+k]=((LL)dp[x][j+k]+(LL)t[j]*dp[to[i]][k])%mod;				

			siz[x]+=siz[to[i]];

		}

	for(int i=0;i<=siz[x];++i)

		dp[x][0]=((LL)dp[x][0]-(LL)dp[x][i]*f[i])%mod;

}

int main()

{

	cin>>n;

	for(int i=1,x,y;i<n;++i)

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

	f[0]=1;

	for(int i=2;i<=n;i+=2)f[i]=(LL)f[i-2]*(i-1)%mod;

	dfs(1,0);

	cout<<(mod-dp[1][0])%mod;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.390598363021563x):
#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;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define re register int

#define F(x,y,z) for(re x=y;x<=z;x++)

#define FOR(x,y,z) for(re x=y;x>=z;x--)

typedef long long ll;

#define I inline void

#define IN inline int

#define C(x,y) memset(x,y,sizeof(x))

#define STS system("pause")

template<class D>I read(D &res){

	res=0;register D g=1;register char ch=getchar();

	while(!isdigit(ch)){

		if(ch=='-')g=-1;

		ch=getchar();

	}

	while(isdigit(ch)){

		res=(res<<3)+(res<<1)+(ch^48);

		ch=getchar();

	}

	res*=g;

}

const int Mod=1e9+7;

vector<int>e[5050];

int n,m,ans,X,Y,f[5050][5050],s[5050],siz[5050];

I add(int &x,int y){(x+=y)>=Mod?x-=Mod:0;}

I D_1(int x,int fa){

	f[x][1]=1;siz[x]=1;

	for(auto d:e[x]){

		if(d==fa)continue;

		D_1(d,x);static int g[5050];

		F(i,0,siz[x]+siz[d])g[i]=0;

		F(i,1,siz[x])F(j,1,siz[d]){

			add(g[i],Mod-(ll)f[x][i]*f[d][j]%Mod*s[j]%Mod);

			add(g[i+j],(ll)f[x][i]*f[d][j]%Mod);

		}

		siz[x]+=siz[d];F(i,0,siz[x])f[x][i]=g[i];

	}

}

int main(){

	read(n);

	F(i,1,n-1){

		read(X);read(Y);e[X].emplace_back(Y);e[Y].emplace_back(X);

	}

	s[0]=1;for(re i=2;i<=n;i+=2)s[i]=(ll)s[i-2]*(i-1)%Mod;

	D_1(1,0);

	for(re i=2;i<=n;i+=2)add(ans,(ll)f[1][i]*s[i]%Mod);

	printf("%d",ans);

	return 0;

}




// Faster C++ solution for the same problem (measured speedup: 6.033093424307884x):
#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;

}