#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>
#include <cstddef>
#include <type_traits>
#include <vector>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define rep(i, n) for(int i=0;i<(int)(n);i++)

// トポソ
// O(V + E)
// [入力] 重みなし有効グラフ
// [出力] ソートされた頂点列(0-indexed) DAG じゃ無い場合は空列を返す
// verify http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_4_B
vector<int> toposort(vector<vector<int>> &g){
    int n = (int)g.size();
    vector<int> d(n, 0);     // 入次数
    for(int i = 0; i < n; i++){
        for(int j = 0; j < (int)g[i].size(); j++){
            d[g[i][j]]++;
        }
    }
     
    // 入次数が 0 の頂点を queue に入れる
    queue<int> que;
    for(int i = 0; i < n; i++){
        if(d[i] == 0) que.push(i);
    }
 
    vector<int> ret;
    while(!que.empty()){
        int cur = que.front();
        que.pop();
        ret.push_back(cur);
 
        for(int i = 0; i < (int)g[cur].size(); i++){
            int nxt = g[cur][i];
            d[nxt]--;
            if(d[nxt] == 0) que.push(nxt);
        }
    }
 
    // DAG じゃなかったら、頂点列が不足しているはず
    if(ret.size() == n) return ret;
    else return vector<int>();
}

int main() {
  
  lint n, m; cin >> n >> m;
  vector<vector<lint>> dp(n, vector<lint>(2, -INF));
  vector<lint> a(n);
  rep (i, n) cin >> a[i];

  vector<vector<int>> g(n);
  rep (i, m) {
    int x, y; cin >> x >> y;
    x--;
    y--;
    g[x].push_back(y);
  }

  vector<int> nodes = toposort(g);
  assert(nodes.size() != 0);

  for (auto node : nodes) {
    // 買う
    dp[node][0] = max(dp[node][0], -a[node]);

    for (auto nxt : g[node]) {
      // うらない
      dp[nxt][0] = max(dp[nxt][0], dp[node][0]);

      // 売る
      dp[nxt][1] = max(dp[nxt][1], dp[node][0] + a[nxt]);
    }
  }

  lint ans = -INF;
  for (int node = 0; node < n; node++) {
    ans = max(ans, dp[node][1]);
  }
  cout << ans << endl;
  return 0;
}

#include<bits/stdc++.h>
#define int long long
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pi;
const int mod = 1e9 + 7;
const int nax = 1e6;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int a[nax], dp[nax], deg[nax], mn[nax];
vector<int> E[nax];

int32_t main() {
 
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        mn[i] = 2e18;
        dp[i] = -2e18;
    }
    for(int i = 1; i <= n; i++) cin >> a[i];
        
    for(int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        E[x].pb(y);
        deg[y]++;
    }

    queue<int> Q;
    vector<int> ord;
    for(int i = 1; i <= n; i++) {
        if(!deg[i]) {
            Q.push(i);
        }
    }

    while(Q.size()) {
        int node = Q.front();
        Q.pop();
        ord.pb(node);
        for(auto it : E[node]) {
            deg[it]--;
            if(!deg[it]) {
                Q.push(it);
            }
        }
    }

    int ans = -2e18;

    for(auto x : ord) {
        mn[x] = min(mn[x], a[x]);
        for(auto it : E[x]) {
            ans = max(ans, a[it] - mn[x]);
            mn[it] = min(mn[it], mn[x]);
        }
    }
    cout << ans << '\n';
    
    
    return 0;
}
 


// 9