#include<iostream>
#include<cstdio>
#include<stack>
#include<queue>
#include<stdbool.h>
using namespace std;
const int SIZE=1e5;
int _max(int x,int y){return x>y?x:y;}
stack<int> st;
queue<int> qu;
struct Edge{
int v,next;
}edge[SIZE+10];
Edge ned[SIZE+10];
int head[SIZE+10],head1[SIZE+10],a[10010],cnt,cnt1;
int dfn[10010],low[10010],q[10010],tot,tot1;
int belong[10010],topn[10010],from[10010],cnt2;
int dp[10010];
bool vis[10010];
void add_edge(int u,int v){
edge[++cnt].next=head[u];
edge[cnt].v=v;
head[u]=cnt;
}
void add_edge1(int u,int v){
ned[++cnt1].next=head1[u];
ned[cnt1].v=v;
head1[u]=cnt1;
}
void tarjan(int u){
dfn[u]=++tot;
low[u]=tot;
vis[u]=true;
st.push(u);
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
if(vis[u]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
tot1++;
vis[u]=false;
while(st.size()!=0)
{
int x=st.top();st.pop();
belong[x]=tot1;
q[tot1]+=a[x];
vis[u]=false;
}
}
}
void topsort(){
for(int i=1;i<=tot1;i++)
if(!from[i])
qu.push(i);
while(!qu.empty())
{
int x=qu.front();qu.pop();
topn[++cnt2]=x;
for(int i=head[x];i;i=edge[i].next)
from[edge[i].v]--;
for(int i=1;i<=tot1;i++)
if(!from[i])
qu.push(i);
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
tarjan(1);
// for(int i=1;i<=n;i++)
// cout<<belong[i]<<" ";
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].next)
{
int v=edge[i].v;
if(belong[v]!=belong[i])
{
add_edge1(i,v);
from[v]++;
}
}
}
topsort();
dp[topn[1]]=q[topn[1]];
for(int i=1;i<=tot1;i++)
{
int u=topn[i];
for(int j=head[u];j;j=ned[j].next)
{
int v=ned[j].v;
dp[v]=max(dp[v],dp[u]+q[v]);
}
}
int ans=0;
for(int i=1;i<=tot1;i++)
ans=_max(ans,dp[i]);
printf("%d",ans);
return 0;
}
感谢dalao