#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld =long double;
const ld eps = 1e-9;


//namespace cent {
//
//	struct Edge {
//		int src;
//		int dst;
//		long long int cost;
//	};
//	using Graph = vector<vector<Edge>>;
//
//	class Centroid {
//	private:
//		int dfs(const Graph&g, const int now, const int from, vector<int>&ch_nums, const vector<int>&oks) {
//			int sum = 1;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					sum += dfs(g, e.dst, e.src, ch_nums, oks);
//				}
//			}
//			return ch_nums[now] = sum;
//		}
//
//		int find_centroid(const int asize, const vector<vector<Edge>>&graph, const int pre_root, const int pre_from, const vector<int>&ch_nums, const vector<int>&oks) {
//			for (auto&& e : graph[pre_root]) {
//				if (e.dst == pre_from)continue;
//				if (oks[e.dst] != -1)continue;
//				if (ch_nums[e.dst]>asize / 2)return find_centroid(asize, graph, e.dst, e.src, ch_nums, oks);
//			}
//			return pre_root;
//		}
//
//		void dfs2(const Graph&g, const int root,const int now, const int from, const vector<int>&oks,int depth) {
//			mp[make_pair(root,now)]=depth;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					dfs2(g,root,e.dst,e.src,oks,depth+1);
//				}
//			}
//		};
//
//
//		void cent(const vector<vector<Edge>>&graph, vector<int>&oks, const int root, const int from, vector<vector<int>>&centroid_edges, int& fst_centroid, int depth, vector<int>&ch_nums) {
//			dfs(graph, root, from, ch_nums, oks);
//
//			int cent_id = find_centroid(ch_nums[root], graph, root, from, ch_nums, oks);
//
//
//			dfs2(graph,cent_id,cent_id,-1,oks,0);
//			lens1[cent_id][make_pair(0,0)]--;
//			lens2[cent_id][0]--;
//
//
//			oks[cent_id] = depth;
//
//			//for (auto&& e : graph[cent_id]) {
//			//	if (e.dst == from)continue;
//			//	if (oks[e.dst] != -1)continue;
//
//			//	dfs2(graph, e.dst, e.dst, e.src, oks,e.cost%mod,e.cost%mod,1);
//
//			//	for (auto&& l1 : lens1[e.dst]) {
//			//		int keta = l1.first.second;
//			//		long long int num = l1.first.first;
//
//			//		long long int need = (mod - num) / mod_pow(10, keta);
//			//		need%=mod;
//			//		auto it = lens2[e.dst].find(need);
//			//		if (it != lens2[e.dst].end()) {
//			//			ans -= l1.second*it->second;
//			//		}
//			//	}
//			//	lens1[e.dst].clear();
//			//	lens2[e.dst].clear();
//			//}
//
//			if (from != -1) {
//				centroid_edges[from].push_back(cent_id);
//			}
//			else {
//				fst_centroid = cent_id;
//			}
//			for (auto&& e : graph[cent_id]) {
//				if (e.dst == from)continue;
//				if (oks[e.dst] != -1)continue;
//				cent(graph, oks, e.dst, e.src, centroid_edges, fst_centroid, depth + 1, ch_nums);
//			}
//		}
//
//	public:
//
//		map<pair<int,int>,int>mp;
//
//		vector<map<pair<long long int,int>, long long int>>lens1;
//		vector<map<long long int, long long int>>lens2;
//		vector<vector<int>> centroid_graph;
//		vector<int>ts;
//		vector<int>parents;
//		vector<int>oks;
//		vector<int>anss;
//
//		//fst:root  snd:centroid_graph
//		void init(const Graph&g) {
//			lens1.resize(g.size());
//			lens2.resize(g.size());
//			oks = vector<int>(g.size(), -1);
//			int root = -1;
//			centroid_graph.resize(g.size());
//			parents = vector<int>(g.size(), -1);
//			ts=vector<int>(g.size(),-1);
//			anss=vector<int>(g.size(),100000);
//
//			vector<int>ch_nums(g.size());
//			cent(g, oks, 0, -1, centroid_graph, root, 0, ch_nums);
//
//			for (int i = 0; i < centroid_graph.size(); ++i) {
//				for (auto&& e : centroid_graph[i]) {
//					parents[e] = i;
//				}
//			}
//			return ;
//		}
//	}centroid;
//
//
//	void addEdge(Graph& g, int a, int b, long long int c) {
//		g[a].push_back(Edge{ a,b,c });
//		g[b].push_back(Edge{ b,a,c });
//	}
//}


