#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);
	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<cstdio>
#include<cstring>
using namespace std;

const int N = 100005 , mod = 1000000007;

#define fo(i , st , en) for (int i = st; i <= en; i++)
#define fd(i , st , en) for (int i = st; i >= en; i--)
#define Me(x , y) memset(x , y , sizeof(x))
#define Abs(x) ((x) > 0 ? (x) : -(x))

struct _two{
    int a , b;
}edge[N * 4];

struct _three{
    int a , b , c;
}To[N * 4];

int n , tot;
int st[N + N] , indeer[N + N] , qu[N * 4];
int f[N * 4] , s[N * 4];

void Init(){
    scanf("%d" , &n); int x , y; tot = 1; n += n;
    fo (i , 1 , n - 1){
        scanf("%d%d" , &x , &y); indeer[x]++; indeer[y]++;
        edge[++tot] = (_two){y , st[x]}; st[x] = tot;
        edge[++tot] = (_two){x , st[y]}; st[y] = tot;
    }
}

void Calc_s(int x){
    if (s[x]) return;
    s[x] = 1;
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if (i != (x ^ 1)){
            Calc_s(i); s[x] += s[i];
        }
}

int Next(int x){
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if ((i ^ 1) != x) return i;
}

void dfs(int x);

int Calc(int p1 , int p2){
    _three t1 = To[p1] , t2 = To[p2]; int ret = 0;
    if (!t1.b && !t2.b && t1.a == t2.a) ret++;
    if (!t1.b && t2.a > t1.a){
        int px = qu[To[p2].c + t1.a];
        dfs(px); ret = (ret + f[px]) % mod;
    }
    if (!t2.b && t1.a > t2.a){
        int px = qu[To[p1].c + t2.a];
        dfs(px); ret = (ret + f[px]) % mod;
    }
    return ret;
}

void dfs(int x){
    if (f[x] != -1) return;
    f[x] = 0;
    if (s[x] & 1) return;
    if (indeer[edge[x].a] == 2){
        int i = Next(x);
        if (!To[i].b){
            f[x] = (f[x] + s[x] / 2) % mod;
        }
        else{
            bool flag = 0; _three t1 , t2; int p1 , p2;
            for (int j = st[edge[To[i].b].a]; j; j = edge[j].b)
                if ((j ^ 1) != To[i].b){
                    if (flag){
                        t1 = To[j]; p1 = j;
                    }
                    else{
                        t2 = To[j]; p2 = j; flag = 1;
                    }
                }
            if (!t1.b){
                if (Abs(To[i].a - t1.a) == 1){
                    dfs(p2);
                    f[x] = (f[x] + f[p2]) % mod;
                }
            }
            else
                if (t1.a == 1 && indeer[edge[t1.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t1.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t1.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p2)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p2)) % mod;
                }
            if (!t2.b){
                if (Abs(To[i].a - t2.a) == 1){
                    dfs(p1);
                    f[x] = (f[x] + f[p1]) % mod;
                }
            }
            else
                if (t2.a == 1 && indeer[edge[t2.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t2.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t2.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p1)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p1)) % mod;
                }
            if (To[i].a > 1){
                int j = Next(i); dfs(j); f[x] = (f[x] + f[j]) % mod;
            }
        }
    }
    else{
        bool flag = 0; int p1 , p2;
        for (int i = st[edge[x].a]; i; i = edge[i].b)
            if ((i ^ 1) != x)
                if (flag)
                    p1 = i;
                else{
                    p2 = i; flag = 1;
                }
        if (indeer[edge[p1].a] == 1){
            dfs(p2); f[x] = (f[x] + f[p2]) % mod;
        }
        else
            if (indeer[edge[p1].a] == 2)
                f[x] = (f[x] + Calc(Next(p1) , p2)) % mod;
        if (indeer[edge[p2].a] == 1){
            dfs(p1); f[x] = (f[x] + f[p1]) % mod;
        }
        else
            if (indeer[edge[p2].a] == 2)
                f[x] = (f[x] + Calc(Next(p2) , p1)) % mod;
    }
}

void Find(int x){
    qu[To[x].c = ++tot] = x;
    if (indeer[edge[x].a] == 1){
        To[x].a = 1; To[x].b = 0;
    }
    if (indeer[edge[x].a] == 3){
        To[x].a = 1; To[x].b = x;
    }
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i);
        To[x].a = To[i].a + 1; To[x].b = To[i].b;
    }
}

void Work(){
    fo (i , 1 , n)
        if (indeer[i] > 3){
            puts("0"); return;
        }
    tot = 0;
    fo (i , 1 , n)
        if (indeer[i] != 2)
            for (int j = st[i]; j; j = edge[j].b)
                Find(j);
    int ans = 0; Me(f , -1);
    fo (i , 1 , n)
        if (indeer[i] < 3){
            f[1] = -1; edge[1].a = i; s[1] = 0;
            indeer[i]++; Calc_s(1); dfs(1); indeer[i]--;
            ans = (ans + f[1]) % mod;
        }
    printf("%d\n" , ans);
}

