#include<bits/stdc++.h>

using namespace std;

#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));

#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);


struct UnionFind
{
  vector< int > data;

  UnionFind(int sz)
  {
    data.assign(sz, -1);
  }

  bool unite(int x, int y)
  {
    x = find(x), y = find(y);
    if(x == y) return (false);
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k)
  {
    if(data[k] < 0) return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k)
  {
    return (-data[find(k)]);
  }
};

struct Bipartite_Graph : UnionFind
{
  vector< int > color;
  bool las;

  Bipartite_Graph(int v) : color(v + v, -1), UnionFind(v + v), las(false) {}

  bool bipartite_graph_coloring()
  {
    for(int i = 0; i < color.size() / 2; i++) {
      int a = find(i);
      int b = find(i + (int) color.size() / 2);
      if(a == b) return (las = false);
      if(color[a] < 0) color[a] = 0, color[b] = 1;
    }
    return (las = true);
  }

  bool operator[](int k)
  {
    if(!las) return (0);
    return (bool(max(0, color[find(k)])));
  }
};

struct StronglyConnectedComponents
{
  vector< vector< int > > gg, rg;
  vector< int > comp, order, used;

  StronglyConnectedComponents(size_t v) : gg(v), rg(v), comp(v, -1), used(v, 0) {}

  void add_edge(int x, int y)
  {
    gg[x].push_back(y);
    rg[y].push_back(x);
  }

  int operator[](int k)
  {
    return (comp[k]);
  }

  void dfs(int idx)
  {
    if(used[idx]) return;
    used[idx] = true;
    for(int to : gg[idx]) dfs(to);
    order.push_back(idx);
  }

  void rdfs(int idx, int cnt)
  {
    if(comp[idx] != -1) return;
    comp[idx] = cnt;
    for(int to : rg[idx]) rdfs(to, cnt);
  }

  int build()
  {
    for(int i = 0; i < gg.size(); i++) dfs(i);
    reverse(begin(order), end(order));
    int ptr = 0;
    for(int i : order) if(comp[i] == -1) rdfs(i, ptr), ptr++;
    return (ptr);
  }
};


int dp[200000][5];
vector< Bipartite_Graph > bb;
int SUM[2][200000];
vector< vector< int > > ventex;
int convert[200000];

int rec(int idx, int in, StronglyConnectedComponents &scc)
{
  if(~dp[idx][in]) return (dp[idx][in]);
  int ret = 0;
  for(auto &j : ventex[idx]) {
    for(auto &to : scc.gg[j]) {
      if(scc[to] == idx) continue;
      if(bb[idx].las) {
        ret = max(ret, rec(scc[to], bb[scc[to]][convert[to]] ^ bb[idx][convert[j]] ^ in ^ 1, scc));
      } else {
        ret = max(ret, rec(scc[to], in, scc));
        ret = max(ret, rec(scc[to], in ^ 1, scc));
      }
    }
  }
  return (dp[idx][in] = SUM[in][idx] + ret);
}

int main()
{
  BEGIN_STACK_EXTEND(128 * 1024 * 1024);

  int N, M, C[200000];

  cin >> N >> M;
  StronglyConnectedComponents scc(N);

  for(int i = 0; i < N; i++) {
    cin >> C[i];
  }
  for(int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a, b);
  }

  int gg = scc.build();
  ventex.resize(gg);
  for(int i = 0; i < N; i++) ventex[scc[i]].push_back(i);
  for(int i = 0; i < ventex.size(); i++) {
    Bipartite_Graph tree(ventex[i].size());

    if(ventex[i].size() > 1) {
      for(int j = 0; j < ventex[i].size(); j++) {
        convert[ventex[i][j]] = j;
      }
      for(auto &j : ventex[i]) {
        for(auto &to : scc.gg[j]) {
          if(scc[to] != i) continue;
          tree.unite(convert[j], convert[to] + ventex[i].size());
          tree.unite(convert[j] + ventex[i].size(), convert[to]);
        }
      }
    }
    if(tree.bipartite_graph_coloring()) {
      for(auto &j : ventex[i]) {
        SUM[tree[convert[j]]][i] += C[j];
      }
    } else {
      for(auto &j : ventex[i]) {
        SUM[0][i] += C[j];
        SUM[1][i] += C[j];
      }
    }
    bb.emplace_back(tree);
  }
  memset(dp, -1, sizeof(dp));
  cout << rec(scc[0], bb[scc[0]][convert[0]], scc) << endl;
  END_STACK_EXTEND;
}