#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <random>
#include <ctime>
#include <string>
#include <iomanip>
#include <set>
#include <map>
#include <queue>
#include <numeric>
#include <limits>
#include <fstream>
#include <stack>
#include <unordered_set>
#include <sstream>
#include <array>
#include <chrono>
#include <unordered_map>
#include <cassert>

using namespace std;

typedef unsigned long long uli;
typedef long long li;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;


#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
//#define x first
//#define y second
#define pb push_back
#define mp make_pair
#define left 2 * v + 1
#define right 2 * v + 2
#define forn(i, n) for(int i = 0; i < (int)n; ++i)

const int INF = 1e9 + 1000;
const li INF64 = 1e18;

const int N = 4e5 + 1000;
const int MOD = (int)1e9 + 7;
const double EPS = 1E-9;
const double PI = acos(-1.);


vector<int> g21[N];
vector<int> g32[N];
vector<int> g43[N];


int T[4][4 * N];

void build_tree(int idx, vi & a, int v, int l, int r) {

	if (r - l == 1) {
		T[idx][v] = a[l];
		return;
	}

	int m = (r + l) / 2;
	build_tree(idx, a, left, l, m);
	build_tree(idx, a, right, m, r);

	T[idx][v] = min(T[idx][left], T[idx][right]);
}


int get(int idx) {
	return T[idx][0];
}


void upd(int idx, int v, int l, int r, int i, int val) {
	if (r - l == 1) {
		T[idx][v] = val;
		return;
	}


	int m = (r + l) / 2;
	if (i < m) {
		upd(idx, left, l, m, i, val);
	}
	else {
		upd(idx, right, m, r, i, val);
	}

	T[idx][v] = min(T[idx][left], T[idx][right]);
}

int main() {


	int n1, n2, n3, n4;
	cin >> n1 >> n2 >> n3 >> n4;

	vi a(n1), b(n2), c(n3), d(n4);
	forn(i, n1) {
		cin >> a[i];
	}

	forn(i, n2) {
		cin >> b[i];
	}

	forn(i, n3) {
		cin >> c[i];
	}

	forn(i, n4) {
		cin >> d[i];
	}

	int m1, m2, m3;
	cin >> m1;
	forn(i, m1) {
		int x, y;
		cin >> x >> y;
		--x, --y;
		g21[y].pb(x);
	}

	cin >> m2;
	forn(i, m2) {
		int x, y;
		cin >> x >> y;
		--x, --y;
		g32[y].pb(x);
	}

	cin >> m3;
	forn(i, m3) {
		int x, y;
		cin >> x >> y;
		--x, --y;
		g43[y].pb(x);
	}

	vector<int> dp1(n1), dp2(n2, INF), dp3(n3, INF), dp4(n4, INF);

	dp1 = a;
	build_tree(0, dp1, 0, 0, n1);

	for (int i = 0; i < n2; ++i) {

		for (auto j : g21[i]) {
			upd(0, 0, 0, n1, j, INF);
		}

		dp2[i] = get(0) + b[i];
		dp2[i] = min(INF, dp2[i]);

		for (auto j : g21[i]) {
			upd(0, 0, 0, n1, j, dp1[j]);
		}
	}


	build_tree(1, dp2, 0, 0, n2);

	for (int i = 0; i < n3; ++i) {

		for (auto j : g32[i]) {
			upd(1, 0, 0, n2, j, INF);
		}

		dp3[i] = get(1) + c[i];
		dp3[i] = min(INF, dp3[i]);

		for (auto j : g32[i]) {
			upd(1, 0, 0, n2, j, dp2[j]);
		}
	}

	build_tree(2, dp3, 0, 0, n3);

	for (int i = 0; i < n4; ++i) {

		for (auto j : g43[i]) {
			upd(2, 0, 0, n3, j, INF);
		}

		dp4[i] = get(2) + d[i];
		dp4[i] = min(INF, dp4[i]);

		for (auto j : g43[i]) {
			upd(2, 0, 0, n3, j, dp3[j]);
		}
	}

	int ans = *min_element(all(dp4));
	if (ans == INF) ans = -1;


	cout << ans;

}