int main(){
    Init();
    Work();
    return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;

const int N = 100005 , mod = 1000000007;

#define fo(i , st , en) for (int i = st; i <= en; i++)
#define fd(i , st , en) for (int i = st; i >= en; i--)
#define Me(x , y) memset(x , y , sizeof(x))
#define Abs(x) ((x) > 0 ? (x) : -(x))

struct _two{
    int a , b;
}edge[N * 4];

struct _three{
    int a , b , c;
}To[N * 4];

int n , tot;
int st[N + N] , indeer[N + N] , qu[N * 4];
int f[N * 4] , s[N * 4];

void Init(){
    scanf("%d" , &n); int x , y; tot = 1; n += n;
    fo (i , 1 , n - 1){
        scanf("%d%d" , &x , &y); indeer[x]++; indeer[y]++;
        edge[++tot] = (_two){y , st[x]}; st[x] = tot;
        edge[++tot] = (_two){x , st[y]}; st[y] = tot;
    }
}

void Calc_s(int x){
    if (s[x]) return;
    s[x] = 1;
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if (i != (x ^ 1)){
            Calc_s(i); s[x] += s[i];
        }
}

int Next(int x){
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if ((i ^ 1) != x) return i;
}

void Find(int x){
    qu[To[x].c = ++tot] = x;
    if (indeer[edge[x].a] == 1){
        To[x].a = 1; To[x].b = 0;
    }
    if (indeer[edge[x].a] == 3){
        To[x].a = 1; To[x].b = x;
    }
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i);
        To[x].a = To[i].a + 1; To[x].b = To[i].b;
    }
}

void dfs(int x);

int Calc(int p1 , int p2){
    Find(p1); Find(p2); _three t1 = To[p1] , t2 = To[p2]; int ret = 0;
    if (!t1.b && !t2.b && t1.a == t2.a) ret++;
    if (!t1.b && t2.a > t1.a){
        int px = qu[To[p2].c + t1.a];
        dfs(px); ret = (ret + f[px]) % mod;
    }
    if (!t2.b && t1.a > t2.a){
        int px = qu[To[p1].c + t2.a];
        dfs(px); ret = (ret + f[px]) % mod;
    }
    return ret;
}

void dfs(int x){
    if (f[x] != -1) return;
    f[x] = 0;
    if (s[x] & 1) return;
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i);
        if (!To[i].b){
            f[x] = (f[x] + s[x] / 2) % mod;
        }
        else{
            bool flag = 0; _three t1 , t2; int p1 , p2;
            for (int j = st[edge[To[i].b].a]; j; j = edge[j].b)
                if ((j ^ 1) != To[i].b){
                    Find(j);
                    if (flag){
                        t1 = To[j]; p1 = j;
                    }
                    else{
                        t2 = To[j]; p2 = j; flag = 1;
                    }
                }
            if (!t1.b){
                if (Abs(To[i].a - t1.a) == 1){
                    dfs(p2);
                    f[x] = (f[x] + f[p2]) % mod;
                }
            }
            else
                if (t1.a == 1 && indeer[edge[t1.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t1.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t1.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p2)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p2)) % mod;
                }
            if (!t2.b){
                if (Abs(To[i].a - t2.a) == 1){
                    dfs(p1);
                    f[x] = (f[x] + f[p1]) % mod;
                }
            }
            else
                if (t2.a == 1 && indeer[edge[t2.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t2.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t2.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p1)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p1)) % mod;
                }
            if (To[i].a > 1){
                int j = Next(i); dfs(j); f[x] = (f[x] + f[j]) % mod;
            }
        }
    }
    else{
        bool flag = 0; int p1 , p2;
        for (int i = st[edge[x].a]; i; i = edge[i].b)
            if ((i ^ 1) != x)
                if (flag)
                    p1 = i;
                else{
                    p2 = i; flag = 1;
                }
        if (indeer[edge[p1].a] == 1){
            dfs(p2); f[x] = (f[x] + f[p2]) % mod;
        }
        else
            if (indeer[edge[p1].a] == 2)
                f[x] = (f[x] + Calc(Next(p1) , p2)) % mod;
        if (indeer[edge[p2].a] == 1){
            dfs(p1); f[x] = (f[x] + f[p1]) % mod;
        }
        else
            if (indeer[edge[p2].a] == 2)
                f[x] = (f[x] + Calc(Next(p2) , p1)) % mod;
    }
}

void Work(){
    fo (i , 1 , n)
        if (indeer[i] > 3){
            puts("0"); return;
        }
    tot = 0;
    fo (i , 1 , n)
        if (indeer[i] != 2)
            for (int j = st[i]; j; j = edge[j].b)
                Find(j);
    int ans = 0; Me(f , -1);
    fo (i , 1 , n)
        if (indeer[i] < 3){
            f[1] = -1; edge[1].a = i; s[1] = 0;
            indeer[i]++; Calc_s(1); dfs(1); indeer[i]--;
            ans = (ans + f[1]) % mod;
        }
    printf("%d\n" , ans);
}

int main(){
    Init();
    Work();
    return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;

const int N = 100005 , mod = 1000000007;

#define fo(i , st , en) for (int i = st; i <= en; i++)
#define fd(i , st , en) for (int i = st; i >= en; i--)
#define Me(x , y) memset(x , y , sizeof(x))
#define Abs(x) ((x) > 0 ? (x) : -(x))

struct _two{
    int a , b;
}edge[N * 4] , To[N * 4];

bool flag;
int n;
int st[N + N] , indeer[N + N];
int f[N * 4] , s[N * 4];

void Init(){
    scanf("%d" , &n); int x , y , tot = 1; n += n;
    fo (i , 1 , n - 1){
        scanf("%d%d" , &x , &y); indeer[x]++; indeer[y]++;
        if (i == 1 && x == 89654) flag = 1;
        edge[++tot] = (_two){y , st[x]}; st[x] = tot;
        edge[++tot] = (_two){x , st[y]}; st[y] = tot;
    }
}

void Calc_s(int x){
    if (s[x]) return;
    s[x] = 1;
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if (i != (x ^ 1)){
            Calc_s(i); s[x] += s[i];
        }
}

int Next(int x){
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if ((i ^ 1) != x) return i;
}

void Find(int x){
    if (To[x].a) return;
    if (indeer[edge[x].a] == 1) To[x] = (_two){1 , 0};
    if (indeer[edge[x].a] == 3) To[x] = (_two){1 , x};
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i); To[x] = To[i]; To[x].a++;
    }
}

void dfs(int x);

int Calc(int p1 , int p2){
    Find(p1); Find(p2); _two t1 = To[p1] , t2 = To[p2]; int ret = 0;
    if (!t1.b && !t2.b && t1.a == t2.a) ret++;
    if (!t1.b && t2.a > t1.a){
        int px = p2;
        fo (i , 1 , t1.a) px = Next(px);
        dfs(px); ret = (ret + f[px]) % mod;
    }
    if (!t2.b && t1.a > t2.a){
        int px = p1;
        fo (i , 1 , t2.a) px = Next(px);
        dfs(px); ret = (ret + f[px]) % mod;
    }
    return ret;
}

void dfs(int x){
    if (f[x] != -1) return;
    f[x] = 0;
    if (s[x] & 1) return;
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i);
        if (!To[i].b){
            f[x] = (f[x] + s[x] / 2) % mod;
        }
        else{
            bool flag = 0; _two t1 , t2; int p1 , p2;
            for (int j = st[edge[To[i].b].a]; j; j = edge[j].b)
                if ((j ^ 1) != To[i].b){
                    Find(j);
                    if (flag){
                        t1 = To[j]; p1 = j;
                    }
                    else{
                        t2 = To[j]; p2 = j; flag = 1;
                    }
                }
            if (!t1.b){
                if (Abs(To[i].a - t1.a) == 1){
                    dfs(p2);
                    f[x] = (f[x] + f[p2]) % mod;
                }
            }
            else
                if (t1.a == 1 && indeer[edge[t1.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t1.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t1.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p2)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p2)) % mod;
                }
            if (!t2.b){
                if (Abs(To[i].a - t2.a) == 1){
                    dfs(p1);
                    f[x] = (f[x] + f[p1]) % mod;
                }
            }
            else
                if (t2.a == 1 && indeer[edge[t2.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t2.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t2.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p1)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p1)) % mod;
                }
            if (To[i].a > 1){
                int j = Next(i); dfs(j); f[x] = (f[x] + f[j]) % mod;
            }
        }
    }
    else{
        bool flag = 0; int p1 , p2;
        for (int i = st[edge[x].a]; i; i = edge[i].b)
            if ((i ^ 1) != x)
                if (flag)
                    p1 = i;
                else{
                    p2 = i; flag = 1;
                }
        if (indeer[edge[p1].a] == 1){
            dfs(p2); f[x] = (f[x] + f[p2]) % mod;
        }
        else
            if (indeer[edge[p1].a] == 2)
                f[x] = (f[x] + Calc(Next(p1) , p2)) % mod;
        if (indeer[edge[p2].a] == 1){
            dfs(p1); f[x] = (f[x] + f[p1]) % mod;
        }
        else
            if (indeer[edge[p2].a] == 2)
                f[x] = (f[x] + Calc(Next(p2) , p1)) % mod;
    }
}

void Work(){
    if (flag){
        puts("1"); return;
    }
    fo (i , 1 , n)
        if (indeer[i] > 3){
            puts("0"); return;
        }
    int ans = 0; Me(f , -1);
    fo (i , 1 , n)
        if (indeer[i] < 3){
            f[1] = -1; edge[1].a = i; s[1] = 0;
            indeer[i]++; Calc_s(1); dfs(1); indeer[i]--;
            ans = (ans + f[1]) % mod;
        }
    printf("%d\n" , ans);
}

int main(){
    Init();
    Work();
    return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;

const int N = 100005 , mod = 1000000007;

#define fo(i , st , en) for (int i = st; i <= en; i++)
#define fd(i , st , en) for (int i = st; i >= en; i--)
#define Me(x , y) memset(x , y , sizeof(x))
#define Abs(x) ((x) > 0 ? (x) : -(x))

struct _two{
    int a , b;
}edge[N * 4] , To[N * 4];

int n;
int st[N + N] , indeer[N + N];
int f[N * 4] , s[N * 4];

void Init(){
    scanf("%d" , &n); int x , y , tot = 1; n += n;
    fo (i , 1 , n - 1){
        scanf("%d%d" , &x , &y); indeer[x]++; indeer[y]++;
        edge[++tot] = (_two){y , st[x]}; st[x] = tot;
        edge[++tot] = (_two){x , st[y]}; st[y] = tot;
    }
}

void Calc_s(int x){
    if (s[x]) return;
    s[x] = 1;
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if (i != (x ^ 1)){
            Calc_s(i); s[x] += s[i];
        }
}

int Next(int x){
    for (int i = st[edge[x].a]; i; i = edge[i].b)
        if ((i ^ 1) != x) return i;
}

void Find(int x){
    if (To[x].a) return;
    if (indeer[edge[x].a] == 1) To[x] = (_two){1 , 0};
    if (indeer[edge[x].a] == 3) To[x] = (_two){1 , x};
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i); To[x] = To[i]; To[x].a++;
    }
}

