#include<bits/stdc++.h>
using namespace std;
const int maxn = 5000050;
int dfn[maxn],low[maxn],dfs_clock,sccno[maxn],scc_cnt;
stack<int> S;
int n,m;
int h[maxn],cnt,h1[maxn],cnt1;
int size[maxn];//记录每个强连通分量里的点权和;
int a[100010];
int f[maxn],ans,maxnn;
struct node{
int to,nxt;
}e[maxn],ee[maxn];
void add(int u,int v){
e[++cnt].to = v;
e[cnt].nxt = h[u];
h[u] = cnt;
}
void add1(int u,int v){
ee[++cnt1].to = v;
ee[cnt1].nxt = h1[u];
h1[u] = cnt1;
}
void tarjan(int u){
dfn[u] = low[u] = ++dfs_clock;
S.push(u);
for(int i = h[u] ; i ; i = e[i].nxt){
int v = e[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(!sccno[v]){
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u] == low[u]){
scc_cnt++;
while(true){
int v = S.top();
S.pop();
sccno[v] = scc_cnt;
size[scc_cnt] += a[v];
if(v == u){
break;
}
}
}
}
void search(int x){//记忆化搜索
if(f[x]){
return;
}
f[x] = size[x];
for(int i = h1[x] ; i ; i = ee[i].nxt){
int v = ee[i].to;//遍历能到达的点;
if(!f[v]){
search(v);
}
maxnn = max(maxnn,f[v]);
}
f[x] += maxnn;//不断记录更新f
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin >> n >> m;
for(int i = 1 ; i <= n ; i++){
cin >> a[i];
}
for(int i = 1 ; i <= m ; i++){
int u,v;
cin >> u >> v;
add(u,v);
}
for(int i = 1 ; i <= n ; i++){
if(!dfn[i]){
tarjan(i);
}
}
for(int i = 1 ; i <= n ; i++){
for(int j = h[i] ; j ; j = e[j].nxt){
int v = e[j].to;
int a = sccno[i];
int b = sccno[v];
if(a != b){
add1(a,b);
}
}
}
for(int i = 1 ; i <= scc_cnt ; i++){
if(!f[i]){//遍历新图的每一个点
search(i);
ans = max(ans,f[i]);
}
}
cout << ans << endl;
return 0;
}