// $%D%$.$%M%$.$%Y%$
// $%h%$:$%m%$:$%s%$

#pragma GCC optimize("O3")

#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;

#define IOS ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ld long double
#define rep(i,a,n) for (int i=(int)(a);i<(int)(n);i++)
#define per(i,a,n) for (int i=(int)(n-1);i>=(int)(a);i--)
#define mp(a, b) make_pair(a, b)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pil pair<int, ll>
#define pli pair<ll, int>
#define fi first
#define se second


const int MOD = 1e9+7; // 998244353; // = (119<<23)+1
const int MX = 2e5+5;
const ll INF = 1e18;
const ld PI = 4*atan((ld)1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};


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


int cmp(pii a, pii b) {
    swap(a.first, a.second);
    swap(b.first, b.second);
    return a < b;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<ll> a(n), dp(n, 1e18);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<pll> e(m);

    for (int i = 0; i < m; ++i) {
        cin >> e[i].first >> e[i].second;
        --e[i].first, --e[i].second;
    }
    ll res = -1e18;

    sort(e.begin(), e.end(), cmp);
    for (auto x : e) {
        dp[x.second] = min(dp[x.second], dp[x.first]);
        dp[x.second] = min(dp[x.second], a[x.first]);

        res = max(res, a[x.second] - dp[x.second]);
    }

    cout << res << '\n';
}
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
constexpr int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

std::vector<int> topological_sort(const std::vector<std::vector<int>> &graph) {
  int n = graph.size();
  std::vector<int> deg(n, 0);
  for (int i = 0; i < n; ++i) {
    for (int e : graph[i]) ++deg[e];
  }
  std::queue<int> que;
  for (int i = 0; i < n; ++i) {
    if (deg[i] == 0) que.emplace(i);
  }
  std::vector<int> res;
  while (!que.empty()) {
    int ver = que.front(); que.pop();
    res.emplace_back(ver);
    for (int e : graph[ver]) {
      if (--deg[e] == 0) que.emplace(e);
    }
  }
  return res.size() == n ? res : std::vector<int>();
}

int main() {
  int n, m; cin >> n >> m;
  vector<int> a(n); REP(i, n) cin >> a[i];
  vector<vector<int>> graph(n);
  while (m--) {
    int x, y; cin >> x >> y; --x; --y;
    graph[x].emplace_back(y);
  }
  vector<int> ts = topological_sort(graph);
  int ans = -INF;
  vector<int> dp(n, -INF);
  for (int i = n - 1; i >= 0; --i) {
    int town = ts[i];
    for (int e : graph[town]) chmax(dp[town], max(dp[e], a[e]));
    chmax(ans, dp[town] - a[town]);
  }
  cout << ans << '\n';
  return 0;
}
