#include<bits/stdc++.h>
using namespace std;
void next_low(int &low,int a[],int n,int &extreme_count,int &mid_count,int start,int mid)
{
    low++;
    while(low<n && a[low]!=start)
    {
        if(a[low]==start)
        {
            extreme_count++;
        }
        else if(a[low]==mid)
        {
            mid_count--;
        }
        low++;
    }
    if(a[low]==start)
    {
        extreme_count++;
    }
}
void next_high(int &high,int a[],int n,int &extreme_count,int &mid_count,int start,int mid)
{
    high--;
    while(high>-1 && a[high]!=start)
    {
        if(a[high]==start)
        {
            extreme_count++;
        }
        else if(a[high]==mid)
        {
            mid_count--;
        }
        high--;
    }
    if(a[high]==start)
    {
        extreme_count++;
    }
}
int three_block_length(int start,int mid,int freq[],int a[],int n)
{
    //cout<<"tbl\n";
    if(start==mid)
        return freq[start];
    if(freq[start]==0)
    {
        return freq[mid];
    }
    if(freq[mid]==0)
    {
        return freq[start];
    }
    int low=-1;
    int high=n;
    int mid_count=freq[mid];
    int extreme_count=0;
    /*if(a[low]==start)
    {
        extreme_count++;
    }
    if(a[low]==mid)
    {
        mid_count--;
    }
    if(a[high]==start)
    {
        extreme_count++;
    }
    if(a[high]==mid)
    {
        mid_count--;
    }*/
    int maxLength=-1;//extreme_count+mid_count;
    //cout<<low<<endl;
    //cout<<high<<endl;
    //cout<<extreme_count<<endl;
    //cout<<mid_count<<endl;
    while(low<high)
    {
        //cout<<"low!=high\n";
        // make low point to next a[low] = start and decrement mid_count acc.
        next_low(low,a,n,extreme_count,mid_count,start,mid);
        next_high(high,a,n,extreme_count,mid_count,start,mid);
        //cout<<"low - "<<low<<endl;
        //cout<<"high - "<<high<<endl;
        //cout<<"extreme - "<<extreme_count<<endl;
        //cout<<"mid - "<<mid_count<<endl;
        if(low<high)
        {
            //update(maxLength,extreme_count,mid_count);
            maxLength=max(maxLength,extreme_count+mid_count);
        }
        else
        {
            return maxLength;
        }
    }
}
void set_freq(int f[],int n,int a[])
{
    for(int i=1;i<=200;i++)
        f[i]=0;
    for(int i=0;i<n;i++)
    {
        f[a[i]]++;
    }
}
int main()
{
    int t;
    cin>>t;
    int n;
    while(t--)
    {
        cin>>n;
        int a[n];
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        int freq[201];
        set_freq(freq,n,a);
        int maxLength=0;
        //cout<<"loop starts\n";
        for(int extreme_number=1;extreme_number<=200;extreme_number++)
        {
            for(int mid_number=1;mid_number<=200;mid_number++)
            {
                maxLength=max(maxLength,three_block_length(extreme_number,mid_number,freq,a,n));
            }
        }
        //cout<<"loop ends\n";
        //cout<<"done\n";
        //cout<<three_block_length(1,2,freq,a,n)<<endl;
        cout<<maxLength<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
void next_low(int &low,int a[],int n,int &extreme_count,int &mid_count,int start,int mid)
{
    low++;
    while(low<n && a[low]!=start)
    {
        if(a[low]==start)
        {
            extreme_count++;
        }
        else if(a[low]==mid)
        {
            mid_count--;
        }
        low++;
    }
    if(a[low]==start)
    {
        extreme_count++;
    }
}
void next_high(int &high,int a[],int n,int &extreme_count,int &mid_count,int start,int mid)
{
    high--;
    while(high>-1 && a[high]!=start)
    {
        if(a[high]==start)
        {
            extreme_count++;
        }
        else if(a[high]==mid)
        {
            mid_count--;
        }
        high--;
    }
    if(a[high]==start)
    {
        extreme_count++;
    }
}
int getFreqMid(vector< vector<int> > occ,int start,int index,int f[][201],int mid)
{
    int start_index=index;
    int end_index=occ[start][occ[start].size()-1-index];
    return f[end_index][mid]-f[start_index][mid];
}
int three_block_length(int start,int mid,int freq[][201],int a[],int n,vector< vector<int> > occ)
{
    if(start==mid)
        return freq[n-1][start];
    if(freq[n-1][start]==0)
    {
        return freq[n-1][mid];
    }
    if(freq[n-1][mid]==0)
    {
        return freq[n-1][start];
    }
    int maxLength=0;
    for(int i=0;i<occ[start].size()/2;i++)
    {
        maxLength=max(maxLength,2*(i+1)+getFreqMid(occ,start,i,freq,mid));
    }
    for(int i=0;i<occ[mid].size()/2;i++)
    {
        maxLength=max(maxLength,2*(i+1)+getFreqMid(occ,mid,i,freq,start));
    }
    return maxLength;
}
void set_freq(int f[][201],int n,int a[],int &maxL)
{
    for(int i=1;i<=200;i++)
    {
        f[0][i]=a[0]==i?1:0;
        maxL=max(maxL,f[0][i]);
    }
    for(int i=1;i<=200;i++)
    {
        for(int j=1;j<n;j++)
        {
            f[j][i]=a[j]==i?f[j-1][i]+1:f[j-1][i];
            maxL=max(maxL,f[j][i]);
            //cout<<"setted\n";
        }
    }
}
int main()
{
    int t;
    cin>>t;
    int n;
    while(t--)
    {
        cin>>n;
        int a[n];
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        int freq[n][201];
        int maxLength=0;
        set_freq(freq,n,a,maxLength);
        vector< vector<int> > occ(201);
        for(int i=0;i<n;i++)
        {
            occ[a[i]].push_back(i);
            //maxLength=max(maxLength,occ[a[i]]);
        }
        for(int extreme_number=1;extreme_number<201;extreme_number++)
        {
            if(freq[n-1][extreme_number]>=2)
            {
                for(int mid_number=extreme_number;mid_number<201;mid_number++)
                {
                    maxLength=max(maxLength,three_block_length(extreme_number,mid_number,freq,a,n,occ));
                }
            }

        }
        cout<<maxLength<<"\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#define pb          emplace_back
#define ll          long long
#define fi          first
#define se          second
#define mp          make_pair
//#define int         int64_t

using namespace std;

const int N = int(1e2) + 7;
const int inf = int(1e6);
typedef pair<int, int> pii;

int x[N], y[N], u, v, n, m, s, t, k;
int d[N][N], f[N][N], must[N][N], dis[N], deg[N][N];
bool del[N][N];
queue<int> q;
vector<int> adj[N];
vector<pii> rg[N][N];

bool can(int s, int t, int x) {
    return d[s][x] + d[x][t] == d[s][t];
}

bool bfs(int s, int t, int x) {
    if(!can(s, t, x)) return 1;
    if(x == s || x == t) return 0;
    fill(dis, dis + n + 1, inf);
    dis[s] = 0;
    for(q.push(s); q.size(); q.pop()) {
        u = q.front();
        for(int& v: adj[u]) {
            if(v == x) continue;
            if(dis[v] > dis[u] + 1) {
                dis[v] = dis[u] + 1;
                q.push(v);
            }
        }
    }
    return dis[t] == d[s][t];
}

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    #define Task        "test"
    if(fopen(Task".inp", "r")) {
        freopen(Task".inp", "r", stdin);
        freopen(Task".out", "w", stdout);
    }
    cin >> n >> m >> s >> t;
    for(int i = 1; i <= n; ++i) {
        fill(d[i], d[i] + n + 1, inf);
        d[i][i] = 0;
    }
    for(int i = 0; i < m; ++i) {
        cin >> u >> v;
        adj[u].pb(v);
        d[u][v] = 1;
    }
    for(int x = 1; x <= n; ++x) {
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= n; ++j) {
                d[i][j] = min(d[i][j], d[i][x] + d[x][j]);
            }
        }
    }
    cin >> k;
    for(int i = 1; i <= k; ++i) {
        cin >> x[i] >> y[i];
        for(int j = 1; j <= n; ++j)
            must[i][j] = bfs(x[i], y[i], j) ^ 1;
    }
    deque<pii> dp;
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= k; ++j) {
            for(int& v: adj[i]) {
                if(d[x[j]][i] + 1 + d[v][y[j]] == d[x[j]][y[j]]) { /// (i, j) -> (v, j)
                    ++deg[i][j];
                    rg[v][j].pb(i, j);
                    //cout << i << ' ' << j << ' ' << v << ' ' << j << '\n';
                }
            }
            f[i][j] = inf;
            if(t == i && d[x[j]][y[j]] < inf) dp.push_back({i, j}), f[i][j] = 1;
        }
    }
    //cout << '\n';
    int res = inf;
    while(dp.size()) {
        tie(u, v) = dp.front(); dp.pop_front();
        if(del[u][v]) continue;
        if(u == s && must[v][u]) res = min(res, f[u][v]);
        del[u][v] = 1;
        //cout << u << ' ' << v << ' ' << f[u][v] << '\n';
        if(must[v][u]) {
            for(int i = 1; i <= k; ++i) {
                if(i != v && can(x[i], y[i], v)) {
                    if(f[u][i] > f[u][v] + 1) {
                        f[u][i] = f[u][v] + 1;
                        //cout << u << ' ' << i << ' ' << u << ' ' << v << '\n';
                        dp.push_back({u, i});
                    }
                }
            }
        }
        for(pii& a: rg[u][v]) {
            //cout << u << ' ' << v << ' ' << a.fi << ' ' << a.se << '\n';
            if(--deg[a.fi][a.se] == 0 && f[a.fi][a.se] > f[u][v]) {
                f[a.fi][a.se] = f[u][v];
                dp.push_front({a.fi, a.se});
            }
        }
    }
    if(res >= inf) res = -1;
    cout << res;
}


