#include<bits/stdc++.h>
#define re register
#define il inline
#define inf 0x3f3f3f3f
#define Wanderer 0
using namespace std;
const int MAXN = 1e5+5;
int n, m;
int tot, head1[MAXN], head2[MAXN], sum, val[MAXN], valat[MAXN];
int dfn[MAXN], low[MAXN], cnt, at[MAXN], num, vis[MAXN], dp[MAXN], ans, maxx = -inf;
bool book[MAXN];
stack <int> s;
struct node {
int to, next;
} edge[MAXN], now[MAXN];
il void add1(int x, int y) {
edge[++tot].next = head1[x];
edge[tot].to = y;
head1[x] = tot;
}
il void add2(int x, int y) {
now[++sum].next = head2[x];
now[sum].to = y;
head2[x] = sum;
}
void tarjan(int u) {
dfn[u] = low[u] = ++cnt;
s.push(u);
book[u] = true;
for (re int k = head1[u]; k; k = edge[k].next) {
int v = edge[k].to;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (book[v])
low[u] = min(low[u], low[v]);
}
if (dfn[u] == low[u]) {
num++;
int t;
do {
t = s.top();
s.pop();
book[t] = false;
at[t] = num;
} while (t != u);
}
}
il void build() {
for (re int i = 1; i <= n; ++i)
for (re int j = head1[i]; j; j = edge[j].next)
if (at[i] != at[edge[j].to]) {
add2(at[i], at[edge[j].to]);
vis[at[edge[j].to]]++;
}
for (re int i = 1; i <= n; ++i)
valat[at[i]] += val[i];
}
il void toposort() {
queue <int> q;
for (re int i = 1; i <= num; ++i)
if (!vis[i])
q.push(i);
while (!q.empty()) {
int v = q.front();
int ans = dp[v] = valat[v];
q.pop();
for (re int i = head2[v]; i; i = now[i].next) {
dp[now[i].to] = valat[now[i].to] + ans;
ans = dp[now[i].to];
}
if (!(--vis[now[v].to]))
q.push(vis[now[v].to]);
}
for (re int i = 1; i <= num; ++i)
maxx = max(dp[i], maxx);
cout << maxx << endl;
}
int main() {
cin >> n >> m;
for (re int i = 1; i <= n; ++i)
cin >> val[i];
for (re int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
add1(x, y);
}
for (re int i = 1; i <= n; ++i)
if (!dfn[i])
tarjan(i);
build();
toposort();
return Wanderer;
}