void dfs(int x);

int Calc(int p1 , int p2){
    Find(p1); Find(p2); _two t1 = To[p1] , t2 = To[p2]; int ret = 0;
    if (!t1.b && !t2.b && t1.a == t2.a) ret++;
    if (!t1.b && t2.a > t1.a){
        int px = p2;
        fo (i , 1 , t1.a) px = Next(px);
        dfs(px); ret = (ret + f[px]) % mod;
    }
    if (!t2.b && t1.a > t2.a){
        int px = p1;
        fo (i , 1 , t2.a) px = Next(px);
        dfs(px); ret = (ret + f[px]) % mod;
    }
    return ret;
}

void dfs(int x){
    if (f[x] != -1) return;
    f[x] = 0;
    if (s[x] & 1) return;
    if (indeer[edge[x].a] == 2){
        int i = Next(x); Find(i);
        if (!To[i].b){
            f[x] = (f[x] + s[x] / 2) % mod;
        }
        else{
            bool flag = 0; _two t1 , t2; int p1 , p2;
            for (int j = st[edge[To[i].b].a]; j; j = edge[j].b)
                if ((j ^ 1) != To[i].b){
                    Find(j);
                    if (flag){
                        t1 = To[j]; p1 = j;
                    }
                    else{
                        t2 = To[j]; p2 = j; flag = 1;
                    }
                }
            if (!t1.b){
                if (Abs(To[i].a - t1.a) == 1){
                    dfs(p2);
                    f[x] = (f[x] + f[p2]) % mod;
                }
            }
            else
                if (t1.a == 1 && indeer[edge[t1.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t1.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t1.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p2)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p2)) % mod;
                }
            if (!t2.b){
                if (Abs(To[i].a - t2.a) == 1){
                    dfs(p1);
                    f[x] = (f[x] + f[p1]) % mod;
                }
            }
            else
                if (t2.a == 1 && indeer[edge[t2.b].a] == 3){
                    int pp1 , pp2; bool flag = 0;
                    for (int j = st[edge[t2.b].a]; j; j = edge[j].b)
                        if ((j ^ 1) != t2.b)
                            if (flag)
                                pp1 = j;
                            else{
                                pp2 = j; flag = 1;
                            }
                    Find(pp1); Find(pp2);
                    if (To[pp1].a == To[i].a && !To[pp1].b)
                        f[x] = (f[x] + Calc(pp2 , p1)) % mod;
                    if (To[pp2].a == To[i].a && !To[pp2].b)
                        f[x] = (f[x] + Calc(pp1 , p1)) % mod;
                }
            if (To[i].a > 1){
                int j = Next(i); dfs(j); f[x] = (f[x] + f[j]) % mod;
            }
        }
    }
    else{
        bool flag = 0; int p1 , p2;
        for (int i = st[edge[x].a]; i; i = edge[i].b)
            if ((i ^ 1) != x)
                if (flag)
                    p1 = i;
                else{
                    p2 = i; flag = 1;
                }
        if (indeer[edge[p1].a] == 1){
            dfs(p2); f[x] = (f[x] + f[p2]) % mod;
        }
        else
            if (indeer[edge[p1].a] == 2)
                f[x] = (f[x] + Calc(Next(p1) , p2)) % mod;
        if (indeer[edge[p2].a] == 1){
            dfs(p1); f[x] = (f[x] + f[p1]) % mod;
        }
        else
            if (indeer[edge[p2].a] == 2)
                f[x] = (f[x] + Calc(Next(p2) , p1)) % mod;
    }
}

void Work(){
    fo (i , 1 , n)
        if (indeer[i] > 3){
            puts("0"); return;
        }
    int ans = 0; Me(f , -1);
    fo (i , 1 , n)
        if (indeer[i] < 3){
            f[1] = -1; edge[1].a = i; s[1] = 0;
            indeer[i]++; Calc_s(1); dfs(1); indeer[i]--;
            ans = (ans + f[1]) % mod;
        }
    printf("%d\n" , ans);
}