#include <bits/stdc++.h>

const int N = 100;
const int M = 2;
const int INF = 1e9;
const int MODS[M] = {1000000007, 1000000009};

struct Hash {
  Hash(int v = 0) {
    for (size_t i = 0; i < M; ++i) {
      rs[i] = v % MODS[i];
    }
  }

  Hash &operator+=(const Hash &o) {
    for (size_t i = 0; i < M; ++i) {
      rs[i] += o.rs[i];
      if (rs[i] >= MODS[i]) {
        rs[i] -= MODS[i];
      }
    }
    return *this;
  }

  int rs[sizeof(MODS)];
};

bool cmp(const Hash &a, const Hash &b, const Hash &c) {
  for (size_t i = 0; i < M; ++i) {
    if (1LL * a.rs[i] * b.rs[i] % MODS[i] != c.rs[i]) {
      return false;
    }
  }
  return true;
}

int n, m, dist[N][N], s[N], t[N], deg[N][N], dp[N][N];
bool graph[N][N], on[N][N], must[N][N], visited[N][N];
Hash ways[N][N];

void sssp(int s, int dist[N], Hash ways[N]) {
  for (int i = 0; i < n; ++i) {
    dist[i] = n;
  }
  memset(ways, 0, sizeof(*ways) * n);
  dist[s] = 0;
  ways[s] = 1;
  std::priority_queue<std::pair<long long, int>> queue;
  queue.emplace(0, s);
  while (!queue.empty()) {
    auto t = queue.top();
    queue.pop();
    if (t.first == -dist[t.second]) {
      int u = t.second;
      for (int v = 0; v < n; ++v) {
        if (graph[u][v]) {
          if (dist[u] + 1 < dist[v]) {
            dist[v] = dist[u] + 1;
            ways[v] = 0;
            queue.emplace(-dist[v], v);
          }
          if (dist[u] + 1 == dist[v]) {
            ways[v] += ways[u];
          }
        }
      }
    }
  }
}

int main() {
  int src, dst;
  scanf("%d%d%d%d", &n, &m, &src, &dst);
  src--, dst--;
  for (int i = 0, u, v; i < m; ++i) {
    scanf("%d%d", &u, &v);
    u--, v--;
    graph[u][v] = true;
  }
  for (int s = 0; s < n; ++s) {
    sssp(s, dist[s], ways[s]);
  }
  scanf("%d", &m);
  // dp(bus, u) -> min{max_{u->v} dp(bus, v), min_{bus'} dp(bus', u) + 1}
  // (u, bus) -> (loc, bus') if loc must be on bus'
  for (int i = 0; i < m; ++ i) {
    for (int v = 0; v < n; ++ v) {
      dp[i][v] = INF;
    }
  }
  std::deque<std::pair<int, int>> queue;
  for (int i = 0; i < m; ++ i) {
    scanf("%d%d", s + i, t + i);
    s[i] --, t[i] --;
    if (dist[s[i]][t[i]] < n) {
      // for (int u = 0; u < n; ++ u) {
      //   if (dst[s[i]][u] + dst[u][t[i]] == dst[s[i]][t[i]]) {
      //     for (int v = 0; v < n; ++ v) {
      //       deg[i][u] += graph[u][v] && dst[s[i]][t]
      //     }
      //   }
      // }
      for (int v = 0; v < n; ++ v) {
        on[i][v] = dist[s[i]][v] + dist[v][t[i]] == dist[s[i]][t[i]];
        must[i][v] = on[i][v] && cmp(ways[s[i]][v], ways[v][t[i]], ways[s[i]][t[i]]);
      }
      for (int u = 0; u < n; ++ u) {
        if (on[i][u]) {
          for (int v = 0; v < n; ++ v) {
            deg[i][u] += graph[u][v] && dist[s[i]][u] + 1 + dist[v][t[i]];
          }
        }
      }
      if (must[i][dst]) {
        dp[i][dst] = 1;
        queue.emplace_back(i, dst);
      }
    }
  }
  while (!queue.empty()) {
    auto i = queue.front().first;
    auto v = queue.front().second;
    queue.pop_front();
    if (visited[i][v]) {
      continue;
    }
    visited[i][v] = true;
    if (must[i][v]) {
      for (int j = 0; j < m; ++ j) {
        if (on[j][v] && dp[j][v] > dp[i][v] + 1) {
          dp[j][v] = dp[i][v] + 1;
          queue.emplace_back(j, v);
        }
      }
    }
    for (int u = 0; u < n; ++ u) {
      if (graph[u][v] && dist[s[i]][u] + 1 + dist[v][t[i]] == dist[s[i]][t[i]]) {
        deg[i][u] --;
        if (deg[i][u] == 0 && dp[i][u] > dp[i][v]) {
          dp[i][u] = dp[i][v];
          queue.emplace_front(i, u);
        }
      }
    }
  }
  int result = INF;
  for (int i = 0; i < m; ++ i) {
    if (must[i][src]) {
      result = std::min(result, dp[i][src]);
    }
  }
  printf("%d\n", result < INF ? result : -1);
}


