/*
    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;
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)
			rep(j, 1, n)
				if (i != j && dis[sp][i] < dis[0][0] && dis[i][j] < dis[0][0] && dis[j][ep] < dis[0][0] &&
				dis[sp][i] + dis[i][j] + dis[j][ep] == dis[sp][ep] && cnt[dis[sp][i]] == 1 && cnt[dis[sp][j]] == 1)
					e[j][_].pb(i), d[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] && cnt[dis[sp][i]] == 1)
				pass[_][i] = 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(_, 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 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], S[200], T[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);
		S[i] = sp; T[i] = 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 (dis[S[j]][i] < dis[0][0] && dis[E[i][k]][T[j]] < dis[0][0]
			&& dis[S[j]][T[j]] == dis[S[j]][i] + 1 + dis[E[i][k]][T[j]])
				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 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);
		S[_] = sp; T[_] = 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, 100)
	{
		rep(i, 1, n)
			rep(j, 1, K)
				if (pass1[j][i])
				{
					int tmp = -1;
					rep(k, 1, n)
						if (dis[i][k] == 1 && dis[i][T[j]] == 1 + dis[k][T[j]])
							tmp = max(tmp, f[k][j]);
					if (tmp != -1) f[i][j] = min(f[i][j], tmp);
					rep(k, 1, K)
						if (pass2[k][i])
							f[i][j] = min(f[i][j], f[i][k] + 1);
				}
	}

/*	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 (pass2[i][s]) ans = min(ans, f[s][i]);
	if (ans > 1e6) 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] == 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)
					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;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <queue>
#include <iostream>
#define maxn 109
using namespace std;
const int INF=0x3f3f3f3f;
int d[maxn][maxn],n,m,dis[maxn][maxn],must[maxn][maxn];
vector<int>Next[maxn][maxn],V[maxn];
int main()
{
	int a,b;
	memset(d,0x3f,sizeof(d));
	scanf("%d%d%d%d",&n,&m,&a,&b);
	for(int i=1;i<=n;i++)
		d[i][i]=0;
	for(int i=0;i<m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		d[x][y]=1;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
	int Q;
	scanf("%d",&Q);
	for(int i=1;i<=Q;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		if(d[x][y]==INF)
			continue;
		for(int j=1;j<=n;j++)
		{
			if(d[x][j]+d[j][y]==d[x][y])
			{
				for(int k=1;k<=n;k++)
				{
					if(d[j][k]==1&&1+d[k][y]==d[j][y])
					{
						Next[j][i].push_back(k);
					}
				}
			}
		}
		for(int j=0;j<=d[x][y];j++)
			V[j].clear();
		for(int j=1;j<=n;j++)
		{
			if(d[x][y]==d[x][j]+d[j][y])
			{
				V[d[x][j]].push_back(j);
			}
		}
		for(int j=0;j<=d[x][y];j++)
		{
			if((int)V[j].size()==1)
			{
				must[V[j][0]][i]=1;
			}
		}
	}
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=Q;i++)
	{
		dis[b][i]=0;
	}
	int flag=1;
	while(flag)
	{
		flag=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=Q;j++)
			{
				if((int)Next[i][j].size()!=0)
				{
					int ws=0;
					for(int k=0;k<(int)Next[i][j].size();k++)
					{
						ws=max(ws,dis[Next[i][j][k]][j]);
					}
					if(dis[i][j]>ws)
					{
						dis[i][j]=ws;
						flag=1;
					}
				}
				for(int k=1;k<=Q;k++)
				{
					if(must[i][k]&&k!=j)
					{
						if(dis[i][j]>dis[i][k]+1)
						{
							dis[i][j]=dis[i][k]+1;
							flag=1;
						}
					}
				}
			}
		}
	}
	int ans=INF;
	for(int i=1;i<=Q;i++)
		if(must[a][i])
			ans=min(ans,dis[a][i]);
	if(ans==INF)
		printf("-1\n");
	else
		printf("%d\n",ans+1);
	//system("pause");
	return 0;
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N],can[N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	//if (ti==1) printf("x = %d\n",x);
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int dfs(int x,int y)
{
	//printf("%d %d\n",x,y);
	int ans=0;
	rep(i,1,n)
	if (dis[y][i]==dis[y][x]+1) ans=max(ans,dfs(i,y));
	if (ans==0) ans=INF;
	ans=min(ans,dp[x][y]);
	ans=min(ans,can[x]+1);
	return ans;
}
int main()
{
	//freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x);
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
		//,printf("%d %d\n",Road[j][0],i);
	}
	rep(i,1,n) can[i]=INF;
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1,can[T]=1;
	//printf("%d %d\n",ok[4][1],ok[7][1]);
	//printf("!!!!!! %d\n",dfs(5,3));
	//exit(0);
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			Max=dfs(i,j);
			//if (i==1 && j==1) printf("Max = %d  %d %d\n",Max,can[2],can[3]);
			if (dp[i][j]>Max) dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			/*
			for (int k=0;k<full[j].size();k++)
			if (full[j][k]!=i && dis[j][full[j][k]]>=dis[j][i])
			{
				if (i==1 && j==1) printf(" to %d\n",full[j][k]);
				size++;
				if (can[full[j][k]]==INF) {flag=0;break;}
				Max=max(Max,dp[full[j][k]][j]);
			}

			if (dp[i][j]>Max) dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			rep(k,1,n)
			if (ok[k][j] && dp[k][j]<dp[i][j] && dis[j][i]<dis[j][k])
			{
				//if (i==1 && j==1) printf("from %d %d\n",k,j);
				dp[i][j]=dp[k][j],F=1;
				can[i]=min(can[i],dp[i][j]);
			}
			flag=0;int Min=INF;
			for (int k=0;k<Up[i].size();k++)
			if (dp[i][Up[i][k]]) flag=1,Min=min(Min,dp[i][Up[i][k]]);
			if (flag && dp[i][j]>Min+1) dp[i][j]=Min+1,can[i]=min(can[i],dp[i][j]),F=1;
			*/
		}
		if (!F) break;
	}
	//puts("\n");
	//rep(i,1,n){ rep(j,1,K)
	//printf("%d ",dp[i][j]);
	//puts("");}
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N],can[N],Vis[N][N],G[N][N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	Vis[ti][x]=1;
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int dfs(int x,int y)
{
	int ans=0;
	rep(i,1,n)
	if (Vis[y][i] && G[x][i] && dis[y][i]==dis[y][x]+1) ans=max(ans,dfs(i,y));
	if (ans==0) ans=INF;
	ans=min(ans,dp[x][y]);
	ans=min(ans,can[x]+1);
	return ans;
}
int main()
{
	//freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x),G[x][y]=1;
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
	}
	rep(i,1,n) can[i]=INF;
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1,can[T]=1;
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			Max=dfs(i,j);
			if (dp[i][j]>Max)
			{
				dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			}
		}
		if (!F) break;
	}
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N],can[N],Vis[N][N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	//if (ti==1) printf("x = %d\n",x);
	Vis[ti][x]=1;
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int dfs(int x,int y)
{
	//printf("dfs %d %d    \n",x,y,dis[y][x]);
	int ans=0;
	rep(i,1,n)
	if (dis[x][y]!=1 && Vis[y][i] && dis[y][i]==dis[y][x]+1) ans=max(ans,dfs(i,y));
	if (ans==0) ans=INF;
	ans=min(ans,dp[x][y]);
	ans=min(ans,can[x]+1);
	return ans;
}
int main()
{
	freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x);
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
		//,printf("%d %d\n",Road[j][0],i);
	}
	rep(i,1,n) can[i]=INF;
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1,can[T]=1;
	//printf("%d %d\n",ok[2][2],ok[7][1]);
	//printf("!!!!!! %d\n",dfs(2,2));
	//exit(0);
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			Max=dfs(i,j);
			if (dp[i][j]>Max)
			{
				//printf("%d %d %d\n",i,j,Max);
				dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			}
			/*
			for (int k=0;k<full[j].size();k++)
			if (full[j][k]!=i && dis[j][full[j][k]]>=dis[j][i])
			{
				if (i==1 && j==1) printf(" to %d\n",full[j][k]);
				size++;
				if (can[full[j][k]]==INF) {flag=0;break;}
				Max=max(Max,dp[full[j][k]][j]);
			}

			if (dp[i][j]>Max) dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			rep(k,1,n)
			if (ok[k][j] && dp[k][j]<dp[i][j] && dis[j][i]<dis[j][k])
			{
				//if (i==1 && j==1) printf("from %d %d\n",k,j);
				dp[i][j]=dp[k][j],F=1;
				can[i]=min(can[i],dp[i][j]);
			}
			flag=0;int Min=INF;
			for (int k=0;k<Up[i].size();k++)
			if (dp[i][Up[i][k]]) flag=1,Min=min(Min,dp[i][Up[i][k]]);
			if (flag && dp[i][j]>Min+1) dp[i][j]=Min+1,can[i]=min(can[i],dp[i][j]),F=1;
			*/
		}
		if (!F) break;
	}

	/*
	puts("\n");
	rep(i,1,n){ rep(j,1,K)
	printf("%d ",dp[i][j]);
	puts("");}
	*/
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N],can[N],Vis[N][N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	//if (ti==1) printf("x = %d\n",x);
	Vis[ti][x]=1;
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int dfs(int x,int y)
{
	//printf("dfs %d %d    \n",x,y,dis[y][x]);
	int ans=0;
	rep(i,1,n)
	if (dis[x][y]!=1 && Vis[y][i] && dis[y][i]==dis[y][x]+1) ans=max(ans,dfs(i,y));
	if (ans==0) ans=INF;
	ans=min(ans,dp[x][y]);
	ans=min(ans,can[x]+1);
	return ans;
}
int main()
{
	//freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x);
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
		//,printf("%d %d\n",Road[j][0],i);
	}
	rep(i,1,n) can[i]=INF;
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1,can[T]=1;
	//printf("%d %d\n",ok[2][2],ok[7][1]);
	//printf("!!!!!! %d\n",dfs(2,2));
	//exit(0);
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			Max=dfs(i,j);
			if (dp[i][j]>Max)
			{
				//printf("%d %d %d\n",i,j,Max);
				dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			}
			/*
			for (int k=0;k<full[j].size();k++)
			if (full[j][k]!=i && dis[j][full[j][k]]>=dis[j][i])
			{
				if (i==1 && j==1) printf(" to %d\n",full[j][k]);
				size++;
				if (can[full[j][k]]==INF) {flag=0;break;}
				Max=max(Max,dp[full[j][k]][j]);
			}

			if (dp[i][j]>Max) dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			rep(k,1,n)
			if (ok[k][j] && dp[k][j]<dp[i][j] && dis[j][i]<dis[j][k])
			{
				//if (i==1 && j==1) printf("from %d %d\n",k,j);
				dp[i][j]=dp[k][j],F=1;
				can[i]=min(can[i],dp[i][j]);
			}
			flag=0;int Min=INF;
			for (int k=0;k<Up[i].size();k++)
			if (dp[i][Up[i][k]]) flag=1,Min=min(Min,dp[i][Up[i][k]]);
			if (flag && dp[i][j]>Min+1) dp[i][j]=Min+1,can[i]=min(can[i],dp[i][j]),F=1;
			*/
		}
		if (!F) break;
	}

	/*
	puts("\n");
	rep(i,1,n){ rep(j,1,K)
	printf("%d ",dp[i][j]);
	puts("");}
	*/
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	//if (ti==1) printf("x = %d\n",x);
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int main()
{
	//freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x);
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
		//,printf("%d %d\n",Road[j][0],i);
	}
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1;
	//printf("%d %d\n",ok[4][1],ok[7][1]);
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			for (int k=0;k<full[j].size();k++)
			if (full[j][k]!=i && dis[j][full[j][k]]>dis[j][i])
			{
				size++;
				if (dp[full[j][k]][j]==INF) {flag=0;break;}
				Max=max(Max,dp[full[j][k]][j]);
			}
			if (size && flag && dp[i][j]>Max) dp[i][j]=Max,F=1;
			rep(k,1,n)
			if (ok[k][j] && dp[k][j]<dp[i][j]) dp[i][j]=dp[k][j],F=1;
			flag=0;int Min=INF;
			for (int k=0;k<Up[i].size();k++)
			if (dp[i][Up[i][k]]) flag=1,Min=min(Min,dp[i][Up[i][k]]);
			if (flag && dp[i][j]>Min+1) dp[i][j]=Min+1,F=1;
		}
		if (!F) break;
	}
	//rep(i,1,n){ rep(j,1,K)
	//printf("%d ",dp[i][j]);
	//puts("");}
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


