#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	A,
	B,
};

struct Info{
	Info(){

		loc[A] = loc[B] = value = 0;
	}
	Info(int loc_A,int loc_B,int arg_value){
		loc[A] = loc_A;
		loc[B] = loc_B;
		value = arg_value;
	}
	void set(int loc_A,int loc_B,int arg_value){
		loc[A] = loc_A;
		loc[B] = loc_B;
		value = arg_value;
	}
	bool operator<(const struct Info &arg) const{

		return value < arg.value; //valueの昇順(PQ)
	}

	int loc[2],value;
};

int N[2],M[2],in_num[2][105];
char CH[2][105];
vector<int> G[2][105],scc_G[2][105];

struct GROUP{
	vector<int> nodes;
};


#define NUM 105

GROUP group[2][NUM]; //強連結成分のグループ
vector<int> reverse_G[2][NUM];
stack<int> S;

bool check[NUM],can_add[NUM][NUM];
int ans;
int table[NUM],dp[105][105];
double sleep[NUM];

int group_index;

void dfs(Type type,int node_id){
	check[node_id] = true;

	for(int i = 0; i < G[type][node_id].size(); i++){
		if(!check[G[type][node_id][i]])dfs(type,G[type][node_id][i]);
	}
	S.push(node_id);
}

void reverse_dfs(Type type,int node_id){
	check[node_id] = true;

	group[type][group_index].nodes.push_back(node_id); //group[group_index]にノードを突っ込む
	table[node_id] = group_index;

	for(int i = 0; i < reverse_G[type][node_id].size(); i++){
		if(!check[reverse_G[type][node_id][i]])reverse_dfs(type,reverse_G[type][node_id][i]);
	}
}


int func(int node_A,int node_B){


	if(dp[node_A][node_B] != -1){

		return dp[node_A][node_B];
	}

	dp[node_A][node_B] = 0;
	if(can_add[node_A][node_B]){

		dp[node_A][node_B] = 1;
	}

	int tmp = 0;

	//AとBが両方動く
	for(int i = 0; i < scc_G[A][node_A].size(); i++){
		int next_A = scc_G[A][node_A][i];
		for(int k = 0; k < scc_G[B][node_B].size(); k++){
			int next_B = scc_G[B][node_B][k];
			tmp = max(tmp,func(next_A,next_B));
		}
	}


	//Aだけが動く(Bがとどまっていられる場合)
	if(!can_add[node_A][node_B] || (group[B][node_B].nodes.size() > 1)){

		for(int i = 0; i < scc_G[A][node_A].size(); i++){
			int next_A = scc_G[A][node_A][i];
			int next_B = node_B;

			tmp = max(tmp,func(next_A,next_B));
		}
	}

	//Bだけが動く(Aがとどまっていられる場合)
	if(!can_add[node_A][node_B] || (group[A][node_A].nodes.size() > 1)){

		int next_A = node_A;
		for(int k = 0; k < scc_G[B][node_B].size(); k++){
			int next_B = scc_G[B][node_B][k];

			tmp = max(tmp,func(next_A,next_B));
		}
	}

 	 dp[node_A][node_B] += tmp;
 	 ans = max(ans,dp[node_A][node_B]);

	return dp[node_A][node_B];
}


