#include <bits/stdc++.h>

using namespace std;

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 BiConnectedComponents
{
  UnionFind uf;
  vector< vector< int > > g;
  vector< pair< int, int > > edges;
  vector< int > used, ord, low, comp;

  BiConnectedComponents(size_t v) : uf(v), g(v), used(v, 0), comp(v), ord(v), low(v)
  {
  }

  void add_edge(int x, int y)
  {
    g[x].push_back(y);
    g[y].push_back(x);
    edges.push_back(minmax(x, y));
  }

  void dfs(int idx, int &k, int par = -1)
  {
    used[idx] = true;
    ord[idx] = k++;
    low[idx] = ord[idx];

    for(auto &to : g[idx]) {
      if(!used[to]) {
        dfs(to, k, idx);
        low[idx] = min(low[idx], low[to]);
        if(ord[idx] >= low[to]) uf.unite(idx, to);
      } else if(to != par) {
        low[idx] = min(low[idx], ord[to]);
      }
    }
  }

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

  size_t size()
  {
    return (g.size());
  }

  void build(vector< vector< int > > &t)
  {
    int kk = 0;
    dfs(0, kk);

    int ptr = 0;
    vector< int > cc(g.size());
    for(int i = 0; i < g.size(); i++) {
      if(i == uf.find(i)) cc[i] = ptr++;
    }

    t.resize(ptr);
    for(int i = 0; i < g.size(); i++) {
      comp[i] = cc[uf.find(i)];
    }
    for(auto &e : edges) {
      int x = comp[e.first], y = comp[e.second];
      if(x == y) continue;
      t[x].push_back(y);
      t[y].push_back(x);
    }
  }
};

int N, M, W[100000];
vector< vector< int > > g;
vector< int > weightSum, sz;
int dp1[100000], dp2[100000], dp3[100000];

int rec(int idx, int par = -1)
{
  int ret = 0;
  for(auto &to : g[idx]) {
    if(to == par) continue;
    rec(to, idx);
    dp2[idx] = max(dp2[idx], dp2[to]);
    dp1[idx] += dp1[to];
  }
  dp2[idx] += weightSum[idx];
  if(sz[idx] >= 3 || dp1[idx] > 0) dp1[idx] += weightSum[idx];
  for(auto &to : g[idx]) {
    if(to == par) continue;
    else ret = max(ret, dp1[idx] - dp1[to] + dp3[to]);
  }
  return (dp3[idx] = max(dp2[idx], ret));
}

int main()
{
  cin >> N >> M;
  BiConnectedComponents tree(N);
  for(int i = 0; i < N; i++) {
    cin >> W[i];
  }
  while(M--) {
    int U, V;
    cin >> U >> V;
    tree.add_edge(--U, --V);
  }
  tree.build(g);
  weightSum.assign(g.size(), 0);
  sz.assign(g.size(), 0);
  for(int i = 0; i < N; i++) {
    weightSum[tree[i]] += W[i];
    sz[tree[i]]++;
  }
  cout << rec(tree[0]) << endl;
}