import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void log(A...)(A arg) {
    stderr.writeln(arg);
}
int size(T)(in T s) {
    return cast(int)s.length;
}

class Edge {
    int from, to;
    bool isBridge;
    this(int from, int to) {
        this.from = from;
        this.to = to;
    }
    override string toString() {
        return [from, to, isBridge].to!string;
    }
}
class Graph {
    Edge[][] G;
    int V;
    this(int V) {
        this.V = V;
        G = new Edge[][V];
    }
    void addEdge(int from, int to) {
        G[from] ~= new Edge(from, to);
        G[to] ~= new Edge(to, from);
    }
}

const int INF = int.max/4;
void solve() {
    int N, M; scanf("%d %d\n", &N, &M);
    auto W = stdin.readln.chomp.split(" ").map!(to!int).array;
    auto graph = new Graph(N);
    foreach (i; 0 .. M) {
        int u, v; scanf("%d %d\n", &u, &v); u--; v--;
        graph.addEdge(u, v);
    }
    auto g = graph.G;

    auto visited = new bool[N];
    Tuple!(bool, int, int) dfs(int v, int prev) {
        visited[v] = true;
        int ans = W[v];
        int diff_max = 0;
        bool can_ret = false;
        foreach (e; g[v]) {
            if (e.to == prev) continue;
            if (visited[e.to]) {
                can_ret = true;
                continue;
            }
            auto r = dfs(e.to, v);
            if (r[0]) can_ret = true;
            ans += max(0, r[1]);
            diff_max = max(diff_max, r[2] - max(0, r[1]));
        }
        return tuple( can_ret, (can_ret ? ans : -INF), ans + diff_max);
    }
    dfs(0, -1)[2].writeln;
}


void main() {
    solve();
}