#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<string>
#include<vector>
#include<cmath>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define lch rt<<1
#define rch rt<<1|1
#define P pair<ll,ll>
const ll maxn = 100000;
const ll N = 100005;
const ll mod = 998244353;
const ll mod2 = 1000000009;
ll read() {
char c = getchar(); ll x = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {x = x * 10 + c - '0'; c = getchar();}
return x * f;
}
template<class T> void gmax(T& a, T b) {
if(a < b) a = b;
}
template<class T> void gmin(T& a, T b) {
if(a > b) a = b;
}
ll head[maxn],cnt;
struct Edge{
ll to,next,from;
}edge[maxn],ee[maxn];
void addEdge(ll u, ll v) {
edge[++cnt].to = v;
edge[cnt].next = head[u];
edge[cnt].from = u;
head[u] = cnt;
}
ll cc;
ll hh[maxn];
void add(ll u, ll v) {
ee[++cc].to = v;
ee[cc].next = hh[u];
hh[u] = cc;
}
ll dfn[maxn],low[maxn],num;
ll Stack[maxn],t;
bool out[maxn];
ll p[maxn];
ll point[maxn];
ll n,m;
void tarjan(ll u) {
dfn[u] = low[u] = ++num;
Stack[++t] = u;
for(ll iter = head[u]; iter; iter = edge[iter].next) {
ll v = edge[iter].to;
if(dfn[v] == 0) {
tarjan(v);
gmin(low[u],low[v]);
}else if(!out[v]) {
low[u] = low[v];
}
}
if(dfn[u] == low[u]) {
while(Stack[t] != u) {
ll v = Stack[t];
// printf("%d ",v);
p[v] = u;
point[u] += point[v];
out[Stack[t--]] = true;
}
p[Stack[t]] = u;
out[Stack[t--]] = true;
// printf("%d\n",Stack[t+1]);
}
}
ll inde[maxn];
ll dis[maxn];
int main() {
freopen("input.in","r",stdin);
n = read(), m = read();
for(ll i = 1; i <= n; i++) point[i] = read();
for(ll i = 1; i <= m; i++) {
int u = read(),v = read();
addEdge(u,v);
}
// for(ll i = 1; i <= n; i++) p[i] = i;
for(ll i = 1; i <= n; i++) {
if(!dfn[i]) tarjan(i);
}
// for(int i = 1; i <= n; i++) {
// if(i == p[i]) printf("%d:%d\n",i,p[i]);
// }
// for(u = 1; u <= n; u++) {
// for(ll iter = head[u]; iter; iter = edge[iter].next) {
// v = edge[iter].to;
// if(p[u] != p[v]) {
// // printf("%d %d\n",p[u],p[v]);
// add(p[u],p[v]);
// inde[p[v]]++;
// }
// }
// }
for(int i = 1; i <= m; i++) {
int u = edge[i].from, v = edge[i].to;
u = p[u], v = p[v];
if(u != v) {
add(u,v);
inde[v]++;
}
}
queue<ll> q;
for(ll i = 1; i <= n; i++) {
if(i == p[i] && inde[i] == 0) {
printf("%d\n",i);
q.push(i);
dis[i] = point[i];
}
}
while(!q.empty()) {
int u = q.front(); q.pop();
for(ll iter = hh[u]; iter; iter = ee[iter].next) {
int v = ee[iter].to;
inde[v]--;
gmax(dis[v],dis[u] + point[v]);
if(inde[v] == 0) {
q.push(v);
}
}
}
ll ans = 0;
for(ll i = 1; i <= n; i++) {
if(i == p[i]) {
gmax(ans,dis[i]);
}
}
printf("%lld",ans);
return 0;
}