#include<bits/stdc++.h>
#define ll long long int
#define pll pair<ll,ll>
#define vpll vector< pll >
#define mpll map<ll,ll>
#define MOD 1000000007
#define all(v) v.begin(),v.end()
#define s(v) v.size()
#define test ll t;cin>>t;while(t--)
#define vec vector<ll>
#define read0(v,n) for(int i=0;i<n;i++)cin>>v[i];
#define read1(v,n) for(int i=1;i<=n;i++)cin>>v[i];
#define trav(a,x) for (auto& a: x)
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);
#define cut(x) {cout<<x;return 0;}
#define print(x) {cout<<x<<nl;continue;}
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FORB(i,a,b) for(int i=a;i>=b;i--)
#define err1(a) {cout<<#a<<' '<<a<<nl;}
#define err2(a,b) {cout<<#a<<' '<<a<<' '<<#b<<' '<<b<<nl;}

#define mp make_pair
#define pb push_back
#define eb emplace_back
#define f first
#define sc second
#define lb lower_bound
#define ub upper_bound
#define nl '\n'
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;
#define oset tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
ll gcd(ll a, ll b)
{
	if (b==0)return a;
	return gcd(b, a % b);
}
ll lcm(ll a,ll b)
{
    return (a*b)/gcd(a,b);
}
ll pow(ll a, ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*a)%MOD;
		b/=2;
		a=(a*a)%MOD;
	}
	return ans;
}
struct node{
    ll x,t,k;
};
const int N=1e5+5;
vec d(N,(ll)1e18);
vec v[N];
vector<node> g[N];
ll dis(ll x,ll y)
{
    ll p=x/y;
    if(x%y!=0)p++;
    p*=y;
    return p;
}
void solve(ll n,ll u)
{
    multiset<pll> q;
    d[u]=0;
    q.insert({0,u});
    while(!q.empty())
    {
        pll p=*q.begin();
        q.erase(q.begin());
        trav(it,g[p.sc])
        {
            ll c=dis(p.f,it.k);

            if(d[it.x]>c+it.t)
            {
                d[it.x]=c+it.t;
                q.insert({d[it.x],it.x});
            }
        }
    }

}
int main()
{
	fast
	int n,m,x,y;
	cin>>n>>m>>x>>y;
	FOR(i,1,m)
	{
	    ll a,b,c,d;
	    cin>>a>>b>>c>>d;
	    node temp;
	    temp.x=b;temp.t=c;temp.k=d;
	    g[a].pb(temp);
	    node kemp;
	    kemp.x=a;kemp.t=c;kemp.k=d;
	    g[b].pb(kemp);
	}
    solve(n,x);
    if(d[y]==(ll)1e18)cut(-1)
	//FOR(i,1,n)cout<<d[i]<<' ';
    cut(d[y])

}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll ;
#define rep(i,a,n) for(int i=a ; i<n ; i++)
#define pb push_back

vector<vector<int> > adj ;
vector<ll> val,m ;
vector<bool> vis ;
ll ans ;

ll dfs(int x)
{
	if(vis[x]) return m[x] ;
	ll ma=-1e9 ;
	vis[x]=1 ;
	rep(i,0,adj[x].size())
	{
		ma=max(ma,dfs(adj[x][i])) ;
	}
	ans=max(ans,ma-val[x]) ;
	ma=max(ma,val[x]) ;
	m[x]=ma ;
	return m[x] ;
}

int main()
{
	int T=1;
	// cin >> T ;

	while(T--)
	{
		int n,me ;
		cin>>n>>me ;
		adj.resize(0) ;
		adj.resize(n) ;
		val.resize(n) ;
		rep(i,0,n) cin>>val[i] ;
		m.resize(n) ;
		rep(i,0,n) m[i]=val[i] ;
		int x,y ;
		rep(i,0,me)
		{
			cin>>x>>y ; x-- ; y-- ;
			adj[x].pb(y) ;
		}
		vis.resize(0) ;
		vis.resize(n) ;
		rep(i,0,n) vis[i]=0 ;
		ans=-1e9 ;
		rep(i,0,n)
		{
			if(!vis[i]) 
			{
				dfs(i) ;
				
			}
		}
		
		cout<<ans<<endl ;
	}
	return 0;
}