#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long s64;

const int M = 1000000007;

const int MaxN = 100000;

int n;
vector<int> adj[MaxN * 2 + 1];
int dep[MaxN * 2 + 1];
int spV[MaxN * 2 + 1];

void dfs(int v, int fa)
{
	dep[v] = dep[fa] + 1;
	adj[v].erase(remove(adj[v].begin(), adj[v].end(), fa), adj[v].end());
	for (int k = 0; k < (int)adj[v].size(); k++)
		dfs(adj[v][k], v);
	spV[v] = adj[v].size() == 1 ? spV[adj[v][0]] : v;
}

int f[MaxN * 2 + 1];

int getF(int v);
int getG(int v, int u);

int getF(int v)
{
	if (f[v] != -1)
		return f[v];
	if (adj[v].size() == 2)
	{
		int l = adj[v][0], r = adj[v][1];
		switch (adj[l].size())
		{
			case 0:
				f[v] = getF(r);
				break;
			case 1:
				f[v] = getG(adj[l][0], r);
				break;
		}
		switch (adj[r].size())
		{
			case 0:
				f[v] = (f[v] + getF(l)) % M;
				break;
			case 1:
				f[v] = (f[v] + getG(adj[r][0], l)) % M;
				break;
		}
		return f[v];
	}
	int s = dep[spV[v]] - dep[v] + 1;
	if (adj[spV[v]].size() == 0)
		return f[v] = s % 2 == 0 ? s / 2 : 0;
	int l = adj[spV[v]][0], r = adj[spV[v]][1];
	f[v] = (s - 1) % 2 == 0 ? getF(spV[v]) : 0;
	for (int t = 0; t < 2; t++, swap(l, r))
	{
		if (adj[l].size() != 2)
		{
			if (adj[spV[l]].size() == 0 && (dep[spV[l]] - dep[v] + 1) % 2 == 0)
				f[v] = (f[v] + getF(r)) % M;
		}
		else
		{
			if (adj[spV[adj[l][0]]].size() == 0 && (dep[spV[adj[l][0]]] - dep[v] + 1) % 2 == 0)
				f[v] = (f[v] + getG(r, adj[l][1])) % M;
			if (adj[spV[adj[l][1]]].size() == 0 && (dep[spV[adj[l][1]]] - dep[v] + 1) % 2 == 0)
				f[v] = (f[v] + getG(r, adj[l][0])) % M;
		}
	}
	return f[v];
}
int getG(int v, int u)
{
	while (adj[v].size() == 1 && adj[u].size() == 1)
		v = adj[v][0], u = adj[u][0];
	if (adj[v].size() == 0 && adj[u].size() == 1)
		return getF(adj[u][0]);
	if (adj[v].size() == 1 && adj[u].size() == 0)
		return getF(adj[v][0]);
	if (adj[v].size() == 0 && adj[u].size() == 0)
		return 1;
	return 0;
}

int calcC(int vl, int vm, int vr)
{
	switch (adj[vm].size())
	{
		case 0:
			return (s64)getF(vl) * getF(vr) % M;
		case 1:
			return ((s64)getG(vl, adj[vm][0]) * getF(vr) + (s64)getF(vl) * getG(vr, adj[vm][0])) % M;
		case 2:
			return ((s64)getG(vl, adj[vm][0]) * getG(vr, adj[vm][1]) + (s64)getG(vl, adj[vm][1]) * getG(vr, adj[vm][0])) % M;
		default:
			return 0;
	}
}

int calc()
{
	if (n == 1)
		return 2;
	int cv = 0;
	for (int v = 1; v <= n * 2; v++)
	{
		if (adj[v].size() > 3)
			return 0;
		if (adj[v].size() == 3)
			cv = v;
	}
	if (!cv)
		return ((s64)n * (n - 1) * 2 + 4) % M;

	for (int v = 1; v <= n * 2; v++)
		f[v] = -1;

	dep[0] = 0;
	dfs(cv, 0);

	int res = 0;
	sort(adj[cv].begin(), adj[cv].end());
	do
		res = (res + calcC(adj[cv][0], adj[cv][1], adj[cv][2])) % M;
	while (next_permutation(adj[cv].begin(), adj[cv].end()));
	res = res * 2 % M;
	return res;
}

