stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



#define IOS ios::sync_with_stdio(false); cin.tie(0);

#define FOR(i,s,n) for(int i = s; i < (n); i++)

#define REP(i,n) FOR(i,0,n)

#define ALL(n) (n).begin(), (n).end()

#define RALL(n) (n).rbegin(), (n).rend()

using ll = long long;

using ull = unsigned long long;





int main(void)

{

    IOS

    int n,m; cin >> n >> m;

    vector<set<int>> vs(n+1);

    REP(i,m) {

        int u,v; cin >> u >>v;

        vs[u].emplace(v);

    }

    int s,t; cin >> s >> t;



    int dp[3][100010];

    REP(i,3) REP(j,100010) dp[i][j] = 0;

    dp[0][s] = 1;



    set<int> next(vs[s]);



    int ans = 1;

    while(true) {

        FOR(i,0,3) {

            set<int> tmp;

            //cerr << next.size() << endl;

            int j = i == 2 ? 0:i+1;

            for(auto x:next) {

                if (dp[j][x]!=1) {

                    dp[j][x] = 1;

                    tmp.insert(ALL(vs[x]));

                }

            }

            next = tmp;

        }

        if (dp[0][t]== 1) break;

        //cerr << next.size()<<endl;

        if (next.size() == 0) {

            ans = -1;

            break;

        }

        ans++;

    }



    cout << ans << endl;



    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



#define IOS ios::sync_with_stdio(false); cin.tie(0);

#define FOR(i,s,n) for(int i = s; i < (n); i++)

#define REP(i,n) FOR(i,0,n)

#define ALL(n) (n).begin(), (n).end()

#define RALL(n) (n).rbegin(), (n).rend()

using ll = long long;

using ull = unsigned long long;





int main(void)

{

    IOS

    int n,m; cin >> n >> m;

    vector<set<int>> vs(n+1);

    REP(i,m) {

        int u,v; cin >> u >>v;

        vs[u].emplace(v);

    }

    int s,t; cin >> s >> t;



    bool dp[3][100010];

    memset(dp,0,sizeof dp);

    dp[0][s] = 1;



    set<int> next(vs[s]);



    int ans = 1;

    while(true) {

        FOR(i,0,3) {

            set<int> tmp;

            //cerr << next.size() << endl;

            int j = i == 2 ? 0:i+1;

            for(auto x:next) {

                if (dp[j][x]!=1) {

                    dp[j][x] = 1;

                    tmp.insert(ALL(vs[x]));

                }

            }

            next = tmp;

        }

        if (dp[0][t]== 1) break;

        //cerr << next.size()<<endl;

        if (next.size() == 0) {

            ans = -1;

            break;

        }

        ans++;

    }



    cout << ans << endl;



    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



#define IOS ios::sync_with_stdio(false); cin.tie(0);

#define FOR(i,s,n) for(int i = s; i < (n); i++)

#define REP(i,n) FOR(i,0,n)

#define ALL(n) (n).begin(), (n).end()

#define RALL(n) (n).rbegin(), (n).rend()

using ll = long long;

using ull = unsigned long long;





int main(void)

{

    IOS

    int n,m; cin >> n >> m;

    vector<set<int>> vs(n+1);

    REP(i,m) {

        int u,v; cin >> u >>v;

        vs[u].emplace(v);

    }

    int s,t; cin >> s >> t;



    int dp[3][100010];

    memset(dp,0,sizeof dp);

    dp[0][s] = 1;



    set<int> next(vs[s]);



    int ans = 1;

    while(true) {

        FOR(i,0,3) {

            set<int> tmp;

            //cerr << next.size() << endl;

            int j = i == 2 ? 0:i+1;

            for(auto x:next) {

                if (dp[j][x]!=1) {

                    dp[j][x] = 1;

                    tmp.insert(ALL(vs[x]));

                }

            }

            next = tmp;

        }

        if (dp[0][t]== 1) break;

        //cerr << next.size()<<endl;

        if (next.size() == 0) {

            ans = -1;

            break;

        }

        ans++;

    }



    cout << ans << endl;



    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



#define IOS ios::sync_with_stdio(false); cin.tie(0);

#define FOR(i,s,n) for(int i = s; i < (n); i++)

#define REP(i,n) FOR(i,0,n)

#define ALL(n) (n).begin(), (n).end()

#define RALL(n) (n).rbegin(), (n).rend()

using ll = long long;

using ull = unsigned long long;





int main(void)

{

    IOS

    int n,m; cin >> n >> m;

    vector<set<int>> vs(n+1);

    REP(i,m) {

        int u,v; cin >> u >>v;

        vs[u].emplace(v);

    }

    int s,t; cin >> s >> t;



    bool dp[3][100010];

    memset(dp,0,sizeof dp);

    dp[0][s] = 1;



    set<int> next(vs[s]);



    int ans = 1;

    while(true) {

        FOR(i,0,3) {

            set<int> tmp;

            //cerr << next.size() << endl;

            int j = i == 2 ? 0:i+1;

            for(auto x:next) {

                if (dp[j][x]!=1) {

                    dp[j][x] = 1;

                    tmp.insert(ALL(vs[x]));

                }

            }

            next = tmp;

        }

        if (dp[0][t]== 1) break;

        //cerr << next.size()<<endl;

        if (next.size() == 0) {

            ans = -1;

            break;

        }

        ans++;

    }



    cout << ans << endl;



    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int> pp;

const int INF = 1e9;

const int MOD = 1000000007;

#define rep(i,n) for(int i=0;i<n;i++)

const int MAX = 100005;

vector<vector<pp>> graph(3*MAX,vector<pp>(0));

int n = MAX,s,t;



ll dijkstra(ll goal){

  priority_queue<pp,vector<pp>,greater<pp>> pq;

  pq.push(make_pair(0,s));

  vector<int> visited(3*n,0);

  while (!pq.empty()){

    auto now = pq.top();

    pq.pop();

    ll cost,node;

    tie(cost,node) = now;

    if(node == goal){

      return cost/3 ;

    }

    if(visited.at(node)==1){

      continue;

    }else{

      visited.at(node) = 1;

      for(auto next:graph.at(node)){

        ll next_cost,next_node;

        tie(next_cost,next_node) = next;

        pq.push(make_pair(cost+next_cost,next_node));

      }

    }

  }

  return -1;

} 

int main() {

  int n,m ;

  cin >> n >> m;

  rep(i,m){

    int v,u;

    cin >> v >> u;

    --v; --u;

    graph.at(v).push_back(make_pair(1,u+n));

    graph.at(v+n).push_back(make_pair(1,u+2*n));

    graph.at(v+2*n).push_back(make_pair(1,u));

  }

  cin >> s >> t;

  --s; --t;

  

  ll ans = dijkstra(t);

  if(ans == -1) cout << -1 << endl;

  else cout << ans << endl;

}

  

  

 

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)(n);i++)

using namespace std;

using ll = long long ;

using P = pair<int,int> ;

using pll = pair<long long,long long>;

constexpr int INF = 1e9;

constexpr long long LINF = 1e17;

constexpr int MOD = 1000000007;

constexpr double PI = 3.14159265358979323846;



int seen[100005][3];

vector<int> graph[100005];



int main(){

    int n,m;

    cin >> n >> m;

    rep(i,n)rep(j,3) seen[i][j] = -1;

    rep(i,m){

        int a,b;

        cin >> a >> b;

        --a;--b;

        graph[a].push_back(b);

    }

    int s,t;

    cin >> s >> t;

    --s;--t;

    queue<pair<int,int>> q;

    q.push(P(3*s+0,0));

    while(!q.empty()){

        int now = q.front().first / 3;

        int c = q.front().first % 3;

        int len = q.front().second;

        q.pop();

        if(seen[now][c]>=0) continue;

        seen[now][c] = len;

        c = (c+1)%3;

        for(int j:graph[now]){

            if(seen[j][c]>=0) continue;

            q.push(P(3*j+c,len+1));

        }

    }

    if(seen[t][0]>=0) cout << seen[t][0] / 3 << endl;

    else cout << -1 << endl;

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



const int MAXN = 2e5;



const int INF = 1e9;



vector <int> g[MAXN];





int main()

{

#ifdef LOCAL

    freopen("input.txt", "r", stdin);

#endif // LOCAL

    ios_base::sync_with_stdio(0);

    cin.tie(0);

    int n, m;

    cin >> n >> m;

    vector <vector<int>> dist(n + 1, vector<int>(3, INF));

    for (int i = 0; i < m; i++) {

        int x, y;

        cin >> x >> y;

        g[x].push_back(y);

    }

    int s, t;

    cin >> s >> t;

    dist[s][0] = 0;

    queue <pair<int, int>> q;

    q.push({s, 0});

    while (!q.empty()) {

        int v = q.front().first;

        int r = q.front().second;

        q.pop();

        for (auto u : g[v]) {

            if (dist[v][r] + 1 < dist[u][(r + 1) % 3]) {

                dist[u][(r + 1) % 3] = dist[v][r] + 1;

                q.push({u, (r + 1) % 3});

            }

        }

    }

    if (dist[t][0] == INF) {

        cout << -1;

    } else {

        cout << dist[t][0] / 3;

    }

    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

 

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

template<class T> using ordered_multiset = tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;



typedef long long  ll;

typedef unsigned long long  ull;

#define lp(i,n)      for(int i=0;i<n;i++)

#define lpi(i,j,n)   for(int i=j;i<n;i++)

#define lpd(i,j,n)   for(int i=j;i>=n;i--)

#define MP           make_pair

#define clr(v, d)    (memset(v, d, sizeof(v)))

#define all(v)     (v.begin()),(v.end())

#define N 100005

const double pi = acos(-1);



ll n,t,m,k;



ll ans;

ll mod = 1e9 +7;

vector<int>adj[N];

int dis[N],vis[N][3];



queue<int>q;

void dfs(int node, int num, int reach){

  if(num==3){

    if(dis[node]==-1){

      dis[node]=reach;

      q.push(node);

    }

    return;

  }

  if(vis[node][num])return;

  vis[node][num]=1;

  for(auto& u:adj[node])dfs(u,num+1,reach);

}





int main() {

 

ios_base::sync_with_stdio(0);

cin.tie(0);cout.tie(0);

// freopen("e.txt","r",stdin); 

// freopen("e_out.txt","w",stdout); 

cout.precision(7);



cin>>n>>m;

lp(i,m){

  int x,y;

  cin>>x>>y;

  adj[x].push_back(y);

}

int S,T;

cin>>S>>T;

lp(i,n+1)dis[i]=-1;

q.push(S);

dis[S]=0;

while(!q.empty()){

  int node = q.front();

  q.pop();

  dfs(node,0,dis[node]+1);

}

cout<<dis[T];











  

}

  

 







// bool isPrime(ll h){

//      for(ll i=0;primes[i]*primes[i]<= h;i++)

//      if (h%primes[i]==0)

//      	return 0;

//      return h!=1;

//  }

 bool isPrime(ll g){

   if((g%2==0 && g>2) || g==1)return 0;

   for(ll i=3;i*i<=g;i+=2)if(g%i==0)return 0;

   return 1;   

 

 }

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define maxn 100005

using namespace std;

struct Node{

    int to,next;

}q[maxn];

int head[maxn],cnt=0,dis[maxn][10];

int n,m;

void add_edge(int from,int to){

    q[cnt].to=to;

    q[cnt].next=head[from];

    head[from]=cnt++;

}

typedef pair<int,int>pll;

void bfs(int x){

    queue<pll>que;

    que.push(pll(x,0));

    memset(dis,-1,sizeof(dis) );

    dis[x][0]=0;

    while(!que.empty()){

        x=que.front().first;

        int y=que.front().second;

        que.pop();

        for(int i=head[x];i!=-1;i=q[i].next){

            int to=q[i].to;

            int cost=(y+1)%3;

            if(dis[to][cost]>=0) continue;

            dis[to][cost]=dis[x][y]+1;

            que.push(pll(to,cost));

        }

    }

}

int main()

{

    memset(head,-1, sizeof(head));

    scanf("%d%d",&n,&m);

    for(int i=1;i<=m;i++){

        int from,to;

        scanf("%d%d",&from,&to);

        add_edge(from,to);

    }

    int s,t;

    scanf("%d%d",&s,&t);

    bfs(s);

    if(dis[t][0]>=0) dis[t][0]/=3;

    printf("%d\n",dis[t][0]);

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

 

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

template<class T> using ordered_multiset = tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;



typedef long long  ll;

typedef unsigned long long  ull;

#define lp(i,n)      for(int i=0;i<n;i++)

#define lpi(i,j,n)   for(int i=j;i<n;i++)

#define lpd(i,j,n)   for(int i=j;i>=n;i--)

#define MP           make_pair

#define clr(v, d)    (memset(v, d, sizeof(v)))

#define all(v)     (v.begin()),(v.end())

#define N 100005

const double pi = acos(-1);



ll n,t,m,k;



ll ans;

ll mod = 1e9 +7;

vector<int>adj[N];

int dis[N],vis[N][3];



queue<int>q;

void dfs(int node, int num, int reach){

  if(num==3){

    if(dis[node]==-1){

      dis[node]=reach;

      q.push(node);

    }

    return;

  }

  if(vis[node][num])return;

  vis[node][num]=1;

  for(auto& u:adj[node])dfs(u,num+1,reach);

}





int main() {

 

ios_base::sync_with_stdio(0);

cin.tie(0);cout.tie(0);

// freopen("e.txt","r",stdin); 

// freopen("e_out.txt","w",stdout); 

cout.precision(7);



cin>>n>>m;

lp(i,m){

  int x,y;

  cin>>x>>y;

  adj[x].push_back(y);

}

int S,T;

cin>>S>>T;

lp(i,n+1)dis[i]=-1;

q.push(S);

dis[S]=0;

while(!q.empty()){

  int node = q.front();

  q.pop();

  dfs(node,0,dis[node]+1);

}

cout<<dis[T];











  

}

  

 







// bool isPrime(ll h){

//      for(ll i=0;primes[i]*primes[i]<= h;i++)

//      if (h%primes[i]==0)

//      	return 0;

//      return h!=1;

//  }

 bool isPrime(ll g){

   if((g%2==0 && g>2) || g==1)return 0;

   for(ll i=3;i*i<=g;i+=2)if(g%i==0)return 0;

   return 1;   

 

 }

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;

#define  ll long long

#define ld long double

#define f first

#define s second

const int N = 2e5+5;



int n , m , s , t;

vector<int> adj[N];



int bfs()

{

    queue< pair<int,int> > q;

    int d[n+2][4];

    for(int i=1; i<=n; i++)

    {

        d[i][0]=1e8 , d[i][1] =1e8 , d[i][2] = 1e8;

    }

    q.push({s , 0});

    d[s][0] = 0;



    while(q.size())

    {

        int node = q.front().f , mod = q.front().s;

        q.pop();



        for(auto ch : adj[node])

        {

            int m = (mod+1)%3;

            if (d[ch][m] == 1e8)

            {

                d[ch][m] = d[node][mod]+1;

                q.push({ch,m});

            }

        }

    }



    if (d[t][0] == 1e8) return -1;

    else return d[t][0]/3;

}



int main()

{



    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);



    cin >> n >> m;

    for(int i=1; i<=m; i++)

    {

        int x,y;

        cin >> x >> y;

        adj[x].push_back(y);

    }



    cin >> s >> t;

    cout << bfs() << '\n';



    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

 

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

template<class T> using ordered_multiset = tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;



typedef long long  ll;

typedef unsigned long long  ull;

#define lp(i,n)      for(int i=0;i<n;i++)

#define lpi(i,j,n)   for(int i=j;i<n;i++)

#define lpd(i,j,n)   for(int i=j;i>=n;i--)

#define MP           make_pair

#define clr(v, d)    (memset(v, d, sizeof(v)))

#define all(v)     (v.begin()),(v.end())

#define N 100005

const double pi = acos(-1);



ll n,t,m,k;



ll ans;

ll mod = 1e9 +7;

vector<int>adj[N];

int dis[N],vis[N][3];



queue<int>q;

void dfs(int node, int num, int reach){

  if(num==3){

    if(dis[node]==-1){

      dis[node]=reach;

      q.push(node);

    }

    return;

  }

  if(vis[node][num])return;

  vis[node][num]=1;

  for(auto& u:adj[node])dfs(u,num+1,reach);

}





int main() {

 

ios_base::sync_with_stdio(0);

cin.tie(0);cout.tie(0);

// freopen("e.txt","r",stdin); 

// freopen("e_out.txt","w",stdout); 

cout.precision(7);



cin>>n>>m;

lp(i,m){

  int x,y;

  cin>>x>>y;

  adj[x].push_back(y);

}

int S,T;

cin>>S>>T;

lp(i,n+1)dis[i]=-1;

q.push(S);

dis[S]=0;

while(!q.empty()){

  int node = q.front();

  q.pop();

  dfs(node,0,dis[node]+1);

}

cout<<dis[T];











  

}

  

 







// bool isPrime(ll h){

//      for(ll i=0;primes[i]*primes[i]<= h;i++)

//      if (h%primes[i]==0)

//      	return 0;

//      return h!=1;

//  }

 bool isPrime(ll g){

   if((g%2==0 && g>2) || g==1)return 0;

   for(ll i=3;i*i<=g;i+=2)if(g%i==0)return 0;

   return 1;   

 

 }

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

 

using namespace std;

 

#define INF 1000000007

#define LINF 1000000000000000007

 

typedef long long i64;

typedef pair<i64,i64> P;





int n, m, s, t;

vector<int> v[101010];

int dp[101010][3];



int main(){

	cin >> n >> m;

	for(int i = 0; i < m; i++){

		int a,b;

		cin >> a >> b;

		v[a].push_back(b);

	}

	cin >> s >> t;

	

	for(int i = 0; i < 101010; i++) for(int j = 0; j < 3; j++){

		dp[i][j] = INF;

	}

	int ans = INF;

	queue<pair<int,int>> q;

	q.push(make_pair(s, 0));

	dp[s][0] = 0;

	while(!q.empty()){

		pair<int,int> p = q.front();

		q.pop();

		int pos = p.first, cnt = p.second;

		for(int i = 0; i < v[pos].size(); i++){

			if(dp[v[pos][i]][(cnt+1)%3] <= cnt+1) continue;

			dp[v[pos][i]][(cnt+1) % 3] = cnt+1;

			q.push(make_pair(v[pos][i], cnt+1));

		}

	}

	

	if(dp[t][0] == INF){

		cout << -1 << endl;

	}

	else{

		cout << dp[t][0]/3 << endl;

	}

	

	return 0;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<string>

#include<queue>

#include<algorithm>

#include<map>

#include<set>

#include<vector>



using namespace std;



#define INF 1000000007

#define LINF 1000000000000000007



typedef long long i64;

typedef pair<i64,i64> P;





int n, m, s, t;

vector<int> v[101010];

bool used[101010][3];



int main(){

	cin >> n >> m;

	for(int i = 0; i < m; i++){

		int a,b;

		cin >> a >> b;

		v[a].push_back(b);

	}

	cin >> s >> t;

	

	i64 ans = LINF;

	queue<P> q;

	q.push(P(s,0));

	while(!q.empty()){

		P p = q.front();

		q.pop();

		i64 now = p.first, cnt = p.second;

		if(used[now][cnt%3]) continue;

		used[now][cnt%3] = 1;

		if(now == t && cnt % 3 == 0){

			ans = min(ans, cnt/3);

		}

		for(int i = 0; i < v[now].size(); i++){

			q.push(P(v[now][i], cnt+1));

		}

	}

	

	if(ans == LINF) cout << -1 << endl;

	else cout << ans << endl;

	

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;

using ll = long long;



const int maxn = 1e5+10;

const int INF = 1e9+10;



vector<int> g[maxn];

int p[maxn][3];



void bfs(int x){

	queue<pair<int,int>> q;

	q.push({x,0});

	p[x][0] = 0;

	while(!q.empty()){

		int nxt = q.front().first;

		int moves = q.front().second;

		q.pop();

		for(int i=0;i<g[nxt].size();++i){

			int v = g[nxt][i];

			if(p[nxt][moves]+1 < p[v][(moves+1)%3]){

				p[v][(moves+1)%3] = p[nxt][moves]+1;

				q.push({v,(moves+1)%3});

			}

		}

	}

}



void init(){

	for(int i=0;i<maxn;++i)

		for(int j=0;j<3;++j)

			p[i][j] = INF;

}



void solve(){

	int n,m,s,t;

	init();

	cin >> n >> m;

	for(int i=1;i<=m;++i){

		int u,v;

		cin >> u >> v;

		g[u].push_back(v);

	}

	cin >> s >> t;

	bfs(s);

	if(p[t][0] == INF){

		cout << -1 << '\n';

	}

	else{

		cout << p[t][0]/3 << '\n';

	}

}



int main(){

	ios_base::sync_with_stdio(false);

	cin.tie(0);

	cout.tie(0);

	int t = 1;

	//cin >> t;

	while(t--){ 

		solve();

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define ll long long

#define F first

#define S second

#define Tsetso ios_base::sync_with_stdio(0) ; cin.tie(0) ;

using namespace std;

const ll N = 1e5+50, inf = 1e3+5, mod = 1e9+7, NN = 1e5+10;

int vis[N][3] ;

vector < int > graph[N] ;

int n, m, t,s, u, v ;

int main()

{

    Tsetso

    cin >> n >> m ;

    for ( int i = 0 ; i < m ; i++)

    {

        cin >> u >> v ;

        graph[u].push_back(v);

    }

    cin >> s >> t ;

    queue < int > q ;

    q.push(s);

    vis[s][0] = 1 ;

    int cnt = 1 ;

    while ( q.size())

    {

        int y = q.size() ;

        for ( int i = 0 ; i < y ; i++)

        {

            for ( auto j : graph[q.front()])

            {

                if ( !vis[j][cnt%3])

                {

                    if ( cnt%3 == 0 && j == t )

                        return cout << cnt/3, 0 ;

                    q.push(j);

                    vis[j][cnt%3] = 1 ;

                }

            }

            q.pop();

        }

        cnt++ ;

    }

    cout << -1 ;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;

typedef pair<ll,ll> pi;

typedef vector <ll> vi;

typedef vector <pi> vpi;

#define f first

#define s second

#define FOR(i,s,e) for(ll i=s;i<=ll(e);++i)

#define DEC(i,s,e) for(ll i=s;i>=ll(e);--i)

#define pb push_back

#define all(x) (x).begin(), (x).end()

#define lbd(x, y) lower_bound(all(x), y)

#define ubd(x, y) upper_bound(all(x), y)

#define aFOR(i,x) for (auto i: x)

#define mem(x,i) memset(x,i,sizeof x)

#define fast ios_base::sync_with_stdio(false),cin.tie(0)

#define maxn 100001



int N,M,S,T;

vi adj[maxn];

vpi adj2[maxn];

bool vis[maxn][3];

int dist[maxn][3];

vpi nodes[3];



int main(){

	fast;

	

	cin>>N>>M;

	

	FOR(i,0,M-1){

		int a,b; cin>>a>>b; adj[a].pb(b);

	}

	

	cin>>S>>T;

	



		

	queue <pi> q;

	q.push(pi(S,0));

		

	while (!q.empty()){

		pi cur = q.front(); q.pop();

			

		if (vis[cur.f][cur.s%3]) continue;

		vis[cur.f][cur.s%3] = 1;

		

		dist[cur.f][cur.s%3] = cur.s;

		aFOR(i,adj[cur.f]){

			q.push(pi(i,cur.s+1));

		}

	}

	

	if (vis[T][0] == 1) cout<<dist[T][0]/3;

	else cout<<-1;



		

}




// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



#define MAX 100005



using namespace std;



int n, m, s, t;

vector<int> G[MAX];

int8_t mark[MAX];;



int bfs()

{

        queue<pair<int,int>> q;

        int ls = 0;

        int kkp = 0;

        q.emplace(s,0);



        while (!q.empty()) {

                auto curr = q.front();

                q.pop();

                if (curr.second != 3) {

                        kkp += (ls == 3);

                        ls = curr.second;



                        if ((mark[curr.first] & (1<<curr.second))) continue;

                        mark[curr.first] |= (1<<curr.second);

                        for (auto e : G[curr.first])

                                q.emplace(e, curr.second+1);

                } else {

                        if (curr.first == t) return kkp+1;

                        else if ((mark[curr.first] & (1<<curr.second))) continue;



                        mark[curr.first] |= (1<<curr.second);

                        ls = curr.second;

                        for (auto e : G[curr.first])

                                q.emplace(e, 1);

                }

        }

        return -1;

}



int main()

{

        cin >> n >> m;

        for (int i = 0; i < m; i++) {

                int u, v;

                cin >> u >> v;

                G[u].push_back(v);

        }

        cin >> s >> t;

        cout << bfs() << endl;

        return 0;

}

// Fastest known solution for this problem: