link

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <cstring>
#include <queue>
#include <stack>
# define LL long long
using namespace std;
const int maxn = 10000 + 10;
const int maxm = 100000 + 10;
int w[maxn];
int sccw[maxn];
int ui[maxm];
int vi[maxm];
struct Edge {
int to;
int next;
}e1[maxm],e2[maxm];
int head1[maxn];
int head2[maxn];
int en1;
int en2;
void addEdge1(int from, int to) {
e1[en1].next = head1[from];
e1[en1].to = to;
head1[from] = en1++;
}
void addEdge2(int from, int to) {
e2[en2].next = head2[from];
e2[en2].to = to;
head2[from] = en2++;
}
int timer;
int scc_num;
int col[maxn];
int dict[maxn];
int low[maxn];
stack<int> stk;
int instack[maxn];
int indeg[maxn];
int dp[maxn];
void tarjan(int u) {
stk.push(u);
instack[u] = 1;
++timer;
dict[u] = timer;
low[u] = timer;
for (int i = head1[u]; i != -1; i = e1[i].next) {
int v = e1[i].to;
if (dict[v] == -1) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else {
if (instack[v]) {
low[u] = min(low[u], dict[v]);
}
}
}
if (low[u] == dict[u]) {
++scc_num;
while (stk.top() != u) {
int t = stk.top();
stk.pop();
col[t] = scc_num;
sccw[scc_num] += w[t];
instack[t] = 0;
}
stk.pop();
instack[u] = 0;
col[u] = scc_num;
sccw[scc_num] += w[u];
}
}
int main() {
memset(head1, -1, sizeof(head1));
memset(head2, -1, sizeof(head2));
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
for (int i = 0; i < m; i++) {
scanf("%d%d", &ui[i], &vi[i]);
addEdge1(ui[i], vi[i]);
}
memset(dict, -1, sizeof(dict));
for (int i = 1; i <= n; i++) {
if (dict[i] == -1) {
tarjan(i);
}
}
vector<unordered_set<int>> added(scc_num + 1);
for (int i = 0; i < m; i++) {
if (col[ui[i]] == col[vi[i]]) continue;
int u = col[ui[i]];
int v = col[vi[i]];
if (added[u].find(v) != added[u].end()) continue;
added[u].insert(v);
addEdge2(u, v);
indeg[v]++;
}
queue<int> q;
int res = 0;
for (int i = 1; i <= scc_num; i++) {
if (indeg[i] == 0) {
q.push(i);
dp[i] = sccw[i];
res = max(res, dp[i]);
}
}
while (!q.empty()) {
int cur = q.front();
q.pop();
for (int i = head2[cur]; i != -1; i = e2[i].next) {
int v = e2[i].to;
dp[v] = max(dp[v], dp[cur] + sccw[v]);
res = max(res, dp[v]);
indeg[v]--;
if (indeg[v] == 0) q.push(v);
}
}
printf("%d", res);
return 0;
}