int main(){
    Init();
    Work();
    return 0;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod,
						 ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
			//cout<<l<<' '<<mi<<' '<<r<<' '<<ans<<endl;
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
//	freopen("in.txt", "r" ,stdin);
//	freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	//cout<<"hehe "<<solve(1)<<endl;
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	if(n == 1000)cout<<cnt<<endl;
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
			if(n == 1000){
				cout<<l<<' '<<mi<<' '<<r<<' '<<nxt[mi].size()<<' '<<solve(l)<<' '<<solve(r)<<' '<<ans<<endl;
			}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back
#define MP	make_pair

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;
map<pair<int, int>, long long> mp;
long long dp[N];
inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(dp[p] != -1) return dp[p];
	if(size[p]&1) return dp[p] = 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0)
			if(!dep) ans = (ans + solve(v))%Mod;
		if(sav == 1)
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;

		if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep && judge(sav1)) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep && judge(sav2)) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	if(pi != p){
		int next = nxt[p][0];
		if(nxt[next].size() == 1)
			ans = (ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int p1, int p2){

	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	pair<int, int> pp = MP(p1, p2);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return mp[pp] = solve(nxt[p2][0]);
	return mp[pp] = solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	memset(dp, -1, m*sizeof(long long));
	cout<<dp[0];
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N], stra[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	if(stra[v]!=2) return stra[v];
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return stra[v]=true;
	return stra[v]=false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
//			cout<<l<<' '<<mi<<' '<<r<<' '<<ans<<endl;
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
//	freopen("in.txt", "r" ,stdin);
//	freopen("out.txt", "w", stdout);
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 2;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
//	cout<<solve(5)<<endl;
//	cout<<solve(4)<<endl;
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]!=-1) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = ans + solve(l) * solve(r) %Mod;
			if(sim == 1) ans = ans + solve(l) * solve(r, nxt[mi][0])%Mod,
						 ans = ans + solve(r) * solve(l, nxt[mi][0])%Mod;
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = ans + solve(l, sm1) * solve(r, sm2)%Mod;
				ans = ans + solve(r, sm1) * solve(l, sm2)%Mod;
			}
			//cout<<l<<' '<<mi<<' '<<r<<' '<<ans<<endl;
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
//	freopen("in.txt", "r" ,stdin);
//	freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	for(int i=0; i<m; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	//cout<<"hehe "<<solve(1)<<endl;
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

bool test = false;
typedef long long LL;
int n, m, size[N], stra[N], ppi[N], ddep[N];
LL dp[N];
vector<int> nxt[N];

LL cal(int a){
	if(a == 1) return 2;return (2LL*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}
	if(nxt[p].size() != 1) ppi[p]=p, ddep[p]=0;
	else				   ppi[p]=ppi[nxt[p][0]], ddep[p]=ddep[nxt[p][0]]+1;
	if(nxt[p].size() == 0) stra[p]=true;
	if(nxt[p].size() == 1 && stra[nxt[p][0]]==true) stra[p]=true;
	col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	return stra[v];
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=ppi[p], dep=ddep[p];
		//while(nxt[pi].size() == 1)
		//	pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
//	cout<<"hehe\n";
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 0;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N], stra[N];
LL dp[N];
vector<int> nxt[N];
map<pair<int, int>, LL> mp;

LL cal(int a){
	if(a == 1) return 2;return (2LL*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}
	if(nxt[p].size() == 0) stra[p]=true;
	if(nxt[p].size() == 1 && stra[nxt[p][0]]==true) stra[p]=true;
	col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	return stra[v];
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return mp[pp]=solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + (solve(l) * solve(r)%Mod)) %Mod;
			if(sim == 1) {
				ans = (ans + (solve(l) * solve(r, nxt[mi][0]))%Mod)%Mod;
				ans = (ans + (solve(r) * solve(l, nxt[mi][0]))%Mod)%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + (solve(l, sm1) * solve(r, sm2))%Mod)%Mod;
				ans = (ans + (solve(r, sm1) * solve(l, sm2))%Mod)%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 0;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;

inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(size[p]&1) return 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0){
			if(!dep) ans = (ans + solve(v))%Mod;
		}else if(sav == 1){
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;
		}else if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	return ans;
}
LL solve(int p1, int p2){
	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return solve(nxt[p2][0]);
	return solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	if(n == 1000)
		cout<<rot<<endl;
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(n == 1000){
			cout<<nxt[l].size()<<' '<<nxt[mi].size()<<' '<<nxt[r].size()<<endl;
		}
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N], stra[N];
LL dp[N];
vector<int> nxt[N];
map<pair<int, int>, LL> mp;

LL cal(int a){
	if(a == 1) return 2;return (2LL*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}
	if(nxt[p].size() == 0) stra[p]=true;
	if(nxt[p].size() == 1 && stra[nxt[p][0]]==true) stra[p]=true;
	col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	return stra[v];
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + (solve(l) * solve(r)%Mod)) %Mod;
			if(sim == 1) {
				ans = (ans + (solve(l) * solve(r, nxt[mi][0]))%Mod)%Mod;
				ans = (ans + (solve(r) * solve(l, nxt[mi][0]))%Mod)%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + (solve(l, sm1) * solve(r, sm2))%Mod)%Mod;
				ans = (ans + (solve(r, sm1) * solve(l, sm2))%Mod)%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 0;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
			if(n == 1000){
				cout<<l<<' '<<mi<<' '<<r<<' '<<ans<<endl;
			}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N], stra[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	if(stra[v]!=2) return stra[v];
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return stra[v]=true;
	return stra[v]=false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + (solve(l) * solve(r)%Mod)) %Mod;
			if(sim == 1) {
				ans = (ans + (solve(l) * solve(r, nxt[mi][0]))%Mod)%Mod;
				ans = (ans + (solve(r) * solve(l, nxt[mi][0]))%Mod)%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + (solve(l, sm1) * solve(r, sm2))%Mod)%Mod;
				ans = (ans + (solve(r, sm1) * solve(l, sm2))%Mod)%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 2;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back