//+-------------------------------------+
//|     By   qwer_zcc                   |
//|     Date 30/10/2014                 |
//+-------------------------------------+
#include <bits/stdc++.h>
#define INF ((~0U>>1)-3)
#define LLINF ((~0ULL>>1)-3)
#define LL long long
#define uLL unsigned long long
#define uint unsigned int
#define D double
#define LD long double
#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 M(a) memset(a,0,sizeof(a));
#define pb push_back
#define mp make_pair
#define Pi M_PI
using namespace std;
template<class T> inline T min(T &a,T &b) {return a<b?a:b;}
template<class T> inline T max(T &a,T &b) {return a>b?a:b;}
template<class T> void read(T &x)
{
    char ch;
    while ((ch=getchar()) && !isdigit(ch));x=ch-'0';
    while ((ch=getchar()) && isdigit(ch)) x=x*10+ch-'0';
}
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y) : x(_x),y(_y) {}
} ;
LL Pow(LL a,LL b,LL mod) {LL res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=200;
int n,m,K,dis[N][N],ti,ok[N][N],dp[N][N],vis[N],can[N];
vector<int> E[N],F[N],full[N],Road[N],Up[N];
int S,T;
void bfs(int st)
{
	queue<int> Q;
	rep(i,1,n) dis[ti][i]=INF;
	dis[ti][st]=0;Q.push(st);
	while (Q.size())
	{
		int x=Q.front();Q.pop();
		for (int i=0;i<E[x].size();i++)
		if (dis[ti][E[x][i]]>dis[ti][x]+1)
		{
			dis[ti][E[x][i]]=dis[ti][x]+1;
			Q.push(E[x][i]);
		}
	}
}
void dfs(int x)
{
	//if (ti==1) printf("x = %d\n",x);
	if (vis[x]!=ti)
	{
		full[ti].pb(x);
		Road[dis[ti][x]].pb(x);
	}
	vis[x]=ti;
	for (int i=0;i<F[x].size();i++)
	if (dis[ti][F[x][i]]==dis[ti][x]-1) dfs(F[x][i]);
}
int dfs(int x,int y)
{
	//printf("dfs %d %d    \n",x,y,dis[y][x]);
	int ans=0;
	rep(i,1,n)
	if (dis[x][y]!=1 && dis[y][i]==dis[y][x]+1) ans=max(ans,dfs(i,y));
	if (ans==0) ans=INF;
	ans=min(ans,dp[x][y]);
	ans=min(ans,can[x]+1);
	return ans;
}
int main()
{
	//freopen("E.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&S,&T);int x,y;
	if (S==T) {puts("0");return 0;}
	rep(i,1,m) scanf("%d%d",&x,&y),E[x].pb(y),F[y].pb(x);
	scanf("%d",&K);
	rep(i,1,K)
	{
		scanf("%d%d",&x,&y);ti=i;
		rep(j,0,n) Road[j].clear();
		bfs(x);dfs(y);
		rep(j,0,n)
		if (Road[j].size()==1) Up[Road[j][0]].pb(i),ok[Road[j][0]][i]=1;
		//,printf("%d %d\n",Road[j][0],i);
	}
	rep(i,1,n) can[i]=INF;
	rep(i,1,n) rep(j,0,K) dp[i][j]=INF;
	for (int i=0;i<Up[T].size();i++) dp[T][Up[T][i]]=1,can[T]=1;
	//printf("%d %d\n",ok[4][1],ok[7][1]);
	//printf("!!!!!! %d\n",dfs(5,3));
	//exit(0);
	while(1)
	{
		int F=0;
		rep(i,1,n) rep(j,1,K)
		if (ok[i][j]==1)
		{
			int flag=1,Max=0,size=0;
			Max=dfs(i,j);
			if (dp[i][j]>Max)
			{
				//printf("%d %d %d\n",i,j,Max);
				dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			}
			/*
			for (int k=0;k<full[j].size();k++)
			if (full[j][k]!=i && dis[j][full[j][k]]>=dis[j][i])
			{
				if (i==1 && j==1) printf(" to %d\n",full[j][k]);
				size++;
				if (can[full[j][k]]==INF) {flag=0;break;}
				Max=max(Max,dp[full[j][k]][j]);
			}

			if (dp[i][j]>Max) dp[i][j]=Max,can[i]=min(can[i],dp[i][j]),F=1;
			rep(k,1,n)
			if (ok[k][j] && dp[k][j]<dp[i][j] && dis[j][i]<dis[j][k])
			{
				//if (i==1 && j==1) printf("from %d %d\n",k,j);
				dp[i][j]=dp[k][j],F=1;
				can[i]=min(can[i],dp[i][j]);
			}
			flag=0;int Min=INF;
			for (int k=0;k<Up[i].size();k++)
			if (dp[i][Up[i][k]]) flag=1,Min=min(Min,dp[i][Up[i][k]]);
			if (flag && dp[i][j]>Min+1) dp[i][j]=Min+1,can[i]=min(can[i],dp[i][j]),F=1;
			*/
		}
		if (!F) break;
	}

	/*
	puts("\n");
	rep(i,1,n){ rep(j,1,K)
	printf("%d ",dp[i][j]);
	puts("");}
	*/
	int ans=INF;
	rep(i,1,K) ans=min(ans,dp[S][i]);
	if (ans==INF) puts("-1");else printf("%d\n",ans);
}


#include<algorithm>
#include<cstring>
#include<cstdio>

using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)
#define ms(x,y) memset(x,y,sizeof(x))

const int N=105,inf=1061109567;

int n,m,S,T,a[N],b[N],f[N],ls[N],w[N][N];
bool vis[N],Must[N][N];

int dfs(int x,int lst)
{
	if (vis[x]) return ls[x];
	vis[x]=1,ls[x]=f[x]+1;int tmp=-1;
	rep(i,1,n) if (w[x][i]==1&&w[i][lst]+1==w[x][lst]) tmp=max(tmp,dfs(i,lst));
	if (tmp>=0) ls[x]=min(ls[x],tmp);
	return ls[x];
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&S,&T);
	ms(w,63);rep(i,1,n) w[i][i]=0;
	rep(i,1,m) {int x,y;scanf("%d%d",&x,&y);w[x][y]=1;}
	rep(k,1,n) rep(i,1,n) rep(j,1,n) w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
	scanf("%d",&m);rep(i,1,m)
	{
		scanf("%d%d",&a[i],&b[i]);int A=a[i],B=b[i],C=w[A][B];if (C>=inf) continue;
		rep(j,1,n) Must[i][j]=(w[A][j]+w[j][B]==C);
		rep(j,1,n-1) if (w[A][j]+w[j][B]==C)
		  rep(k,j+1,n) if (w[A][j]==w[A][k]&&w[j][B]==w[k][B])
		    Must[i][j]=Must[i][k]=0;
	}
	for (ms(f,63),f[T]=0;1;)
	{
		bool fl=0;
		rep(i,1,m) rep(j,1,n) if (Must[i][j])
		  {ms(vis,0);int tmp=dfs(j,b[i]);if (tmp<f[j]) f[j]=tmp,fl=1;}
		if (!fl) break;
	}
	printf("%d\n",f[S]>=inf?-1:f[S]);
	return 0;
}


#include <cstdio>
#include <cstring>

#ifdef _WIN32
#define LLFORMAT "I64"
#else
#define LLFORMAT "ll"
#endif

const int MAXN = 105;
const int MAXK = 105;
const int MAXS = 10005;
const int INF = 0x3f3f3f3f;

int n, s0, t0, q;
bool g[MAXN][MAXN];
int s[MAXK];
int t[MAXK];
int dist[MAXN][MAXN];
bool ok[MAXK][MAXN];
bool must[MAXK][MAXN];
int f[MAXK][MAXN];

void input()
{
	int m;
	scanf("%d%d%d%d", &n, &m, &s0, &t0);
	--s0; --t0;
	for (int i = 0; i < m; ++i)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		--x; --y;
		g[x][y] = true;
	}
	scanf("%d", &q);
	for (int i = 0; i < q; ++i)
	{
		scanf("%d%d", &s[i], &t[i]);
		--s[i]; --t[i];
	}
}

void init()
{
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
		{
			if (i == j) dist[i][j] = 0;
			else if (g[i][j]) dist[i][j] = 1;
			else dist[i][j] = INF;
		}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				if (dist[i][k] + dist[k][j] < dist[i][j])
					dist[i][j] = dist[i][k] + dist[k][j];

	for (int i = 0; i < q; ++i)
	{
		if (dist[s[i]][t[i]] == INF) continue;
		int cnt[MAXN] = {0};
		for (int j = 0; j < n; ++j)
			if (dist[s[i]][j] + dist[j][t[i]] == dist[s[i]][t[i]])
				ok[i][j] = true, ++cnt[dist[s[i]][j]];
		for (int j = 0; j < n; ++j)
			if (dist[s[i]][j] + dist[j][t[i]] == dist[s[i]][t[i]] && cnt[dist[s[i]][j]] == 1)
				must[i][j] = true;
	}
}

void solve()
{
	static int que[MAXS][2];
	static int badcnt[MAXK][MAXN];
	int qb = 0, qe = 0;

	for (int i = 0; i < q; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k < n; ++k)
				if (ok[i][j] && g[j][k] && dist[j][t[i]] == dist[k][t[i]] + 1)
					++badcnt[i][j];

	memset(f, -1, sizeof(f));
	for (int i = 0; i < q; ++i)
	{
		f[i][t0] = 0;
		que[qe][0] = i;
		que[qe][1] = t0;
		qe = (qe + 1) % MAXS;
	}

	while (qb != qe)
	{
		int x = que[qb][0], y = que[qb][1];
		qb = (qb + 1) % MAXS;
		if (must[x][y])
		{
			for (int i = 0; i < q; ++i)
				if (f[i][y] == -1)
				{
					f[i][y] = f[x][y] + 1;
					que[qe][0] = i;
					que[qe][1] = y;
					qe = (qe + 1) % MAXS;
				}
		}
		for (int i = 0; i < n; ++i)
			if (ok[x][i] && g[i][y] && dist[i][t[x]] == dist[y][t[x]] + 1)
			{
				--badcnt[x][i];
				if (badcnt[x][i] == 0)
				{
					f[x][i] = f[x][y];
					qb = (qb + MAXS - 1) % MAXS;
					que[qb][0] = x;
					que[qb][1] = i;
				}
			}
	}

	int ans = -1;
	for (int i = 0; i < q; ++i)
		if (must[i][s0] && f[i][s0] != -1 && (ans == -1 || f[i][s0] + 1 < ans))
			ans = f[i][s0] + 1;

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

int main()
{
#ifndef ONLINE_JUDGE
	freopen("8772.in", "r", stdin);
	freopen("8772.out", "w", stdout);
#endif

	input();
	init();
	solve();

#ifndef ONLINE_JUDGE
	fclose(stdin); fclose(stdout);
#endif
	return 0;
}


#include <cstdio>
#include <cstring>

#ifdef _WIN32
#define LLFORMAT "I64"
#else
#define LLFORMAT "ll"
#endif

const int MAXN = 105;
const int MAXK = 105;
const int MAXS = 20005;
const int INF = 0x3f3f3f3f;

int n, s0, t0, q;
bool g[MAXN][MAXN];
int s[MAXK];
int t[MAXK];
int dist[MAXN][MAXN];
bool ok[MAXK][MAXN];
bool must[MAXK][MAXN];
int f[MAXK][MAXN];

void input()
{
	int m;
	scanf("%d%d%d%d", &n, &m, &s0, &t0);
	--s0; --t0;
	for (int i = 0; i < m; ++i)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		--x; --y;
		g[x][y] = true;
	}
	scanf("%d", &q);
	for (int i = 0; i < q; ++i)
	{
		scanf("%d%d", &s[i], &t[i]);
		--s[i]; --t[i];
	}
}

void init()
{
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
		{
			if (i == j) dist[i][j] = 0;
			else if (g[i][j]) dist[i][j] = 1;
			else dist[i][j] = INF;
		}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				if (dist[i][k] + dist[k][j] < dist[i][j])
					dist[i][j] = dist[i][k] + dist[k][j];

	for (int i = 0; i < q; ++i)
	{
		if (dist[s[i]][t[i]] == INF) continue;
		int cnt[MAXN] = {0};
		for (int j = 0; j < n; ++j)
			if (dist[s[i]][j] + dist[j][t[i]] == dist[s[i]][t[i]])
				ok[i][j] = true, ++cnt[dist[s[i]][j]];
		for (int j = 0; j < n; ++j)
			if (dist[s[i]][j] + dist[j][t[i]] == dist[s[i]][t[i]] && cnt[dist[s[i]][j]] == 1)
				must[i][j] = true;
	}
}

void solve()
{
	static int que[MAXS][2];
	static int badcnt[MAXK][MAXN];
	static bool vis[MAXK][MAXN];
	int qb = 0, qe = 0;

	for (int i = 0; i < q; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k < n; ++k)
				if (ok[i][j] && g[j][k] && dist[j][t[i]] == dist[k][t[i]] + 1)
					++badcnt[i][j];

	memset(f, -1, sizeof(f));
	for (int i = 0; i < q; ++i)
	{
		f[i][t0] = 0;
		que[qe][0] = i;
		que[qe][1] = t0;
		qe = (qe + 1) % MAXS;
	}

	while (qb != qe)
	{
		int x = que[qb][0], y = que[qb][1];
		qb = (qb + 1) % MAXS;
		if (vis[x][y]) continue;
		vis[x][y] = true;
		if (must[x][y])
		{
			for (int i = 0; i < q; ++i)
				if (f[i][y] == -1)
				{
					f[i][y] = f[x][y] + 1;
					que[qe][0] = i;
					que[qe][1] = y;
					qe = (qe + 1) % MAXS;
				}
		}
		for (int i = 0; i < n; ++i)
			if (ok[x][i] && g[i][y] && dist[i][t[x]] == dist[y][t[x]] + 1)
			{
				--badcnt[x][i];
				if (badcnt[x][i] == 0)
				{
					f[x][i] = f[x][y];
					qb = (qb + MAXS - 1) % MAXS;
					que[qb][0] = x;
					que[qb][1] = i;
				}
			}
	}

	int ans = -1;
	for (int i = 0; i < q; ++i)
		if (must[i][s0] && f[i][s0] != -1 && (ans == -1 || f[i][s0] + 1 < ans))
			ans = f[i][s0] + 1;

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

int main()
{
#ifndef ONLINE_JUDGE
	freopen("8772.in", "r", stdin);
	freopen("8772.out", "w", stdout);
#endif

	input();
	init();
	solve();

#ifndef ONLINE_JUDGE
	fclose(stdin); fclose(stdout);
#endif
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#define each(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define maxn 110
using namespace std;
vector<int> can[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T,nB;
int from[maxn],to[maxn];
void read()
{
	cin>>n>>m>>S>>T;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(i!=j)
				dis[i][j]=1<<30;
	for(int i=1,a,b;i<=m;++i)
	{
		cin>>a>>b;
		dis[a][b]=1;
	}
}
void Prepare()
{
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(dis[i][k]!=1<<30)
				for(int j=1;j<=n;++j)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int Q;
	cin>>Q;
	for(int i=1,a,b;i<=Q;++i)
	{
		cin>>a>>b;
		if(dis[a][b]!=1<<30)
		{
			++nB,from[nB]=a,to[nB]=b;
			for(int j=1;j<=n;++j)
				if(dis[from[i]][j]+dis[j][to[i]]==dis[from[i]][to[i]])
					can[i][dis[from[i]][j]].push_back(j);
		}
	}
}
int Dp()
{
	static int dp[maxn],g[maxn];
	fill(dp+1,dp+n+1,1<<30);
	dp[T]=0;
	int now=0;
	for(bool mark=true;mark;)
	{
		mark=false,++now;
		for(int i=1;i<=nB;++i)
		{
			g[to[i]]=dp[to[i]];
			for(int len=dis[from[i]][to[i]]-1;len>=0;--len)
			{
				each(p,can[i][len])
				{
					g[*p]=0;
					each(q,can[i][len+1])
						g[*p]=max(g[*p],g[*q]);
					g[*p]=min(g[*p],dp[*p]);
				}
				if(can[i][len].size()==1)
				{
					int p=can[i][len][0];
					if(dp[p]==1<<30&&g[p]<now)
						dp[p]=now,mark=true;
				}
			}
		}
	}
	return dp[S]==1<<30?-1:dp[S];
}
int main()
{
	read();
	Prepare();
	printf("%d\n",Dp());
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#define maxn 110
using namespace std;
bitset<maxn> must[maxn][maxn];
bool ok[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T;
void read()
{
	cin>>n>>m>>S>>T;
	for(int i=1;i<=n;++i)
	{
		must[i][i]=1;
		for(int j=1;j<=n;++j)
			if(i!=j)
				dis[i][j]=1<<30;
	}
	for(int i=1,a,b;i<=m;++i)
	{
		cin>>a>>b;
		dis[a][b]=1;
	}
}
void Prepare()
{
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(dis[i][k]!=1<<30)
				for(int j=1;j<=n;++j)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	for(int T=1;T<=n;++T)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				if(dis[i][j]==T)
				{
					if(dis[i][j]==1)
						must[i][j][i]=must[i][j][j]=1;
					else
					{
						int t=0;
						for(int k=1;k<=n;++k)
							if(dis[i][k]==1&&dis[k][j]==dis[i][j]-1)
							{
								if(t==0)
									must[i][j]=must[k][j],t=1;
								else
									must[i][j]&=must[k][j];
							}
						must[i][j][i]=1;
					}
				}
}
void Query()
{
	int Q;
	cin>>Q;
	for(int i=1,a,b;i<=Q;++i)
	{
		cin>>a>>b;
		if(dis[a][b]!=1<<30)
			for(int j=1;j<=n;++j)
				if(must[a][b][j])
					for(int k=1;k<=n;++k)
						if(must[a][b][k]&&dis[j][b]>dis[k][b])
							ok[j][k]=1;
	}
}
int BFS()
{
	static int queue[maxn],step[maxn];
	static bool use[maxn];
	int front=0,rear=1;
	queue[rear]=S,use[S]=true;
	while(front<rear)
	{
		int p=queue[++front];
		if(p==T)
			return step[p];
		for(int i=1;i<=n;++i)
			if(ok[p][i]&&!use[i])
			{
				queue[++rear]=i;
				use[i]=true;
				step[i]=step[p]+1;
			}
	}
	return -1;
}
int main()
{
	read();
	Prepare();
	Query();
	printf("%d\n",BFS());
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#define each(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define maxn 110
using namespace std;
vector<int> can[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T,nB;
int from[maxn],to[maxn];
void read()
{
	cin>>n>>m>>S>>T;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(i!=j)
				dis[i][j]=1<<30;
	for(int i=1,a,b;i<=m;++i)
	{
		cin>>a>>b;
		dis[a][b]=1;
	}
}
void Prepare()
{
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(dis[i][k]!=1<<30)
				for(int j=1;j<=n;++j)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int Q;
	cin>>Q;
	for(int i=1,a,b;i<=Q;++i)
	{
		cin>>a>>b;
		if(dis[a][b]!=1<<30)
		{
			++nB,from[nB]=a,to[nB]=b;
			for(int j=1;j<=n;++j)
				if(dis[from[i]][j]+dis[j][to[i]]==dis[from[i]][to[i]])
					can[i][dis[from[i]][j]].push_back(j);
		}
		if(m==24&&i>=10)
			printf("%d %d\n",a,b);
	}
}
int Dp()
{
	static int dp[maxn],g[maxn];
	fill(dp+1,dp+n+1,1<<30);
	dp[T]=0;
	for(bool mark=true;mark;)
	{
		mark=false;
		for(int i=1;i<=nB;++i)
		{
			g[to[i]]=dp[to[i]];
			for(int len=dis[from[i]][to[i]]-1;len>=0;--len)
			{
				each(p,can[i][len])
				{
					g[*p]=0;
					each(q,can[i][len+1])
						if(dis[*p][*q]==1)
							g[*p]=max(g[*p],g[*q]);
					g[*p]=min(g[*p],dp[*p]);
				}
				if(can[i][len].size()==1)
				{
					int p=can[i][len][0];
					if(dp[p]>g[p]+1)
						dp[p]=g[p]+1,mark=true;
				}
			}
		}
	}
	return dp[S]==1<<30?-1:dp[S];
}
int main()
{
	read();
	Prepare();
	printf("%d\n",Dp());
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#define each(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define maxn 110
using namespace std;
vector<int> can[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T,nB;
int from[maxn],to[maxn];
void read()
{
    cin>>n>>m>>S>>T;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            if(i!=j)
                dis[i][j]=1<<30;
    for(int i=1,a,b;i<=m;++i)
    {
        cin>>a>>b;
        dis[a][b]=1;
    }
}
void Prepare()
{
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;++i)
            if(dis[i][k]!=1<<30)
                for(int j=1;j<=n;++j)
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    int Q;
    cin>>Q;
    for(int i=1,a,b;i<=Q;++i)
    {
        cin>>a>>b;
        if(dis[a][b]!=1<<30)
        {
            ++nB,from[nB]=a,to[nB]=b;
            for(int j=1;j<=n;++j)
                if(dis[from[i]][j]+dis[j][to[i]]==dis[from[i]][to[i]])
                    can[i][dis[from[i]][j]].push_back(j);
        }
    }
}
int Dp()
{
    static int dp[maxn],g[maxn];
    fill(dp+1,dp+n+1,1<<30);
    dp[T]=0;
    for(bool mark=true;mark;)
    {
        mark=false;
        for(int i=1;i<=nB;++i)
        {
            g[to[i]]=dp[to[i]];
            for(int len=dis[from[i]][to[i]]-1;len>=0;--len)
            {
                each(p,can[i][len])
                {
                    g[*p]=0;
                    each(q,can[i][len+1])
                        g[*p]=max(g[*p],g[*q]);
                    g[*p]=min(g[*p],dp[*p]);
                }
                if(can[i][len].size()==1)
                {
                    int p=can[i][len][0];
                    if(dp[p]>g[p]+1)
                        dp[p]=g[p]+1,mark=true;
                }
            }
        }
    }
    return dp[S]==1<<30?-1:dp[S];
}
int main()
{
    read();
    Prepare();
    printf("%d\n",Dp());
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#define each(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define maxn 110
using namespace std;
vector<int> can[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T,nB;
int from[maxn],to[maxn];
void read()
{
	cin>>n>>m>>S>>T;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(i!=j)
				dis[i][j]=1<<30;
	for(int i=1,a,b;i<=m;++i)
	{
		cin>>a>>b;
		dis[a][b]=1;
	}
}
void Prepare()
{
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(dis[i][k]!=1<<30)
				for(int j=1;j<=n;++j)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int Q;
	cin>>Q;
	for(int i=1,a,b;i<=Q;++i)
	{
		cin>>a>>b;
		if(dis[a][b]!=1<<30)
		{
			++nB,from[nB]=a,to[nB]=b;
			for(int j=1;j<=n;++j)
				if(dis[a][j]+dis[j][b]==dis[a][b])
					can[nB][dis[a][j]].push_back(j);
		}
	}
}
int Dp()
{
	static int dp[maxn],g[maxn];
	fill(dp+1,dp+n+1,1<<30);
	dp[T]=0;
	for(bool mark=true;mark;)
	{
		mark=false;
		for(int i=1;i<=nB;++i)
		{
			g[to[i]]=dp[to[i]];
			for(int len=dis[from[i]][to[i]]-1;len>=0;--len)
			{
				each(p,can[i][len])
				{
					g[*p]=0;
					each(q,can[i][len+1])
						if(dis[*p][*q]==1)
							g[*p]=max(g[*p],g[*q]);
					g[*p]=min(g[*p],dp[*p]);
				}
				if(can[i][len].size()==1)
				{
					int p=can[i][len][0];
					if(dp[p]>g[p]+1)
						dp[p]=g[p]+1,mark=true;
				}
			}
		}
	}
	return dp[S]==1<<30?-1:dp[S];
}
int main()
{
	read();
	Prepare();
	printf("%d\n",Dp());
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<vector>
#define each(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define maxn 110
using namespace std;
vector<int> can[maxn][maxn];
int dis[maxn][maxn];
int n,m,S,T,nB;
int from[maxn],to[maxn];
void read()
{
	cin>>n>>m>>S>>T;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(i!=j)
				dis[i][j]=1<<30;
	for(int i=1,a,b;i<=m;++i)
	{
		cin>>a>>b;
		dis[a][b]=1;
	}
}
void Prepare()
{
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(dis[i][k]!=1<<30)
				for(int j=1;j<=n;++j)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int Q;
	cin>>Q;
	for(int i=1,a,b;i<=Q;++i)
	{
		cin>>a>>b;
		if(dis[a][b]!=1<<30)
		{
			++nB,from[nB]=a,to[nB]=b;
			for(int j=1;j<=n;++j)
				if(dis[from[i]][j]+dis[j][to[i]]==dis[from[i]][to[i]])
					can[i][dis[from[i]][j]].push_back(j);
		}
	}
}
int Dp()
{
	static int dp[maxn],g[maxn];
	fill(dp+1,dp+n+1,1<<30);
	dp[T]=0;
	for(bool mark=true;mark;)
	{
		mark=false;
		for(int i=1;i<=nB;++i)
		{
			g[to[i]]=dp[to[i]];
			for(int len=dis[from[i]][to[i]]-1;len>=0;--len)
			{
				each(p,can[i][len])
				{
					g[*p]=0;
					each(q,can[i][len+1])
						if(dis[*p][*q]==1)
							g[*p]=max(g[*p],g[*q]);
					g[*p]=min(g[*p],dp[*p]);
				}
				if(can[i][len].size()==1)
				{
					int p=can[i][len][0];
					if(dp[p]>g[p]+1)
						dp[p]=g[p]+1,mark=true;
				}
			}
		}
	}
	return dp[S]==1<<30?-1:dp[S];
}
int main()
{
	read();
	Prepare();
	printf("%d\n",Dp());
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define repu(i,x,y) for (int i=x; i<=y; ++i)
#define repe(i,x) for (edge *i=x; i; i=i->nxt)
using namespace std;

int n,m,s,t,u,v,f[110],dis[110][110],q[110],head,tail,cnt[110][110];
bool flag[110],cut[110][110];
struct edge
{
    int v;
    edge *nxt;
} pool[20100],*tp=pool,*fst1[110],*fst2[110];

void dfs(int x,int k)
{
    flag[x]=1;
    repe(i,fst1[x])
        if (!flag[i->v] && dis[k][x]==dis[k][i->v]+1)
            dfs(i->v,k);
}

void dfs(int x,int k,int w)
{
    cnt[k][x]=-1;
    if (cut[k][x])
        f[x]=min(f[x],w);
    repe(i,fst2[x])
        if (dis[k][i->v]==dis[k][x]+1 && cnt[k][i->v]!=-1 && !--cnt[k][i->v])
            dfs(i->v,k,w);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    while (m--)
    {
        scanf("%d%d",&u,&v);
        *tp=(edge){v,fst1[u]},fst1[u]=tp++;
        *tp=(edge){u,fst2[v]},fst2[v]=tp++;
    }
    scanf("%d",&m);
    repu(i,1,m)
    {
        scanf("%d%d",&u,&v);
        memset(dis[i],80,sizeof(dis[i]));
        dis[i][q[head=tail=0]=v]=0;
        for (int x; head<=tail; ++head)
            repe(j,fst2[x=q[head]])
                if (dis[i][j->v]>n)
                    dis[i][q[++tail]=j->v]=dis[i][x]+1;
        memset(flag,0,sizeof(flag)),dfs(u,i);
        repu(j,1,n)
        {
            if (!flag[j])
                dis[i][j]=1<<30;
            repe(k,fst1[j])
                cnt[i][j]+=dis[i][j]==dis[i][k->v]+1;
        }
        repu(j,1,n)
            if (dis[i][j]<=n)
            {
                cut[i][j]=1;
                repu(k,1,n)
                    cut[i][j]&=k==j || dis[i][k]!=dis[i][j];
            }
    }
    memset(f,80,sizeof(f)),f[t]=0;
    repu(i,1,n)
        repu(j,1,m)
            repu(k,1,n)
                if (f[k]==i-1 && dis[j][k]<=n & cut[j][k])
                    dfs(k,j,i);
    printf("%d\n",f[s]<=n?f[s]:-1);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define repu(i,x,y) for (int i=x; i<=y; ++i)
#define repe(i,x) for (edge *i=x; i; i=i->nxt)
using namespace std;

int n,m,s,t,u,v,f[110],dis[110][110],q[110],head,tail,cnt[110][110];
bool flag[110],cut[110][110];
struct edge
{
    int v;
    edge *nxt;
} pool[20100],*tp=pool,*fst1[110],*fst2[110];

void dfs(int x,int k)
{
    flag[x]=1;
    repe(i,fst1[x])
        if (!flag[i->v] && dis[k][x]==dis[k][i->v]+1)
            dfs(i->v,k);
}

void dfs(int x,int k,int w)
{
    cnt[k][x]=-1;
    if (cut[k][x])
        f[x]=min(f[x],w);
    repe(i,fst2[x])
        if (dis[k][i->v]==dis[k][x]+1 && cnt[k][i->v]!=-1 && !--cnt[k][i->v])
            dfs(i->v,k,w);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    while (m--)
    {
        scanf("%d%d",&u,&v);
        *tp=(edge){v,fst1[u]},fst1[u]=tp++;
        *tp=(edge){u,fst2[v]},fst2[v]=tp++;
    }
    scanf("%d",&m);
    repu(i,1,m)
    {
        scanf("%d%d",&u,&v);
        memset(dis[i],80,sizeof(dis[i]));
        dis[i][q[head=tail=0]=v]=0;
        for (int x; head<=tail; ++head)
            repe(j,fst2[x=q[head]])
                if (dis[i][j->v]>n)
                    dis[i][q[++tail]=j->v]=dis[i][x]+1;
        memset(flag,0,sizeof(flag)),dfs(u,i);
        repu(j,1,n)
        {
            if (!flag[j])
                dis[i][j]=1<<30;
            repe(k,fst1[j])
                cnt[i][j]+=dis[i][j]==dis[i][k->v]+1;
        }
        repu(j,1,n)
            if (dis[i][j]<=n)
            {
                cut[i][j]=1;
                repu(k,1,n)
                    cut[i][j]&=k==j || dis[i][k]!=dis[i][j];
            }
    }
    memset(f,80,sizeof(f)),f[t]=0;
    repu(i,1,n)
        repu(j,1,m)
            repu(k,1,n)
                if (f[k]==i-1 && dis[j][k]<=n && cnt[j][k]!=-1)
                    dfs(k,j,i);
    printf("%d\n",f[s]<=n?f[s]:-1);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define repu(i,x,y) for (int i=x; i<=y; ++i)
#define repe(i,x) for (edge *i=fst[x]; i; i=i->nxt)
using namespace std;

int n,m,s,t,u,v,f[110],dis[110][110],q[110],head,tail,cnt[110][110];
bool flag[110];
struct edge
{
    int v;
    edge *nxt;
} pool[20100],*tp=pool,*fst[110];

void dfs(int x,int k)
{
    flag[x]=1;
    repe(i,x)
        if (!flag[i->v] && dis[k][x]==dis[k][i->v]+1)
            dfs(i->v,k);
}

void dfs(int x,int k,int w)
{
    cnt[k][x]=-1,f[x]=min(f[x],w);
    repe(i,x)
        if (dis[k][i->v]==dis[k][x]+1 && cnt[k][i->v]!=-1 && !--cnt[k][i->v])
            dfs(i->v,k,w);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    while (m--)
    {
        scanf("%d%d",&u,&v);
        *tp=(edge){v,fst[u]},fst[u]=tp++;
        *tp=(edge){u,fst[v]},fst[v]=tp++;
    }
    scanf("%d",&m);
    repu(i,1,m)
    {
        scanf("%d%d",&u,&v);
        memset(dis[i],80,sizeof(dis[i]));
        dis[i][q[head=tail=0]=v]=0;
        for (int x; head<=tail; ++head)
            repe(j,x=q[head])
                if (dis[i][j->v]>n)
                    dis[i][q[++tail]=j->v]=dis[i][x]+1;
        memset(flag,0,sizeof(flag)),dfs(u,i);
        repu(j,1,n)
        {
            if (!flag[j])
                dis[i][j]=1<<30;
            repe(k,j)
                cnt[i][j]+=dis[i][j]==dis[i][k->v]+1;
        }
    }
    memset(f,80,sizeof(f)),f[t]=0;
    repu(i,1,n)
        repu(j,1,m)
            repu(k,1,n)
                if (f[k]==i-1 && dis[j][k]<=n)
                    dfs(k,j,i);
    printf("%d\n",f[s]<=n?f[s]:-1);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define repu(i,x,y) for (int i=x; i<=y; ++i)
#define repe(i,x) for (edge *i=x; i; i=i->nxt)
using namespace std;

int n,m,s,t,u,v,f[110],dis[110][110],q[110],head,tail,cnt[110][110];
bool flag[110],cut[110][110];
struct edge
{
    int v;
    edge *nxt;
} pool[20100],*tp=pool,*fst1[110],*fst2[110];

void dfs(int x,int k)
{
    flag[x]=1;
    repe(i,fst1[x])
        if (!flag[i->v] && dis[k][x]==dis[k][i->v]+1)
            dfs(i->v,k);
}

void dfs(int x,int k,int w)
{
    cnt[k][x]=-1;
    if (cut[k][x])
        f[x]=min(f[x],w);
    repe(i,fst2[x])
        if (dis[k][i->v]==dis[k][x]+1 && cnt[k][i->v]!=-1 && !--cnt[k][i->v])
            dfs(i->v,k,w);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    while (m--)
    {
        scanf("%d%d",&u,&v);
        *tp=(edge){v,fst1[u]},fst1[u]=tp++;
        *tp=(edge){u,fst2[v]},fst2[v]=tp++;
    }
    scanf("%d",&m);
    repu(i,1,m)
    {
        scanf("%d%d",&u,&v);
        memset(dis[i],80,sizeof(dis[i]));
        dis[i][q[head=tail=0]=v]=0;
        for (int x; head<=tail; ++head)
            repe(j,fst2[x=q[head]])
                if (dis[i][j->v]>n)
                    dis[i][q[++tail]=j->v]=dis[i][x]+1;
        memset(flag,0,sizeof(flag)),dfs(u,i);
        repu(j,1,n)
        {
            if (!flag[j])
                dis[i][j]=1<<30;
            repe(k,fst1[j])
                cnt[i][j]+=dis[i][j]==dis[i][k->v]+1;
        }
        repu(j,1,n)
            if (dis[i][j]<=n)
            {
                cut[i][j]=1;
                repu(k,1,n)
                    cut[i][j]&=k==j || dis[i][k]!=dis[i][j];
            }
    }
    memset(f,80,sizeof(f)),f[t]=0;
    repu(i,1,n)
        repu(j,1,m)
            repu(k,1,n)
                if (f[k]==i-1 && dis[j][k]<=n)
                    dfs(k,j,i);
    printf("%d\n",f[s]<=n?f[s]:-1);
    return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 110
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T,x,y,num;
int a[N][N],b[N][N],s[N],t[N],an[N],h[N],f[N],c[N][N];
int dfs(int x,int y) {
	if (h[x]==num) return f[x];
	h[x]=num;
	int i,ans=-1;
	For(i,1,n) if (a[x][i]==1&&a[x][i]+a[i][y]==a[x][y]) ans=max(ans,dfs(i,y));
	if (ans<0) ans=a[0][0];
	f[x]=min(ans,an[x]+1);
	return f[x];
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	memset(a,60,sizeof(a));
	For(i,1,n) a[i][i]=0;
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	For(k,1,n)For(i,1,n)For(j,1,n) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		For(j,1,n) if (a[x][j]<1e9&&a[x][j]+a[j][y]==a[x][y]) b[i][a[x][j]]++;
		For(j,1,n) if (a[x][j]<1e9&&a[x][j]+a[j][y]==a[x][y]&&b[i][a[x][j]]==1)
			c[i][j]=1;
		s[i]=x,t[i]=y;
	}
	memset(an,60,sizeof(an));
	an[T]=0;
	for (;;) {
		int F=0;
		For(i,1,m) {
			For(j,1,n) if (c[i][j]) {
				++num;
				int A=dfs(j,t[i]);
				if (A<an[j]) an[j]=A,F=1;
			}
		}
		if (!F) break;
	}
	printf("%d\n",an[S]>1e9?-1:an[S]);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 21000
#define inf 1000000000
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T;
int a[N],next[N],head[N],f[N],s[N],t[N],g[N],gg[110][110],F[110][110],
	in[110][110];
int dfs(int x);
inline int suan(int x,int y) {
	int l,r,v,i,g[110],b[110],h[110]={};
	g[l=r=1]=y; h[y]=1;
	for (;l<=r;l++) {
		int A=g[l];
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&!h[B]) g[++r]=B,h[B]=1;
		}
	}
	for (i=r;i;i--) {
		int A=g[i],an=-1;
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&gg[x][A]+1==gg[x][B]) an=max(an,b[B]);
		}
		if (an<0) an=inf;
		b[A]=min(an,dfs(A)+1);
	}
	return b[y];
}
int dfs(int x) {
	if (x==T) return 0;
	if (f[x]==inf-1) return inf;
	if (f[x]<inf/2) return f[x];
	f[x]=inf-1;
	int i,an=-1;
	For(i,1,m) if (F[i][x]&&x!=t[i]) {
		int A=suan(i,x);
		an=max(an,A);
	}
	if (an<0) f[x]=inf-1;
	else f[x]=min(inf-1,an);
	return f[x];
}
inline void bfs(int x) {
	int l,r,v,i;
	g[l=r=1]=s[x]; gg[x][s[x]]=0;
	for (;l<=r;l++) for (v=head[g[l]];v;v=next[v]) {
		int A=a[v];
		if (gg[x][A]>inf) {
			gg[x][A]=gg[x][g[l]]+1;
			g[++r]=A;
		}
	}
	F[x][t[x]]=1;
	for (i=r;i;i--) {
		int A=g[i];
		for (v=head[A];v;v=next[v]) if (gg[x][A]+1==gg[x][a[v]]&&F[x][a[v]])
			F[x][A]=1;
		if (F[x][A]) in[x][gg[x][A]]++;
	}
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	For(i,1,m) {
		int x,y;
		scanf("%d%d",&x,&y);
		a[i]=y,next[i]=head[x],head[x]=i;
	}
	memset(gg,120,sizeof(gg));
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&s[i],&t[i]);
		bfs(i);
	}
	For(i,1,n) f[i]=inf;
	int an=dfs(S);
	printf("%d\n",an>inf/2?-1:an);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 110
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T,x,y,num;
int a[N][N],b[N][N],s[N],t[N],an[N],h[N],f[N];
int dfs(int x,int y) {
	if (h[x]==num) return f[x];
	h[x]=num;
	int i,ans=-1;
	For(i,1,n) if (a[x][i]==1&&a[x][i]+a[i][y]==a[x][y]) ans=max(ans,dfs(i,y));
	if (ans<0) ans=a[0][0];
	f[x]=min(ans,an[x]+1);
	return f[x];
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	memset(a,120,sizeof(a));
	For(i,1,n) a[i][i]=0;
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	For(k,1,n)For(i,1,n)For(j,1,n) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		For(j,1,n) if (a[x][j]+a[j][y]==a[x][y]) b[x][a[x][j]]++;
		s[i]=x,t[i]=y;
	}
	memset(an,120,sizeof(an));
	an[T]=0;
	for (;;) {
		int F=0;
		For(i,1,m) {
			For(j,1,n) if (b[i][a[s[i]][j]]==1) {
				++num;
				int A=dfs(j,t[i]);
				if (A<an[j]) an[j]=A,F=1;
			}
		}
		if (!F) break;
	}
	printf("%d\n",an[S]>1e9?-1:an[S]);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 21000
#define inf 1000000000
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T;
int a[N],next[N],head[N],f[N],s[N],t[N],g[N],gg[110][110],F[110][110],
	in[110][110];
int dfs(int x);
inline int suan(int x,int y) {
	int l,r,v,i,g[110],b[110],h[110]={};
	g[l=r=1]=y; h[y]=1;
	for (;l<=r;l++) {
		int A=g[l];
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&!h[B]) g[++r]=B,h[B]=1;
		}
	}
	for (i=r;i;i--) {
		int A=g[i],an=-1;
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&gg[x][A]+1==gg[x][B]) an=max(an,b[B]);
		}
		if (an<0) an=inf;
		b[A]=min(an,dfs(A)+1);
	}
	return b[y];
}
int dfs(int x) {
	if (x==T) return 0;
	if (f[x]==inf-1) return inf;
	if (f[x]<inf/2) return f[x];
	f[x]=inf-1;
	int i,an=-1,re=-1;
	For(i,1,m) if (F[i][x]&&x!=t[i]) {
		int A=suan(i,x);
		if (in[i][gg[i][x]]==1) an=max(an,A);
		else re=max(re,A);
	}
	if (an<0) f[x]=inf-1;
	else f[x]=min(inf-1,max(an,re));
	return f[x];
}
inline void bfs(int x) {
	int l,r,v,i;
	g[l=r=1]=s[x]; gg[x][s[x]]=0;
	for (;l<=r;l++) for (v=head[g[l]];v;v=next[v]) {
		int A=a[v];
		if (gg[x][A]>inf) {
			gg[x][A]=gg[x][g[l]]+1;
			g[++r]=A;
		}
	}
	F[x][t[x]]=1;
	for (i=r;i;i--) {
		int A=g[i];
		for (v=head[A];v;v=next[v]) if (gg[x][A]+1==gg[x][a[v]]&&F[x][a[v]])
			F[x][A]=1;
		if (F[x][A]) in[x][gg[x][A]]++;
	}
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	For(i,1,m) {
		int x,y;
		scanf("%d%d",&x,&y);
		a[i]=y,next[i]=head[x],head[x]=i;
	}
	memset(gg,120,sizeof(gg));
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&s[i],&t[i]);
		bfs(i);
	}
	For(i,1,n) f[i]=inf;
	int an=dfs(S);
	printf("%d\n",an>inf/2?-1:an);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 110
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T,x,y,num;
int a[N][N],b[N][N],s[N],t[N],an[N],h[N],f[N];
int dfs(int x,int y) {
	if (h[x]==num) return f[x];
	h[x]=num;
	int i,ans=-1;
	For(i,1,n) if (a[x][i]==1&&a[x][i]+a[i][y]==a[x][y]) ans=max(ans,dfs(i,y));
	if (ans<0) ans=a[0][0];
	f[x]=min(ans,an[x]+1);
	return f[x];
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	memset(a,60,sizeof(a));
	For(i,1,n) a[i][i]=0;
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	For(k,1,n)For(i,1,n)For(j,1,n) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		For(j,1,n) if (a[x][j]<1e9&&a[x][j]+a[j][y]==a[x][y]) b[i][a[x][j]]++;
		s[i]=x,t[i]=y;
	}
	memset(an,60,sizeof(an));
	an[T]=0;
	for (;;) {
		int F=0;
		For(i,1,m) {
			For(j,1,n) if (a[s[i]][j]<1e9&&b[i][a[s[i]][j]]==1) {
				++num;
				int A=dfs(j,t[i]);
				if (A<an[j]) an[j]=A,F=1;
			}
		}
		if (!F) break;
	}
	printf("%d\n",an[S]>1e9?-1:an[S]);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 21000
#define inf 1000000000
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T;
int a[N],next[N],head[N],f[N],s[N],t[N],g[N],gg[110][110],F[110][110],
	in[110][110];
int dfs(int x);
inline int suan(int x,int y) {
	int l,r,v,i,g[110],b[110],h[110]={};
	g[l=r=1]=y; h[y]=1;
	for (;l<=r;l++) {
		int A=g[l];
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&!h[B]) g[++r]=B,h[B]=1;
		}
	}
	for (i=r;i;i--) {
		int A=g[i],an=-1;
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&gg[x][A]+1==gg[x][B]) an=max(an,b[B]);
		}
		if (an<0) an=inf;
		b[A]=min(an,dfs(A)+1);
	}
	return b[y];
}
int dfs(int x) {
	if (x==T) return 0;
	if (f[x]==inf-1) return inf;
	if (f[x]<inf/2) return f[x];
	f[x]=inf-1;
	int i,an=inf-1;
	For(i,1,m) if (F[i][x]&&x!=t[i]) {
		int A=suan(i,x);
		if (in[i][gg[i][x]]==1) an=min(an,A);
	}
	f[x]=an;
	return f[x];
}
inline void bfs(int x) {
	int l,r,v,i;
	g[l=r=1]=s[x]; gg[x][s[x]]=0;
	for (;l<=r;l++) for (v=head[g[l]];v;v=next[v]) {
		int A=a[v];
		if (gg[x][A]>inf) {
			gg[x][A]=gg[x][g[l]]+1;
			g[++r]=A;
		}
	}
	F[x][t[x]]=1;
	for (i=r;i;i--) {
		int A=g[i];
		for (v=head[A];v;v=next[v]) if (gg[x][A]+1==gg[x][a[v]]&&F[x][a[v]])
			F[x][A]=1;
		if (F[x][A]) in[x][gg[x][A]]++;
	}
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	For(i,1,m) {
		int x,y;
		scanf("%d%d",&x,&y);
		a[i]=y,next[i]=head[x],head[x]=i;
	}
	memset(gg,120,sizeof(gg));
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&s[i],&t[i]);
		bfs(i);
	}
	For(i,1,n) f[i]=inf;
	int an=dfs(S);
	printf("%d\n",an>inf/2?-1:an);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 110
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T,x,y,num;
int a[N][N],b[N][N],s[N],t[N],an[N],h[N],f[N];
int dfs(int x,int y) {
	if (h[x]==num) return f[x];
	h[x]=num;
	int i,ans=-1;
	For(i,1,n) if (a[x][i]==1&&a[x][i]+a[i][y]==a[x][y]) ans=max(ans,dfs(i,y));
	if (ans<0) ans=a[0][0];
	f[x]=min(ans,an[x]+1);
	return f[x];
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	memset(a,60,sizeof(a));
	For(i,1,n) a[i][i]=0;
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	For(k,1,n)For(i,1,n)For(j,1,n) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&x,&y);
		For(j,1,n) if (a[x][j]+a[j][y]==a[x][y]) b[i][a[x][j]]++;
		s[i]=x,t[i]=y;
	}
	memset(an,60,sizeof(an));
	an[T]=0;
	for (;;) {
		int F=0;
		For(i,1,m) {
			For(j,1,n) if (a[s[i]][j]<1e9&&b[i][a[s[i]][j]]==1) {
				++num;
				int A=dfs(j,t[i]);
				if (A<an[j]) an[j]=A,F=1;
			}
		}
		if (!F) break;
	}
	printf("%d\n",an[S]>1e9?-1:an[S]);
	return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define N 21000
