#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
public:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;

void dfs(const int now, const vector<vector<int>>&edges, vector<int>&colors,int num) {
	colors[now]=num;
	for (auto e : edges[now]) {
		if(dscc.unis[now]!=dscc.unis[e])continue;
		else {
			if (num != 2) {
				if (colors[e] == num) {
					dfs(e, edges, colors, 2);
					
				}
				else if (colors[e] + num == 1) {

				}
				else if(colors[e]!=2){
					dfs(e,edges,colors,!num);
				}
			}
			else {
				if (colors[e] == 2) {

				}
				else {
					dfs(e,edges,colors,2);
				}
			}
			
		}
	}
}

void cango(const int now, const vector<vector<int>>&edges,vector<int>&can) {
	can[now]=true;
	for (auto e : edges[now]) {
		if(!can[e])cango(e,edges,can);
	}
}
int main() {
	int N,M;
	vector<int>cs;
	cin >> N >> M;
	vector<vector<int>>edges(N);
	{
		for (int i = 0; i < N; ++i) {
			int a; cin >> a;
			cs.push_back(a);
		}
		for (int i = 0; i < M; ++i) {
			int a, b; cin >> a >> b;
			edges[a].push_back(b);
		}
		vector<int>can(N);
		cango(0, edges, can);
		map<int,int>mp;
		int id=0;
		vector<int>ncs;
		for (int i = 0; i < N; ++i) {
			if (can[i]) {
				mp[i] = id++;
				ncs.push_back(cs[i]);
			}
		}
		vector<vector<int>>nedges(ncs.size());
		for (int i = 0; i < N; ++i) {
			if (can[i]) {
				for (int j = 0; j < edges[i].size(); ++j) {
					if (can[i] && can[edges[i][j]]) {
						nedges[mp[i]].push_back(mp[edges[i][j]]);
					}
				}
			}
		}
		cs=ncs;
		edges=nedges;
		N=cs.size();
	}
	
	auto p=dscc.get(edges);
	vector<int>colors(N,-1);
	for (int i = 0; i < N; ++i) {
		if (colors[i] == -1) {

			dfs(i, edges, colors, 0);
		}
	}

	vector<vector<pair<int,bool>>>nextedges(p.second.size());
	vector<vector<int>>sums(p.second.size(),vector<int>(2));
	vector<int>comes(p.second.size());
	vector<int>biparates(p.second.size());
	for (int i = 0; i < N; ++i) {
		if (colors[i] == 2) {
			sums[dscc.unis[i]][0]+=cs[i];
			biparates[dscc.unis[i]]=false;
		}
		else {
			biparates[dscc.unis[i]]=true;
			sums[dscc.unis[i]][colors[i]]+=cs[i];
			
		}
		for (auto e : edges[i]) {
			if (dscc.unis[i] != dscc.unis[e]) {
				const int from=dscc.unis[i];
				const int to=dscc.unis[e];
				if (colors[i] == 2 || colors[e] == 2) {
					nextedges[from].push_back(make_pair(to,true));
				}
				else {
					nextedges[from].push_back(make_pair(to,colors[i]==colors[e]));
				}
				comes[to]--;
			}
		}
	}
	queue<int>que;
	vector<vector<int>>memo(p.second.size(),vector<int>(2,-1e9));


	memo[0][0]=sums[0][0];
	que.push(0);
		
	
	while (!que.empty()) {
		const int now=que.front();
		que.pop();
		for (auto e : nextedges[now]) {
			const int next=e.first;
			comes[next]++;
			if(!comes[next])que.push(next);
			if (!biparates[next]) {
				const int nextcost=max(memo[now][0],memo[now][1])+sums[next][0];
				if (nextcost > memo[next][0]) {
					memo[next][0]=nextcost;
				}
			}
			else if(!biparates[now]){
				for (int i = 0; i < 2; ++i) {
					const int nextcost=memo[now][0]+sums[next][i];
					if (nextcost > memo[next][i]) {
						memo[next][i]=nextcost;
					}
				}
			}
			else {
				for (int i = 0; i < 2; ++i) {
					if (!e.second) {
						const int nextcost = memo[now][i] + sums[next][i];
						if (nextcost > memo[next][i]) {
							memo[next][i] = nextcost;
						}
					}
					else {
						const int nextcost=memo[now][i]+sums[next][!i];
						if (nextcost > memo[next][!i]) {
							memo[next][!i]=nextcost;
						}
					}
				}
			}
		}
	}
	int ans=0;
	for (int i = 0; i < memo.size(); ++i) {
		for (int j = 0; j < 2; ++j) {
			ans=max(ans,memo[i][j]);
		}
	}
	cout<<ans<<endl;
	return 0;
}

Measured memory_bytes: 47228