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

#define ll int64_t
#define Rep(i, n) for (ll i = 0; i < n; i++)
using namespace std;
typedef vector<ll> vec;
typedef vector<vec> mat;

const ll inf = 1LL << 60;

template<class T> inline void chmin(T& a, T b) {
    if (a > b) {
        a = b;
    }
}
template<class T> inline void chmax(T& a, T b) {
    if (a < b) {
        a = b;
    }
}

mat graph;

struct UnionFind {
    vector<ll> par;
    vec siz;

    UnionFind(ll N) : par(N), siz(N, 1) {
        Rep (i, N) {
            par[i] = i;
        }
    }

    ll root (ll x) {
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite (ll x, ll y) {
        ll rx = root(x);
        ll ry = root(y);
        if (rx == ry) return;
        if (siz[rx] < siz[ry]) swap(rx, ry);
        siz[rx] += siz[ry];
        par[ry] = rx;
    }

    bool same (ll x, ll y) {
        ll rx = root(x);
        ll ry = root(y);
        return rx == ry;
    }

    ll size(ll x) {
        return siz[root(x)];
    }
};

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

    ll N, M;
    cin >> N >> M;
    vec a(N);
    Rep (i, N) {
        cin >> a[i];
    }
    graph.assign(N, vec());
    while (M--) {
        ll x, y;
        cin >> x >> y;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }

    UnionFind uf(N);

    vector<bool> used(N, false);
    map<ll, priority_queue<ll, vec, greater<ll>>> m;
    vec tree;
    Rep (i, N) {
        if (!used[i]) {
            used[i] = true;
            tree.push_back(i);
            queue<ll> q;
            m[i].push(a[i]);
            q.push(i);
            while (q.size()) {
                ll v = q.front();
                q.pop();
                for (ll nv : graph[v]) {
                    if (used[nv]) continue;
                    used[nv] = true;
                    q.push(nv);
                    m[i].push(a[nv]);
                    uf.unite(i, nv);
                    
                }
            }
        }
    }

    // Rep (i, N) {
    //     cout << uf.size(i) << " \n"[i==N-1];
    // }
    // Rep (i, N) {
    //     cout << uf.root(i) << " \n"[i==N-1];
    // }
    sort(tree.begin(), tree.end(), [&](ll a, ll b) {return uf.size(a) > uf.size(b);});
    
    ll ans = 0;
    Rep (i, tree.size()) {
        if (i == 0) continue;
        if (m[tree[0]].empty()) {
            cout << "Impossible\n";
            return 0;
        }
        ans += m[tree[0]].top() + m[tree[i]].top();
        // cout << m[tree[0]].top() << " " << m[tree[i]].top() << "\n";
        // cout << m[tree[0]].size() << " " << m[tree[i]].size() << "\n";
        m[tree[0]].pop();
        m[tree[i]].pop();
        // cout << m[tree[0]].size() << " " << m[tree[i]].size() << "\n";
        // cout << m[tree[0]].top() << " " << m[tree[i]].top() << "\n";
        // cout << "0:" << 0 << " " << m[tree[0]].top() << "\n";
        while (m[tree[i]].size()) {
            m[tree[0]].push(m[tree[i]].top());
            m[tree[i]].pop();
        }
    }

    cout << ans << "\n";

    // used[0] = true;
    // queue<ll> q;
    // q.push(0);
    // priority_queue<ll, vec, greater<ll>> pq;
    // pq.push(a[0]);
    // while (q.size()) {
    //     ll v = q.front();
    //     q.pop();
    //     for (ll nv : graph[v]) {
    //         if (used[nv]) continue;
    //         uf.unite(0, nv);
    //         pq.push(a[nv]);
    //         q.push(nv);
    //         used[nv] = true;
    //     }
    // }

    // ll ans = 0;
    // Rep (i, N) {
    //     if (!uf.same(0, i)) {
    //         queue<ll> q2;
    //         q2.push(i);
    //         priority_queue<ll, vec, greater<ll>> pq2;
    //         pq2.push(a[i]);
    //         used[i] = true;
    //         uf.unite(0, i);
    //         while (q2.size()) {
    //             ll v = q2.front();
    //             q2.pop();
    //             for (ll nv : graph[v]) {
    //                 if (used[nv]) continue;
    //                 uf.unite(0, nv);
    //                 pq2.push(a[nv]);
    //                 q2.push(nv);
    //                 used[nv] = true;
    //             }
    //         }

    //         if (pq.empty() or pq2.empty()) {
    //             cout << "Impossible\n";
    //             return 0;
    //         }
    //         // cout << i << " " << pq.top() << " " << pq2.top() << "\n";
    //         // Rep (i, N) {
    //         //     cout << used[i] << " \n"[i==N-1];
    //         // }
    //         ans += pq.top() + pq2.top();
    //         pq.pop(); pq2.pop();

    //         while (pq2.size()) {
    //             ll v = pq2.top();
    //             pq.push(v);
    //             pq2.pop();
    //         }
    //     }
    // }

    // cout << ans << "\n";
}

Measured memory_bytes: 16756