#include <bits/stdc++.h>

const int N = 100;
const int M = 2;
const int INF = 1e9;
const int MODS[M] = {1000000007, 1000000009};

struct Hash {
  Hash(int v = 0) {
    for (size_t i = 0; i < M; ++i) {
      rs[i] = v % MODS[i];
    }
  }

  Hash &operator+=(const Hash &o) {
    for (size_t i = 0; i < M; ++i) {
      rs[i] += o.rs[i];
      if (rs[i] >= MODS[i]) {
        rs[i] -= MODS[i];
      }
    }
    return *this;
  }

  int rs[sizeof(MODS)];
};

bool cmp(const Hash &a, const Hash &b, const Hash &c) {
  for (size_t i = 0; i < M; ++i) {
    if (1LL * a.rs[i] * b.rs[i] % MODS[i] != c.rs[i]) {
      return false;
    }
  }
  return true;
}

int n, m, dist[N][N], s[N], t[N], deg[N][N], dp[N][N];
bool graph[N][N], on[N][N], must[N][N], visited[N][N];
Hash ways[N][N];

void sssp(int s, int dist[N], Hash ways[N]) {
  for (int i = 0; i < n; ++i) {
    dist[i] = INF;
  }
  memset(ways, 0, sizeof(*ways) * n);
  dist[s] = 0;
  ways[s] = 1;
  std::priority_queue<std::pair<long long, int>> queue;
  queue.emplace(0, s);
  while (!queue.empty()) {
    auto t = queue.top();
    queue.pop();
    if (t.first == -dist[t.second]) {
      int u = t.second;
      for (int v = 0; v < n; ++v) {
        if (graph[u][v]) {
          if (dist[u] + 1 < dist[v]) {
            dist[v] = dist[u] + 1;
            ways[v] = 0;
            queue.emplace(-dist[v], v);
          }
          if (dist[u] + 1 == dist[v]) {
            ways[v] += ways[u];
          }
        }
      }
    }
  }
}