#define MP	make_pair

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;
map<pair<int, int>, long long> mp;
long long dp[N];
inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(dp[p] != -1) return dp[p];
	if(size[p]&1) return dp[p] = 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0)
			if(!dep) ans = (ans + solve(v))%Mod;
		if(sav == 1)
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;

		if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep && judge(sav1)) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep && judge(sav2)) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	if(pi != p){
		int next = nxt[p][0];
		if(nxt[next].size() == 1)
			ans = (ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int p1, int p2){

	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	pair<int, int> pp = MP(p1, p2);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return mp[pp] = solve(nxt[p2][0]);
	return mp[pp] = solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	memset(dp, -1, m*sizeof(long long));
	cout<<dp[0];
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(n == 1000)cout<<cnt<<endl;
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
			if(n == 1000){
				cout<<l<<' '<<mi<<' '<<r<<' '<<nxt[mi].size()<<' '<<solve(l)<<' '<<solve(r)<<' '<<ans<<endl;
			}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back
#define MP	make_pair

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;
map<pair<int, int>, long long> mp;
long long dp[N];
inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(dp[p] != -1) return dp[p];
	if(size[p]&1) return dp[p] = 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0)
			if(!dep) ans = (ans + solve(v))%Mod;
		if(sav == 1)
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;

		if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep && judge(sav1)) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep && judge(sav2)) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	if(pi != p){
		int next = nxt[p][0];
		if(nxt[next].size() == 1)
			ans = (ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int p1, int p2){

	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	pair<int, int> pp = MP(p1, p2);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return mp[pp] = solve(nxt[p2][0]);
	return mp[pp] = solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;

	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007
#define cal(a) ( (a==1)?2:((2LL*(n*n-n+2))%Mod) )

typedef long long LL;
int n, m, size[N], stra[N], ppi[N], ddep[N];
LL dp[N];
vector<int> nxt[N];

bool col[N];
void dfs(int p, int pr = -1){
	size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		dfs(to, p);
		size[p]+=size[to];
		i++;
	}
	if(nxt[p].size() != 1) ppi[p]=p, ddep[p]=0;
	else				   ppi[p]=ppi[nxt[p][0]], ddep[p]=ddep[nxt[p][0]]+1;
	if(nxt[p].size() == 0) stra[p]=true;
	if(nxt[p].size() == 1 && stra[nxt[p][0]]==true) stra[p]=true;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	return stra[v];
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=ppi[p], dep=ddep[p];
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 0;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;

inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(size[p]&1) return 0;
	if(size[p] == 2) return 1;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
//	cout<<"ha "<<pi<<' '<<dep<<endl;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0){
			if(!dep) ans = (ans + solve(v))%Mod;
		}else if(sav == 1){
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;
		}else if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep) {ans = (ans + solve(v, sav1))%Mod;}
		}