//const int mod = 1000000007;
//struct Mod {
//public:
//	int num;
//	Mod() : Mod(0) { ; }
//	Mod(long long int n) : num((n % mod + mod) % mod) {
//		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
//	}
//	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
//	operator int() { return num; }
//};
//
//Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
//Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
//Mod operator+(const Mod a, const long long int  b) { return b + a; }
//Mod operator++(Mod &a) { return a + Mod(1); }
//Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
//Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
//Mod operator--(Mod &a) { return a - Mod(1); }
//Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
//Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
//Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
//Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
//Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
//Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
//Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
//Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
//Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
//Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
//Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
//Mod operator^(const Mod a, const int n) {
//	if (n == 0) return Mod(1);
//	Mod res = (a * a) ^ (n / 2);
//	if (n % 2) res = res * a;
//	return res;
//}
//Mod mod_pow(const Mod a, const long long  int n) {
//	if (n == 0) return Mod(1);
//	Mod res = mod_pow((a * a), (n / 2));
//	if (n % 2) res = res * a;
//	return res;
//}
//
////mod が素数の場合のみ　違う場合はextend euclid を用いる。
//Mod inv(const Mod a) { return a ^ (mod - 2); }
//Mod operator/(const Mod a, const Mod b) {
//	assert(b.num != 0);
//	return a * inv(b);
//}
//Mod operator/(const long long int a, const Mod b) {
//	return Mod(a) / b;
//}
//Mod operator/=(Mod &a, const Mod b) {
//	return a = a / b;
//}
//
//#define MAX_MOD_N 1024000
//
//Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
//void init(const int amax = MAX_MOD_N) {
//	fact[0] = Mod(1); factinv[0] = 1;
//	for (int i = 0; i < amax - 1; ++i) {
//		fact[i + 1] = fact[i] * Mod(i + 1);
//		factinv[i + 1] = factinv[i] / Mod(i + 1);
//	}
//}
//Mod comb(const int a, const int b) {
//	return fact[a] * factinv[b] * factinv[a - b];
//}
//
//vector<int>primes;
//void hurui(const int amax=3500) {
//	static bool flag = false;
//	if (flag)return;
//	vector<int>sos;
//	sos = vector<int>(amax + 1, true);
//	sos[0] = false; sos[1] = false;
//	for (int i = 2; i <= amax; ++i) {
//		if (sos[i]) {
//			for (int j = 2 * i; j <= amax; j += i)sos[j] = false;
//		}
//	}
//	for (int i = 0; i <= amax; ++i) {
//		if (sos[i]) {
//			primes.push_back(i);
//		}
//	}
//	flag = true;
//}
//
//
//struct query {
//	int u;
//	int v;
//	map<int,int>mp;
//};
//
//map<int, int>mk_mp(const int a) {
//	int rest(a);
//	map<int,int>as;
//	for (auto pr : primes) {
//		while (rest%pr == 0) {
//			as[pr]++;
//			rest /= pr;
//		}
//	}
//	if (rest!=1)as[rest]++;
//	return as;
//}
//
//#define Seg_Max_N (1<<18) 
//
//class Tree {
//public:
//	Tree(int V, int root) : V(V), root(root), cnum(V), place(V), id(V) {
//		T.resize(V);
//		for (int i = 0; i < MAXLOGV; i++) {
//			parent[i].resize(V);
//		}
//		depth.resize(V);
//	}
//	// uとvをつなぐ
//	// lcaを求めることが主目的なので無向グラフとしている
//	void unite(int u, int v) {
//		T[u].push_back(v);
//		T[v].push_back(u);
//	}
//	void unite(vector<vector<int>>&e) {
//		T = e;
//	}
//	// initする
//	// コンストラクタだけじゃなくてこれも呼ばないとlcaが求められないぞ
//	void init() {
//		dfs(root, 0, 0);
//		int id = 0;
//		getid(root, 0, id);
//	}
//	// uとvのlcaを求める
//	int lca(int u, int v) const {
//		if (depth[u] > depth[v]) swap(u, v);
//		for (int k = 0; k < MAXLOGV; k++) {
//			if ((depth[v] - depth[u]) >> k & 1) {
//				v = parent[k][v];
//			}
//		}
//		if (u == v) return u;
//		for (int k = MAXLOGV - 1; k >= 0; k--) {
//			if (parent[k][u] != parent[k][v]) {
//				u = parent[k][u];
//				v = parent[k][v];
//			}
//		}
//		return parent[0][u];
//	}
//	// uとvの距離を求める
//	// edgeを定義しないといけない時はこれじゃダメ
//	int dist(int u, int v) const {
//		int p = lca(u, v);
//		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
//	}
//	int dfs(int v, int p, int d) {
//		parent[0][v] = p;
//		depth[v] = d;
//		cnum[v] = 0;
//		for (int i = 1; i < MAXLOGV; i++) {
//			parent[i][v] = parent[i - 1][parent[i - 1][v]];
//		}
//		for (int next : T[v]) {
//			if (next != p) cnum[v] += dfs(next, v, d + 1);
//		}
//		return cnum[v] + 1;
//	}
//
//	void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
//		for (int next : T[v]) {
//			if (next != p) dfs2(next, v, doubles, nums);
//		}
//		doubles[0][v] = nums[v];
//		for (int j = 1; j < MAXLOGV; ++j) {
//			doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
//		}
//		for (int j = 0; j < MAXLOGV - 1; ++j) {
//			doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
//		}
//	}
//	//ここでは親から距離2^iの部分木の最小値を求めている
//	vector<vector<int>>get_doubles(const vector<int>&nums) {
//		vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
//		dfs2(root, -1, doubles, nums);
//		return doubles;
//	}
//
//	void getid(const int v, const int p, int &nplace) {
//		place[v] = nplace;
//		id[nplace] = v;
//		nplace++;
//		for (int next : T[v]) {
//			if (next != p) getid(next, v, nplace);
//		}
//	}
//	static const int MAXLOGV = 25;
//	// グラフの隣接リスト表現
//	vector<vector<int> > T;
//	// 頂点の数
//	int V;
//	// 根ノードの番号
//	int root;
//
//	// 親ノード
//	vector<int> parent[MAXLOGV];
//	// 根からの深さ
//	vector<int> depth;
//
//	//子の数
//	vector<int>cnum;
//
//	//変換
//	vector<int>place;
//	vector<int>id;
//
//};
//
//vector<int>pas;
//void adfs(vector<pair<int, int>>&lrs, vector<int>&tos,const vector<vector<int>>&edges, const int now, const int from,int &id) {
//	tos[now]=id;
//	lrs[tos[now]].first=id++;
//	for (auto e : edges[now]) {
//		if (e == from) {
//			pas[now] = from;
//			continue;
//		}
//		adfs(lrs,tos,edges,e,now,id);
//	}
//	lrs[tos[now]].second=id;
//}
//
//vector<pair<int, int>>get_lrs(vector<int>&tos,const vector<vector<int>>&edges, const int root) {
//	pas.resize(tos.size());pas[0]=-1;
//	vector<pair<int,int>>lrs(edges.size());
//	int id=0;
//	adfs(lrs,tos,edges,0,-1,id);
//	return lrs;
//}


