#include<iostream>
#include<vector>
#include<algorithm>
#include <iterator>
#include<queue>
#include <string>
#include <numeric>
#include<stack>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) v.begin(),v.end()
vector< vector<int> > e[2];
struct Node{
	int id;
	int alpha;
	vector<int> ToCole;
};
struct To{
	int x1;
	int x2;
	int score;
	To(int a, int b, int c,int d ,int e){
		x1 = a; x2 = b;score = c;
	}
	To(int a, int b, int c){
		x1 = a; x2 = b; score = c;
	}
};
bool operator <(const To& T1, const To& T2){
	return T1.score < T2.score;
}
priority_queue < To > aStack;
vector<char> AlphaCole;
vector<vector<Node>> NodeColes(2);
vector<vector<int>> Tag(2,vector<int>(100));
int GetAns(vector<vector<int>>& memo, int p1, int p2){

	while (!aStack.empty()){
		p1 = aStack.top().x1;
		p2 = aStack.top().x2;
		int ascore = aStack.top().score;
		aStack.pop();
		if (ascore > 150){
			return -1;
		}
		if (Tag[0][p1] == Tag[1][p2]){
			for (auto i : e[0][p1]){
				for (auto j : e[1][p2]){
					if (Tag[0][i]==Tag[1][j]){
						if  (memo[i][j] <= ascore){
							aStack.push({ i, j, ascore+1 });
							memo[i][j] = ascore+1;
						}
					}
					else{
						if (memo[i][j] < ascore){
							aStack.push({ i, j, ascore });
							memo[i][j] = ascore;
						}
					}
				}
			}
		}
		else{
			for (auto i : e[0][p1]){
				for (auto j : e[1][p2]){
					if (Tag[0][i] == Tag[1][j]){
						if (memo[i][j] <= ascore){
							aStack.push({ i, j, ascore+1 });
							memo[i][j] = ascore + 1;
						}
					}
					else{
						if (memo[i][j] < ascore){
							aStack.push({ i, j, ascore });
							memo[i][j] = ascore;
						}
					}
				}
			}
			for (auto j : e[1][p2]){
				int i = p1;
				if (Tag[0][i] == Tag[1][j]){
					if (memo[i][j] <= ascore){
						aStack.push({ i, j, ascore+1 });
						memo[i][j] = ascore + 1;
					}
				}
				else{
					if (memo[i][j] < ascore){
						aStack.push({ i, j, ascore });
						memo[i][j] = ascore;
					}
				}
			}
			for (auto i : e[0][p1]){
				int j = p2;
				if (Tag[0][i] == Tag[1][j]){
					if (memo[i][j] <= ascore){
						aStack.push({ i, j, ascore+1 });
						memo[i][j] = ascore + 1;
					}
				}
				else{
					if (memo[i][j] < ascore){
						aStack.push({ i, j, ascore });
						memo[i][j] = ascore;
					}
				}
			}
		}
	}
	return 0;
}
int main(){
	e[0].resize(100);
	e[1].resize(100);
	int boardNums[2];
	rep(i, 2){
		int n, m;
		cin >> boardNums[i] >> m;
		rep(j, boardNums[i]){
			char c;
			cin >> c;
			int aalpha;
			if (find(AlphaCole.begin(), AlphaCole.end(), c) == AlphaCole.end()){
				AlphaCole.push_back(c);			
			}
			else{
			}
			aalpha = find(AlphaCole.begin(), AlphaCole.end(), c) - AlphaCole.begin();
			NodeColes[i].push_back({ j, aalpha });
			
			Tag[i][j] = aalpha;
		}
		rep(j, m){
			int a, b;
			cin >> a >> b;
			NodeColes[i][a - 1].ToCole.push_back(b - 1);
			e[i][a - 1].push_back(b - 1);
		}
	}
	vector<vector<int>>memo(boardNums[0], vector<int>(boardNums[1],0));
	
	rep(i, boardNums[0]){
		rep(j, boardNums[1]){
			if (Tag[0][i] == Tag[1][j]){
				memo[i][j] = 1;
				aStack.push({ i, j, 1, boardNums[0], (boardNums[1]) });
			}
			else
				aStack.push({ i, j, 0, boardNums[0], (boardNums[1]) });
		}
	}
	if (GetAns(memo, 0, 0) ){
		cout << -1 << endl;
		return 0;
	}
	vector<int>maxCol;
	rep(i, boardNums[0]){
		
		maxCol.push_back(*max_element(memo[i].begin(), memo[i].end()));
	}
	cout << *max_element(maxCol.begin(), maxCol.end())<<endl;
	return 0;
}

Measured memory_bytes: 8776