#define inf 1000000000
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
int i,j,k,n,m,S,T;
int a[N],next[N],head[N],f[N],s[N],t[N],g[N],gg[110][110],F[110][110],
	in[110][110];
int dfs(int x);
inline int suan(int x,int y) {
	int l,r,v,i,g[110],b[110],h[110]={};
	g[l=r=1]=y; h[y]=1;
	for (;l<=r;l++) {
		int A=g[l];
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&!h[B]) g[++r]=B,h[B]=1;
		}
	}
	for (i=r;i;i--) {
		int A=g[i],an=-1;
		for (v=head[A];v;v=next[v]) {
			int B=a[v];
			if (F[x][B]&&gg[x][A]+1==gg[x][B]) an=max(an,b[B]);
		}
		if (an<0) an=inf;
		b[A]=min(an,dfs(A)+1);
	}
	return b[y];
}
int dfs(int x) {
	if (x==T) return 0;
	if (f[x]==inf-1) return inf;
	if (f[x]<inf/2) return f[x];
	f[x]=inf-1;
	int i,an=inf-1;
	For(i,1,m) if (F[i][x]&&x!=t[i]&&in[i][gg[i][x]]==1) {
		int A=suan(i,x);
		an=min(an,A);
	}
	f[x]=an;
	return f[x];
}
inline void bfs(int x) {
	int l,r,v,i;
	g[l=r=1]=s[x]; gg[x][s[x]]=0;
	for (;l<=r;l++) for (v=head[g[l]];v;v=next[v]) {
		int A=a[v];
		if (gg[x][A]>inf) {
			gg[x][A]=gg[x][g[l]]+1;
			g[++r]=A;
		}
	}
	F[x][t[x]]=1;
	for (i=r;i;i--) {
		int A=g[i];
		for (v=head[A];v;v=next[v]) if (gg[x][A]+1==gg[x][a[v]]&&F[x][a[v]])
			F[x][A]=1;
		if (F[x][A]) in[x][gg[x][A]]++;
	}
}
int main() {
	scanf("%d%d%d%d",&n,&m,&S,&T);
	For(i,1,m) {
		int x,y;
		scanf("%d%d",&x,&y);
		a[i]=y,next[i]=head[x],head[x]=i;
	}
	memset(gg,120,sizeof(gg));
	scanf("%d",&m);
	For(i,1,m) {
		scanf("%d%d",&s[i],&t[i]);
		bfs(i);
	}
	For(i,1,n) f[i]=inf;
	int an=dfs(S);
	printf("%d\n",an>inf/2?-1:an);
	return 0;
}