ld memo[101][101][101][3][3];

ld solve(int a, int b, int c, int d, int e) ;

ld solve(vector<int>v, int joker, int player) {
	if(!(v[0]>=0&&v[1]>=0&&v[2]>=0&&joker>=0&&joker<=2&&player>=0&&player<=2))return 0;
	if (memo[v[0]][v[1]][v[2]][joker][player] < -0.5) {
		if (v[0] == 0 && v[1] == 0 && v[2] == 0) {
			if (joker == 1) {
				memo[v[0]][v[1]][v[2]][joker][player]=0;
			}
			else {
				memo[v[0]][v[1]][v[2]][joker][player]=1;
			}
		}
		else {
			const int n_player=(player+1)%3;
			// A no card
			if (v[0] == 0 && v[2] == 0 && joker != 0) {
				if (player == 0) {
					memo[v[0]][v[1]][v[2]][joker][player] = solve(v, joker, n_player);
				}
				else {
					const int drawn_player=(player^3);
					ld ans = 0;
					if (drawn_player == 2) {
						ans+=(joker==drawn_player)*solve(v,player, n_player);
						ans+=v[1]*solve(v[0],v[1]-1,v[2],joker, n_player);

						ans/=(joker==2)+v[1];
					}
					else {
						assert(v[1]);
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player]=ans;
				}
			}
			// B no card
			else if (v[0] == 0 && v[1] == 0 && joker != 1) {
				memo[v[0]][v[1]][v[2]][joker][player] = 1;
			}
			// C no card
			else if (v[1] == 0 && v[2] == 0 && joker != 2) {
				if (player == 2) {
					memo[v[0]][v[1]][v[2]][joker][player]=solve(v,joker,n_player);
				}
				else {
					const int drawn_player = (player ^ 1);
					ld ans = 0;
					if (drawn_player==0) {
						ans += (joker == drawn_player)*solve(v, player ,n_player);
						ans += v[0]*solve(v[0]-1, v[1], v[2], joker, n_player);

						assert((joker==0)+v[0]>=1);
						ans /= (joker == 0) + v[0];
					}
					else {
						assert(v[0]);
						ans = solve(v[0]-1, v[1], v[2], joker, n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player] = ans;
				}
			}
			else {
				ld ans=0;
				int drawn_player=(player+2)%3;
				if (player == 0) {
					ans+=v[1]*solve(v[0]+1,v[1]-1,v[2],joker,n_player);
					ans+=v[2]*solve(v[0],v[1],v[2]-1,joker,n_player);
					ans+=(joker==2)*solve(v[0],v[1],v[2],0,n_player);

					assert(v[1]+v[2]+(joker==2)>=1);
					ans/=v[1]+v[2]+(joker==2);
				}
				else if (player == 1) {
					ans+=v[2]*solve(v[0],v[1]+1,v[2]-1,joker,n_player);
					ans+=v[0]*solve(v[0]-1,v[1],v[2],joker,n_player);
					ans+=(joker==0)*solve(v[0],v[1],v[2],1,n_player);

					assert(v[2]+v[0]+(joker==0)>=1);
					ans/=v[2]+v[0]+(joker==0);
				}
				else if (player == 2) {
					if (v[1]) {
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}
					else if (v[0]) {
						ans=solve(v[0]-1,v[1],v[2]+1,joker,n_player);
					}
					else {
						assert(joker==1);
						ans=solve(v,player,n_player);
					}
				}
				memo[v[0]][v[1]][v[2]][joker][player] = ans;
			}
		}
	}
	return memo[v[0]][v[1]][v[2]][joker][player];
}

ld solve(int a, int b, int c, int d, int e) {
	return solve(vector<int>{a, b, c},d,e);
}

int main()
{

	int AB=0,BC=0,CA=0;
	int joker=-1;

	for (int i = 0; i < 101; ++i) {
		for (int j = 0; j < 101; ++j) {
			for (int k = 0; k < 101; ++k) {
				for (int l = 0; l < 3; ++l) {
					for (int m = 0; m < 3; ++m) {
						memo[i][j][k][l][m]=-1;
					}
				}
			}
		}
	}
	{
		int N; cin >> N;

		vector<vector<int>>nums(3, vector<int>(101));
		for (int i = 0; i < 3; ++i) {
			int m; cin >> m;
			map<int, int>mp;
			while (m--) {
				int a; cin >> a;
				mp[a]++;
			}
			for (auto m : mp) {
				if (m.second % 2)nums[i][m.first]++;
			}
		}

		for (int i = 0; i <= N; ++i) {
			if (i == 0) {
				for (int j = 0; j < 3; ++j) {
					if (nums[j][i]) {
						joker=j;
					}
				}
			}
			else {
				if (nums[0][i] && nums[1][i]) {
					AB++;
				}
				else if (nums[1][i] && nums[2][i]) {
					BC++;
				}
				else if (nums[2][i] && nums[0][i]) {
					CA++;
				}
			}
		}
	}

	ld ans=solve(AB,BC,CA,joker,0);

	cout<<setprecision(10)<<fixed<<double(ans)<<endl;
	
	return 0;
}


Measured memory_bytes: 148208