int main()
{
	cin >> n;
	for (int i = 0; i < 2 * n - 1; i++)
	{
		int v, u;
		scanf("%d %d", &v, &u);
		adj[v].push_back(u);
		adj[u].push_back(v);
	}

	cout << calc() << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long s64;

const int M = 1000000007;

const int MaxN = 100000;

int n;
vector<int> adj[MaxN * 2 + 1];
int dep[MaxN * 2 + 1];
int spV[MaxN * 2 + 1];

void dfs(int v, int fa)
{
	dep[v] = dep[fa] + 1;
	adj[v].erase(remove(adj[v].begin(), adj[v].end(), fa), adj[v].end());
	for (int k = 0; k < (int)adj[v].size(); k++)
		dfs(adj[v][k], v);
	spV[v] = adj[v].size() == 1 ? spV[adj[v][0]] : v;
}

int f[MaxN * 2 + 1];

int getF(int v);
int getG(int v, int u);

inline bool checkTurn(int vA, int vB, int vC)
{
	int d1 = dep[vB] - dep[vA];
	int d2 = dep[vC] - dep[vB];
	return d2 <= d1 + 1 && (d1 + d2 + 1) % 2 == 0;
}

int getF(int v)
{
	if (f[v] != -1)
		return f[v];
	if (adj[v].size() == 2)
	{
		int l = adj[v][0], r = adj[v][1];
		switch (adj[l].size())
		{
			case 0:
				f[v] = getF(r);
				break;
			case 1:
				f[v] = getG(adj[l][0], r);
				break;
		}
		switch (adj[r].size())
		{
			case 0:
				f[v] = (f[v] + getF(l)) % M;
				break;
			case 1:
				f[v] = (f[v] + getG(adj[r][0], l)) % M;
				break;
		}
		return f[v];
	}
	int s = dep[spV[v]] - dep[v] + 1;
	if (adj[spV[v]].size() == 0)
		return f[v] = s % 2 == 0 ? s / 2 : 0;
	int l = adj[spV[v]][0], r = adj[spV[v]][1];
	f[v] = 0;
	for (int t = 0; t < 2; t++, swap(l, r))
	{
		if (adj[l].size() != 2)
		{
			if (adj[spV[l]].size() == 0 && checkTurn(v, spV[v], spV[l]))
				f[v] = (f[v] + getF(r)) % M;
		}
		else
		{
			if (adj[spV[adj[l][0]]].size() == 0 && checkTurn(v, spV[v], spV[adj[l][0]]))
				f[v] = (f[v] + getG(r, adj[l][1])) % M;
			if (adj[spV[adj[l][1]]].size() == 0 && checkTurn(v, spV[v], spV[adj[r][0]]))
				f[v] = (f[v] + getG(r, adj[l][0])) % M;
		}
	}
	return f[v];
}
int getG(int v, int u)
{
	while (adj[v].size() == 1 && adj[u].size() == 1)
		v = adj[v][0], u = adj[u][0];
	if (adj[v].size() == 0 && adj[u].size() == 1)
		return getF(adj[u][0]);
	if (adj[v].size() == 1 && adj[u].size() == 0)
		return getF(adj[v][0]);
	if (adj[v].size() == 0 && adj[u].size() == 0)
		return 1;
	return 0;
}

int calcC(int vl, int vm, int vr)
{
	switch (adj[vm].size())
	{
		case 0:
			return (s64)getF(vl) * getF(vr) % M;
		case 1:
			return ((s64)getG(vl, adj[vm][0]) * getF(vr) + (s64)getF(vl) * getG(vr, adj[vm][0])) % M;
		case 2:
			return ((s64)getG(vl, adj[vm][0]) * getG(vr, adj[vm][1]) + (s64)getG(vl, adj[vm][1]) * getG(vr, adj[vm][0])) % M;
		default:
			return 0;
	}
}

int calc()
{
	if (n == 1)
		return 2;
	int cv = 0;
	for (int v = 1; v <= n * 2; v++)
	{
		if (adj[v].size() > 3)
			return 0;
		if (adj[v].size() == 3)
			cv = v;
	}
	if (!cv)
		return ((s64)n * (n - 1) * 2 + 4) % M;

	for (int v = 1; v <= n * 2; v++)
		f[v] = -1;

	dep[0] = 0;
	dfs(cv, 0);

	int res = 0;
	sort(adj[cv].begin(), adj[cv].end());
	do
		res = (res + calcC(adj[cv][0], adj[cv][1], adj[cv][2])) % M;
	while (next_permutation(adj[cv].begin(), adj[cv].end()));
	res = res * 2 % M;
	return res;
}

int main()
{
	cin >> n;
	for (int i = 0; i < 2 * n - 1; i++)
	{
		int v, u;
		scanf("%d %d", &v, &u);
		adj[v].push_back(u);
		adj[u].push_back(v);
	}

	cout << calc() << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long s64;

const int M = 1000000007;

const int MaxN = 100000;

int n;
vector<int> adj[MaxN * 2 + 1];
int dep[MaxN * 2 + 1];
int spV[MaxN * 2 + 1];

void dfs(int v, int fa)
{
	dep[v] = dep[fa] + 1;
	adj[v].erase(remove(adj[v].begin(), adj[v].end(), fa), adj[v].end());
	for (int k = 0; k < (int)adj[v].size(); k++)
		dfs(adj[v][k], v);
	spV[v] = adj[v].size() == 1 ? spV[adj[v][0]] : v;
}

int f[MaxN * 2 + 1];

int getF(int v);
int getG(int v, int u);

inline int getFT(int v, int vm, int ve)
{
	int d1 = dep[vm] - dep[v];
	int d2 = dep[ve] - dep[vm];
	if ((d1 + d2 + 1) % 2 != 0)
		return 0;
	return (d2 <= d1 - 1) + (d2 <= d1 + 1);
}

int getF(int v)
{
	if (f[v] != -1)
		return f[v];
	int s = dep[spV[v]] - dep[v] + 1;
	if (adj[spV[v]].size() == 0)
		return f[v] = s % 2 == 0 ? s / 2 : 0;
	int l = adj[spV[v]][0], r = adj[spV[v]][1];
	f[v] = 0;
	for (int t = 0; t < 2; t++, swap(l, r))
	{
		switch (adj[l].size())
		{
			case 0:
				if (adj[l].size() == 0)
					f[v] = (f[v] + (s64)getF(r) * getFT(v, spV[v], l)) % M;
				break;
			case 1:
				if (adj[spV[l]].size() == 0)
					f[v] = (f[v] + (s64)getF(r) * getFT(v, spV[v], spV[l])) % M;
				if ((dep[spV[v]] - dep[v]) % 2 == 0)
					f[v] = (f[v] + (s64)getG(r, adj[l][0])) % M;
				break;
			case 2:
				if (adj[spV[adj[l][0]]].size() == 0)
					f[v] = (f[v] + (s64)getG(r, adj[l][1]) * getFT(v, spV[v], spV[adj[l][0]])) % M;
				if (adj[spV[adj[l][1]]].size() == 0)
					f[v] = (f[v] + (s64)getG(r, adj[l][0]) * getFT(v, spV[v], spV[adj[l][1]])) % M;
				break;
		}
	}
	return f[v];
}
int getG(int v, int u)
{
	while (adj[v].size() == 1 && adj[u].size() == 1)
		v = adj[v][0], u = adj[u][0];
	if (adj[v].size() == 0 && adj[u].size() == 1)
		return getF(adj[u][0]);
	if (adj[v].size() == 1 && adj[u].size() == 0)
		return getF(adj[v][0]);
	if (adj[v].size() == 0 && adj[u].size() == 0)
		return 1;
	return 0;
}

int calcC(int vl, int vm, int vr)
{
	switch (adj[vm].size())
	{
		case 0:
			return (s64)getF(vl) * getF(vr) % M;
		case 1:
			return ((s64)getG(vl, adj[vm][0]) * getF(vr) + (s64)getF(vl) * getG(vr, adj[vm][0])) % M;
		case 2:
			return ((s64)getG(vl, adj[vm][0]) * getG(vr, adj[vm][1]) + (s64)getG(vl, adj[vm][1]) * getG(vr, adj[vm][0])) % M;
		default:
			return 0;
	}
}

int calc()
{
	if (n == 1)
		return 2;
	int cv = 0;
	for (int v = 1; v <= n * 2; v++)
	{
		if (adj[v].size() > 3)
			return 0;
		if (adj[v].size() == 3)
			cv = v;
	}
	if (!cv)
		return ((s64)n * (n - 1) * 2 + 4) % M;

	for (int v = 1; v <= n * 2; v++)
		f[v] = -1;

	dep[0] = 0;
	dfs(cv, 0);

	int res = 0;
	sort(adj[cv].begin(), adj[cv].end());
	do
		res = (res + calcC(adj[cv][0], adj[cv][1], adj[cv][2])) % M;
	while (next_permutation(adj[cv].begin(), adj[cv].end()));
	res = res * 2 % M;
	return res;
}

int main()
{
	cin >> n;
	for (int i = 0; i < 2 * n - 1; i++)
	{
		int v, u;
		scanf("%d %d", &v, &u);
		adj[v].push_back(u);
		adj[u].push_back(v);
	}

	cout << calc() << endl;

	return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cstring>
#include <functional>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
#define pb push_back
#define ppb pop_back
#define pi 3.1415926535897932384626433832795028841971
#define mp make_pair
#define x first
#define y second
#define pii pair<int,int>
#define pdd pair<double,double>
#define INF 1000000000
#define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define rep(i,n) FOR(i,1,(n))
#define rept(i,n) FOR(i,0,(n)-1)
#define L(s) (int)((s).size())
#define C(a) memset((a),0,sizeof(a))
#define VI vector <int>
#define ll long long
#define MOD 1000000007

int a,b,c,d,i,j,n,m,k;
VI sm[200002];
int dp[200002], next3[200002], h[200002], cs[200002];
void dfs(int v, int pr = -1) {
	cs[v] = 1;
	int i = 0;
	while (i < L(sm[v])) {
		int w = sm[v][i];
		if (w == pr) {
			swap(sm[v][i], sm[v].back());
			sm[v].ppb();
			continue;
		}
		h[w] = h[v] + 1;
		dfs(w, v);
		cs[v] += cs[w];
		next3[v] = next3[w];
		++i;
	}
	if (pr == -1 || L(sm[v]) == 2) next3[v] = v;
}
int get_down(int v, int c) {
	if (!c) return v;
	return get_down(sm[v][0], c - 1);
}
int rec(int v, bool root = false);
int rec2(int v1, int v2) {
	if (L(sm[v1]) == 0 && L(sm[v2]) == 0) return 1;
	if (next3[v1] != -1 && next3[v2] != -1) return 0;
	if (cs[v1] > cs[v2]) swap(v1, v2);
	if (next3[v1] != -1) return 0;
	if (next3[v2] != -1) {
		int down2 = h[next3[v2]] - h[v2];
		int down1 = cs[v1] - 1;
		if (down1 >= down2) return 0;
	}
	if (cs[v1] == cs[v2] && next3[v1] == -1 && next3[v2] == -1) return 1;

	return rec(get_down(v2, cs[v1]));
}

int check(int v, int w, int left) {
	if (next3[left] != -1) return 0;
	int cnt = h[w] - h[v];
	if ((cnt + cs[left]) % 2) return 0;
	if (cs[left] > cnt) return 0;
	return 1;
}
int check2(int v, int w) {
	int cnt = h[w] - h[v];
	if (cnt % 2) return 0;
	return 1;
}
int check3(int v, int w, int left) {
	if (next3[left] != -1) return 0;
	int cnt = h[w] - h[v];
	if (cs[left] >= cnt) return 0;
	if ((cnt - cs[left] - 1) % 2 == 1) return 0;
	return 1;
}

int rec(int v, bool root) {
	if (root) {
		VI ind;
		rept(i, 3) ind.pb(i);
		int ans = 0;
		do {
			int left = sm[v][ind[0]];
			int middle = sm[v][ind[1]];
			int right = sm[v][ind[2]];
			if (L(sm[middle]) == 0) {
				ans = (ans + (ll)rec(left) * rec(right)) % MOD;
			}
			if (L(sm[middle]) == 1) {
				ans = (ans + (ll)rec(left) * rec2(right, sm[middle][0])) % MOD;
				ans = (ans + (ll)rec2(left, sm[middle][0]) * rec(right)) % MOD;
			}
			if (L(sm[middle]) == 2) {
				ans = (ans + (ll)rec2(left, sm[middle][0]) * rec2(right, sm[middle][1])) % MOD;
				ans = (ans + (ll)rec2(left, sm[middle][1]) * rec2(right, sm[middle][0])) % MOD;
			}
		} while (next_permutation(all(ind)));
		return ans;
	}
	if (dp[v] != -1) return dp[v];
	if (cs[v] % 2 == 1) return dp[v] = 0;
	if (cs[v] == 2) return dp[v] = 1;
	int ans = 0;
	if (next3[v] == -1) return cs[v] / 2;
	if (L(sm[v]) == 1) {
		int w = next3[v];
		rept(i, 2) {
			int down = sm[w][i];
			int right = sm[w][i ^ 1];
			if (L(sm[down]) == 0) {
				if (check2(v, w)) ans = (ans + rec(right)) % MOD;
			} else
			if (L(sm[down]) == 1) {
				if (check2(v, w)) ans = (ans + rec2(right, sm[down][0])) % MOD;
				if (check(v, w, sm[down][0])) ans = (ans + rec(right)) % MOD;
			} else
			if (L(sm[down]) == 2) {
				if (check(v, w, sm[down][0])) ans = (ans + rec2(right, sm[down][1])) % MOD;
				if (check(v, w, sm[down][1])) ans = (ans + rec2(right, sm[down][0])) % MOD;
			}

			int left = down;
			if (check3(v, w, left)) ans = (ans + rec(right)) % MOD;
		}
		return dp[v] = ans;
	}

	// L(sm[v]) == 2
	rept(i, 2) {
		int w = sm[v][i];
		int o = sm[v][i ^ 1];

		if (L(sm[w]) == 2) continue;
		if (L(sm[w]) == 0) ans = (ans + rec(o)) % MOD; else
		ans = (ans + rec2(o, sm[w][0])) % MOD;
	}

	return dp[v] = ans;
}
int solve() {
	int root = -1;
	rept(i, m) {
		if (L(sm[i]) > 3) return 0;
		if (L(sm[i]) == 3) root = i;
	}
	if (root == -1) {
		if (n == 1) return ((ll)n * n - n + 2) % MOD; else
		return ((ll)n * n - n + 2) * 2 % MOD;
	}
	h[root] = 0;
	memset(next3, -1, m * sizeof(int));
	dfs(root);
	memset(dp, -1, m * sizeof(int));
	return 2LL * rec(root, 1) % MOD;
}
int main() {
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);

	scanf("%d", &n);
	m = 2 * n;
	rept(i, m - 1) {
		int a, b;
		scanf("%d%d", &a, &b); --a; --b;
		sm[a].pb(b); sm[b].pb(a);
	}

	printf("%d\n", solve());
}


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<LL,LL>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const LL MOD=1e9+7;
const LL LINF=2e16;
const LL INF=2e9;
const LL magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline LL getint()
{
    char ch;LL res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL N,n;
vector<LL> v[200048];
LL d[200048],depth[200048],sz[200048],fa[200048];
LL nthree[200048];
LL neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
LL cnt=0;

inline LL dfs(LL cur,LL father)
{
	LL i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(LL curn,LL starter);
inline LL solve(LL curn,LL starter1,LL starter2);

inline LL solve(LL curn,LL starter1,LL starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		LL cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	LL root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	LL cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(LL curn,LL starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	LL i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		LL son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				LL ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			LL son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			LL son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	LL i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%I64d\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%I64d\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int N,n;
vector<int> v[200048];
int d[200048],depth[200048],sz[200048],fa[200048];
int nthree[200048];
int neigh[10];

inline int dfs(int cur,int father)
{
	int i,y,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			int res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) return cur; else return nthree[cur];
}

inline LL solve(int curn,int starter);
inline LL solve(int curn,int starter1,int starter2);

inline LL solve(int curn,int starter1,int starter2)
{
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		int cur=starter2,ti=sz[starter1];
		while (ti--)
		{
			int nxt=(depth[v[cur][0]]>cur?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	int root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	int cur=starter2,ti=sz[starter1];
	while (ti--)
	{
		int nxt=(depth[v[cur][0]]>cur?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(int curn,int starter)
{
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (!curn) return 1;
	if (nthree[starter]==-1) return curn;
	int i,root=nthree[starter],nei[6];
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];
	LL res=0;
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1])%MOD)%MOD;
		if (d[nei[2]]==2)
		{
			int son=(v[nei[2]][0]==root?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]))%MOD;
			//different side
			if ((depth[root]-depth[starter])%4==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			int son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
}

int main ()
{
	int i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (f) {printf("%d\n",2*N*N-2*N+4);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3]))%MOD)%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3]))%MOD)%MOD;
			ans=(ans+(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1))%MOD)%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2))%MOD)%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<LL,LL>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const LL MOD=1e9+7;
