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

#define Rint register int

using namespace std;

typedef long long LL;

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

int n, head[N], to[N << 1], nxt[N << 1], siz[N], f[N][N], tmp[N], g[N];

inline void qmo(int &x){x += (x >> 31) & mod;}

inline void add(int a, int b){

    static int cnt = 0;

    to[++ cnt] = b; nxt[cnt] = head[a]; head[a] = cnt;

}

inline void dfs(int x, int fa = 0){

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

    for(Rint i = head[x];i;i = nxt[i]) if(to[i] != fa){

        dfs(to[i], x);

        memcpy(tmp + 1, f[x] + 1, siz[x] << 2);

        memset(f[x] + 1, 0, siz[x] << 2);

        for(Rint j = 1;j <= siz[x];++ j)

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

                qmo(f[x][j + k] += (LL) tmp[j] * f[to[i]][k] % mod - mod);

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

    }

    for(Rint i = 2;i <= siz[x];i += 2)

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

}

int main(){

    scanf("%d", &n);

    for(Rint i = 1, u, v;i < n;++ i){

        scanf("%d%d", &u, &v); add(u, v); add(v, u);

    }

    g[0] = 1;

    for(Rint i = 2;i <= n;i += 2) g[i] = (i - 1ll) * g[i - 2] % mod;

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

}


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



const int MAXN = 5000, MOD = 1e9 + 7;

int n, ecnt, head[MAXN + 5], siz[MAXN + 5];

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



struct Edge { int to, nxt; } graph[MAXN * 2 + 5];



inline void addeq ( int& a, const int b ) { if ( ( a += b ) >= MOD ) a -= MOD; }



inline void link ( const int s, const int t ) {

	graph[++ ecnt] = { t, head[s] };

	head[s] = ecnt;

}



inline void solve ( const int u, const int fa ) {

	static int tmp[MAXN + 5];

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

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

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

			solve ( v, u );

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

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

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

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

				}

			}

			for ( int j = 1; j <= siz[u] + siz[v]; ++ j ) f[u][j] = tmp[j];

			siz[u] += siz[v];

		}

	}

	for ( int i = 2; i <= siz[u]; i += 2 ) addeq ( f[u][0], 1ll * f[u][i] * g[i] % MOD );

	f[u][0] = ( MOD - f[u][0] ) % MOD;

}



int main () {

	scanf ( "%d", &n );

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

		scanf ( "%d %d", &u, &v );

		link ( u, v ), link ( v, u );

	}

	g[0] = 1;

	for ( int i = 2; i <= n; i += 2 ) g[i] = ( i - 1ll ) * g[i - 2] % MOD;

	solve ( 1, 0 );

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

	return 0;

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

#include <iostream>

#include <vector>

using namespace std;

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

int n, x, y, dp[N][N], siz[N], tmp[N], g[N];

vector<int> G[N];

void dfs(int u, int fa) {

    siz[u] = 1; 

    dp[u][1] = 1;

    for(auto v : G[u]) {

        if(v == fa) continue;

        dfs(v, u);

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

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

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

                (tmp[i + j] += 1ll * dp[u][i] * dp[v][j] % mod) %= mod;

        siz[u] += siz[v];

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

    }

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

        (dp[u][0] += 1ll * dp[u][i] * g[i] % mod) %= mod;

    if(fa) dp[u][0] = mod - dp[u][0];

}

int main() {

    scanf("%d", &n);

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

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

        G[x].push_back(y); 

        G[y].push_back(x);

    }

    g[0] = 1;

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

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

    dfs(1, 0);

    printf("%d\n", dp[1][0]);

    return 0;

}


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



const int MAXN = 5000, MOD = 1e9 + 7;

int n, ecnt, head[MAXN + 5], siz[MAXN + 5];

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



struct Edge { int to, nxt; } graph[MAXN * 2 + 5];



inline void addeq ( int& a, const int b ) { if ( ( a += b ) >= MOD ) a -= MOD; }



inline void link ( const int s, const int t ) {

	graph[++ ecnt] = { t, head[s] };

	head[s] = ecnt;

}



