Link to this code: https://cses.fi/paste/d0f62ec82cb4b91269254d/
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
class CoinCollector{
  vector<vector<int>>graph,flipGraph;
  vector<bool>vis;
  vector<int>index;
  stack<int>st;
public:
  vector<int>c;
  CoinCollector(int n){
     graph.resize(n+1);
     flipGraph=graph;
     vis.resize(n+1,false);
     index.resize(n+1);
     c=index;
  }
  void traverse(int u){
    if(vis[u])return;
    vis[u]=true;
    for(int v:graph[u]){
      traverse(v);
    }
    st.push(u);
  }
  void revTraverse(int u,int i){
   if(vis[u])return;
    vis[u]=true;
    index[u]=i;
    for(int v:flipGraph[u]){
      revTraverse(v,i);
    } 
  }
  long long solveDP(vector<long long>&cost,vector<long long>&dp,int u,vector<int>*g){
    if(dp[u]!=-1){
      return dp[u];
    }
    long long ans=0;
    for(int v:g[u]){
      ans=max(ans,solveDP(cost,dp,v,g));
    }
    return dp[u]=ans+cost[u];
  }
  long long getSol(int n){
    for(int i=1;i<=n;i++){
      if(!vis[i]){
        traverse(i);
      }
    }
    fill(vis.begin(),vis.end(),false);
    int num,ind=1;
    while(!st.empty()){
      num=st.top();
      st.pop();
      if(!vis[num]){
        revTraverse(num,ind++);
      }
    }
      fill(vis.begin(),vis.end(),false);
    vector<long long>cost(ind,0),dp(ind,-1);
    for(int i=1;i<=n;i++){
      cost[index[i]]+=c[i];
    }
    long long ans=0;
    vector<int>g[ind];
    for(int i=1;i<=n;i++){
      for(int j:graph[i]){
        if(index[i]!=index[j]){
          g[index[i]].push_back(index[j]);
        }
      }
    }

    for(int i=1;i<ind;i++){
        ans=max(ans,solveDP(cost,dp,i,g));
    }
    return ans;
  }
  void addEdge(int a,int b){
    graph[a].push_back(b);
    flipGraph[b].push_back(a);
  }
};
int main(){
   int n,m,a,b;
   cin>>n>>m;
   CoinCollector sol(n);
   for(int i=1;i<=n;i++){
    cin>>sol.c[i];
   }
   for(int i=0;i<m;i++){
      cin>>a>>b;
      sol.addEdge(a,b);
   }
   cout<<sol.getSol(n);
  return 0;
}