#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

using ll = long long int;
#define int ll

const int MOD = 1e9 + 7;
const int INF = 1e15 + 373;

#define rep(i, n) for (int i = 0; i < (n); ++i)

template <typename T>
using vector2 = vector<vector<T>>;
template <typename T>
vector2<T> init_vector2(size_t n0, size_t n1, T e = T()) {
    return vector2<T>(n0, vector<T>(n1, e));
}

template <typename T>
using vector3 = vector<vector<vector<T>>>;
template <typename T>
vector3<T> init_vector3(size_t n0, size_t n1, size_t n2, T e = T()) {
    return vector3<T>(n0, vector2<T>(n1, vector<T>(n2, e)));
}

class union_find_tree {
   private:
    vector<int> p;
    vector<int> h;
    vector<int> w;

   public:
    union_find_tree(int n) : p(n, -1), h(n, 0), w(n, 1) {}

    int find(int u) {
        if (p[u] == -1) {
            return u;
        }
        return p[u] = find(p[u]);
    }

    void unite(int u, int v) {
        const int u_rt = find(u);
        const int v_rt = find(v);

        if (u_rt == v_rt) {
            return;
        }

        if (h[u_rt] > h[v_rt]) {
            p[v_rt] = u_rt;
            w[u_rt] += w[v_rt];
        } else {
            p[u_rt] = v_rt;
            w[v_rt] += w[u_rt];
            if (h[u_rt] == h[v_rt]) {
                h[v_rt]++;
            }
        }
    }

    int weight(int u) { return w[find(u)]; }
    bool same(int u, int v) { return find(u) == find(v); }
};

map<int, int> compress(const vector<int>& a) {
    vector<int> b(a);
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());

    map<int, int> c;
    ll m = b.size();
    rep(i, m) { c[b[i]] = i; }

    return c;
}

typedef pair<int, int> P;
ostream& operator<<(ostream& os, P& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
void dump(const vector<T>& v) {
    cout << "[";
    for (T e : v) {
        cout << e << ", ";
    }
    cout << "]" << endl;
}

/*
int solve(int k, vector2<P>& ts) {
    priority_queue<P, vector<P>, greater<P>> q;

    rep(i, k) {
        q.push(ts[i][0]);
        ts[i].erase(ts[i].begin());
    }

    union_find_tree uft(k);

    int cost = 0;
    while (k > 1) {
        if (q.empty()) {
            return -1;
        }
        P p0 = q.top();
        q.pop();

        if (q.empty()) {
            return -1;
        }
        P p1 = q.top();
        q.pop();

        cost += p0.first;
        cost += p1.first;
        k--;

        if (k == 1) {
            break;
        }

        int r0 = uft.find(p0.second);
        int r1 = uft.find(p1.second);
        uft.unite(p0.second, p1.second);

        vector<P> merged(ts[r0].size() + ts[r1].size());
        merge(ts[r0].begin(), ts[r0].end(), ts[r1].begin(), ts[r1].end(),
              merged.begin());

        int dst = r0 == uft.find(r0) ? r0 : r1;
        ts[dst] = merged;
        ts[dst].resize(min((int)ts[dst].size(), k));
        if (!ts[dst].empty()) {
            q.push(ts[dst][0]);
            ts[dst].erase(ts[dst].begin());
        }
    }

    return cost;
}

signed main() {
    int n, m;
    cin >> n >> m;

    vector<int> a(n);
    rep(i, n) { cin >> a[i]; }

    union_find_tree uft(n);
    rep(i, m) {
        int x, y;
        cin >> x >> y;
        uft.unite(x, y);
    }

    vector<int> rs;
    rep(i, n) {
        if (uft.find(i) == i) {
            rs.push_back(i);
        }
    }
    map<int, int> cmap = compress(rs);

    int k = rs.size();
    vector2<P> ts(k);
    rep(i, n) {
        int j = cmap[uft.find(i)];
        ts[j].push_back(make_pair(a[i], j));
    }

    rep(i, k) {
        sort(ts[i].begin(), ts[i].end());
        ts[i].resize(min((int)ts[i].size(), k - 1));
    }

    int ans = solve(k, ts);
    if (ans == -1) {
        cout << "Impossible" << endl;
    } else {
        cout << ans << endl;
    }

    return 0;
}
*/

signed main() {
    int n, m;
    cin >> n >> m;

    vector<int> a(n);
    rep(i, n) { cin >> a[i]; }

    union_find_tree uft(n);
    rep(i, m) {
        int x, y;
        cin >> x >> y;
        uft.unite(x, y);
    }

    vector<int> rs;
    rep(i, n) {
        if (uft.find(i) == i) {
            rs.push_back(i);
        }
    }
    map<int, int> cmap = compress(rs);

    int k = rs.size();
    if (k == 1) {
        cout << 0 << endl;
        return 0;
    }

    vector2<int> ts(k);
    rep(i, n) {
        int j = cmap[uft.find(i)];
        ts[j].push_back(i);
    }

    int cost = 0;
    rep(i, k) {
        int p = 0;
        for (size_t j = 1; j < ts[i].size(); j++) {
            if (a[ts[i][j]] < a[ts[i][p]]) {
                p = j;
            }
        }
        cost += a[ts[i][p]];
        a[ts[i][p]] = -1;
    }

    vector<int> all;
    rep(i, n) {
        if (a[i] != -1) {
            all.push_back(a[i]);
        }
    }

    sort(all.begin(), all.end());

    if ((int)all.size() < k - 2) {
        cout << "Impossible" << endl;
        return 0;
    }

    rep(i, k - 2) { cost += all[i]; }

    cout << cost << endl;

    return 0;
}


Measured memory_bytes: 15852