int main() {
  int src, dst;
  scanf("%d%d%d%d", &n, &m, &src, &dst);
  src--, dst--;
  for (int i = 0, u, v; i < m; ++i) {
    scanf("%d%d", &u, &v);
    u--, v--;
    graph[u][v] = true;
  }
  for (int s = 0; s < n; ++s) {
    sssp(s, dist[s], ways[s]);
  }
  scanf("%d", &m);
  for (int i = 0; i < m; ++i) {
    for (int v = 0; v < n; ++v) {
      dp[i][v] = INF;
    }
  }
  std::deque<std::pair<int, int>> queue;
  for (int i = 0; i < m; ++i) {
    scanf("%d%d", s + i, t + i);
    s[i]--, t[i]--;
    if (dist[s[i]][t[i]] < INF) {
      for (int v = 0; v < n; ++v) {
        on[i][v] = dist[s[i]][v] + dist[v][t[i]] == dist[s[i]][t[i]];
        must[i][v] =
            on[i][v] && cmp(ways[s[i]][v], ways[v][t[i]], ways[s[i]][t[i]]);
      }
      for (int u = 0; u < n; ++u) {
        if (on[i][u]) {
          for (int v = 0; v < n; ++v) {
            deg[i][u] += graph[u][v] && dist[s[i]][u] + 1 + dist[v][t[i]] == dist[s[i]][t[i]];
          }
        }
      }
      if (must[i][dst]) {
        dp[i][dst] = 1;
        queue.emplace_back(i, dst);
      }
    }
  }
  while (!queue.empty()) {
    auto i = queue.front().first;
    auto v = queue.front().second;
    queue.pop_front();
    if (visited[i][v]) {
      continue;
    }
    visited[i][v] = true;
    if (must[i][v]) {
      for (int j = 0; j < m; ++j) {
        if (on[j][v] && dp[j][v] > dp[i][v] + 1) {
          dp[j][v] = dp[i][v] + 1;
          queue.emplace_back(j, v);
        }
      }
    }
    for (int u = 0; u < n; ++u) {
      if (graph[u][v] &&
          dist[s[i]][u] + 1 + dist[v][t[i]] == dist[s[i]][t[i]]) {
        deg[i][u]--;
        if (deg[i][u] == 0 && dp[i][u] > dp[i][v]) {
          dp[i][u] = dp[i][v];
          queue.emplace_front(i, u);
        }
      }
    }
  }
  int result = INF;
  for (int i = 0; i < m; ++i) {
    if (must[i][src]) {
      result = std::min(result, dp[i][src]);
    }
  }
  printf("%d\n", result < INF ? result : -1);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <iomanip>
#include <map>
#include <deque>
#include <list>
#include <fstream>
#include <limits.h>

using namespace std;

#define pint pair <int, int>
#define F first
#define S second
#define PI 3.141592653589793
#define LL long long
#define RPQ priority_queue<LL, vector<LL>, std::greater<LL> >
#define puf push_front
#define pub push_back
#define pob pop_back
#define pof pop_front
#define MP make_pair
#define mod (LL)(1e5)
#define inf int(1e9)
#define M int(1e2) + 10

int dp[M][M];
vector <pint> com[M];
int n, m, s, e;
int ans[M], tt[M];
bool mark[M];

int dfs(int v, int tail) {
	if (v == tail) return ans[v];
	if (mark[v]) return tt[v];
	mark[v] = true;

	tt[v] = 0;
	for (int i = 1; i <= n; i++) {
		if (dp[v][i] + dp[i][tail] == dp[v][tail] && dp[v][i] == 1) {
			tt[v] = max(tt[v], dfs(i, tail));
		}
		tt[v] = min(ans[v], tt[v]);
	}
	return tt[v];
}

int main() {
	std::ios::sync_with_stdio(false);

	for (int i = 0; i < M; i++) fill(dp[i], dp[i] + M, inf), dp[i][i] = 0;
	fill(ans, ans + M, 1000);

	cin >> n >> m >> s >> e;
	for (int i = 0; i < m; i++) {
		int a, b; cin >> a >> b;
		dp[a][b] = 1;
	}

	for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) dp[j][k] = min(dp[j][k], dp[j][i] + dp[i][k]);
	if (dp[s][e] >= inf) return cout << -1, 0;

	int q; cin >> q;
	for (int l = 1; l <= q; l++) {
		int a, b; cin >> a >> b;
		if (dp[a][b] >= inf) continue;
		for (int i = 1; i <= n; i++) {
			if (dp[a][b] == dp[a][i] + dp[i][b]) {
				bool flag = false;
				for (int j = 1; j <= n; j++) {
					if (j != i && dp[a][i] == dp[a][j] && dp[i][b] == dp[j][b]) { flag = 1; break; }
				}
				if (!flag) {
					com[l].pub({dp[a][i], i});
				}
			}
		}
	}
	for (int i = 1; i <= q; i++) sort(com[i].begin(), com[i].end());

	fill(ans, ans + M, 500);
	fill(tt, tt + M, 500);
	ans[e] = 0;
	for (int c = 0; c <= 100; c++) {
		for (int i = 1; i <= q; i++) {
			fill(mark, mark + M, false);
			for (pint b: com[i]) {
				int temp = dfs(b.S, com[i][com[i].size() - 1].S) + 1;
				ans[b.S] = min(ans[b.S], temp);
			}
		}
	}
	cout << (ans[s] > 200 ? -1 : ans[s]);
	return 0;
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <iomanip>
#include <map>
#include <deque>
#include <list>
#include <fstream>
#include <limits.h>

using namespace std;

#define pint pair <int, int>
#define F first
#define S second
#define PI 3.141592653589793
#define LL long long
#define RPQ priority_queue<LL, vector<LL>, std::greater<LL> >
#define puf push_front
#define pub push_back
#define pob pop_back
#define pof pop_front
#define MP make_pair
#define mod (LL)(1e5)
#define inf int(1e9)
#define M int(1e2) + 10

int dp[M][M];
vector <pint> com[M];
int n, m, s, e;
int ans[M], tt[M];
bool mark[M];

int dfs(int v, int tail) {
	if (v == tail) return ans[v];
	if (mark[v]) return tt[v];
	mark[v] = true;

	tt[v] = 0;
	for (int i = 1; i <= n; i++) {
		if (dp[v][i] + dp[i][tail] == dp[v][tail] && dp[v][i] == 1) {
			tt[v] = max(tt[v], dfs(i, tail));
		}
		tt[v] = min(ans[v], tt[v]);
	}
	return tt[v];
}

int main() {
	std::ios::sync_with_stdio(false);

	for (int i = 0; i < M; i++) fill(dp[i], dp[i] + M, inf), dp[i][i] = 0;
	fill(ans, ans + M, 1000);

	cin >> n >> m >> s >> e;
	for (int i = 0; i < m; i++) {
		int a, b; cin >> a >> b;
		dp[a][b] = 1;
	}

	for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) dp[j][k] = min(dp[j][k], dp[j][i] + dp[i][k]);
	if (dp[s][e] >= inf) return cout << -1, 0;

	int q; cin >> q;
	for (int l = 1; l <= q; l++) {
		int a, b; cin >> a >> b;
		if (dp[a][b] >= inf) continue;
		for (int i = 1; i <= n; i++) {
			if (dp[a][b] == dp[a][i] + dp[i][b]) {
				bool flag = false;
				for (int j = 1; j <= n; j++) {
					if (j != i && dp[a][i] == dp[a][j] && dp[i][b] == dp[j][b]) { flag = 1; break; }
				}
				if (!flag) {
					com[l].pub({dp[a][i], i});
				}
			}
		}
	}
	for (int i = 1; i <= q; i++) sort(com[i].begin(), com[i].end());

	fill(ans, ans + M, 500);
	fill(tt, tt + M, 500);
	ans[e] = 0;
	for (int c = 0; c <= 500; c++) {
		for (int i = 1; i <= q; i++) {
			fill(mark, mark + M, false);
			for (pint b: com[i]) {
				int temp = dfs(b.S, com[i][com[i].size() - 1].S) + 1;
				ans[b.S] = min(ans[b.S], temp);
			}
		}
	}
	cout << (ans[s] > 200 ? -1 : ans[s]);
	return 0;
}


