#4#7双WA,有无大佬帮忙看下
#include<bits/stdc++.h>
#define maxn 10005
using namespace std;
int n,m,cnt,ans,top;
int w[maxn],dfn[maxn],vs[maxn],bol[maxn],val[maxn],dis[maxn],low[maxn],stac[maxn],vis[maxn];
vector<int> e[maxn],g[maxn];
void dfs(int i)
{
low[i]=dfn[i]=++cnt;
stac[++top]=i;
for(int j=0;j<e[i].size();j++) {
int nex=e[i][j];
if(nex==i) continue;
if(!dfn[nex]) {
dfs(nex);
low[i]=min(low[nex],low[i]);
}
else low[i]=min(low[i],dfn[nex]);
}
bol[i]=i; val[i]=w[i];
if(dfn[i]==low[i]) {
int t=stac[top--];
while(t!=i) {
bol[t]=i;
val[i]+=val[t];
t=stac[top--];
}
}
}
void tarjan(int s)
{
dfs(s);
}
struct edge
{
int x,d;
edge(){};
edge(int a,int b) {x=a; d=b;}
bool operator<(const edge &a) const {
return a.d<d;
}
};
priority_queue<edge> q;
void dij(int s)
{
if(!dis[s]) dis[s]=val[s];
q.push(edge(s,dis[s]));
while(!q.empty()) {
edge tt;
tt=q.top();
q.pop();
int now=tt.x;
for(int j=0;j<g[now].size();j++) {
int nex=g[now][j];
if(dis[nex]<dis[now]+val[nex]) {
dis[nex]=dis[now]+val[nex];
q.push(edge(nex,dis[nex]));
}
}
}
for(int i=1;i<=n;i++) ans=max(ans,dis[bol[i]]);
}
void sd()
{
for(int i=1;i<=n;i++)
for(int j=0;j<e[i].size();j++) {
int nex=e[i][j];
int x=bol[i],y=bol[nex];
if(!x) bol[i]=i;
if(!y) bol[nex]=nex;
if(!val[x]) val[x]=w[x];
if(!val[y]) val[y]=w[y];
if(x==y) continue;
g[x].push_back(y);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=m;i++) {
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
sd();
for(int i=1;i<=n;i++) {
int now=bol[i];
if(!vis[now]) dij(now);
vis[now]=1;
}
printf("%d\n",ans);
}