int main(){

	scanf("%d %d",&N[A],&M[A]);

	char buf[2];

	for(int i = 0; i < N[A]; i++){

		in_num[A][i] = 0;
	}

	for(int i = 0; i < N[A]; i++){

		scanf("%s",buf);
		CH[A][i] = buf[0];
	}

	int from,to;
	for(int i = 0; i < M[A]; i++){

		scanf("%d %d",&from,&to);
		from--;
		to--;
		G[A][from].push_back(to);
		reverse_G[A][to].push_back(from);

	}

	scanf("%d %d",&N[B],&M[B]);

	for(int i = 0; i < N[B]; i++){

		in_num[B][i] = 0;
	}

	for(int i = 0; i < N[B]; i++){

		scanf("%s",buf);
		CH[B][i] = buf[0];
	}

	for(int i = 0; i < M[B]; i++){

		scanf("%d %d",&from,&to);
		from--;
		to--;
		G[B][from].push_back(to);
		reverse_G[B][to].push_back(from);
	}

	for(int i = 0; i < N[A]; i++)check[i] = false;

	//まずは帰りがけ順を計算
	for(int i = 0; i < N[A];i++){
		if(!check[i])dfs(A,i);
	}

	for(int i = 0; i < N[A];i++)check[i] = false;

	group_index = -1;
	//ノードを、帰りがけ順の逆順に、各強連結成分(グループ)に分解
	while(!S.empty()){
		if(!check[S.top()]){
			group_index++;

			reverse_dfs(A,S.top());
		}
		S.pop();
	}

	int num_A = group_index;

	//SCC分解した状態で、DAGにおける入次数を計算する
	for(int i = 0; i <= num_A; i++)in_num[A][i] = 0;

	for(int i = 0; i <= num_A; i++){
		for(int k = 0; k < group[A][i].nodes.size(); k++){
			for(int p = 0; p < G[A][group[A][i].nodes[k]].size(); p++){
				int next_group = table[G[A][group[A][i].nodes[k]][p]];
				if(next_group != i){
					in_num[A][next_group]++;
					scc_G[A][i].push_back(next_group);
				}
			}
		}
	}
	for(int i = 0; i <= num_A; i++){
		if(scc_G[A][i].size() == 0)continue;

		sort(scc_G[A][i].begin(),scc_G[A][i].end());
		scc_G[A][i].erase(unique(scc_G[A][i].begin(),scc_G[A][i].end()),scc_G[A][i].end());
	}


	for(int i = 0; i < N[B]; i++)check[i] = false;

	//まずは帰りがけ順を計算
	for(int i = 0; i < N[B];i++){
		if(!check[i])dfs(B,i);
	}

	for(int i = 0; i < N[B];i++)check[i] = false;

	group_index = -1;
	//ノードを、帰りがけ順の逆順に、各強連結成分(グループ)に分解
	while(!S.empty()){
		if(!check[S.top()]){
			group_index++;

			reverse_dfs(B,S.top());
		}
		S.pop();
	}

	int num_B = group_index;

	for(int i = 0; i <= num_A; i++){
		for(int k = 0; k <= num_B; k++){

			can_add[i][k] = false;
			dp[i][k] = -1;
		}
	}

	//無限かチェック
	for(int i = 0; i <= num_A; i++){
		for(int k = 0; k <= num_B; k++){
			bool FLG = false;

			for(int a = 0; a < group[A][i].nodes.size(); a++){
				for(int b = 0; b < group[B][k].nodes.size(); b++){
					//無限に増える
					if(CH[A][group[A][i].nodes[a]] == CH[B][group[B][k].nodes[b]]){
						FLG = true;
						break;
					}
				}
				if(FLG)break;
			}
			if(FLG){
				if(group[A][i].nodes.size() > 1 && group[B][k].nodes.size() > 1){

					printf("-1\n");
					return 0;
				}
				can_add[i][k] = true; //増える
			}
		}
	}

	//SCC分解した状態で、DAGにおける入次数を計算する
	for(int i = 0; i <= num_B; i++)in_num[B][i] = 0;

	for(int i = 0; i <= num_B; i++){
		for(int k = 0; k < group[B][i].nodes.size(); k++){
			for(int p = 0; p < G[B][group[B][i].nodes[k]].size(); p++){
				int next_group = table[G[B][group[B][i].nodes[k]][p]];
				if(next_group != i){
					in_num[B][next_group]++;
					scc_G[B][i].push_back(next_group);
				}
			}
		}
	}
	for(int i = 0; i <= num_B; i++){
		if(scc_G[B][i].size() == 0)continue;

		sort(scc_G[B][i].begin(),scc_G[B][i].end());
		scc_G[B][i].erase(unique(scc_G[B][i].begin(),scc_G[B][i].end()),scc_G[B][i].end());
	}

	vector<int> vec_A,vec_B;

	//入次数0の連結成分をpush
	for(int i = 0; i <= num_A; i++){
		if(in_num[A][i] == 0){

			vec_A.push_back(i);
		}
	}
	for(int i = 0; i <= num_B; i++){
		if(in_num[B][i] == 0){

			vec_B.push_back(i);
		}
	}

	ans = 0;

	for(int i = 0; i < vec_A.size(); i++){
		for(int k = 0; k < vec_B.size(); k++){
			func(vec_A[i],vec_B[k]);
		}
	}

	printf("%d\n",ans);

	return 0;
}



Measured memory_bytes: 3488