#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cassert>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<climits>
#define X first
#define Y second
#define DB double
#define MP make_pair
#define LL long long
#define pb push_back
#define sqr(_) ((_)*(_))
#define INF 0x3f3f3f3f
#define pii pair<int,int>
#define pdd pair<DB,DB>
#define ull unsigned LL
#define DEBUG(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int MAXN=101,MAXM=10001;
int n,m,S,T,s[MAXN],t[MAXN],vis[MAXN],dis[MAXN][MAXN],dp[MAXN],g[MAXN],e,K;
bool pass[MAXN][MAXN];
int dfs(int u,int M)
{
	if(u==M)return dp[M];
	if(vis[u])return g[u];
	vis[u]=1;g[u]=0;
	for(int i=1;i<=n;i++)
	{
		if(dis[u][i]+dis[i][M]==dis[u][M]&&dis[i][M]+1==dis[u][M])
			g[u]=max(g[u],dfs(i,M));
	}
	return g[u]=min(g[u],dp[u]);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("her.in","r",stdin);
	freopen("her.out","w",stdout);
#endif
	scanf("%d %d %d %d",&n,&m,&S,&T);
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)dis[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		dis[a][b]=1;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			if(dis[i][k]!=INF)
				for(int j=1;j<=n;j++)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int flag=1;
	scanf("%d",&K);
	for(int i=1;i<=K;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		s[i]=a;t[i]=b;
		if(dis[a][b]==INF)
			continue;
		for(int j=0;j<=dis[a][b];j++)
		{
			int cnt=0;
			vector<int> A;
			for(int k=1;k<=n;k++)
			{
				if(dis[a][k]==j&&dis[s[i]][t[i]]==dis[s[i]][k]+dis[k][t[i]])
					cnt++,A.pb(k);
			}
			if(cnt==1)
				pass[i][A[0]]=1;
		}
	}
	memset(dp,INF,sizeof(dp));
	dp[T]=0;
	while(flag)
	{
		flag=0;
		for(int i=1;i<=K;i++)
		{
			memset(vis,0,sizeof(vis));
			for(int j=1;j<=n;j++)
			{
				if(pass[i][j])
				{
					int tmp=dfs(j,t[i]);
					if(tmp+1<dp[j])
					{
						dp[j]=tmp+1;
						flag=1;
					}
				}
			}
		}
	}
	printf("%d\n",dp[S]==INF?-1:dp[S]);
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define INF ~0U>>2
#define MAXN 111
using namespace std;
int n,m,a,b,dist[MAXN][MAXN],from[MAXN],to[MAXN],ans,f[MAXN],g[MAXN],t;
bool can[MAXN][MAXN],visit[MAXN];
inline int dfs(int x,int aim)
{
	if(x==aim)return f[x];
	if(visit[x]==true)return g[x];
	visit[x]=true;
	g[x]=0;
	for (int i=1;i<=n;i++)
		if(dist[x][i]+dist[i][aim]==dist[x][aim]&&dist[x][aim]==dist[i][aim]+1)
			g[x]=max(g[x],dfs(i,aim));
	return g[x]=min(g[x],f[x]);
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&a,&b);
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			dist[i][j]=INF;
	for (int i=1;i<=n;i++)
		dist[i][i]=0;
	for (int i=1,u,v;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		dist[u][v]=1;
	}
	for (int k=1;k<=n;k++)
		for (int i=1;i<=n;i++)
			for (int j=1;j<=n;j++)
				if(dist[i][j]>dist[i][k]+dist[k][j])
					dist[i][j]=dist[i][k]+dist[k][j];
	scanf("%d",&t);
	for (int k=1;k<=t;k++)
	{
		scanf("%d%d",&from[k],&to[k]);
		int S=from[k],T=to[k];
		if(dist[S][T]==INF)continue;
		for (int i=1;i<=n;i++)
		{
			if(dist[S][i]+dist[i][T]==dist[S][T])
			{
				bool flag=true;
				for (int j=1;j<=n&&flag;j++)
				{
					if(j==i)continue;
					if(dist[S][j]+dist[j][T]==dist[S][T])
						if(dist[S][i]==dist[S][j])
							flag=false;
				}
				if(flag)can[k][i]=1;
			}
		}
	}
	for (int i=1;i<=n;i++)f[i]=INF;
	f[b]=0;
	while(1)
	{
		bool ff=false;
		for (int i=1;i<=t;i++)
		{
			if(dist[from[i]][to[i]]==INF)continue;
			memset(visit,0,sizeof(visit));
			for (int j=1;j<=n;j++)
			{
				if(can[i][j])
				{
					int temp=dfs(j,to[i])+1;
					if(temp<f[j])
					{
						f[j]=temp;
						ff=true;
					}
				}
			}
		}
		if(ff==false)break;
	}
	int ans=f[a];
	if(ans>=INF)ans=-1;
	printf("%d\n",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
using namespace std;

const int INF = 0x3f3f3f3f;

const int MAXN = 105;
int n, m, a, b;
int dis[MAXN][MAXN];
int ans[MAXN], temp[MAXN];
vector<int> ms[MAXN];
vector<int> vec[MAXN][MAXN];
int s[MAXN], t[MAXN];

void solved(int cas)
{
	int x, y;
	scanf("%d %d %d %d", &n, &m, &a, &b);
	memset(dis, INF, sizeof(dis));
	for (int i = 1; i <= n; i++)
		dis[i][i] = 0;
	while (m--)
	{
		scanf ("%d %d", &x, &y);
		dis[x][y] = 1;
	}
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	scanf ("%d", &m);
	for (int i = 0; i < m; i++)
	{
		scanf ("%d %d", &s[i], &t[i]);
		x = s[i], y = t[i];
		if (dis[s[i]][t[i]] == INF)
		{
			i--, m--;
			continue;
		}
		for (int j = 1; j <= n; j++)
		{
			if (dis[x][j] + dis[j][y] != dis[x][y])
				continue;
			vec[i][dis[x][j]].push_back(j);
			int cnt = 0;
			for (int k = 1; k <= n; k++)
				if (j != k && dis[x][j] == dis[x][k] && dis[k][y] == dis[j][y])
					cnt++;
			if (!cnt)
				ms[i].push_back(j);
		}
	}
	memset(ans, INF, sizeof(ans));
	ans[b] = 0;
	bool flag = true;
	while (flag)
	{
		flag = false;
		for (int i = 0; i < m; i++)
		{
			x = s[i], y = t[i];
			memset(temp, INF, sizeof(temp));
			temp[y] = min(temp[y], ans[y] + 1);
			for (int len = dis[x][y] - 1; len >= 0; len--)
			{
				for (int j = 0; j < vec[i][len].size(); j++)
				{
					int val = -1;
					for (int k = 0; k < vec[i][len+1].size(); k++)
						if (dis[vec[i][len][j]][vec[i][len+1][k]] == 1)
							val = max(val, temp[vec[i][len+1][k]]);
					if (val != -1)
						temp[vec[i][len][j]] = min(ans[vec[i][len][j]] + 1, val);
				}
			}
			for (int j = 0; j < ms[i].size(); j++)
			{
				if (temp[ms[i][j]] < ans[ms[i][j]])
				{
					ans[ms[i][j]] = temp[ms[i][j]];
					flag = true;
				}
			}
		}
	}
	if (ans[a] == INF)
		printf ("-1\n");
	else
		printf ("%d\n", ans[a]);
}

int main()
{
	//freopen("input.txt","r",stdin);
	int T = 1;
	//scanf ("%d", &T);
	for (int i = 1; i <= T; i++)
		solved(i);
	return 0;
}


#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cassert>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<climits>
#define X first
#define Y second
#define DB double
#define MP make_pair
#define LL long long
#define pb push_back
#define sqr(_) ((_)*(_))
#define INF 0x3f3f3f3f
#define pii pair<int,int>
#define pdd pair<DB,DB>
#define ull unsigned LL
#define DEBUG(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int MAXN=101,MAXM=10001;
int n,m,S,T,s[MAXN],t[MAXN],vis[MAXN],dis[MAXN][MAXN],dp[MAXN],g[MAXN],e,K;
bool pass[MAXN][MAXN];
int dfs(int u,int M)
{
	if(u==M)return dp[M];
	if(vis[u])return g[u];
	vis[u]=1;g[u]=0;
	for(int i=1;i<=n;i++)
	{
		if(dis[u][i]+dis[i][M]==dis[u][M]&&dis[i][M]+1==dis[u][M])
			g[u]=max(g[u],dfs(i,M));
	}
	return g[u]=min(g[u],dp[u]);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("her.in","r",stdin);
	freopen("her.out","w",stdout);
#endif
	scanf("%d %d %d %d",&n,&m,&S,&T);
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)dis[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		dis[a][b]=1;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			if(dis[i][k]!=INF)
				for(int j=1;j<=n;j++)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int flag=1;
	scanf("%d",&K);
	for(int i=1;i<=K;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		s[i]=a;t[i]=b;
		if(dis[a][b]==INF)continue;
		for(int j=0;j<=dis[a][b];j++)
		{
			int cnt=0;
			vector<int> A;
			for(int k=1;k<=n;k++)
			{
				if(dis[a][k]==j&&dis[s[i]][t[i]]==dis[s[i]][k]+dis[k][t[i]])
					cnt++,A.pb(k);
			}
			if(cnt==1)
				pass[i][A[0]]=1;
		}
	}
	memset(dp,INF,sizeof(dp));
	dp[T]=0;
	flag=0;
	while(flag)
	{
		flag=0;
		for(int i=1;i<=K;i++)
		{
			memset(vis,0,sizeof(vis));
			for(int j=1;j<=n;j++)
			{
				if(pass[i][j])
				{
					int tmp=dfs(j,t[i]);
					if(tmp+1<dp[j])
					{
						dp[j]=tmp+1;
						flag=1;
					}
				}
			}
		}
	}
	printf("%d\n",dp[S]==INF?-1:dp[S]);
}


#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cassert>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<climits>
#define X first
#define Y second
#define DB double
#define MP make_pair
#define LL long long
#define pb push_back
#define sqr(_) ((_)*(_))
#define INF 0x3f3f3f3f
#define pii pair<int,int>
#define pdd pair<DB,DB>
#define ull unsigned LL
#define DEBUG(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
const int MAXN=101,MAXM=10001;
int n,m,S,T,s[MAXN],t[MAXN],vis[MAXN],dis[MAXN][MAXN],dp[MAXN],g[MAXN],e,K;
bool pass[MAXN][MAXN];
int dfs(int u,int M)
{
	if(u==M)return dp[M];
	if(vis[u])return g[u];
	vis[u]=1;g[u]=0;
	for(int i=1;i<=n;i++)
	{
		if(dis[u][i]+dis[i][M]==dis[u][M]&&dis[i][M]+1==dis[u][M])
			g[u]=max(g[u],dfs(i,M));
	}
	return g[u]=min(g[u],dp[u]);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("her.in","r",stdin);
	freopen("her.out","w",stdout);
#endif
	scanf("%d %d %d %d",&n,&m,&S,&T);
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)dis[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		dis[a][b]=1;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			if(dis[i][k]!=INF)
				for(int j=1;j<=n;j++)
					dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	int flag=1;
	scanf("%d",&K);
	for(int i=1;i<=K;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		s[i]=a;t[i]=b;
		for(int j=0;j<=dis[a][b];j++)
		{
			int cnt=0;
			vector<int> A;
			for(int k=1;k<=n;k++)
			{
				if(dis[a][k]==j&&dis[s[i]][t[i]]==dis[s[i]][k]+dis[k][t[i]])
					cnt++,A.pb(k);
			}
			if(cnt==1)
				pass[i][A[0]]=1;
		}
	}
	memset(dp,INF,sizeof(dp));
	dp[T]=0;
	while(flag)
	{
		flag=0;
		for(int i=1;i<=K;i++)
		{
			memset(vis,0,sizeof(vis));
			for(int j=1;j<=n;j++)
			{
				if(pass[i][j])
				{
					int tmp=dfs(j,t[i]);
					if(tmp+1<dp[j])
					{
						dp[j]=tmp+1;
						flag=1;
					}
				}
			}
		}
	}
	printf("%d\n",dp[S]==INF?-1:dp[S]);
}


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

using namespace std;

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

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}


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

using namespace std;

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

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

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

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

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

	return 0;
}