#include<bits/stdc++.h>
using namespace std;
using cint = const int&;
const int maxn = 1e5 + 10;
struct {
int nxt, v;
}edge[maxn], tpe[maxn];
int head[maxn], tph[maxn], cnt, tpcnt, in[maxn];
inline void addedge(cint u, cint v) {
edge[++cnt] = { head[u],v };
head[u] = cnt;
}
inline void addtpe(cint u, cint v) {
tpe[++tpcnt] = { tph[u],v };
tph[u] = tpcnt;
++in[v];
}
stack<int> sta;
int n, m, u, v, dfn[maxn], scc[maxn], low[maxn], dfns, val[maxn];
void tarjan(cint u) {
dfn[u] = low[u] = ++dfns;
sta.push(u);
for (auto i = head[u]; i; i = edge[i].nxt) {
const int v = edge[i].v;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[v], low[u]);
}
else if (!scc[v]) low[u] = min(dfn[v], low[u]);
}
if (low[u] == dfn[u]) {
scc[u] = u;
while (sta.top() != u) {
scc[sta.top()] = u;
val[u] += val[sta.top()];
sta.pop();
}
sta.pop();
}
}
inline void rebuild() {
for (int i = 1; i <= n; ++i)
for (int j = head[i]; j; j = edge[j].nxt)
if (scc[i] != scc[j])
addtpe(scc[i], scc[j]);
}
int p[maxn];
inline void toposort() {
queue<int> q;
for (int i = 1; i <= n; ++i)
if (!in[i] && scc[i] == i)
q.push(i), p[i] = val[i];
while (!q.empty()) {
const int u = q.front();
q.pop();
for (int i = tph[u]; i; i = tpe[i].nxt) {
const int v = tpe[i].v;
val[v] = max(val[v], val[u] + p[v]);
if (--in[v] == 0) q.push(v);
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> val[i];
for (int i = 1; i <= m; ++i) {
cin >> u >> v;
addedge(u, v);
}
for (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i);
rebuild();
toposort();
int maxv = 0;
for (int i = 1; i <= n; ++i) maxv = max(maxv, val[i]);
cout << maxv;
}
WA, 40pts