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

using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define REP(NAME, NUM) for (int NAME = 0; NAME < (NUM); ++NAME)
#define BREP(NAME, NUM) for (int NAME = (NUM)-1; NAME >= 0; --NAME)
#define ALL(NAME) (NAME).begin(), (NAME).end()

#define cMOD 1000000007ULL
#define cINF ((1ll<<62)-1)
#define cINFINT ((1<<30)-1)


class Graph
{
public:
	explicit Graph( int nodeSize )
		: mNodeSize( nodeSize )
		, mEdgeSize( 0 )
		, mEdge( nodeSize )
		, mDepth( nodeSize )
		, mMark( nodeSize )
		, mMark2( 0 )
		{}
	
	// Edge定義
	struct Edge
	{
		bool operator<( const Edge& other )
		{ return this->cost != other.cost ?
			this->cost < other.cost : this->to < other.to;  }
		int to; int cost; int rev;
	};
	
	// Edge情報を読み取る
	void readEdge_Undirect_NoCost( int m ) { readEdge_( m, false, false ); }
	void readEdge_Direct_NoCost( int m ) { readEdge_( m, true, false ); }
	void readEdge_Undirect_Cost( int m ) { readEdge_( m, false, true ); }
	void readEdge_Direct_Cost( int m ) { readEdge_( m, true, true ); }
	void readEdge_Direct_Flow( int m ) { readEdge_Flow_( m ); }
	
private:
	void readEdge_( int m, bool isDirected, bool isCost )
	{
		REP( i, m )
		{
			int a, b, c = 1, r = -1;
			cin >> a >> b;
			if( isCost ) cin >> c;
			mEdge[a-1].push_back( { b-1, c, -1 } );
			if( !isDirected ) mEdge[b-1].push_back( { a-1, c, r } );
			++mEdgeSize;
		}
	}
	void readEdge_Flow_( int m )
	{
		REP( i, m )
		{
			int a, b, c;
			cin >> a >> b >> c;
			mEdge[a-1].push_back( { b-1, c, int(mEdge[b-1].size()) } );
			mEdge[b-1].push_back( { a-1, 0, int(mEdge[a-1].size() - 1) } );
			++mEdgeSize;
		}
	}
	
public:
	// 必要なときだけメモリ確保するように
	void assignMark2()
	{
		vector<int> tmp( mNodeSize, cINFINT );
		mMark2.assign( mNodeSize, tmp );
	}
	void setupMark2ForCost()
	{
		REP( i, mNodeSize )
		{
			mMark2[i][i] = 0;
			for( const auto& e : mEdge[i] ) mMark2[i][e.to] = e.cost;
		}
	}


public:
	// MARK構造体
	struct MARK
	{
		int num = 0;
		MARK& operator+=( const MARK& rhs )
		{
			this->num += rhs.num;
			return *this;
		}
	};

public:
	int mNodeSize; // VertexSize
	int mEdgeSize; // EdgeSize
	vector< vector< Edge > > mEdge; // 隣接リスト
	
	// 作業用変数
	vector<int> mDepth /* Used */;
	vector<int> mMark;
	// 必要なときだけメモリ確保するように
	vector< vector<int> > mMark2;
};


vector<int>& dijkstra( Graph& g, int startNode )
{
	auto& mark = g.mMark;
	fill( ALL( mark ), cINFINT );
	using P = pair<int, int>;
	priority_queue<P, vector<P>, greater<P>> que;
	mark[startNode] = 0; que.push( P( 0, startNode ) );
	while( !que.empty() )
	{
		P p = que.top(); que.pop();
		int v = p.second;
		if( mark[v] < p.first ) continue;
		for( const auto& e : g.mEdge[v] )
		{
			if( !( mark[e.to] > mark[v] + e.cost ) ) continue;
			mark[e.to] = mark[v] + e.cost;
			que.push( P( mark[e.to], e.to ) ); 
		}
	}
	return mark;
}

int main()
{
	cin.tie( 0 ); ios::sync_with_stdio( false );
	int n, m;
	cin >> n >> m;
	Graph g( 3 * n );
	REP( i, m )
	{
		int a, b, c = 1;
		cin >> a >> b;--a;--b;
		g.mEdge[a].push_back( { b+n, c, -1 } );
		g.mEdge[a+n].push_back( { b+2*n, c, -1 } );
		g.mEdge[a+2*n].push_back( { b, c, -1 } );
		g.mEdgeSize += 3;
	}
	int s,t;cin>>s>>t;
	--s;--t;
	
	ll ans = dijkstra( g, s )[t];
	cout << ( ans == cINFINT ? -1 : ans / 3 ) << endl;
	
	return 0;
}

Measured memory_bytes: 19072