/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];

	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
/*		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
					f[e[i].to] = 1;
				}
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff) is[i1][num] = 1;
		}*/
	}
	if(n > 20) return 0;
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
//		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
				if(can[i] * can1[i] >= can1[ter]){
					orig[i1][lorig[i1]].no = i;
					orig[i1][lorig[i1]++].dis = dis[i];
				}
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];

	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
if(n < 20)	while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
					f[e[i].to] = 1;
				}
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff) is[i1][num] = 1;
		}
	}
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
				if(can[i] * can1[i] >= can1[ter]){
					orig[i1][lorig[i1]].no = i;
					orig[i1][lorig[i1]++].dis = dis[i];
				}
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	if(dis[from] == 1) {
		cout << "1" << endl;
		return 0;
	}
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];

	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					f[e[i].to] = 1;
				}
				if(r == maxn) r = 0;
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff) is[i1][num] = 1;
		}
	}
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn], q[maxn], l, r, dp[maxn][maxn][2], no[maxn];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn];

/*int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(!(mpdis[e[i].to][ter] + 1 == mpdis[no][ter])) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
//		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}*/

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
//	if(n == 50) cout << nt << endl;
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
//		if(n == 50) cout << mpdis[a][b] << endl;
/*		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));q
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		if(can1[ter] == 0) cout << 1 << endl;
		if(can[a] == 0) cout << 0 << endl;
		for(int i = 0; i < n; i++){
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;*/
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					f[e[i].to] = 1;
				}
				if(r == maxn) r = 0;
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff){
				is[i1][num] = 1;
				no[lno++] = num;
			}
		}
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
/*	l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}*/
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2], no[maxn];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	if(n > 20) return 0;
	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					f[e[i].to] = 1;
				}
				if(r == maxn) r = 0;
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff){
				is[i1][num] = 1;
				no[lno++] = num;
			}
		}
	}
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	if(n == 50) cout << nt << endl;
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		if(can1[ter] == 0) cout << 1 << endl;
		if(can[a] == 0) cout << 0 << endl;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn * maxn * 2];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) mpdis[i][i] = 0;
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];

	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
					f[e[i].to] = 1;
				}
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff) is[i1][num] = 1;
		}
	}

	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lno;
int head[maxn], tail[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int q[maxn], l, r, dp[maxn][maxn][2];
bool f[maxn], is[maxn][maxn];
int route[maxn][2];

struct edge{
	int to, nxt1, from, nxt2;
} e[maxn * maxn * 2];

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	memset(tail, -1, sizeof(tail));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b, e[i].from = a;
		e[i].nxt1 = head[a]; e[i].nxt2 = tail[b];
		head[a] = i; tail[b] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];

	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		route[i1][0] = a; route[i1][1] = b;
		if(mpdis[a][b] == inf) continue;
		memset(f, 0, sizeof(f));
		l = 0; r = 1;
		q[0] = a; f[a] = 1;
		bool ff = 0;
		while(l != r){
			int num = q[l++]; if(l == maxn) l = 0;
			f[num] = 0;
			ff = 0;
			if(l == r) ff = 1;
			int stat1 = 0;
			for(int i = head[num]; i != -1; i = e[i].nxt1){
//				if(e[i].to> maxn || e[i].to < 0) {cout << e[i].to << endl; return 0;}
				if(mpdis[e[i].to][b] != mpdis[num][b] - 1) continue;
				if(!f[e[i].to]){
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
					f[e[i].to] = 1;
				}
				stat1++;
			}
			dp[i1][num][0] = stat1;
			if(ff) is[i1][num] = 1;
		}
	}
	l = 0; r = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	q[0] = to;
	for(; l != r; ){
		int num = q[l++]; if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++){
			int q1[maxn], l1 = 0, r1 = 1;
			q1[0] = num;
			for(; l1 != r1; ){
				int num1 = q1[l1++]; if(l1 == maxn) l1 = 0;
				for(int j = tail[num1]; j != -1; j = e[j].nxt2){
					if(mpdis[route[i][0]][e[j].from] + mpdis[e[j].from][route[i][1]] == mpdis[route[i][0]][route[i][1]] && mpdis[e[j].from][route[i][1]] == mpdis[num1][route[i][1]] + 1){
						dp[i][e[j].from][1]++;
						if(dp[i][e[j].from][1] == dp[i][e[j].from][0]){
							q1[r1++] = e[j].from;
							if(r1 == maxn) r1 = 0;
							if(dis[e[j].from] == inf && is[i][e[j].from]){
								dis[e[j].from] = dis[num] + 1;
								q[r++] = e[j].from;
								if(r == maxn) r++;
							}
						}
					}
				}
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig;
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	memset(mp, 0, sizeof(mp));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig = 0;
		for(int i = 0; i < n; i++){
			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[lorig].no = i;
				orig[lorig++].dis = dis[i];
			}
		}
		sort(orig, orig + lorig);
		for(int i = 0; i < lorig; i++) for(int j = i + 1; j < lorig; j++) mp[orig[i].no][orig[j].no] = 1;
	}
	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}
	if(dis[to] == inf) dis[to] = -1;
	cout << dis[to] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
	if(n == 50) cout << nt << endl;
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		if(can1[ter] * can[a] == 0) continue;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(!(mpdis[e[i].to][ter] + 1 == mpdis[no][ter])) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
//		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
//	if(n == 50) cout << nt << endl;
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
//		if(can1[ter] == 0) cout << 1 << endl;
//		if(can[a] == 0) cout << 0 << endl;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pll;
const double pi = acos(0) * 2;
template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
template <class T> inline int bitnum(T num){
	int ans = 0;
	while(num){
		num -= lb(num);
		ans++;
	}
	return ans;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}
const int maxn = 200;
const int inf = 100000;
int n, m, from, to, ter, lorig[maxn];
int head[maxn];
int mp[maxn][maxn], mpdis[maxn][maxn];
int dis[maxn];
int can[maxn], can1[maxn];
bool f[maxn];
vector <int> route[maxn][maxn];
int incl[maxn][maxn];

struct edge{
	int to, nxt;
} e[maxn];
struct node{
	int no, dis;
	inline bool operator < (const node &a) const{
		return dis > a.dis;
	}
} orig[maxn][maxn];

int dfs(int no, int fa){
	f[no] = 1;
	for(int i = head[no]; i != -1; i = e[i].nxt){
		if(f[e[i].to] && dis[e[i].to] == -1) continue;
		if(!(mpdis[e[i].to][ter] + 1 == mpdis[no][ter])) continue;
		if(dis[e[i].to] == -1 && !f[e[i].to]) dfs(e[i].to, no);
//		if(dis[e[i].to] == -1) continue;
		if(dis[e[i].to] + 1 < dis[no] || dis[no] == -1) can[no] = can[e[i].to], dis[no] = dis[e[i].to] + 1;
		else if(dis[e[i].to] + 1 == dis[no]) can[no] += can[e[i].to];
	}
	return can[no];
}
void bfs(int no){
	memset(can1, 0, sizeof(can1));
	can1[no] = 1;
	int q[maxn], l = 0, r = 1;
	q[0] = no;
	memset(f, 0, sizeof(f));
	f[no] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		for(int i = head[num]; i != -1; i = e[i].nxt){
			if(dis[e[i].to] == dis[num] - 1){
				can1[e[i].to] += can1[num];
				if(f[e[i].to] == 0){
					f[e[i].to] = 1;
					q[r++] = e[i].to;
					if(r == maxn) r = 0;
				}
			}
		}
	}
}

int main(){
//	freopen("input.txt","r", stdin);
//	ifstream cin("input.txt");
	scanf("%d%d%d%d", &n, &m, &from, &to);
	from--; to--;
	memset(head, -1, sizeof(head));
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) {
		if(i == j) mpdis[i][j] = 0;
		else mpdis[i][j] = inf;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		mpdis[a][b] = 1;
		e[i].to = b;
		e[i].nxt = head[a];
		head[a] = i;
	}
	for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) if(mpdis[j][i] + mpdis[i][k] < mpdis[j][k])
		mpdis[j][k] = mpdis[i][k] + mpdis[j][i];
	int nt;
	scanf("%d", &nt);
