#include <bits/stdc++.h>
using namespace std;
#define int long long   // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i,n) for (int i=0;i<(n);++i)
#define rep2(i,a,b) for (int i=(a);i<(b);++i)
#define rrep(i,n) for (int i=(n)-1;i>=0;--i)
#define rrep2(i,a,b) for (int i=(a)-1;i>=b;--i)
#define chmin(a,b) (a)=min((a),(b));
#define chmax(a,b) (a)=max((a),(b));
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define printV(v) cout<<(#v)<<":";for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;
#define printVS(vs) cout<<(#vs)<<":"<<endl;for(auto(s):(vs)){cout<<(s)<< endl;}
#define printVV(vv) cout<<(#vv)<<":"<<endl;for(auto(v):(vv)){for(auto(x):(v)){cout<<" "<<(x);}cout<<endl;}
#define printP(p) cout<<(#p)<<(p).first<<" "<<(p).second<<endl;
#define printVP(vp) cout<<(#vp)<<":"<<endl;for(auto(p):(vp)){cout<<(p).first<<" "<<(p).second<<endl;}

inline void output(){ cout << endl; }
template<typename First, typename... Rest>
inline void output(const First& first, const Rest&... rest) {
    cout << first << " "; output(rest...);
}

using ll = long long;
using Pii = pair<int, int>;
using TUPLE = tuple<int, int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
const int inf = 1e9;
const int mod = 1e9 + 7;
using Graph = vector<vector<int>>;

typedef vector<vector<int>> Graph;
typedef pair<int, int> Edge; // (a < b: undirected)

vi w;
vi wcmp;

class BICC {
private:
    const int n;

    Graph G;
    vector<int> depth;
    vector<int> par;
    map<Edge, int> imosEdge;
    map<Edge, int> EdgeType;
    enum {UNUSED, USED_DFS, BRIDGE};
    vector<Edge> bridges;

	vector<int> cmp;
	int num_cc;
	vector<int> size_of_vertex;
	Graph G_cc;
public:
    BICC(int _n) : n(_n), G(_n), depth(_n, -1), par(_n, -1), cmp(_n, -1), num_cc(0) {}
    Edge getEdge(int a, int b) {
        if (a > b) swap(a, b);
        return Edge(a, b);
    }
    void updateEdgeType(int a, int b, int type) {
        if (a < 0 || b < 0) return;
        EdgeType[getEdge(a, b)] = type;
    }
    void addEdge(int a, int b) {
        G[a].emplace_back(b);
        G[b].emplace_back(a);
        updateEdgeType(a, b, UNUSED);
    }
    void dfsTreeConstruct(int v, int pre) {
        if (depth[v] != -1) return;
        depth[v] = (pre == -1 ? 0 : depth[pre] + 1);
        par[v] = pre;
        updateEdgeType(pre, v, USED_DFS);
        for (auto&& nxt : G[v]) {
            if (nxt != pre) dfsTreeConstruct(nxt, v);
        }
    }
    void updateImos(int a, int b) {
        if (depth[a] < depth[b]) swap(a, b);

        if (par[a] != -1) {
            imosEdge[getEdge(a, par[a])]++;
        }
        if (par[b] != -1) {
            imosEdge[getEdge(b, par[b])]--;
        }
    }
    int imosFinal(int v, int pre) {
        int t = 0;
        for (auto&& nxt : G[v]) {
            if (nxt != pre && EdgeType[getEdge(nxt, v)] == USED_DFS) {
                t += imosFinal(nxt, v);
            }
        }
        if (pre != -1) imosEdge[getEdge(v, pre)] += t;
        return pre == -1 ? 0 : imosEdge[getEdge(v, pre)];
    }
    int extractCC(int v, int color) {
    	if (cmp[v] != -1) return 0;
    	cmp[v] = color;
    	int t = 1;
    	for (auto&& nxt : G[v]) {
    		if (EdgeType[getEdge(v, nxt)] != BRIDGE) {
    			t += extractCC(nxt, color);
    		}
    	}
    	return t;
    }
    tuple<Graph, vector<int>, vector<int>> bicc() {
        dfsTreeConstruct(0, -1);
        for (auto&& p : EdgeType) {
            Edge e;
            int type;
            tie(e, type) = p;
            if (type == UNUSED) {
                updateImos(e.first, e.second);
            }
        }
        imosFinal(0, -1);
        for (auto&& p : EdgeType) {
            Edge e;
            int type;
            tie(e, type) = p;
            if (type == USED_DFS) {
                if (imosEdge[e] == 0) {
                    EdgeType[e] = BRIDGE;
                    bridges.emplace_back(e);
                }
            }
        }

		rep(i, n) {
			int size_cc = extractCC(i, num_cc);
			if (size_cc > 0) {
				size_of_vertex.emplace_back(size_cc);
				num_cc++;
			}
		}

        // for this problem
        wcmp.resize(num_cc);
        rep(i, n) {
            wcmp[cmp[i]] += w[i];
        }

	 	vector<set<int>> G_cc_st(num_cc);
		for (auto&& p : EdgeType) {
            Edge e;
            int type;
            tie(e, type) = p;
            if (type == BRIDGE) {
				G_cc_st[cmp[e.first]].insert(cmp[e.second]);
				G_cc_st[cmp[e.second]].insert(cmp[e.first]);
            }
        }

		rep(i, num_cc) {
			G_cc.emplace_back(vector<int>(all(G_cc_st[i])));
		}

        return make_tuple(G_cc, size_of_vertex, cmp);
    }
    vector<Edge> getBridges() {
        return bridges;
    }
};

Graph G;
vi sz;
vi cmp;
int s;
vector<int> cand;
vector<bool> red;

bool dfs(int now, int pre) {
    bool ch_red = (now == s || sz[now] >= 2);
    for (auto nxt : G[now]) {
        if (nxt == pre) continue;
        ch_red |= dfs(nxt, now);
    }
    return red[now] = ch_red;
}

void dfs2(int now, int pre, int sm) {
    if (!red[now]) sm += wcmp[now];
    if ((int)G[now].size() == 1 && !red[now]) {
        cand.emplace_back(sm);
        return;
    }

    for (auto nxt : G[now]) {
        if (nxt == pre) continue;
        dfs2(nxt, now, sm);
    }
}

main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int n, m;
    cin >> n >> m;
    w.resize(n);
    rep(i, n) cin >> w[i];
    BICC bicc(n);
    rep(i, m) {
        int u, v;
        cin >> u >> v;
        u--; v--;
        bicc.addEdge(u, v);
    }

    tie(G, sz, cmp) = bicc.bicc();
    int s = cmp[0];
    int num_cc = sz.size();
    red.resize(num_cc);
    dfs(s, -1);

    int sm_red = 0;
    rep(i, n) {
        if (red[cmp[i]]) {
            sm_red += w[i];
        }
    }

    dfs2(s, -1, 0);
    int ma_path = (cand.empty() ? 0 : *max_element(all(cand)));

    cout << sm_red + ma_path << endl;

}

Measured memory_bytes: 62740