inline void solve ( const int u, const int fa ) {

	static int tmp[MAXN + 5];

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

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

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

			solve ( v, u );

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

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

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

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

				}

			}

			for ( int j = 1; j <= siz[u] + siz[v]; ++ j ) f[u][j] = tmp[j];

			siz[u] += siz[v];

		}

	}

	for ( int i = 2; i <= siz[u]; i += 2 ) addeq ( f[u][0], 1ll * f[u][i] * g[i] % MOD );

	f[u][0] = ( MOD - f[u][0] ) % MOD;

}



int main () {

	scanf ( "%d", &n );

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

		scanf ( "%d %d", &u, &v );

		link ( u, v ), link ( v, u );

	}

	g[0] = 1;

	for ( int i = 2; i <= n; i += 2 ) g[i] = ( i - 1ll ) * g[i - 2] % MOD;

	solve ( 1, 0 );

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

	return 0;

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

using namespace std;



#define Int register int

#define mod 1000000007

#define MAXN 5005



template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}

template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}

template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}



int mul (int a,int b){return 1ll * a * b % mod;}

int dec (int a,int b){return a >= b ? a - b : a + mod - b;}

int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}



int n,top = 1,to[MAXN << 1],nxt[MAXN << 1],head[MAXN],t[MAXN],g[MAXN],dp[MAXN][MAXN],siz[MAXN];

void Add_Edge (int u,int v){

	to[++ top] = v,nxt[top] = head[u],head[u] = top;

	to[++ top] = u,nxt[top] = head[v],head[v] = top;

}

void dfs (int u,int fa){

	siz[u] = dp[u][1] = 1;

	for (Int i = head[u];i;i = nxt[i]){

		int v = to[i];

		if (v == fa) continue;

		dfs (v,u);

		for (Int j = 0;j <= siz[u];++ j) t[j] = dp[u][j],dp[u][j] = 0;

		for (Int j = 0;j <= siz[u];++ j)

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

				dp[u][j + k] = add (dp[u][j + k],mul (dp[v][k],t[j]));

		siz[u] += siz[v]; 

	}

	for (Int i = 1;i <= siz[u];++ i) dp[u][0] = dec (dp[u][0],mul (dp[u][i],i & 1 ? 0 : g[i]));

}



signed main(){

	read (n);

	for (Int i = 2,u,v;i <= n;++ i) read (u,v),Add_Edge (u,v);

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

	dfs (1,0),write (dec (0,dp[1][0])),putchar ('\n');

	return 0;

}

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



const int MAXN = 5000, MOD = 1e9 + 7;

int n, ecnt, head[MAXN + 5], siz[MAXN + 5];

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



struct Edge { int to, nxt; } graph[MAXN * 2 + 5];



inline void addeq ( int& a, const int b ) { if ( ( a += b ) >= MOD ) a -= MOD; }



inline void link ( const int s, const int t ) {

	graph[++ ecnt] = { t, head[s] };

	head[s] = ecnt;

}



inline void solve ( const int u, const int fa ) {

	static int tmp[MAXN + 5];

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

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

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

			solve ( v, u );

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

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

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

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

				}

			}

			for ( int j = 1; j <= siz[u] + siz[v]; ++ j ) f[u][j] = tmp[j];

			siz[u] += siz[v];

		}

	}

	for ( int i = 2; i <= siz[u]; i += 2 ) addeq ( f[u][0], 1ll * f[u][i] * g[i] % MOD );

	f[u][0] = ( MOD - f[u][0] ) % MOD;

}



int main () {

	scanf ( "%d", &n );

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

		scanf ( "%d %d", &u, &v );

		link ( u, v ), link ( v, u );

	}

	g[0] = 1;

	for ( int i = 2; i <= n; i += 2 ) g[i] = ( i - 1ll ) * g[i - 2] % MOD;

	solve ( 1, 0 );

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

	return 0;

}
// 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: 1.1116759961782814x):
#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;

}
// 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: 1.1117591799328312x):
#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;

}
// 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: 1.1332489558399224x):
#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);

}

///
// 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: 1.133333753841598x):
#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);

}

///
// 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: 1.1409068161944393x):
#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);

}

///
// 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: 3.0271934027988765x):
#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);

}