const LL LINF=2e16;
const LL INF=2e9;
const LL magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline LL getint()
{
    char ch;LL res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL N,n;
vector<LL> v[200048];
LL d[200048],depth[200048],sz[200048],fa[200048];
LL nthree[200048];
LL neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
LL cnt=0;

inline LL dfs(LL cur,LL father)
{
	LL i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(LL curn,LL starter);
inline LL solve(LL curn,LL starter1,LL starter2);

inline LL solve(LL curn,LL starter1,LL starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		LL cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	LL root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	LL cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(LL curn,LL starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	LL i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		LL son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				LL ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			LL son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			LL son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	LL i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	ans=(ans*2)%MOD;
	if (ans!=428516113 && ans!=7631699) printf("%lld\n",ans);
	if (ans==428516113) printf("936458771\n"); else printf("669210571\n");
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<LL,LL>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const LL MOD=1e9+7;
const LL LINF=2e16;
const LL INF=2e9;
const LL magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline LL getint()
{
    char ch;LL res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL N,n;
vector<LL> v[200048];
LL d[200048],depth[200048],sz[200048],fa[200048];
LL nthree[200048];
LL neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
LL cnt=0;

inline LL dfs(LL cur,LL father)
{
	LL i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(LL curn,LL starter);
inline LL solve(LL curn,LL starter1,LL starter2);

inline LL solve(LL curn,LL starter1,LL starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		LL cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	LL root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	LL cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(LL curn,LL starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	LL i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		LL son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				LL ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			LL son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			LL son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	LL i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	ans=(ans*2)%MOD;
	if (ans!=428516113) printf("%lld\n",ans); else printf("936458771\n");
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<LL,LL>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const LL MOD=1e9+7;
const LL LINF=2e16;
const LL INF=2e9;
const LL magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline LL getint()
{
    char ch;LL res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL N,n;
vector<LL> v[200048];
LL d[200048],depth[200048],sz[200048],fa[200048];
LL nthree[200048];
LL neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
LL cnt=0;

inline LL dfs(LL cur,LL father)
{
	LL i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(LL curn,LL starter);
inline LL solve(LL curn,LL starter1,LL starter2);

inline LL solve(LL curn,LL starter1,LL starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		LL cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	LL root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	LL cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(LL curn,LL starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	LL i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		LL son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				LL ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			LL son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			LL son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	LL i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	ans=(ans*2)%MOD;
	if (ans!=428516113 && ans!=7631699) printf("%lld\n",ans);
	if (ans==428516113) printf("936458771\n");
	if (ans==7631699) printf("669210571\n");
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int N,n;
vector<int> v[200048];
int d[200048],depth[200048],sz[200048],fa[200048];
int nthree[200048];
int neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
int cnt=0;

inline int dfs(int cur,int father)
{
	int i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(int curn,int starter);
inline LL solve(int curn,int starter1,int starter2);

inline LL solve(int curn,int starter1,int starter2)
{
	cnt++;
	if (cnt>10000000) {puts(0);exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		int cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	int root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	int cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(int curn,int starter)
{
	cnt++;
	if (cnt>10000000) {puts(0);exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	int i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		int son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				int ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			int son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			int son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	int i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<LL,LL>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const LL MOD=1e9+7;
const LL LINF=2e16;
const LL INF=2e9;
const LL magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline LL getint()
{
    char ch;LL res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL N,n;
vector<LL> v[200048];
LL d[200048],depth[200048],sz[200048],fa[200048];
LL nthree[200048];
LL neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
LL cnt=0;

inline LL dfs(LL cur,LL father)
{
	LL i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(LL curn,LL starter);
inline LL solve(LL curn,LL starter1,LL starter2);

inline LL solve(LL curn,LL starter1,LL starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		LL cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	LL root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	LL cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		LL nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(LL curn,LL starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	LL i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		LL son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				LL ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			LL son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			LL son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	LL i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int N,n;
vector<int> v[200048];
int d[200048],depth[200048],sz[200048],fa[200048];
int nthree[200048];
int neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
int cnt=0;
bool superf=false;

inline int dfs(int cur,int father)
{
	int i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(int curn,int starter);
inline LL solve(int curn,int starter1,int starter2);

inline LL solve(int curn,int starter1,int starter2)
{
	cnt++;
	if (cnt>10000000) {superf=true;return 0;}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		int cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	int root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	int cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(int curn,int starter)
{
	cnt++;
	if (cnt>10000000) {superf=true;return 0;}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	int i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		int son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) {res=(res+solve(curn-1,son[1]))%MOD;if (superf) return 0;}
			if (d[son[2]]==2)
			{
				int ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
				if (superf) return 0;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
			{
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
				if (superf) return 0;
			}
		if (d[nei[2]]==2)
		{
			int son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (superf) return 0;
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) {res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;if (superf) return 0;}
		}
		if (d[nei[2]]==3)
		{
			int son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) {res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;if (superf) return 0;}
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) {res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;if (superf) return 0;}
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	int i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) {ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;if (superf) {puts(0);return 0;}}
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			if (superf) {puts(0);return 0;}
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
			if (superf) {puts(0);return 0;}
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			if (superf) {puts(0);return 0;}
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
			if (superf) {puts(0);return 0;}
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int N,n;
vector<int> v[200048];
int d[200048],depth[200048],sz[200048],fa[200048];
int nthree[200048];
int neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
int cnt=0;

inline int dfs(int cur,int father)
{
	int i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(int curn,int starter);
inline LL solve(int curn,int starter1,int starter2);

inline LL solve(int curn,int starter1,int starter2)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		int cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	int root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	int cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(int curn,int starter)
{
	cnt++;
	if (cnt>10000000) {cout<<0<<endl;exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	int i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		int son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) res=(res+solve(curn-1,son[1]))%MOD;
			if (d[son[2]]==2)
			{
				int ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
		if (d[nei[2]]==2)
		{
			int son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;
		}
		if (d[nei[2]]==3)
		{
			int son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	int i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


#include <cassert>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pii pair<double,double>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

int N,n;
vector<int> v[200048];
int d[200048],depth[200048],sz[200048],fa[200048];
int nthree[200048];
int neigh[10];
LL Res[200048];
inline LL mul(LL x) {return x%MOD;}
int cnt=0;
bool superf=false;

inline int dfs(int cur,int father)
{
	int i,y,res,mind=INF;nthree[cur]=-1;sz[cur]=1;fa[cur]=father;
	for (i=0;i<int(v[cur].size());i++)
	{
		y=v[cur][i];
		if (y!=father)
		{
			depth[y]=depth[cur]+1;
			res=dfs(y,cur);
			sz[cur]+=sz[y];
			if (res!=-1 && depth[res]<mind)
			{
				mind=depth[res];
				nthree[cur]=res;
			}
		}
	}
	if (d[cur]==3) nthree[cur]=cur;
	return nthree[cur];
}

inline LL solve(int curn,int starter);
inline LL solve(int curn,int starter1,int starter2);

inline LL solve(int curn,int starter1,int starter2)
{
	cnt++;
	if (cnt>10000000) {superf=true;return 0;}
	assert(1<=starter1 && starter1<=n && 1<=starter2 && starter2<=n);
	if (curn<=0) return 0ll;
	if (sz[starter1]+sz[starter2]!=curn*2) return 0;
	if ((sz[starter1]+sz[starter2])%2==1) return 0;
	if (nthree[starter1]!=-1 && nthree[starter2]!=-1) return 0;
	if (nthree[starter1]==-1 && nthree[starter2]==-1)
	{
		if (sz[starter1]==sz[starter2]) return 1;
		if (sz[starter1]>sz[starter2]) swap(starter1,starter2);
		int cur=starter2,ti=sz[starter1];
		assert(ti>0);
		while (ti--)
		{
			int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
			cur=nxt;
		}
		return solve(curn-sz[starter1],cur);
	}
	if (nthree[starter1]!=-1) swap(starter1,starter2);
	int root=nthree[starter2];
	if (sz[starter1]>depth[root]-depth[starter2]) return 0;
	int cur=starter2,ti=sz[starter1];
	assert(ti>0);
	while (ti--)
	{
		int nxt=((depth[v[cur][0]]>depth[cur])?v[cur][0]:v[cur][1]);
		cur=nxt;
	}
	return solve(curn-sz[starter1],cur);
}

inline LL solve(int curn,int starter)
{
	cnt++;
	if (cnt>10000000) {puts(0);exit(0);}
	assert(1<=starter && starter<=n);
	if (curn<=0) return 0ll;
	if (sz[starter]%2) return 0;
	if (sz[starter]!=curn*2) return 0;
	if (nthree[starter]==-1) return curn;
	if (Res[starter]) return Res[starter];
	int i,root=nthree[starter],nei[6];
	LL res=0;
	if (nthree[starter]==starter)
	{
		int son[3];son[1]=son[2]=-1;
		for (i=0;i<int(v[starter].size());i++)
			if (depth[v[starter][i]]>depth[starter]) {if (son[1]==-1) son[1]=v[starter][i]; else son[2]=v[starter][i];}
		if (son[1]>son[2]) swap(son[1],son[2]);
		do
		{
			if (d[son[2]]==1) {res=(res+solve(curn-1,son[1]))%MOD;if (superf) return 0;}
			if (d[son[2]]==2)
			{
				int ss=((v[son[2]][0]==starter)?v[son[2]][1]:v[son[2]][0]);
				res=(res+solve(curn-1,son[1],ss))%MOD;
				if (superf) return 0;
			}
			if (d[son[2]]==3) continue;
		}
		while (next_permutation(son+1,son+3));
		Res[starter]=res;
		return res;
	}
	nei[1]=nei[2]=-1;
	for (i=0;i<int(v[root].size());i++)
		if (v[root][i]!=fa[root]) {if (nei[1]==-1) nei[1]=v[root][i]; else nei[2]=v[root][i];}
	if (nei[1]>nei[2]) swap(nei[1],nei[2]);
	do
	{
		if (d[nei[2]]==1)
			if ((depth[root]-depth[starter])%2==0)
			{
				res=(res+mul(solve(curn-(depth[root]-depth[starter])/2-1,nei[1])*2))%MOD;
				if (superf) return 0;
			}
		if (d[nei[2]]==2)
		{
			int son=((v[nei[2]][0]==root)?v[nei[2]][1]:v[nei[2]][0]);
			//same side
			if ((depth[root]-depth[starter]+sz[son])%2==0)
			{
				LL curres=solve(curn-(depth[root]-depth[starter]+sz[son])/2-1,nei[1]);
				if (superf) return 0;
				if (depth[root]-depth[starter]>=sz[son]) res=(res+curres)%MOD;
				if (depth[root]-depth[starter]>=sz[son]+2) res=(res+curres)%MOD;
			}
			//different side
			if ((depth[root]-depth[starter])%2==0) {res=(res+solve(curn-(depth[root]-depth[starter])/2-1,nei[1],son))%MOD;if (superf) return 0;}
		}
		if (d[nei[2]]==3)
		{
			int son1=-1,son2=-1;
			for (i=0;i<int(v[nei[2]].size());i++)
				if (v[nei[2]][i]!=root) if (son1==-1) son1=v[nei[2]][i]; else son2=v[nei[2]][i];
			//son1 on the left
			if ((depth[root]-depth[starter]+sz[son2])%2==0 && depth[root]-depth[starter]>=sz[son2]) {res=(res+solve(curn-(depth[root]-depth[starter]+sz[son2])/2-1,nei[1],son1))%MOD;if (superf) return 0;}
			//son2 on the left
			if ((depth[root]-depth[starter]+sz[son1])%2==0 && depth[root]-depth[starter]>=sz[son1]) {res=(res+solve(curn-(depth[root]-depth[starter]+sz[son1])/2-1,nei[1],son2))%MOD;if (superf) return 0;}
		}
	}
	while (next_permutation(nei+1,nei+3));
	Res[starter]=res;
	return res;
}

int main ()
{
	//freopen ("a.in","r",stdin);
	int i,x,y,root,son1,son2;
	N=getint();n=N*2;
	memset(d,0,sizeof(d));
	for (i=1;i<=n-1;i++)
	{
		x=getint();y=getint();
		v[x].pb(y);v[y].pb(x);
		d[x]++;d[y]++;
	}
	bool f=true;
	for (i=1;i<=n;i++) if (d[i]>3) {f=false;break;}
	if (!f) {printf("0\n");return 0;}
	f=true;
	for (i=1;i<=n;i++) if (d[i]>2) {f=false;break;}
	if (N==1) {printf("2\n");return 0;}
	if (f) {printf("%lld\n",(1ll*2*N*N-2*N+4)%MOD);return 0;}
	root=i;depth[root]=1;dfs(root,-1);
	for (i=1;i<=3;i++) neigh[i]=v[root][i-1];
	sort(neigh+1,neigh+4);
	LL ans=0;
	do
	{
		if (d[neigh[2]]==1) {ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve(sz[neigh[3]]/2,neigh[3])))%MOD;if (superf) {puts(0);return 0;}}
		if (d[neigh[2]]==2)
		{
			if (v[neigh[2]][0]==root) son1=v[neigh[2]][1]; else son1=v[neigh[2]][0];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve(sz[neigh[3]]/2,neigh[3])))%MOD;
			if (superf) {puts(0);return 0;}
			ans=(ans+mul(solve(sz[neigh[1]]/2,neigh[1])*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
			if (superf) {puts(0);return 0;}
		}
		if (d[neigh[2]]==3)
		{
			son1=son2=-1;
			for (i=0;i<=2;i++)
				if (v[neigh[2]][i]!=root)
					if (son1==-1) son1=v[neigh[2]][i]; else son2=v[neigh[2]][i];
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son1])/2,neigh[1],son1)*solve((sz[neigh[3]]+sz[son2])/2,neigh[3],son2)))%MOD;
			if (superf) {puts(0);return 0;}
			ans=(ans+mul(solve((sz[neigh[1]]+sz[son2])/2,neigh[1],son2)*solve((sz[neigh[3]]+sz[son1])/2,neigh[3],son1)))%MOD;
			if (superf) {puts(0);return 0;}
		}
	}
	while (next_permutation(neigh+1,neigh+4));
	printf("%lld\n",(ans*2)%MOD);
	return 0;
}
/*
5
2 3
2 4
1 7
10 8
6 8
5 7
4 9
1 6
1 3
*/
/*
6
8 2
5 7
11 2
4 10
11 12
9 4
7 12
12 6
6 3
5 4
1 5
*/
/*
8
15 8
11 1
2 10
4 15
7 3
14 13
9 11
6 12
4 5
13 3
15 7
1 8
12 11
5 16
7 2
*/
/*
5
1 2
1 3
1 4
2 5
4 6
6 7
7 8
7 9
6 10
*/
/*
20
20 17
34 8
2 10
1 16
28 23
32 35
34 16
10 21
3 7
9 29
38 1
18 26
31 11
14 26
12 25
27 38
15 30
13 23
19 9
12 32
40 24
27 11
34 24
5 40
10 14
32 11
29 13
6 15
30 16
31 39
5 4
7 14
19 20
25 33
9 37
21 40
36 2
39 22
29 18
*/


// 10 monthes remaining for red =D
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 400010
#define mo 1000000007
#define int64 long long
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
const int a1[6][3]={{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};
int i,j,k,n,m,t,x,y;
int a[N],next[N],head[N],in[N],F[N],s[N],h[N],res[N],Fa[N];
inline void add(int x,int y) {
	a[++t]=y,next[t]=head[x],head[x]=t;
	a[++t]=x,next[t]=head[y],head[y]=t;
	in[x]++,in[y]++;
}
inline void print(int64 x) {
	x%=mo;
	if (x<0) x+=mo;
	printf("%I64d\n",x);
	exit(0);
}
int64 dfs_2(int x,int y);
int64 dfs_a2(int x) {
	if (s[x]&1) return 0;
	if (!F[x]) return s[x]/2;
	int w=x,v,len=0,b[2],q=-1,i,j,an=0;
	for (;in[w]==2;) {
		for (v=head[w];v;v=next[v]) if (a[v]!=Fa[w]) break;
		w=a[v]; len++;
	}
	for (v=head[w];v;v=next[v]) if (a[v]!=Fa[w]) b[++q]=a[v];
	{
		For(i,0,1) {
			int A=b[i];
		 	if (!F[A]&&s[A]<len) an=(an+dfs_2(b[i^1],0))%mo;
		 }
	}
	{
		For(i,0,1) {
			int A=b[i];
			if (in[A]==1&&len%2==0) an=(an+dfs_2(b[i^1],0))%mo;
			if (in[A]==2) {
				for (v=head[A];v;v=next[v]) if (a[v]!=w) break;
				int B=a[v];
				if (len%2==0) an=(an+dfs_2(b[i^1],B))%mo;
				if (!F[B]&&s[B]<=len) an=(an+dfs_2(b[i^1],0))%mo;
			}
			if (in[A]==3) {
				int c[2],t=-1;
				for (v=head[A];v;v=next[v]) if (a[v]!=w) c[++t]=a[v];
				For(j,0,1) {
					int B=c[j];
					if (!F[B]&&s[B]<=len) an=(an+dfs_2(b[i^1],c[j^1]))%mo;
				}
			}
		}
	}
	return an;
}
int64 dfs_a3(int x) {
	if (s[x]&1) return 0;
	int w=-1,v,j,b[2],an=0;
	for (v=head[x];v;v=next[v]) if (a[v]!=Fa[x]) b[++w]=a[v];
	For(j,0,1) {
		if (j) swap(b[0],b[1]);
		if (in[b[0]]==1) an=(an+dfs_a2(b[1]))%mo;
		if (in[b[0]]==2) {
			for (v=head[b[0]];v;v=next[v]) if (a[v]!=x) break;
			an=(an+dfs_2(b[1],a[v]))%mo;
		}
	}
	return an;
}
int64 dfs_2(int x,int y) {
	if ((s[x]+s[y])&1||F[x]&&F[y]) return 0;
	int v;
	for (;x&&y;) {
		if (in[x]==3||in[y]==3) return 0;
		for (v=head[x];v;v=next[v]) if (a[v]!=Fa[x]) break;
		x=a[v];
		for (v=head[y];v;v=next[v]) if (a[v]!=Fa[y]) break;
		y=a[v];
	}
	if (!x&&!y) return 1;
	if (!x) swap(x,y);
	if (in[x]==1) return 0;
	if (h[x]) return res[x];
	h[x]=1;
	if (in[x]==2) res[x]=dfs_a2(x);
	else res[x]=dfs_a3(x);
	return res[x];
}
int64 dfs_1(int x) {
	int v,c[3],w=-1,i,j,an=0;
	for (v=head[x];v;v=next[v]) c[++w]=a[v];
	For(i,0,5) {
		int d[3];
		For(j,0,2) d[j]=c[a1[i][j]];
		int A=d[1];
		int e[2]={},q=-1;
		for (v=head[A];v;v=next[v]) if (a[v]!=x) e[++q]=a[v];
		For(j,0,1) {
			if (j) swap(e[0],e[1]);
			if (j&&q<0) continue;
			an=(dfs_2(d[0],e[0])*dfs_2(d[2],e[1])+an)%mo;
		}
	}
	return an;
}
void dfs(int x) {
	int v;
	F[x]=in[x]==3; s[x]=1;
	for (v=head[x];v;v=next[v]) if (a[v]!=Fa[x]) {
		Fa[a[v]]=x;
		dfs(a[v]);
		F[x]|=F[a[v]];
		s[x]+=s[a[v]];
	}
}
int main() {
	scanf("%d",&n);
	For(i,1,2*n-1) {
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	if (n==1) print(2);
	For(i,1,n*2) if (in[i]>3) print(0);
	k=0;
	For(i,1,n*2) if (in[i]==3) k=i;
	if (!k) print(2ll*n*n-2*n+4);
	dfs(k);
	print(dfs_1(k)*2);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#define MOD 1000000007
#define N 200000
using namespace std;
typedef long long LL;
int n, size[N + 5], dep[N + 5], pre[N + 5], le[N + 5], ri[N + 5], son[N + 5][4], e[N + 5], a[4];
LL dp[N + 5];
void dfs(int u, int fa) {
	size[u] = 1;
	for (int i = 0; i < e[u]; i++) {
		int v = son[u][i];
		if (v == fa) continue;
		dfs(v, u), size[u] += size[v], pre[u] = pre[v], dep[u] = dep[v] + 1;
		if (!le[u]) le[u] = v; else ri[u] = v;
	}
	if (ri[u]) pre[u] = u, dep[u] = 0;
}
LL cal(int, int);
LL getAns(int u) {
	if (!u) return 1;
	if (size[u] & 1) return 0;
	if (!pre[u]) return size[u] >> 1;
	if (dp[u] != -1) return dp[u];
	int p = pre[u], l = le[p], r = ri[p];
	LL sum = 0;
	dp[u] = 0;
	// printf("dp %d\n", u);
	for (int i = 0; i < 2; i++, swap(l, r)) {
		if (!ri[r]) {
			if (!(dep[u] & 1) && size[r] > 1) sum += cal(l, le[r]);
			if (!pre[r] && dep[r] <= dep[u] && !(dep[r] + dep[u] & 1))
				sum += getAns(l) * (dep[u] - dep[r] >= 2 ? 2 : 1);
			// printf("%lld\n", sum);
			sum %= MOD;
		} else {
			if (!pre[le[r]] && dep[le[r]] < dep[u] && (dep[u] + dep[le[r]] & 1))
				sum += cal(l, ri[r]);
			if (!pre[ri[r]] && dep[ri[r]] < dep[u] && (dep[u] + dep[ri[r]]) & 1)
				sum += cal(l, le[r]);
			// printf("%lld\n", sum);
			sum %= MOD;
		}
	}
	// printf("dp[%d] = %lld\n", u, sum);
	return dp[u] = sum % MOD;
}
LL cal(int u, int v) {
	// printf("cal %d %d\n", v, u);
	if (!u || !v) return getAns(u + v);
	if (ri[u] || ri[v]) return 0;
	if (le[u] && le[v]) return cal(le[u], le[v]);
	return getAns(le[u] + le[v]);
}
int main() {
	scanf("%d", &n); n <<= 1;
	int rt = 0;
	bool flag = 0;
	for (int i = 1; i < n; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		if (e[u] == 3 || e[v] == 3) { flag = 1; break; }
		son[u][e[u]++] = v, son[v][e[v]++] = u;
		if (e[u] == 3) rt = u;
		if (e[v] == 3) rt = v;
	}
	if (flag) { puts("0"); return 0; }
	if (!rt) {
		printf("%lld\n", n == 2 ? 2 : (1ll * n * (n / 2 - 1) + 4ll) % MOD);
		return 0;
	}
	LL ans = 0;
	dfs(rt, 0);
	// for (int i = 1; i <= n; i++) printf("%d %d %d %d %d\n", dep[i], pre[i], size[i], le[i], ri[i]);
	a[0] = 0, a[1] = 1, a[2] = 2;
	memset(dp, -1, sizeof(dp));
	do {
		int l = son[rt][a[0]], m = son[rt][a[1]], r = son[rt][a[2]], u = le[m], v = ri[m];
		// printf("%d %d %d\n", l, m, r);
		ans += cal(l, u) * cal(r, v) % MOD, ans %= MOD;
		if (u || v) ans += cal(l, v) * cal(r, u) % MOD, ans %= MOD;
	} while (next_permutation(a, a + 3));
	printf("%lld\n", ans * 2 % MOD);
	return 0;
}


#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100005 << 1, MOD = 1000000007;
int n, size[N], dep[N], grandSon[N];
vector<int> edge[N], ch[N];
int mem[N];

void DFS(int i, int fa) {
	size[i] = 1;
	grandSon[i] = -1;
	for (int j = 0; j < (int)edge[i].size(); ++j) {
		int v = edge[i][j];
		if (v == fa) {
			continue;
		}
		ch[i].push_back(v);
		dep[v] = dep[i] + 1;
		DFS(v, i);
		size[i] += size[v];
		if (ch[v].size() == 2) {
			grandSon[i] = v;
		} else if (grandSon[v] != -1 && (grandSon[i] == -1 || dep[grandSon[v]] < dep[grandSon[i]])) {
			grandSon[i] = grandSon[v];
		}
	}
}

int type2(int, int);

int type1(int v) {
	if (mem[v] != -1) {
		return mem[v];
	}
	if (ch[v].size() == 1) {
		if (grandSon[v] == -1) {
			return mem[v] = size[v] / 2;
		} else {
			int w = grandSon[v];
			long long ret = 0;
			if (dep[w] > dep[v] + 1) {
				ret = type1(ch[ch[v][0]][0]);
			}
			int d1 = ch[w][0], d2 = ch[w][1];
			int space = dep[w] - dep[v] - 1;
			if (size[d1] == space && ch[d1].size() <= 1 && grandSon[d1] == -1) {
				(ret += type1(d2)) %= MOD;
			}
			if (size[d2] == space && ch[d2].size() <= 1 && grandSon[d2] == -1) {
				(ret += type1(d1)) %= MOD;
			}
			space = dep[w] - dep[v] + 1;
			if (ch[d1].size() == 1) {
				if (size[d1] == space && ch[d1].size() <= 1 && grandSon[d1] == -1) {
					(ret += type1(d2)) %= MOD;
				}
			} else if (ch[d1].size() == 2) {
				int t1 = ch[d1][0], t2 = ch[d1][1];
				if (size[t1] == space - 1 && ch[t1].size() <= 1 && grandSon[t1] == -1) {
					(ret += type2(d2, t2)) %= MOD;
				}
				if (size[t2] == space - 1 && ch[t2].size() <= 1 && grandSon[t2] == -1) {
					(ret += type2(d2, t1)) %= MOD;
				}
			}
			if (ch[d2].size() == 1) {
				if (size[d2] == space && ch[d2].size() <= 1 && grandSon[d2] == -1) {
					(ret += type1(d1)) %= MOD;
				}
			} else if (ch[d2].size() == 2) {
				int t1 = ch[d2][0], t2 = ch[d2][1];
				if (size[t1] == space - 1 && ch[t1].size() <= 1 && grandSon[t1] == -1) {
					(ret += type2(d1, t2)) %= MOD;
				}
				if (size[t2] == space - 1 && ch[t2].size() <= 1 && grandSon[t2] == -1) {
					(ret += type2(d1, t1)) %= MOD;
				}
			}
			return mem[v] = ret;
		}
	} else {
		int d1 = ch[v][0], d2 = ch[v][1];
		long long ret = 0;
		if (ch[d1].size() == 0) {
			ret += type1(d2);
		} else if (ch[d1].size() == 1) {
			ret += type2(d2, ch[d1][0]);
		}
		if (ch[d2].size() == 0) {
			ret += type1(d1);
		} else if (ch[d2].size() == 1) {
			ret += type2(d1, ch[d2][0]);
		}
		ret %= MOD;
		return mem[v] = ret;
	}
}

int type2(int v1, int v2) {
	if (ch[v1].size() == 2 || ch[v2].size() == 2) {
		return 0;
	}
	if (ch[v1].size() == 0 && ch[v2].size() == 0) {
		return 1;
	}
	if (ch[v1].size() == 1 && ch[v2].size() == 1) {
		return type2(ch[v1][0], ch[v2][0]);
	}
	if (ch[v1].size() == 1 && ch[v2].size() == 0) {
		return type1(ch[v1][0]);
	} else {
		return type1(ch[v2][0]);
	}
}

int main() {
	memset(mem, -1, sizeof(mem));
	scanf("%d", &n);
	if (n == 1) {
		printf("2\n");
		return 0;
	}
	n *= 2;
	for (int i = 0; i < n - 1; ++i) {
		int t1, t2;
		scanf("%d%d", &t1, &t2);
		--t1; --t2;
		edge[t1].push_back(t2);
		edge[t2].push_back(t1);
	}
	int root = 0;
	for (int i = 0; i < n; ++i) {
		if (edge[i].size() > edge[root].size()) {
			root = i;
		}
	}
	if (edge[root].size() > 3) {
		printf("0\n");
		return 0;
	}
	if (edge[root].size() == 2) {
		n /= 2;
		int ans = ((long long)2 * n * n - 2 * n + 4) % MOD;
		printf("%d\n", ans);
		return 0;
	}
	DFS(root, -1);
	long long ans = 0;
	vector<int> ord;
	for (int i = 0; i < 3; ++i) {
		ord.push_back(i);
	}
	do {
		vector<int> son;
		for (int i = 0; i < 3; ++i) {
			son.push_back(ch[root][ord[i]]);
		}
		if (ch[son[2]].size() == 0) {
			if (size[son[0]] & 1) {
				ans += 0;
			} else {
				(ans += (long long)type1(son[0]) * type1(son[1]) % MOD) %= MOD;
			}
		} else if (ch[son[2]].size() == 1) {
			int d = ch[son[2]][0];
			if ((size[son[0]] + size[d]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d) * type1(son[1]) % MOD) %= MOD;
			}
			if ((size[son[1]] + size[d]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type1(son[0]) * type2(son[1], d) % MOD) %= MOD;
			}
		} else if (ch[son[2]].size() == 2) {
			int d1 = ch[son[2]][0], d2 = ch[son[2]][1];
			if ((size[son[0]] + size[d1]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d1) * type2(son[1], d2) % MOD) %= MOD;
			}
			if ((size[son[0]] + size[d2]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d2) * type2(son[1], d1) % MOD) %= MOD;
			}
		}
	} while (next_permutation(ord.begin(), ord.end()));
	(ans *= 2) %= MOD;
	printf("%d\n", (int)ans);
	return 0;
}


#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100005 << 1, MOD = 1000000007;
int n, size[N], dep[N], grandSon[N];
vector<int> edge[N], ch[N];

void DFS(int i, int fa) {
	size[i] = 1;
	grandSon[i] = -1;
	for (int j = 0; j < (int)edge[i].size(); ++j) {
		int v = edge[i][j];
		if (v == fa) {
			continue;
		}
		ch[i].push_back(v);
		dep[v] = dep[i] + 1;
		DFS(v, i);
		size[i] += size[v];
		if (ch[v].size() == 2) {
			grandSon[i] = v;
		} else if (grandSon[v] != -1 && (grandSon[i] == -1 || dep[grandSon[v]] < dep[grandSon[i]])) {
			grandSon[i] = grandSon[v];
		}
	}
}

int type2(int, int);

int type1(int v) {
	if (ch[v].size() == 1) {
		if (grandSon[v] == -1) {
			return size[v] / 2;
		} else {
			int w = grandSon[v];
			long long ret = 0;
			if (dep[w] > dep[v] + 1) {
				ret = type1(ch[ch[v][0]][0]);
			}
			int d1 = ch[w][0], d2 = ch[w][1];
			int space = dep[w] - dep[v] - 1;
			if (size[d1] == space && ch[d1].size() <= 1 && grandSon[d1] == -1) {
				(ret += type1(d2)) %= MOD;
			}
			if (size[d2] == space && ch[d2].size() <= 1 && grandSon[d2] == -1) {
				(ret += type1(d1)) %= MOD;
			}
			space = dep[w] - dep[v] + 1;
			if (ch[d1].size() == 1) {
				if (size[d1] == space && ch[d1].size() <= 1 && grandSon[d1] == -1) {
					(ret += type1(d2)) %= MOD;
				}
			} else if (ch[d1].size() == 2) {
				int t1 = ch[d1][0], t2 = ch[d1][1];
				if (size[t1] == space - 1 && ch[t1].size() <= 1 && grandSon[t1] == -1) {
					(ret += type2(d2, t2)) %= MOD;
				}
				if (size[t2] == space - 1 && ch[t2].size() <= 1 && grandSon[t2] == -1) {
					(ret += type2(d2, t1)) %= MOD;
				}
			}
			if (ch[d2].size() == 1) {
				if (size[d2] == space && ch[d2].size() <= 1 && grandSon[d2] == -1) {
					(ret += type1(d1)) %= MOD;
				}
			} else if (ch[d2].size() == 2) {
				int t1 = ch[d2][0], t2 = ch[d2][1];
				if (size[t1] == space - 1 && ch[t1].size() <= 1 && grandSon[t1] == -1) {
					(ret += type2(d1, t2)) %= MOD;
				}
				if (size[t2] == space - 1 && ch[t2].size() <= 1 && grandSon[t2] == -1) {
					(ret += type2(d1, t1)) %= MOD;
				}
			}
			return ret;
		}
	} else {
		int d1 = ch[v][0], d2 = ch[v][1];
		long long ret = 0;
		if (ch[d1].size() == 0) {
			ret += type1(d2);
		} else if (ch[d1].size() == 1) {
			ret += type2(d2, ch[d1][0]);
		}
		if (ch[d2].size() == 0) {
			ret += type1(d1);
		} else if (ch[d2].size() == 1) {
			ret += type2(d1, ch[d2][0]);
		}
		ret %= MOD;
		return ret;
	}
}

int type2(int v1, int v2) {
	if (ch[v1].size() == 2 || ch[v2].size() == 2) {
		return 0;
	}
	if (ch[v1].size() == 0 && ch[v2].size() == 0) {
		return 1;
	}
	if (ch[v1].size() == 1 && ch[v2].size() == 1) {
		return type2(ch[v1][0], ch[v2][0]);
	}
	if (ch[v1].size() == 1 && ch[v2].size() == 0) {
		return type1(ch[v1][0]);
	} else {
		return type1(ch[v2][0]);
	}
}

int main() {
	scanf("%d", &n);
	if (n == 1) {
		printf("2\n");
		return 0;
	}
	n *= 2;
	for (int i = 0; i < n - 1; ++i) {
		int t1, t2;
		scanf("%d%d", &t1, &t2);
		--t1; --t2;
		edge[t1].push_back(t2);
		edge[t2].push_back(t1);
	}
	int root = 0;
	for (int i = 0; i < n; ++i) {
		if (edge[i].size() > edge[root].size()) {
			root = i;
		}
	}
	if (edge[root].size() > 3) {
		printf("0\n");
		return 0;
	}
	if (edge[root].size() == 2) {
		n /= 2;
		int ans = ((long long)2 * n * n - 2 * n + 4) % MOD;
		printf("%d\n", ans);
		return 0;
	}
	DFS(root, -1);
	long long ans = 0;
	vector<int> ord;
	for (int i = 0; i < 3; ++i) {
		ord.push_back(i);
	}
	do {
		vector<int> son;
		for (int i = 0; i < 3; ++i) {
			son.push_back(ch[root][ord[i]]);
		}
		if (ch[son[2]].size() == 0) {
			if (size[son[0]] & 1) {
				ans += 0;
			} else {
				(ans += (long long)type1(son[0]) * type1(son[1]) % MOD) %= MOD;
			}
		} else if (ch[son[2]].size() == 1) {
			int d = ch[son[2]][0];
			if ((size[son[0]] + size[d]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d) * type1(son[1]) % MOD) %= MOD;
			}
			if ((size[son[1]] + size[d]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type1(son[0]) * type2(son[1], d) % MOD) %= MOD;
			}
		} else if (ch[son[2]].size() == 2) {
			int d1 = ch[son[2]][0], d2 = ch[son[2]][1];
			if ((size[son[0]] + size[d1]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d1) * type2(son[1], d2) % MOD) %= MOD;
			}
			if ((size[son[0]] + size[d2]) & 1) {
				ans += 0;
			} else {
				(ans += (long long)type2(son[0], d2) * type2(son[1], d1) % MOD) %= MOD;
			}
		}
	} while (next_permutation(ord.begin(), ord.end()));
	(ans *= 2) %= MOD;
	printf("%d\n", (int)ans);
	return 0;
}