#include<iostream>
#include<cstdio>
using std::cout;
using std::endl;

const int p=1e9+7;
const int MAXN=10010;
int n;
struct Edge{
	int to;
	int nxt;
}edge[MAXN];
int frm[MAXN];
int cnt;
long long H[MAXN];
int siz[MAXN];
long long dp[MAXN>>1][MAXN>>1];
long long tmp[MAXN]; 
long long ans; 

void insert(int u,int v){
	cnt++;
	edge[cnt].to=v;
	edge[cnt].nxt=frm[u];
	frm[u]=cnt;
} 

void pre(){
	H[0]=1;
	for(int i=2;i<=n;i+=2){
		H[i]=(H[i-2]*(i-1))%p;//考虑第i个点有i-1种连边方式，还剩i-2个点没连边 
	}
}

void Dp(int u,int fa){//树形DP的时候如果要合并子树答案，要用一个临时数组记录昂 
	siz[u]=1;
	dp[u][1]=1;//但是不是不可能有1嘛wsl又 
	//但这里是不考虑u所在联通块的答案嘛qwq 
	for(int i=frm[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v!=fa){
			Dp(v,u);
			for(int szu=1;szu<=siz[u];szu++){
				for(int szv=1;szv<=siz[v];szv++){
					if(!(szv&1))tmp[szu]=(tmp[szu]+(-1*dp[u][szu]*dp[v][szv])%p*H[szv]%p)%p;//v所在联通块自己连边，所以大小必须为偶数
					tmp[szu+szv]=(tmp[szu+szv]+(dp[u][szu]*dp[v][szv])%p)%p;
				}
			}
			siz[u]+=siz[v];//先加siz再处理下面这一段 
			for(int szu=1;szu<=siz[u];szu++){
				dp[u][szu]=tmp[szu];
				tmp[szu]=0;
			}
		}
	}
	//cout<<u<<' '<<dp[u][1]<<' '<<dp[u][2]<<endl;
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		insert(u,v);
		insert(v,u);
	}
	pre();
	Dp(1,0);
	for(int szr=2;szr<=n;szr+=2){
		ans=((ans+dp[1][szr]*H[szr]%p)%p+p)%p;
	}
	printf("%lld\n",ans);
	return 0;
}