//	if(n == 50) cout << nt << endl;
	memset(mp, 0, sizeof(mp));
	memset(incl, -1, sizeof(incl));
	for(int i1 = 0; i1 < nt; i1++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--; b--;
		if(mpdis[a][b] == inf) continue;
		if(n == 50) cout << mpdis[a][b] << endl;
		ter = b;
		memset(dis, -1, sizeof(dis));
		memset(can, 0, sizeof(can));
		memset(f, 0, sizeof(f));
		can[ter] = 1; dis[ter] = 0;
		dfs(a, -1);
		bfs(a);
		lorig[i1] = 0;
		if(can1[ter] == 0) cout << 1 << endl;
		if(can[a] == 0) cout << 0 << endl;
		for(int i = 0; i < n; i++){
/*			if(can[i] * can1[i] >= can1[ter] && mpdis[a][i] + mpdis[i][ter] == mpdis[a][ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}*/
			if(can[i] && can1[i]){
				route[i1][dis[i]].push_back(i);
				incl[i1][i] = dis[i];
			}
			if(can[i] * can1[i] >= can1[ter]){
				orig[i1][lorig[i1]].no = i;
				orig[i1][lorig[i1]++].dis = dis[i];
			}
		}
		sort(orig[i1], orig[i1] + lorig[i1]);
		for(int i = 0; i < lorig[i1]; i++) for(int j = i + 1; j < lorig[i1]; j++) mp[orig[i1][i].no][orig[i1][j].no] = 1;
	}
/*	int q[maxn], l = 0, r = 1;
	q[0] = from;
	memset(f, 0, sizeof(f)); f[from] = 1;
	for(int i = 0; i < n; i++) dis[i] = inf; dis[from] = 0;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		f[num] = 0;
		if(num == to) break;
		for(int i = 0; i < n; i++) if(mp[num][i] && (dis[i] == -1 || dis[i] > dis[num] + 1)){
			dis[i] = dis[num] + 1;
			if(!f[i]){
				f[i] = 1;
				q[r++] = i;
				if(r == maxn) r = 0;
			}
		}
	}*/
	for(int i = 0; i < n; i++) dis[i] = inf; dis[to] = 0;
	int q[maxn], l = 0, r = 0;
	for(int i = 0; i < n; i++)  if(mp[i][to]) q[r++] = i, dis[i] = 1;
	for(; l != r; ){
		int num = q[l++];
		if(l == maxn) l = 0;
		for(int i = 0; i < nt; i++) if(incl[i][num] != -1){
			int dis1 = 0;
			for(int k = 0; k < (int)route[i][incl[i][num]].size(); k++)
				dis1 = max1(dis[route[i][incl[i][num]][k]] + 1, dis1);
			if(dis1 >= inf) continue;
			for(int j = 0; j < lorig[i] && orig[i][j].dis >= incl[i][num]; j++){
				if(dis[orig[i][j].no] != inf) continue;
				dis[orig[i][j].no] = min1(dis1, dis[orig[i][j].no]);
				q[r++] = orig[i][j].no;
				if(r == maxn) r = 0;
			}
		}
	}

	if(dis[from] == inf) dis[from] = -1;
	cout << dis[from] << endl;

	return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <ctime>
#include <map>
#include <queue>
#include <set>
using namespace std;

const int maxn=100+15;
int n,m,s,t,x,y,k;
int a[maxn][maxn];
int c[maxn][maxn];
int b[maxn][maxn];
int f[maxn];
int ls[maxn];
int xx[maxn],yy[maxn];
int vis[maxn],sum;
int done(int x,int y)
{
	if (vis[x]==sum) return ls[x];
	vis[x]=sum;
	int ans=-1;
	for (int i=1;i<=n;i++)
	 if (a[x][i]+a[i][yy[y]]==a[x][yy[y]] && a[x][i]==1) ans=max(ans,done(i,y));
	if (ans==-1) ans=f[0];
	ls[x]=min(ans,f[x]+1);
	return ls[x];
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
    memset(a,60,sizeof(a));
    for (int i=1;i<=n;i++)
      a[i][i]=0;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	 for (int k=1;k<=n;k++)
	  a[j][k]=min(a[j][k],a[j][i]+a[i][k]);
	scanf("%d",&k);
	for (int i=1;i<=k;i++)
	{
		scanf("%d%d",&x,&y);
		if (a[x][y]==a[0][0]) continue;
		for (int j=1;j<=n;j++)
		 if (a[x][j]+a[j][y]==a[x][y]) b[i][a[x][j]]++;
		for (int j=1;j<=n;j++)
		 if (a[x][j]+a[j][y]==a[x][y] && b[i][a[x][j]]==1) c[i][j]=1;
		xx[i]=x;yy[i]=y;
	}
	memset(f,60,sizeof(f));
	f[t]=0;
	bool boo=true;
	while (boo)
	{
		boo=false;
		for (int i=1;i<=n;i++)
	     for (int j=1;j<=k;j++)
	      if (c[j][i]==1)
	      {
	      	sum++;
	      	int anss=done(i,j);
	      	if (anss<f[i]) f[i]=anss,boo=true;
	      }
	}
	if (f[s]<f[0]) printf("%d\n",f[s]); else printf("-1\n");
	return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <ctime>
#include <map>
#include <queue>
#include <set>
using namespace std;

const int maxn=100+15;
struct Node
{
	int key,x,y;
	Node() {key=x=y=0;}
	Node(int key,int x,int y):key(key),x(x),y(y) {}
};
const bool operator < (const Node &a,const Node &b)
{
	return a.key>b.key;
}
priority_queue <Node> que;
int n,m,s,t,x,y,k;
int a[maxn][maxn];
int c[maxn][maxn];
int b[maxn][maxn];
int f[maxn][maxn];
int link[maxn][maxn][maxn],deg[maxn][maxn];
int xx[maxn],yy[maxn];
bool boo[maxn][maxn];
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	  if (i!=j)
	  a[i][j]=3*n;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	 for (int k=1;k<=n;k++)
	  a[j][k]=min(a[j][k],a[j][i]+a[i][k]);
	scanf("%d",&k);
	for (int i=1;i<=k;i++)
	{
		scanf("%d%d",&x,&y);
		if (a[x][y]==3*n) continue;
		for (int j=1;j<=n;j++)
		 if (a[x][j]+a[j][y]==a[x][y]) b[i][a[x][j]]++;
		for (int j=1;j<=n;j++)
		 if (a[x][j]+a[j][y]==a[x][y] && b[i][a[x][j]]==1) c[i][j]=1;
		xx[i]=x;yy[i]=y;
	}
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=k;j++)
	  if (a[xx[j]][i]+a[i][yy[j]]==a[xx[j]][yy[j]])
	   for (int l=1;l<=n;l++)
	    if (l!=i && a[xx[j]][i]+a[i][l]+a[l][yy[j]]==a[xx[j]][yy[j]] && a[i][l]==1)
	      link[i][j][l]=true,deg[i][j]++;
	memset(f,60,sizeof(f));
	for (int i=1;i<=k;i++) f[t][i]=0,que.push(Node(0,t,i));
	while (!que.empty())
	{
		Node now=que.top();
		que.pop();
		while (boo[now.x][now.y])
		{
			if (que.empty()) break;
			now=que.top();
			que.pop();
		}
	   if (boo[now.x][now.y]) break;
	   boo[now.x][now.y]=true;
	   for (int i=1;i<=n;i++)
	    if (link[i][now.y][now.x])
	    {
	    	deg[i][now.y]--;
	    	if (deg[i][now.y]==0 && !boo[i][now.y] && f[i][now.y]>now.key)
	    	{
	    		f[i][now.y]=now.key;
	    		que.push(Node(f[i][now.y],i,now.y));
	    	}
	    }
	 if (c[now.y][now.x]==1)
	   for (int i=1;i<=k;i++)
	    if (a[xx[i]][now.x]+a[now.x][yy[i]]==a[xx[i]][yy[i]])
	     if (!boo[now.x][i] && f[now.x][i]>now.key+1)
	     {
	     	f[now.x][i]=now.key+1;
	     	que.push(Node(f[now.x][i],now.x,i));
	     }
	}
	int ans=-1;
	for (int i=1;i<=k;i++)
	 if (boo[s][i])
	  if (ans==-1 || ans>f[s][i]+1)
	   ans=f[s][i]+1;
	printf("%d\n",ans);
	return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct7, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int pass[200][200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(i, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		rep(j, 1, n)
			if (dis[sp][j] < dis[0][0] && dis[j][ep] < dis[0][0] &&
			dis[sp][j] + dis[j][ep] == dis[sp][ep])
				pass[i][j] = 1;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(i, 1, n) rep(j, 1, K)
	if (pass[j][i])
	{
		for (int k = 0; k < E[i].size(); ++k)
			if (pass[j][E[i][k]])
				e[E[i][k]][j].pb(i), d[i][j]++;
	}

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			vis[u.xx][u.yy] = 2;

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j])
			{
				rep(k, 1, K)
					if (!vis[i][k])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 2) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct15, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int cnt[200];
