#include<bits/stdc++.h>
#define read(a) scanf("%d",&a)
using namespace std;
const int N=1e5+5;
int n,m,l,r,tim,top,cnt,rq,num;
int v[N],dfn[N],low[N],stak[N],col[N],rd[N],que[N],f[N],sum[N];
vector<int>a[N];
vector<int>b[N];
void tarjan(int x){
dfn[x]=low[x]=++tim;
stak[++top]=x;
for(auto i:a[x]){
if(!dfn[i]){//没被访问过
tarjan(i);
low[x]=min(low[x],low[i]);
}
else if(!col[i]){//还在栈中,属于是一个强连通分量里的
low[x]=min(low[x],low[i]);
}
}
if(dfn[x]==low[x]){//如果自己是强连通分量的头
col[x]=++cnt;
sum[cnt]=v[x];
// printf("lll=%d\n",x);
while(stak[top]!=x){
sum[cnt]+=v[stak[top--]];
col[stak[top]]=cnt;
// printf("col=%d\n",stak[top]);
}
top--;
}
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++){
read(v[i]);
}
for(int i=1;i<=m;i++){
read(l);read(r);
a[l].push_back(r);
}
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
// for(int i=1;i<=n;i++){//便于理解
// printf("i=%d %d %d %d %d %d\n",i,dfn[i],low[i],col[i],sum[i],cnt);
// }
for(int i=1;i<=n;i++){//建图
for(auto j:a[i]){
if(col[i]!=col[j]){
b[col[i]].push_back(col[j]);//缩点后col相当于新的点编号
rd[col[i]]++;
}
}
}
// for(int i=1;i<=cnt;i++){
// for(auto j:b[i]){
// printf("%d %d %d\n",i,j,sum[j]);
// }
// }
for(int i=1;i<=cnt;i++){//建边之后cnt为新的点数
if(!rd[i]){
que[++rq]=i;
// printf("%d\n",f[i]);
}
f[i]=sum[i];
// num=max(f[i],num);
}
for(int i=1;i<=rq;i++){
for(auto j:b[que[i]]){
f[j]=max(f[j],f[que[i]]+sum[j]);
if(!--rd[j]){
que[++rq]=j;
}
num=max(f[j],num);
}
}
printf("%d",num);
}
/*
6 11
1
2
3
4
5
6
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
6 4
5 3
3 1*/