$$ Tarjan $$
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e4 + 12;
#define re register
int n, m, idx, tim, top, s; // tim (dfs) 次数
int head[N], p[N], sd[N], dfn[N], low[N];
int stac[N], st[N];
int h[N], in[N], dis[N];
struct node{
int to;
int from;
int next;
}edge[N << 3], ed[N << 3];
void add(int u, int v){
edge[++idx].to = v;
edge[idx].from = u;
edge[idx].next = head[u];
head[u] = idx;
}
void Tarjan(int u){
low[u] = dfn[u] = ++tim;
stac[++ top] = u;
st[u] = 1;
for(re int i = head[u]; i; i = edge[i].next)
{
int v = edge[i].to;
if(!dfn[v]){
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(st[v]){
low[u] = min(low[u], low[v]);
}
}
if(dfn[u] == low[u]){
int y;
while(y = stac[top --]){
sd[y] = u;
st[y] = 0;
if(u == y) break;
p[u] += p[y];
}
}
}
int topo()
{
queue<int>q;
int tot = 0;
for(re int i = 1;i <= n;i ++)
if(sd[i] == i && !in[i])
q.push(i),dis[i] = p[i];
while(!q.empty())
{
int u = q.front();
q.pop();
for(re int i = h[u]; i; i = ed[i].next)
{
int v = ed[i].to;
dis[v] = max(dis[v], dis[u] + p[v]);
in[v] --;
if(in[v] == 0)
q.push(v);
}
}
int ans = 0;
for(re int i = 1;i <= n;i ++)
ans = max(ans, dis[i]);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(re int i = 1;i <= n;i ++) scanf("%d",&p[i]);
for(re int i = 1;i <= m;i ++) {
int u, v;
scanf("%d%d",&u, &v);
add(u,v);
}
for(re int i = 1;i <= n;i ++)
if(!dfn[i]) Tarjan(i);
for(re int i = 1;i <= m;i ++){
int u = sd[edge[i].from],v = sd[edge[i].to];
if(u != v){
ed[++s].next = h[u];
ed[s].to = v;
ed[s].from = u;
h[u] = s;
in[v] ++;
}
}
printf("%d\n", topo());
return 0;
}