#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int a[N],low[N],dfn[N],ti=0;
int in[N],sec[N];
int vis[N];
int s[N],top=0;
int cnt=0,head[N],head2[N];
struct node{
int u,v,nxt;
node(){u=v=0;}
}edge[N],edge2[N];
inline int read(){
int x=0;
bool f=true;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')f=false;
for(;isdigit(ch);ch=getchar())
x=(x<<1)+(x<<3)+ch-'0';
return f?x:~(x-1);
}
inline void add(int u,int v){
edge[++cnt].u=u;
edge[cnt].v=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
inline void add2(int u,int v){
edge2[++cnt].u=u;
edge2[cnt].v=v;
edge2[cnt].nxt=head2[u];
head2[u]=cnt;
in[v]++;
}
void dfs(int k){
s[++top]=k;
vis[k]=1;
dfn[k]=++ti,low[k]=ti;
for(int i=head[k];i;i=edge[i].nxt){
int v=edge[i].v;
if(dfn[v]==0){
dfs(v);
low[k]=min(low[k],low[v]);
}else if(vis[v])low[k]=min(low[k],dfn[v]);
}
if(dfn[k]==low[k]){
int x;
while(x=s[top--]){
sec[x]=k;
vis[x]=0;
if(x==k)break;
a[k]+=a[x];
}
}
}
int toupu(){
queue<int>q;
int ans[N],sum=0;
for(int i=1;i<=n;i++){
if(sec[i]==i&&!in[i]){
q.push(i);
ans[i]=a[i];
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head2[u];i;i=edge2[i].nxt){
int v=edge2[i].v;
ans[v]=max(ans[v],ans[u]+a[v]);
if(--in[v]==0)q.push(v);
}
}
for(int i=1;i<=n;i++){
sum=max(sum,a[i]);
}
return sum;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=m;i++){
int u=read(),v=read();
add(u,v);
}
for(int i=1;i<=n;i++){
if(dfn[i]==0)
dfs(i);
}
cnt=0;
for(int i=1;i<=m;i++){
int u=sec[edge[i].u],v=sec[edge[i].v];
if(u!=v)add2(u,v);
}
int ans=toupu();
printf("%d\n",ans);
return 0;
}