#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

const i64 MOD = 1e9 + 7;


struct UnionFind{
    vector<int> par;
    int siz;
    UnionFind(int n) : par(n, -1), siz(n){}
    int Find(int x){return par[x] < 0 ? x : Find(par[x]);}
    bool Unite(int x, int y){
        x = Find(x);
        y = Find(y);
        if(x == y)
            return false;
        if(par[x] > par[y])
            swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return siz--;
    }
};

struct LowLink{
    vector<vector<int>>& edges;
    // 関節点
    vector<int> art;
    vector<pair<int,int>> bridge;

    vector<int> used, ord, low;
    int k;

    void dfs(int idx, int par){
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_art = false;
        int cnt = 0;
        for(auto& to : edges[idx]){
            if(ord[to] == -1){
                ++cnt;
                dfs(to, idx);
                low[idx] = min(low[idx], low[to]);
                is_art |= !par && low[to] >= ord[idx];
                if(ord[idx] < low[to])
                    bridge.emplace_back(idx, to);
            }else if(to != par)
                low[idx] = min(low[idx], ord[to]);
        }
        is_art |= (par == -1 && cnt > 1);
        if(is_art)
            art.emplace_back(idx);
    }

    LowLink(vector<vector<int>>& edges) :
        edges(edges),
        ord(edges.size(), -1),
        low(edges.size(), 0),
        k(0)
    {
        for(int i = 0; i < edges.size(); ++i)
            if(ord[i] == -1)
                dfs(i, -1);
        for(auto& b : bridge)
            b = make_pair(min(b.first, b.second), max(b.first, b.second));
        sort(art.begin(), art.end());
        sort(bridge.begin(), bridge.end());
    }
};

signed main(){
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for(auto& x : a)
        cin >> x;
    vector<int> u(m), v(m);
    vector<vector<int>> edges(n);
    for(int i = 0; i < m; i++){
        cin >> u[i] >> v[i];
        --u[i], --v[i];
        int uu = u[i], vv = v[i];
        u[i] = min(uu, vv);
        v[i] = max(uu, vv);
        edges[u[i]].emplace_back(v[i]);
        edges[v[i]].emplace_back(u[i]);
    }

    UnionFind uf(n);
    auto ll = LowLink(edges);
    for(int i = 0; i < m; ++i){
        auto it = lower_bound(ll.bridge.begin(), ll.bridge.end(), make_pair(u[i], v[i]));
        if(it == ll.bridge.end() || *it != make_pair(u[i], v[i]))
            uf.Unite(u[i], v[i]);
    }
    int siz = 0;
    map<int,int> tai;
    for(int i = 0; i < n; ++i)
        if(tai.find(uf.Find(i)) == tai.end())
            tai[uf.Find(i)] = siz++;
    vector<vector<int>> tr(siz), childs(siz);
    vector<int> score(siz, 0);
    vector<int> size(siz, 0);
    for(int i = 0; i < n; ++i){
        score[tai[uf.Find(i)]] += a[i];
        ++size[tai[uf.Find(i)]];
    }
    for(int i = 0; i < m; ++i){
        if(uf.Find(u[i]) != uf.Find(v[i])){
            int uu = tai[uf.Find(u[i])];
            int vv = tai[uf.Find(v[i])];
            tr[uu].emplace_back(vv);
            tr[vv].emplace_back(uu);
        }
    }

    vector<int> used(siz, -1);
    vector<int> value(siz, 0);
    int ans = 0;
    int dif = 0;
    function<void(int)> f = [&](int from){
        if(used[from] == -1)
            used[from] = (size[from] >= 2);
        for(auto& to : tr[from])
            if(used[to] == -1){
                f(to);
                used[from] |= used[to];
                childs[from].emplace_back(to);
            }
        if(used[from])
            ans += score[from];
    };
    used[0] = 1;
    f(0);

    function<void(int)> g = [&](int from){
        for(auto& to : childs[from])
            g(to);
        if(used[from] == false){
            value[from] = score[from];
            int add = 0;
            for(auto& to : childs[from]){
                add = max(add, value[to]);
            }
            value[from] += add;
            dif = max(dif, value[from]);
        }
    };
    g(0);
    cout << ans + dif << endl;
}



Measured memory_bytes: 36388