// beet hieteruka~~~
#include <bits/stdc++.h>
 
using namespace std;
 
using int64 = long long;
const int mod = 1e9 + 7;
 
const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;
 
struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;
 
 
template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}
 
template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}
 
template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}
 
template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}
 
template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
 
template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
 
template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}
 
template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}
 
template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}
 
template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}
 
template< typename F >
struct FixPoint : F {
  FixPoint(F &&f) : F(forward< F >(f)) {}
 
  template< typename... Args >
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward< Args >(args)...);
  }
};
 
template< typename F >
inline decltype(auto) MFP(F &&f) {
  return FixPoint< F >{forward< F >(f)};
}
 
 
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)]);
  }
};
 
 
#define int long long
 
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[200000], S;
vector< vector< int > > g;
vector< int > weightSum, sz;
int dp1[200000], dp3[200000];
 
int rec(int idx, int par = -1) {
  int ret = 0;
  for(auto &to : g[idx]) {
    if(to == par) continue;
    ret = max(ret, rec(to, idx));
    dp1[idx] += dp1[to];
  }
  ret += 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] = ret);
}
 
signed 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]]++;
  }
  printf("%lld\n", rec(tree[0]));
}


Measured memory_bytes: 34692