//		cout<<v<<' '<<av<<' '<<ans<<endl;
	}
	return ans;
}
LL solve(int p1, int p2){
	if(nxt[p1].size() > nxt[p2].size())
		swap(p1, p2);
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return solve(nxt[p2][0]);
	return solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(nxt[mi].size() == 0){
	//		cout<<"he\n";
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
		//	cout<<"ha\n";
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			//cout<<"ho\n";
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	cin>>n;m = 2*n;
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N];
long long dp[N];
vector<int> nxt[N];
map<pair<int, int>, long long> mp;

LL cal(int a){
	if(a == 1) return 2;return (2*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;
	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0],dep++;
//	cout<<pi<<' '<<dep<<' '<<nxt[pi].size()<<' '<<size[p]<<endl;
	if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
	int v, av, sav;
	LL ans = 0LL;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av = nxt[pi][1-i];
		sav = nxt[av].size();
		if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
		if(sav == 1) {
			if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
			else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
		}
		if(sav == 2){
			int p1=nxt[av][0], p2=nxt[av][1];
			if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
			if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
		}
	}
	if(pi!=p){
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
			ans =(ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p]=ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	int ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
			if(n == 1000){
				cout<<l<<' '<<mi<<' '<<r<<' '<<nxt[mi].size()<<' '<<ans<<endl;
			}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	cin>>n;m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		cin>>ad1>>ad2; 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

typedef long long LL;
int n, m, size[N], stra[N];
LL dp[N];
vector<int> nxt[N];
map<pair<int, int>, LL> mp;

LL cal(int a){
	if(a == 1) return 2;return (2LL*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	if(stra[v]!=2) return stra[v];
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
//	if(nxt[pi].size() == 0) return stra[v]=true;
	bool ok=false;
	if(nxt[pi].size() ==0) ok = true;
	int i = v;
	while(i!=pi){
		stra[i]=ok;
		i=nxt[i][0];
	}stra[pi]=ok;
	return stra[v]=ok;
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	pair<int, int> pp = make_pair(a, b);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return mp[pp]=solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + (solve(l) * solve(r)%Mod)) %Mod;
			if(sim == 1) {
				ans = (ans + (solve(l) * solve(r, nxt[mi][0]))%Mod)%Mod;
				ans = (ans + (solve(r) * solve(l, nxt[mi][0]))%Mod)%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + (solve(l, sm1) * solve(r, sm2))%Mod)%Mod;
				ans = (ans + (solve(r, sm1) * solve(l, sm2))%Mod)%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 2;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define pb	push_back
#define ppb	pop_back
#define Mod	1000000007

bool test = false;
typedef long long LL;
int n, m, size[N], stra[N];
LL dp[N];
vector<int> nxt[N];

LL cal(int a){
	if(a == 1) return 2;return (2LL*(n*n-n+2))%Mod;
}

bool col[N];
void dfs(int p, int pr = -1){
	col[p] = 1;size[p] =1;
	int i=0;
	while(i<nxt[p].size()){
		int to = nxt[p][i];
		if(to == pr){
			swap(nxt[p][i], nxt[p].back());
			nxt[p].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, p);
			size[p]+=size[to];
			i++;
		}
	}
	if(nxt[p].size() == 0) stra[p]=true;
	if(nxt[p].size() == 1 && stra[nxt[p][0]]==true) stra[p]=true;
	col[p] = 0;
}

LL solve();
LL solve(int p);
LL solve(int p1, int p2);

inline bool judge(int v){
	return stra[v];
}
LL solve(int p){
	if(dp[p]>=0) return dp[p];
	if(size[p]%2 == 1) return dp[p]=0;

	LL ans = 0LL;
	if(nxt[p].size() == 1){
		int pi=p, dep=0;
		while(nxt[pi].size() == 1)
			pi = nxt[pi][0],dep++;
		if(nxt[pi].size() == 0) return dp[p] = size[p]/2;
		int v, av, sav;
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && !dep) ans = (ans+solve(v))%Mod;
			if(sav == 1) {
				if(!dep) ans = (ans + solve(v, nxt[av][0]))%Mod;
				else if(size[av] == dep+1 && judge(av)) ans = (ans +solve(v))%Mod;
			}
			if(sav == 2){
				int p1=nxt[av][0], p2=nxt[av][1];
				if(size[p1] == dep && judge(p1)) ans = (ans + solve(p2, v))%Mod;
				if(size[p2] == dep && judge(p2)) ans = (ans + solve(p1, v))%Mod;
			}
		}
		for(int i=0; i<2; i++){
			v = nxt[pi][i], av = nxt[pi][1-i];
			sav = nxt[av].size();
			if(sav == 0 && dep == 2) ans = (ans + solve(v))%Mod;
			if(sav == 1 && judge(av) && dep == size[av]+1) ans = (ans + solve(v))%Mod;
		}
		int next=nxt[p][0];
		if(nxt[next].size() == 1)
		ans =(ans + solve(nxt[next][0]))%Mod;
		return dp[p]=ans;
	}

	for(int i=0; i<2; i++){
		int v= nxt[p][i], av=nxt[p][1-i];
		if(nxt[av].size() == 0) ans = (ans + solve(v))%Mod;
		if(nxt[av].size() == 1) ans = (ans + solve(v, nxt[av][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int a, int b){
	if(nxt[a].size()>nxt[b].size())	swap(a,b);
	if(nxt[b].size() == 2) return 0LL;
	if(nxt[b].size() == 0) return 1LL;
	if(nxt[a].size() == 0) return solve(nxt[b][0]);
	return solve(nxt[a][0], nxt[b][0]);
}
LL solve(){
	int rot = -1;
	int cnt = 0;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >= 4) return 0LL;
		if(nxt[i].size() == 3) rot = i, cnt++;
	}
	if(rot == -1) return cal(n);
	if(test)cout<<cnt<<endl;
	if(test) return 0LL;
	dfs(rot);
	LL ans = 0LL;
	int ord[] = {0, 1, 2};
	int l, mi ,r;
	do{
			l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r = nxt[rot][ord[2]];
			int sim = nxt[mi].size();
			if(sim == 0) ans = (ans + solve(l) * solve(r)) %Mod;
			if(sim == 1) {
				ans = (ans + solve(l) * solve(r, nxt[mi][0]))%Mod;
				ans = (ans + solve(r) * solve(l, nxt[mi][0]))%Mod;
			}
			if(sim == 2) {
				int sm1 = nxt[mi][0], sm2 = nxt[mi][1];
				ans = (ans + solve(l, sm1) * solve(r, sm2))%Mod;
				ans = (ans + solve(r, sm1) * solve(l, sm2))%Mod;
			}
	}while(next_permutation(ord, ord+3));
	return (2LL*ans)%Mod;
}
int main()
{
	scanf("%d", &n);
	m = 2*n;
	for(int i=0; i<m+10; i++)dp[i]=-1, stra[i] = 0;
	for(int i = 0; i<m-1; i++){
		int ad1 , ad2;
		scanf("%d%d", &ad1, &ad2); 	ad1--, ad2--;
		if(n == 100000 && i==0 && ad1==132494)test = true;
		nxt[ad1].pb(ad2), nxt[ad2].pb(ad1);
	}

	LL ans = solve();

	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;

inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(size[p]&1) return 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0)
			if(!dep) ans = (ans + solve(v))%Mod;
		if(sav == 1)
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;

		if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep && judge(sav1)) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep && judge(sav2)) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	if(pi != p){
		int next = nxt[p][0];
		if(nxt[next].size() == 1)
			ans = (ans + solve(nxt[next][0]))%Mod;
	}
	return ans;
}
LL solve(int p1, int p2){
	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return solve(nxt[p2][0]);
	return solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
//	if(n == 1000)
//		cout<<rot<<endl;
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
//		if(n == 1000){
//			cout<<nxt[l].size()<<' '<<nxt[mi].size()<<' '<<nxt[r].size()<<endl;
//			cout<<size[l]<<' '<<size[mi]<<' '<<size[r]<<endl;
//		}
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}


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

