#include<bits/stdc++.h>
using namespace std;
 
typedef long long ll; 
const int N=2e5+5;
 
int res=INT_MIN,a[N],mark[N],m,n;
vector<int> adj[N];
 
void dfs(int u){
  for(int v: adj[u]){
    if(mark[v]==INT_MIN)dfs(v);
    mark[u]=max(mark[u],mark[v]);
    res = max(res,mark[u]-a[u]);
  }
  mark[u]=max(a[u],mark[u]);
}
 
int main() {
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;++i){
    scanf("%d",&a[i]);
    mark[i]=INT_MIN;
  }
  while(m--){
    int u,v;
    scanf("%d%d",&u,&v);
    adj[u].push_back(v);
  }
  for(int i=1;i<=n;++i)if(mark[i]==INT_MIN){
    dfs(i);
  }
  cout << res;
}

#include <bits/stdc++.h>

#define speedup ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr),cout.precision(12)
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef tree<int, int, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_map;
#define sbc __builtin_popcount
#define pb push_back
#define pbk pop_back
#define em emplace
#define emb emplace_back
#define ff first
#define ss second
#define ll long long
const ll mod = 1e9 + 7;

template<typename T> void smax(T& a, T b) { if(a<b) a=b; }
template<typename T> void smin(T& a, T b) { if(a>b) a=b; }
template<typename T> T pw(T a,T b) { T p=1,one=1; while(b) { if(b&one) p=p*a; a=a*a; b >>=1; } return p; }
template<typename T> T pwm(T a,T b,T md=mod) { T p=1,one=1; while(b) { if(b&one) p=p*a%md; a=a*a%md; b >>=1; } return p; }

template<typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (auto &it:v)
        is >> it;
    return is;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &it) {
    os << it.first << ' ' << it.second;
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const array<T, 2> &v) {
    for (auto &it : v) os << it << ' ';
    return os;
}

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for (auto &it : v)
        os << it << ' ';
    return os;
}

#ifndef ONLINE_JUDGE
class Timer { chrono::high_resolution_clock::time_point start_t, end_t; public: Timer() { start_t=chrono::high_resolution_clock::now(); } ~Timer() { end_t = chrono::high_resolution_clock::now(); auto duration = chrono::duration_cast<chrono::milliseconds>(end_t-start_t); cerr<<"\nRunTime: "<<duration.count()<<"ms"<<'\n'; } };
void debug() { cerr << '\n'; }

template<typename T, typename... Args>
void debug(T print, Args... args) {
    cerr << ' ' << print;
    debug(args...);
}

#define deb(...) cerr << "[" << #__VA_ARGS__ << "]" << " --> ", debug(__VA_ARGS__)
#else
#define deb(...) void(0)
#endif
void solve() {	
	int n,m;
	cin>>n>>m;
	vector<vector<int>> g(n);
	int a[n],mx[n];
	for(int i=0;i<n;++i) {
		cin>>a[i];
		mx[i]=-1;
	}
	for(int i=0,x,y;i<m;++i) {
		cin>>x>>y, --x, --y;
		g[y].pb(x);
	}
	for(int i=0;i<n;++i)
		deb(a[i]),deb(g[i]);
	int ans=INT_MIN;
	for(int i=n-1;~i;--i) {
		int val=a[i];
		if(~mx[i]) {
			smax(val,mx[i]);
			smax(ans,mx[i]-a[i]);
		}
		for(const auto& j:g[i])
			smax(mx[j], val);
	}
	cout<<ans<<'\n';
}
int main() {
    speedup;
    //int t; cin >> t; while (t--)
	solve();
}
/**Vim
 *
 *
 *
 *
 *
 *
 *
 *
 */