int pass[200][200], S[200], T[200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
int pass1[200][200], pass2[200][200];
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(_, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		clr(cnt);
		rep(i, 1, n)
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				cnt[dis[sp][i]]++;
		rep(i, 1, n)
		{
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				pass1[_][i] = 1;
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1)
				pass2[_][i] = 1;
		}
		rep(i, 1, n)
			rep(j, 1, n)
				if (pass1[_][i] && pass1[_][j] && dis[i][j] == 1 && dis[i][ep] == 1 + dis[j][ep])
					e[j][_].pb(i), d[i][_]++;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass1[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			vis[u.xx][u.yy] = 2;

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy] && !vis[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j] && pass2[j][i])
			{
				rep(k, 1, K)
					if (!vis[i][k] && pass1[k][i])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 1 && pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct15, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int cnt[200];
int pass[200][200], S[200], T[200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
int pass1[200][200], pass2[200][200];
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(_, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		clr(cnt);
		rep(i, 1, n)
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				cnt[dis[sp][i]]++;
		rep(i, 1, n)
		{
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				pass1[_][i] = 1;
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1)
				pass2[_][i] = 1;
		}
		rep(i, 1, n)
			rep(j, 1, n)
				if (pass1[_][i] && pass1[_][j] && dis[i][j] == 1)
					e[j][_].pb(i), d[i][_]++;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass2[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			vis[u.xx][u.yy] = 2;

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j] && pass2[j][i])
			{
				rep(k, 1, K)
					if (!vis[i][k] && pass1[k][i])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 2 && pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct15, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int cnt[200];
int pass[200][200], S[200], T[200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
int pass1[200][200], pass2[200][200];
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(_, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		clr(cnt);
		rep(i, 1, n)
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				cnt[dis[sp][i]]++;
		rep(i, 1, n)
		{
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				pass1[_][i] = 1;
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1)
				pass2[_][i] = 1;
		}
		rep(i, 1, n)
			rep(j, 1, n)
				if (pass1[_][i] && pass1[_][j] && dis[i][j] == 1 && dis[i][ep] == 1 + dis[j][ep])
					e[j][_].pb(i), d[i][_]++;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass1[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			vis[u.xx][u.yy] = 2;

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j] && pass2[j][i])
			{
				rep(k, 1, K)
					if (!vis[i][k] && pass1[k][i])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 2 && pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct7, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int pass[200][200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(i, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		rep(j, 1, n)
			if (dis[sp][j] + dis[j][ep] == dis[sp][ep])
				pass[i][j] = 1;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(i, 1, n) rep(j, 1, K)
	if (pass[j][i])
	{
		for (int k = 0; k < E[i].size(); ++k)
			if (pass[j][E[i][k]])
				e[E[i][k]][j].pb(i), d[i][j]++;
	}

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			vis[u.xx][u.yy] = 2;

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j])
			{
				rep(k, 1, K)
					if (!vis[i][k])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 2) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct15, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int cnt[200];
int pass[200][200], S[200], T[200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
int pass1[200][200], pass2[200][200];
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(_, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		clr(cnt);
		rep(i, 1, n)
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				cnt[dis[sp][i]]++;
		rep(i, 1, n)
		{
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				pass1[_][i] = 1;
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1)
				pass2[_][i] = 1;
		}
		rep(i, 1, n)
			rep(j, 1, n)
				if (pass1[_][i] && pass1[_][j] && dis[i][j] == 1 && dis[i][ep] == 1 + dis[j][ep])
					e[j][_].pb(i), d[i][_]++;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass1[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();

			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy] && !vis[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j] && pass2[j][i])
			{
				rep(k, 1, K)
					if (!vis[i][k] && pass1[k][i])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 2 && pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}


/*
    Author: Zhouxing Shi
    Created on Oct15, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

int cnt[200];
int pass[200][200], S[200], T[200], d[200][200], dis[200][200], vis[200][200], f[200][200], n, m, s, t, x, y, K;
int pass1[200][200], pass2[200][200];
vector <int> E[200];
vector <int> e[200][200];
queue <pair<int, int> > Q;

int main()
{
	memset(dis, 0x7f, sizeof(dis));
	scanf("%d%d%d%d", &n, &m, &s, &t);
	rep(i, 1, m) scanf("%d%d", &x, &y), E[x].pb(y), dis[x][y] = 1;
	rep(i, 1, n) dis[i][i] = 0;
	rep(k, 1, n) rep(i, 1, n) rep(j, 1, n)
		if (dis[i][k] < dis[0][0] && dis[k][j] < dis[0][0])
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf("%d", &K);
	rep(_, 1, K)
	{
		int sp, ep;
		scanf("%d%d", &sp, &ep);
		if (dis[sp][ep] == dis[0][0]) continue;
		clr(cnt);
		rep(i, 1, n)
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				cnt[dis[sp][i]]++;
		rep(i, 1, n)
		{
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep])
				pass1[_][i] = 1;
			if (dis[sp][i] < dis[0][0] && dis[i][ep] < dis[0][0]
			&& dis[sp][i] + dis[i][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1)
				pass2[_][i] = 1;
		}
		rep(i, 1, n)
			rep(j, 1, n)
				if (pass1[_][i] && pass1[_][j] && dis[i][j] == 1 && dis[i][ep] == 1 + dis[j][ep])
					e[j][_].pb(i), d[i][_]++;
	}
	memset(f, 0x7f, sizeof(f));
	rep(i, 1, K) if (pass1[i][t]) vis[t][i] = 1, f[t][i] = 1, Q.push(mp(t, i));

	rep(_, 1, K)
	{
		while (Q.size())
		{
			pair<int, int> u = Q.front();
			Q.pop();
			//vis[u.xx][u.yy] = 2;
			//
			for (int k = 0; k < e[u.xx][u.yy].size(); ++k)
			{
				d[e[u.xx][u.yy][k]][u.yy]--;
				if (!d[e[u.xx][u.yy][k]][u.yy] && !vis[e[u.xx][u.yy][k]][u.yy])
				{
					vis[e[u.xx][u.yy][k]][u.yy] = 1;
					f[e[u.xx][u.yy][k]][u.yy] = f[u.xx][u.yy];
					Q.push(mp(e[u.xx][u.yy][k], u.yy));
				}
			}
		}

		rep(i, 1, n) rep(j, 1, K)
			if (vis[i][j] && pass2[j][i])
			{
				rep(k, 1, K)
					if (!vis[i][k] && pass1[k][i])
					{
						vis[i][k] = 1;
						f[i][k] = f[i][j] + 1;
						Q.push(mp(i, k));
					}
			}
	}
	int ans = inf;
	rep(i, 1, K) if (vis[s][i] == 1 && pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", ans);
    return 0;
}