#include <iostream>
#include <cstring>
#include <deque>
#include <vector>
using namespace std;

const int INF = 1000000000;
const int N = 105;
int n, m, x, y, r, s[N], t[N], d[N][N] = {}, dp[N][N], st[N][N];
vector<int> adj[N], uni[N][N], rt[N];

int check(int i, int v, bool b){
  if(v == y) return 1;
  if(st[i][v] == 1) return dp[i][v];
  if(st[i][v] == 2) return dp[i][v];
  st[i][v] = 1;
  if(b) dp[i][v] = INF + 1;
  for(int k = 0; k < adj[v].size(); k++){
    if(d[s[i]][v] + d[adj[v][k]][t[i]] + 1 == d[s[i]][t[i]]){
      if(dp[i][v] > INF) dp[i][v] = check(i, adj[v][k], b);
      else dp[i][v] = max(dp[i][v], check(i, adj[v][k], b));
    }
  }
  if(dp[i][v] < 0) dp[i][v] = INF;
  for(int j = 0; j < rt[i].size(); j++){
    dp[i][v] = min(dp[i][v], check(rt[i][j], v, b) + 1);
  }
  st[i][v] = 2;
  return dp[i][v];
}

int main(){
  for(int i = 0; i < N; i++){
    for(int j = 0; j < N; j++){
      if(i != j) d[i][j] = INF;
    }
  }
  cin >> n >> m >> x >> y;
  x--, y--;
  for(int i = 0; i < m; i++){
    int a, b;
    cin >> a >> b;
    a--, b--;
    adj[a].push_back(b);
    d[a][b] = 1;
  }
  cin >> r;
  for(int i = 0; i < r; i++){
    cin >> s[i] >> t[i];
    s[i]--, t[i]--;
  }

  for(int k = 0; k < n; k++){
    for(int i = 0; i < n; i++){
      for(int j = 0; j < n; j++){
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  for(int i = 0; i < r; i++){
    if(d[s[i]][t[i]] == INF) continue;
    for(int j = 0; j < n; j++){
      if(d[s[i]][j] + d[j][t[i]] == d[s[i]][t[i]]){
        uni[i][d[s[i]][j]].push_back(j);
      }
    }
  }
  for(int i = 0; i < r; i++){
    if(d[s[i]][t[i]] == INF) continue;
    for(int j = 0; j <= d[s[i]][t[i]]; j++){
      if(uni[i][j].size() == 1){
        rt[uni[i][j][0]].push_back(i);
      }
    }
  }

  memset(dp, -1, sizeof(dp));
  int res = INF;
  for(int k = 0; k < 100000; k++){
    for(int i = 0; i < rt[x].size(); i++){
      res = min(res, check(rt[x][i], x, !k));
    }
    memset(st, 0, sizeof(st));
    if(k == 0
  }
  cout << (res == INF ? -1 : res);
  return 0;

}


#include <iostream>
#include <cstring>
#include <deque>
#include <vector>
using namespace std;

const int INF = 1000000000;
const int N = 105;
int n, m, x, y, r, s[N], t[N], d[N][N] = {}, dp[N][N], st[N][N];
vector<int> adj[N], uni[N][N], seq[N];

int check(int i, int v){
  if(v == y) return 1;
  if(st[i][v] == 1) return INF;
  if(st[i][v] == 2) return dp[i][v];
  st[i][v] = 1;
  for(int k = 0; k < adj[v].size(); k++){
    if(d[s[i]][v] + d[adj[v][k]][t[i]] + 1 == d[s[i]][t[i]]){
      dp[i][v] = max(dp[i][v], check(i, adj[v][k]));
    }
  }
  if(dp[i][v] < 0) dp[i][v] = INF;
  for(int j = 0; j < r; j++){
    for(int k = 0; k < seq[j].size(); k++){
      if(seq[j][k] == v){
        dp[i][v] = min(dp[i][v], check(j, v) + 1);
      }
    }
  }
  st[i][v] = 2;
  return dp[i][v];
}

int main(){
  for(int i = 0; i < N; i++){
    for(int j = 0; j < N; j++){
      if(i != j) d[i][j] = INF;
    }
  }
  cin >> n >> m >> x >> y;
  x--, y--;
  for(int i = 0; i < m; i++){
    int a, b;
    cin >> a >> b;
    a--, b--;
    adj[a].push_back(b);
    d[a][b] = 1;
  }
  cin >> r;
  for(int i = 0; i < r; i++){
    cin >> s[i] >> t[i];
    s[i]--, t[i]--;
  }

  for(int k = 0; k < n; k++){
    for(int i = 0; i < n; i++){
      for(int j = 0; j < n; j++){
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  for(int i = 0; i < r; i++){
    if(d[s[i]][t[i]] == INF) continue;
    for(int j = 0; j < n; j++){
      if(d[s[i]][j] + d[j][t[i]] == d[s[i]][t[i]]){
        uni[i][d[s[i]][j]].push_back(j);
      }
    }
  }
  for(int i = 0; i < r; i++){
    if(d[s[i]][t[i]] == INF) continue;
    for(int j = 0; j <= d[s[i]][t[i]]; j++){
      if(uni[i][j].size() == 1){
        seq[i].push_back(uni[i][j][0]);
      }
    }
  }

  memset(dp, -1, sizeof(dp));
  int res = INF;
  for(int i = 0; i < r; i++){
    for(int j = 0; j < seq[i].size(); j++){
      if(seq[i][j] == x){
        res = min(res, check(i, x));
      }
    }
  }
  cout << (res == INF ? -1 : res);
  return 0;

}


#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

typedef pair<int,int> pii;
typedef pair<pii,int> ppi;

const int INF = 1000000000;
int n, m, a, b, k, d[105][105], s[105], f[105];
int con[105][105] = {}, vis[105];
vector<int> adj[105], uni[105], use[105][105];
bool st[105][105] = {};
queue<ppi> bq;

int main(){
  cin >> n >> m >> a >> b;
  a--, b--;
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      if(i != j) d[i][j] = INF;
    }
  }
  for(int i = 0; i < m; i++){
    int x, y;
    cin >> x >> y;
    adj[x - 1].push_back(y - 1);
    d[x - 1][y - 1] = 1;
  }
  cin >> k;
  for(int i = 0; i < k; i++){
    cin >> s[i] >> f[i];
    s[i]--, f[i]--;
  }
  for(int x = 0; x < n; x++){
    for(int i = 0; i < n; i++){
      for(int j = 0; j < n; j++){
        d[i][j] = min(d[i][j], d[i][x] + d[x][j]);
      }
    }
  }
  for(int i = 0; i < k; i++){
    for(int j = 0; j < n; j++){
      if(d[s[i]][f[i]] != d[s[i]][j] + d[j][f[i]]) continue;
      use[i][d[s[i]][j]].push_back(j);
      if(j == a) bq.push(ppi(pii(i, a), 0));
    }
    for(int j = 0; j < n; j++){
      if(use[i][j].size() == 1) uni[i].push_back(use[i][j][0]);
    }
  }
  for(int i = 0; i < k; i++){
    for(int j = 0; j < k; j++){
      if(i == j) continue;
      queue<int> q;
      memset(vis, 0, sizeof(vis));
      for(int x = 0; x < uni[j].size(); x++) vis[uni[j][x]] = 2;
      q.push(s[i]);
      while(q.size()){
        int v = q.front();
        q.pop();
        if(vis[v]){
          if(vis[v] == 2){
            con[i][j] = max(con[i][j], d[s[j]][v]);
          }
          continue;
        }
        vis[v] = 1;
        if(v == f[i]){
          con[i][j] = -1;
          break;
        }
        for(int x = 0; x < adj[v].size(); x++){
          int nxt = adj[v][x];
          if(d[s[i]][f[i]] == d[s[i]][nxt] + d[nxt][f[i]]){
            q.push(nxt);
          }
        }
      }
      if(con[i][j] >= 0) con[i][j] = use[j][con[i][j]][0];
    }
  }
  while(bq.size()){
    ppi p = bq.front();
    bq.pop();
    int x = p.first.first, y = p.first.second, z = p.second;
    if(y == b){
      cout << z << '\n';
      return 0;
    }
    if(st[x][y]) continue;
    st[x][y] = 1;
    for(int i = 0; i < k; i++){
      if(con[x][i] < 0) continue;
      if(d[s[x]][con[x][i]] >= d[s[x]][y]){
        bq.push(ppi(pii(i, con[x][i]), z + 1));
      }
    }
  }
  cout << "-1\n";
}


#include <cstdio>
#include <algorithm>
using namespace std;
const int mod = 998244353;
int l[300010], r[300010];
int f[300010], invf[300010], inv[300010];
int c[300010], u[30], v[30];
long long z[30][300010];
void add(long long *b, int p, long long x) {
	while (p < 300010) {
		b[p] += x;
		p += p & -p;
	}
}
long long sum(long long *b, int p) {
	long long res = 0;
	while (p > 0) {
		res += b[p];
		p -= p & -p;
	}
	return res;
}
inline int C(int n, int m) {
	if (n < 0 || m < 0 || m > n) return 0;
	return 1ll * f[n] * invf[m] % mod * invf[n-m] % mod;
}
int go(int L, int R, int p) {
	if (L > R) return 0;
	L = max(L, p);
	long long res = sum(z[p], R) - sum(z[p], L - 1);
	res %= mod;
	if (res < 0) res += mod;
	return res;
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	f[1] = inv[1] = invf[1] = f[0] = invf[0] = 1;
	for (int i = 2; i < 300010; i++) {
		f[i] = f[i-1] * 1ll * i % mod;
		inv[i] = mod - mod / i * 1ll * inv[mod%i] % mod;
		invf[i] = invf[i-1] * 1ll * inv[i] % mod;
	}
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &l[i], &r[i]);
		c[l[i]]++;
		c[r[i]+1]--;
	}
	int t = 0;
	for (int i = 1; i <= n; i++) {
		t += c[i];
		c[i] = t;
		for (int j = 0; j <= 20; j++) {
			if (i >= j) {
				int q = C(c[i], i - j);
				if (q > 0) add(z[j], i, q);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &u[i], &v[i]);
	}
	int ans = 0;
	for (int i = 0; i < 1 << m; i++) {
		int L = 1, R = n, sgn = 1, p = 0;
		for (int j = 0; j < m; j++) {
			if (i >> j & 1) {
				L = max(L, l[u[j]]);
				L = max(L, l[v[j]]);
				R = min(R, r[u[j]]);
				R = min(R, r[v[j]]);
				sgn = -sgn;
				p++;
			}
		}
		ans = ans + sgn * go(L, R, p);
		if (ans < 0) ans += mod;
		if (ans >= mod) ans -= mod;
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;
const int mod = 998244353;
int l[300010], r[300010];
int f[300010], invf[300010], inv[300010];
int c[300010], u[30], v[30];
long long z[30][300010];
void add(long long *b, int p, long long x) {
	while (p < 300010) {
		b[p] += x;
		p += p & -p;
	}
}
long long sum(long long *b, int p) {
	long long res = 0;
	while (p > 0) {
		res += b[p];
		p -= p & -p;
	}
	return res;
}
inline int C(int n, int m) {
	if (n < 0 || m < 0 || m > n) return 0;
	return 1ll * f[n] * invf[m] % mod * invf[n-m] % mod;
}
int go(int L, int R, int p) {
	L = max(L, p);
	if (L > R) return 0;
	long long res = sum(z[p], R) - sum(z[p], L - 1);
	res %= mod;
	if (res < 0) res += mod;
	return res;
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	f[1] = inv[1] = invf[1] = f[0] = invf[0] = 1;
	for (int i = 2; i < 300010; i++) {
		f[i] = f[i-1] * 1ll * i % mod;
		inv[i] = mod - mod / i * 1ll * inv[mod%i] % mod;
		invf[i] = invf[i-1] * 1ll * inv[i] % mod;
	}
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &l[i], &r[i]);
		c[l[i]]++;
		c[r[i]+1]--;
	}
	int t = 0;
	for (int i = 1; i <= n; i++) {
		t += c[i];
		c[i] = t;
		for (int j = 0; j <= 20; j++) {
			if (i >= j && c[i] >= j) {
				int q = C(c[i] - j, i - j);
				if (q > 0) add(z[j], i, q);
			}
		}
	}
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &u[i], &v[i]);
		--u[i]; --v[i];
	}
	int ans = 0;
	for (int i = 0; i < 1 << m; i++) {
		int L = 1, R = n, sgn = 1, p = 0;
		for (int j = 0; j < m; j++) {
			if (i >> j & 1) {
				L = max(L, l[u[j]]);
				L = max(L, l[v[j]]);
				R = min(R, r[u[j]]);
				R = min(R, r[v[j]]);
				sgn = -sgn;
				p++;
			}
		}
		ans = ans + sgn * go(L, R, p);
		if (ans < 0) ans += mod;
		if (ans >= mod) ans -= mod;
	}
	printf("%d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10,mod=998244353;
int inv[maxn],fac[maxn],s[maxn],sum[45][maxn],a[45],b[45],l[maxn],r[maxn],f[maxn];
int qpow(int a,int b) {
	int ans=1;
	while(b) {
		if(b&1)ans=1ll*ans*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return ans;
}
int C(int n,int m) {
	if(m<0||n<m)return 0;
	return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main() {
	int n,m,ans=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		scanf("%d%d",l+i,r+i);
		s[l[i]]++;
		s[r[i]+1]--;
	}
	fac[0]=1;
	for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;
	inv[n]=qpow(fac[n],mod-2);
	for(int i=n-1;i>=0;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	for(int i=0;i<=2*m;i++)
		for(int j=1;j<=n;j++)
			sum[i][j]=(sum[i][j-1]+C(s[j]-i,j-i))%mod;
	for(int i=0;i<m;i++)
		scanf("%d%d",a+i,b+i);
	for(int i=0;i<1<<m;i++) {
		int L=1,R=n,cnt=0,c1=0;
		for(int j=0;j<m;j++)f[a[j]]=f[b[j]]=0;
		for(int j=0;j<m;j++)
			if(i>>j&1) {
				c1^=1;
				if(!f[a[j]])cnt+=(f[a[j]]=1);
				if(!f[b[j]])cnt+=(f[b[j]]=1);
				L=max(L,max(l[a[j]],l[b[j]]));
				R=min(R,min(r[a[j]],r[b[j]]));
			}
		if(L>R)continue;
		if(c1)ans=(0ll+ans-sum[cnt][R]+sum[cnt][L-1]+mod)%mod;
		else ans=(0ll+ans+sum[cnt][R]-sum[cnt][L-1]+mod)%mod;
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10,mod=998244353;
int inv[maxn],fac[maxn],s[maxn],sum[45][maxn],a[45],b[45],l[maxn],r[maxn],f[maxn];
int qpow(int a,int b) {
	int ans=1;
	while(b) {
		if(b&1)ans=1ll*ans*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return ans;
}
int C(int n,int m) {
	if(m<0||n<m)return 0;
	return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main() {
	int n,m,ans=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		scanf("%d%d",l+i,r+i);
		s[l[i]]++;
		s[r[i]+1]--;
	}
	fac[0]=1;
	for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;
	inv[n]=qpow(fac[n],mod-2);
	for(int i=n-1;i>=0;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	for(int i=0;i<=2*m;i++)
		for(int j=1;j<=n;j++)
			sum[i][j]=(sum[i][j-1]+C(s[j]-i,j-i))%mod;
	for(int i=0;i<m;i++)
		scanf("%d%d",a+i,b+i);
	for(int i=0;i<1<<m;i++) {
		int L=1,R=n,cnt=0,c1=0;
		for(int j=0;j<m;j++)f[a[i]]=f[b[i]]=0;
		for(int j=0;j<m;j++)
			if(i>>j&1) {
				c1^=1;
				if(!f[a[j]])cnt+=(f[a[j]]=1);
				if(!f[b[j]])cnt+=(f[b[j]]=1);
				L=max(L,max(l[a[j]],l[b[j]]));
				R=min(R,min(r[a[j]],r[b[j]]));
			}
		if(L>R)continue;
		if(c1)ans=(0ll+ans-sum[cnt][R]+sum[cnt][L-1]+mod)%mod;
		else ans=(0ll+ans+sum[cnt][R]-sum[cnt][L-1]+mod)%mod;
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(i=(l);i<=(r);++i)
#define per(i,l,r) for(i=(l);i>=(r);--i)
#define REP(i,l,r) for(i=(l);i< (r);++i)
#define PER(i,l,r) for(i=(l);i> (r);--i)
typedef long long ll;
const int N=300005,M=25;
const ll p=998244353ll;
inline ll expo(ll a,int b=998244351){
	ll c=1ll;
	while(b){
		if(b&1)c=c*a%p;
		b>>=1; a=a*a%p;
	}
	return c;
}
ll FAC[N],IFA[N];
inline ll comb(int a,int b){
	return (b<0||b>a)?0ll:(FAC[a]*(IFA[b]*IFA[a-b]%p)%p);
}
//==============================================================================================
vector<int>L[N],R[N];
int I[N],C[M<<1];
ll E[M],ss;
inline void dfs(int m,ll a,int w=1){
	if(m){
		dfs(m-1,a,w);
		if((ss&E[m])==E[m])dfs(m-1,a&(~E[m]),-w);
	}else{
		//printf("a=%lld __builtin_popcountll=%d\n",a,__builtin_popcountll(a));
		C[__builtin_popcountll(a)]+=w;
	}
}
int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);

	int n,m,i,a,b,c=0,f=0,c0=0,c1=0;
	ll ans=0ll,s1=0ll;
	vector<int>::iterator d;
	scanf("%d%d",&n,&m);
	FAC[0]=1ll;
	rep(i,1,n)FAC[i  ]=FAC[i-1]*i%p;
	IFA[n]=expo(FAC[n]);
	per(i,n,1)IFA[i-1]=IFA[i  ]*i%p;
	rep(i,1,n){
		scanf("%d%d",&a,&b);
		L[a].push_back(i);
		R[b].push_back(i);
	}
	rep(i,1,m){
		scanf("%d%d",&a,&b);
		if(!I[a])I[a]=++c;
		if(!I[b])I[b]=++c;
		E[i]=(1ll<<I[a])|(1ll<<I[b]);
	}
	C[0]=1;
	rep(i,1,n){
		//printf("\n\n\ni=%d\n",i);
		for(d=L[i].begin();d!=L[i].end();++d){
			a=*d;
			if(I[a]){++c1;f=1;s1|=1ll<<I[a];}
			++c0;
		}
		if(f){
			//Calculate!
			rep(a,0,c1)C[a]=0;
			//printf("CALC\n");
			ss=s1;
			dfs(m,s1);
			f=0;
		}
		//Get the answer
		//printf("CNT0=%d CNT1=%d CNT2=%d i=%d c0=%d\n",C[0],C[1],C[2],i,c0);
		rep(a,0,c1)ans=(ans+(C[c1-a]+p)*comb(c0-a,i-a))%p;
		//printf("ans=%lld\n",ans);
		for(d=R[i].begin();d!=R[i].end();++d){
			a=*d;
			if(I[a]){--c1;f=1;s1^=1ll<<I[a];}
			--c0;
		}
	}
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std ;
#define int long long
int read(){
	int ans = 0 , f = 1  ; char ch = getchar() ;
	while(ch < '0' || ch > '9' ){if(f == '-' ) f = -1 ; ch = getchar() ; }
	while(ch >= '0' && ch <= '9' ) ans  = (ans * 10) + ch - '0' , ch = getchar() ;
	return ans * f ;
}
const int maxn = 500000 ;
const int mod = 998244353 ;
int fac[maxn] , infac[maxn] ;
int sum[maxn][41] ;
int ksm(int a,int b){
	int sum = 1 ;
	while(b){
		if(b & 1) sum = sum * a % mod ;
		a = a * a % mod ;
		b >>= 1 ;
	}
	return sum ;
}
int n , m , ans ;
void pre(){
	fac[0] = 1 ;
	for(int i = 1 ; i <= n ; i++) fac[i] = fac[i - 1] * i % mod ;
	infac[n] = ksm(fac[n] , mod - 2) ;
	for(int i = n - 1 ; i >= 0 ; i--)
		infac[i] = infac[i + 1] * (i + 1) % mod ;
	return ;
}
int C(int n , int m){
	if(n < 0 || m < 0 || m > n) return 0 ;
	return fac[n] * infac[m] % mod * infac[n - m] % mod ;
}
int a[41] , b[41] , l[maxn] , r[maxn];
int cf[maxn] , cnt[maxn];
int len[2000000] ;
set<int> ss ;
signed main(){
	n = read() , m = read() ;
	for(int i = 1 ; i < (1 << m) ; i++) len[i] = len[i & (i - 1)] + 1 ;
//	for(int i = 1 ; i < (1 << m) ; i++)
//		printf("len[%lld] : %lld \n" , i , len[i] ) ;
 	pre() ;
	for(int i = 1 ; i <= n ; i++){
		l[i] = read() , r[i] = read() ;
		cf[l[i]]++ , cf[r[i] + 1]-- ;
//		printf("l[%lld] : %lld r[%lld] : %lld \n" , i , l[i] , i , r[i]) ;
	}
	int temp = 0 ;
	for(int i = 1 ; i <= n ; i++){
//		printf("cf[%lld] : %lld \n" , i , cf[i]) ;
		temp += cf[i] ; cnt[i] = temp ; //printf("cnt[%lld] : %lld \n" , i , cnt[i]) ;
	}
	for(int i = 1 ; i <= m ; i++)
		a[i] = read() , b[i] = read() ;
	for(int i = 0 ; i <= 40 ; i++)
		for(int j = 1 ; j <= n ; j++)
			sum[j][i] = (sum[j - 1][i] + C(cnt[j] - i , j - i)) % mod ;
//	for(int i = 1 ; i <= n ; i++)
//		printf("sum[%lld][0] : %lld \n" , i , sum[i][1]) ;
	for(int s = 0 ; s < (1 << m) ; s++){
		ss.clear() ;
		int ll = 1 , rr = n ;
		for(int j = 1 ; j <= m ; j++){
			if((1 << (j - 1)) & s){
				ll = max(ll , l[a[j]]) , rr = min(rr , r[a[j]]) , ss.insert(a[j]) ;
				ll = max(ll , l[b[j]]) , rr = min(rr , r[b[j]]) , ss.insert(b[j]) ;
			}
		}
		if(ll > rr) continue ;
		int add = sum[rr][ss.size()] - sum[ll - 1][ss.size()] ;
		ans = (ans + ((len[s] & 1) ? -1 : 1) * add % mod + mod) % mod ;
		ans = (ans + mod) % mod ;
	}
	cout << ans ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i)
#define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i)

mt19937 Rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

template <typename T>
inline void chkmax(T &x, T y) { if (x < y) x = y; }

template <typename T>
inline void chkmin(T &x, T y) { if (x > y) x = y; }

inline int read() {
  #define nc getchar()
  int x = 0;
  char c = nc;
  while (c < 48) c = nc;
  while (c > 47) x = x * 10 + (c ^ 48), c = nc;
  return x;
  #undef nc
}

typedef long long ll;
typedef pair <int, int> pii;
const int maxn = 3e5 + 10;

const int P = 998244353;

int Inc(int x, int y) {
  return x + y < P ? x + y : x + y - P;
}

int Dec(int x, int y) {
  return x < y ? x - y + P : x - y;
}

void Add(int &x, int y) {
  x += y;
  if (x >= P) x -= P;
}

void Sub(int &x, int y) {
  x -= y;
  if (x < 0) x += P;
}

int inv[maxn], fac[maxn], ifac[maxn];

int binom(int n, int m) {
  return n < m ? 0 : 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

void init() {
  fac[0] = ifac[0] = 1;
  inv[1] = fac[1] = ifac[1] = 1;
  rep(i, 2, maxn - 1) {
    inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
    fac[i] = 1ll * i * fac[i - 1] % P;
    ifac[i] = 1ll * inv[i] * ifac[i - 1] % P;
  }
}

int n, m, cnt[maxn], val[41][maxn];

struct line {
  int l, r;
} A[maxn], con[20];

void solve() {
  init();
  cin >> n >> m;
  rep(i,1,n){
    int l=read(),r=read();
    A[i]={l,r},cnt[l]++,cnt[r+1]--;
  }
  rep(i,0,m-1)con[i].l=read(),con[i].r=read();
  rep(i,1,n){
    cnt[i]+=cnt[i-1];
    rep(j,0,40)val[j][i]=Inc(val[j][i-1],(cnt[i]>=j&&i>=j?binom(cnt[i]-j,i-j):0));
  }
  int ans=0;
  static int vis[maxn];
  memset(vis, -1, sizeof vis);
  rep(S,0,(1<<m)-1){
    int l=1,r=n,sum=0;
    rep(i,0,m-1)if(S>>i&1){
      int lef=con[i].l,rig=con[i].r;
      if(vis[lef]!=S)vis[lef]=S,sum++;
      if(vis[rig]!=S)vis[rig]=S,sum++;
      chkmax(l,max(A[lef].l,A[rig].l));
      chkmin(r,min(A[lef].r,A[rig].r));
    }
    if(l>r)continue;
    ans=(ans+1ll*(__builtin_popcount(S)%2==1?-1:1)*(val[sum][r]-val[sum][l-1]+P)+P+P)%P;
  }
  cout << ans << endl;
}

signed main() {
//  int T = read();
//  while (T--) solve();
  solve();
  return 0;
}


/* by Natsu Kinmoe */
#include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(),(x).end()
#define loop(i,n) for(int i=0;i<(n);i++)
#define cont(i,n) for(int i=1;i<=(n);i++)
#define circ(i,a,b) for(int i=(a);i<=(b);i++)
#define range(i,a,b,c) for(int i=(a);((c)>0?i<=(b):i>=(b));i+=(c))
#define foreach(it,v) for(__typeof((v).begin()) it=(v).begin(),_e_D_=(v).end();it!=_e_D_;it++)
#define y0 y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1 y1II11II11III11I1III11II111IIII1II1I1
#define pub push_back
#define pob pop_back
#define mak make_pair

typedef long long ll;
typedef long double lf;
const int Inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
/* Source code starts here */

const int jt=998244353;
int n,m;
int jc[1<<19],fjc[1<<19];
int l[1<<19],r[1<<19];
int a[44],b[44];
int xf[1<<19],cs[1<<19][44];
int lgl[1<<19];

int ksmii(int a,int b){
	if(!b)return 1;
	int x=ksmii(a,b>>1);
	x=1ll*x*x%jt;
	if(b&1)x=1ll*x*a%jt;
	return x;
}

int inline C(int a,int b){
	if(b<0||a<b)return 0;
	return 1ll*jc[a]*fjc[b]%jt*fjc[a-b]%jt;
}

int main(){
	jc[0]=1;cont(i,500000)jc[i]=1ll*jc[i-1]*i%jt;
	fjc[500000]=ksmii(jc[500000],jt-2);range(i,500000,1,-1)fjc[i-1]=1ll*fjc[i]*i%jt;
	scanf("%d%d",&n,&m);
	cont(i,n){
		scanf("%d%d",l+i,r+i);
		xf[l[i]]++;xf[r[i]+1]--;
	}
	cont(i,n){
		xf[i]+=xf[i-1];
		loop(j,m<<1|1){
			cs[i][j]=(cs[i-1][j]+C(xf[i]-j,i-j))%jt;
		}
	}
	loop(i,m)scanf("%d%d",a+i,b+i);
	int ans=0;
	loop(i,1<<m){
		int ls=1,rs=n,ts=0;
		loop(j,m){
			if(!((i>>j)&1))continue;
			if(lgl[a[j]]!=i){
				lgl[a[j]]=i;
				ts++;
			}
			if(lgl[b[j]]!=i){
				lgl[b[j]]=i;
				ts++;
			}
			ls=max(ls,max(l[a[j]],l[b[j]]));
			rs=min(rs,min(r[a[j]],r[b[j]]));
		}
		if(ls>rs)continue;
		int res=(cs[rs][ts]-cs[ls-1][ts]+jt)%jt;
		if(__builtin_popcount(i)%2)ans=(ans-res+jt)%jt;
		else ans=(ans+res)%jt;
	}
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

const int mod = 998244353;

int qp(int x, int n) { return n ? 1LL * qp(1LL * x * x % mod, n >> 1) * (n & 1 ? x : 1) % mod : 1; }
int inv(int x) { return qp(x, mod - 2); }

const int mxn = 3e5 + 5, mxm = 25;
int n, m, l[mxn], r[mxn], c[mxn], e[mxm][2], s[mxm * 2][mxn];
int fac[mxn], ifac[mxn];
bool vis[mxn];

int comb(int n, int m) {
	if (m < 0 || m > n) return 0;
	return 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main() {
	rep(i, mxn) fac[i] = i ? 1LL * i * fac[i - 1] % mod : 1;
	ifac[mxn - 1] = inv(fac[mxn - 1]);
	for (int i = mxn - 1; i; -- i) ifac[i - 1] = 1LL * i * ifac[i] % mod;
	scanf("%d %d", &n, &m);
	rep(i, n) scanf("%d %d", &l[i], &r[i]), c[l[i]] ++, c[r[i] + 1] --;
	rep(i, mxn) if (i) c[i] += c[i - 1];
	vector <int> vi;
	rep(i, m) scanf("%d %d", &e[i][0], &e[i][1]), -- e[i][0], -- e[i][1], vi.pb(e[i][0]), vi.pb(e[i][1]);
	sort(vi.begin(), vi.end()); vi.erase(unique(vi.begin(), vi.end()), vi.end());
	rep(sz, mxm * 2) rep(i, mxn) s[sz][i] = ((i ? s[sz][i - 1] : 0) + comb(c[i] - sz, i - sz)) % mod;
	vector <int> sepr; sepr.pb(1); sepr.pb(n + 1);
	rep(i, m) sepr.pb(l[e[i][0]]), sepr.pb(r[e[i][0]] + 1), sepr.pb(l[e[i][1]]), sepr.pb(r[e[i][1]] + 1);
	sort(sepr.begin(), sepr.end()); sepr.erase(unique(sepr.begin(), sepr.end()), sepr.end());
	int ans = 0;
	rep(i, sepr.size() - 1) {
		int L = sepr[i], R = sepr[i + 1] - 1;
		int O = 0;
		rep(j, m) if (l[e[j][0]] <= L && R <= r[e[j][0]] && l[e[j][1]] <= L && R <= r[e[j][1]]) O |= 1 << j;
		for (int mask = O; mask; mask = (mask - 1) & O) {
			int cnt = 0;
			rep(j, vi.size()) vis[vi[j]] = 0;
			rep(j, m) if (mask >> j & 1) {
				if (!vis[e[j][0]]) cnt ++, vis[e[j][0]] = 1;
				if (!vis[e[j][1]]) cnt ++, vis[e[j][1]] = 1;
			}
			int cur = (s[cnt][R] - (L ? s[cnt][L - 1] : 0) + mod) % mod;
			if (__builtin_popcount(mask) & 1) ans = (ans + mod - cur) % mod; else ans = (ans + cur) % mod;
		}
		ans = (ans + (s[0][R] - (L ? s[0][L - 1] : 0) + mod) % mod) % mod;
	}
	printf("%d\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

template <int mxn> struct UF {
	int fa[mxn], sz[mxn];
	UF() { rep(i, mxn) fa[i] = i, sz[i] = 1; }
	int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
	void merge(int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return ;
		if (sz[x] < sz[y]) fa[x] = y, sz[y] += sz[x];
		else fa[y] = x, sz[x] += sz[y];
	}
};

const int mod = 998244353;

int qp(int x, int n) { return n ? 1LL * qp(1LL * x * x % mod, n >> 1) * (n & 1 ? x : 1) % mod : 1; }
int inv(int x) { return qp(x, mod - 2); }

vector <int> conv(const vector <int> &f, const vector <int> &g) {
	vector <int> h(f.size() + g.size() - 1);
	rep(i, f.size()) rep(j, g.size()) (h[i + j] += 1LL * f[i] * g[j] % mod) %= mod;
	return h;
}

const int mxn = 3e5 + 5, mxm = 25;
int n, m, l[mxn], r[mxn], c[mxn], e[mxm][2];
bool impo[mxn];
int vi[mxm * 2], isz, idv[mxn];
ll masks[mxm * 2];
vector <ll> vmasks;
int fac[mxn], ifac[mxn];
UF <mxm * 2> uf;
set <ll> bad;

int comb(int n, int m) {
	if (m < 0 || m > n) return 0;
	return 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main() {
	rep(i, mxn) fac[i] = i ? 1LL * i * fac[i - 1] % mod : 1;
	ifac[mxn - 1] = inv(fac[mxn - 1]);
	for (int i = mxn - 1; i; -- i) ifac[i - 1] = 1LL * i * ifac[i] % mod;
	scanf("%d %d", &n, &m);
	rep(i, n) scanf("%d %d", &l[i], &r[i]);
	rep(i, m) { scanf("%d %d", &e[i][0], &e[i][1]); -- e[i][0]; -- e[i][1]; impo[e[i][0]] = impo[e[i][1]] = 1; }
	rep(i, n) if (impo[i]) idv[i] = isz, vi[isz ++] = i;
	rep(i, m) { int u = e[i][0], v = e[i][1]; uf.merge(idv[u], idv[v]); }
	rep(i, isz) masks[uf.find(i)] |= 1LL << i;
	rep(i, isz) if (uf.find(i) == i) vmasks.pb(masks[i]);
	rep(i, vmasks.size()) for (ll sub = vmasks[i]; sub; sub = (sub - 1) & vmasks[i])
		rep(j, m) if ((sub >> idv[e[j][0]] & 1) && (sub >> idv[e[j][1]] & 1)) bad.insert(sub);
	rep(i, n) if (!impo[i]) c[l[i]] ++, c[r[i] + 1] --;
	rep(i, mxn) if (i) c[i] += c[i - 1];
	vector <int> sepr;
	rep(i, n) if (impo[i]) sepr.pb(l[i]), sepr.pb(r[i] + 1);
	sepr.pb(1); sepr.pb(n + 1);
	sort(sepr.begin(), sepr.end());
	sepr.erase(unique(sepr.begin(), sepr.end()), sepr.end());
	int ans = 0;
	rep(i, sepr.size() - 1) {
		int L = sepr[i], R = sepr[i + 1] - 1;
		ll mask = 0;
		rep(j, isz) if (l[vi[j]] <= L && R <= r[vi[j]]) mask |= 1LL << j;
		vector <int> f(1);
		f[0] = 1;
		rep(j, vmasks.size()) {
			ll nmask = mask & vmasks[j];
			vector <int> g(__builtin_popcountll(nmask) + 1);
			g[0] = 1;
			for (ll sub = nmask; sub; sub = (sub - 1) & nmask) if (bad.find(sub) == bad.end()) g[__builtin_popcountll(sub)] ++;
			f = conv(f, g);
		}
		rep(j, f.size()) {
			for (int k = L; k <= R; ++ k) {
				(ans += 1LL * f[j] * comb(c[k], k - j) % mod) %= mod;
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}