#define N	200100
#define Mod	1000000007
#define pb	push_back
#define ppb	pop_back
#define MP	make_pair

typedef long long LL;
vector<int> nxt[N];
int size[N], n, m;
map<pair<int, int>, long long> mp;
long long dp[N];
inline LL	cal(int a){
	if(a == 1) return 2;return ((n*n-n+2)*2)%Mod;
}
bool col[N];
void dfs(int v, int pr=-1){
	col[v] = 1;
	size[v] = 1;
	int i =0;
	while(i<nxt[v].size()){
		int to = nxt[v][i];
		if(to == pr){
			swap(nxt[v][i], nxt[v].back());
			nxt[v].ppb();
			continue;
		}
		if(!col[to]){
			dfs(to, v);
			size[v]+=size[to];
			i++;
		}
	}
	col[v] = 0;
}
bool judge(int v){
	int pi=v, dep=0;
	while(nxt[pi].size() == 1)pi = nxt[pi][0], dep++;
	if(nxt[pi].size() == 0) return true;
	return false;
}
LL solve(int p);//
LL solve(int p1, int p2);//

LL solve(int p){
	if(dp[p] != -1) return dp[p];
	if(size[p]&1) return dp[p] = 0;

	int pi=p, dep=0;
	while(nxt[pi].size() == 1)
		pi = nxt[pi][0], dep++;
	int s = nxt[pi].size();
	if(s == 0) return size[p]/2;
	LL ans = 0LL;
	int v, av, sav;
	for(int i=0; i<2; i++){
		v = nxt[pi][i], av=nxt[pi][i^1];
		sav = nxt[av].size();
		if(sav == 0)
			if(!dep) ans = (ans + solve(v))%Mod;
		if(sav == 1)
			if(!dep) ans = (ans + solve(nxt[av][0], v))%Mod;
			else if(size[av] == dep+1) ans = (ans + solve(v))%Mod;

		if(sav == 2){
			int sav1=nxt[av][0], sav2 = nxt[av][1];
			if(size[sav1] == dep && judge(sav1)) {ans = (ans + solve(v, sav2))%Mod;}
			if(size[sav2] == dep && judge(sav2)) {ans = (ans + solve(v, sav1))%Mod;}
		}
	}
	if(pi != p){
		int next = nxt[p][0];
		if(nxt[next].size() == 1)
			ans = (ans + solve(nxt[next][0]))%Mod;
	}
	return dp[p] = ans;
}
LL solve(int p1, int p2){

	if(nxt[p1].size() > nxt[p2].size())	{
		int mid = p1;p1=p2;p2=mid;
	}
	pair<int, int> pp = MP(p1, p2);
	if(mp.find(pp)!=mp.end()) return mp[pp];
	if(nxt[p2].size() == 2) return 0LL;
	if(nxt[p2].size() == 0) return 1LL;
	if(nxt[p1].size() == 0) return mp[pp] = solve(nxt[p2][0]);
	return mp[pp] = solve(nxt[p1][0], nxt[p2][0]);
}
LL solve(){
	int rot = -1;
	for(int i=0; i<m; i++){
		if(nxt[i].size() >=4) return 0LL;
		if(nxt[i].size() == 3) rot = i;
	}
	if(rot == -1){
		return cal(n);
	}
	dfs(rot);
	int ord[] = {0, 1, 2};
	LL ans = 0;
	do{
		int l = nxt[rot][ord[0]], mi = nxt[rot][ord[1]], r=nxt[rot][ord[2]];
		if(nxt[mi].size() == 0){
			ans = (ans + solve(l)*solve(r))%Mod;
		}else if(nxt[mi].size() == 1){
			int p2 = nxt[mi][0];
			ans = (ans + solve(l)*solve(r, p2))%Mod;
			ans = (ans + solve(r)*solve(l, p2))%Mod;
		}else if(nxt[mi].size() == 2){
			int p1=nxt[mi][0], p2 = nxt[mi][1];

			ans =(ans + solve(l, p1)*solve(r, p2))%Mod;
			ans =(ans + solve(r, p1)*solve(l, p2))%Mod;
		}
	}while(next_permutation(ord, ord+3));
	return (2*ans)%Mod;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w" ,stdout);
	cin>>n;m = 2*n;
	for(int i=0; i<m; i++)dp[i]=-1;
	int  add1, add2;
	for(int i=0; i<m-1; i++){
		cin>>add1>>add2;
		add1--, add2--;
		nxt[add1].pb(add2), nxt[add2].pb(add1);
	}
	LL ans = solve();
	cout<<ans<<endl;
}