// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

using ll = long long;

vector<ll> v[100000];

bool used[100000] = {};

const ll INF = 1145148931919810;

map<ll, ll> a;

pair<ll, ll> dfs(ll now){

	used[now] = 1;

	pair<ll, ll> ret = pair<ll, ll>(a[now], now);

	for(ll next : v[now]){

		if(used[next]) continue;

		pair<ll, ll> tmp = dfs(next);

		if(tmp.first < ret.first) ret = tmp;

	}

	return ret;

}

int main(){

	ll n, m; cin >> n >> m;

	for(ll i = 0; i < n; i++){

		ll po; cin >> po;

		a[i] = po;

	}

	for(ll i = 0; i < m; i++){

		ll x, y; cin >> x >> y;

		v[x].push_back(y);

		v[y].push_back(x);

	}

	ll ans = 0;

	ll ren = 0;

	for(ll i = 0; i < n; i++){

		if(used[i]) continue;

		pair<ll, ll> tmp = dfs(i);

		ren++;

		ans += tmp.first;

		a.erase(tmp.second);

	}

	if(ren == 1){

		cout << 0 << endl;

		return 0;

	}

	if(2 * ren - 2 > n){

		cout << "Impossible\n";

		return 0;

	}

	vector<ll> po;

	for(auto ite = a.begin(); ite != a.end(); ite++) po.push_back(ite->second);

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

	for(ll i = 0; i + ren < 2 * ren - 2; i++) ans += po[i];

	cout << ans << endl;

	return 0;

}

// Optimized solution to the same problem (faster):
// #define DEBUGGING

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'

#define ALL(V) (V).begin(), (V).end()

#define ALLR(V) (V).rbegin(), (V).rend()



template <typename T> using V = vector<T>;

template <typename T> using VV = V<V<T>>;

using ll = int64_t;

using ull = uint64_t;

using PLL = pair<ll, ll>;



template <typename T> const T& var_min(const T &t) { return t; }

template <typename T> const T& var_max(const T &t) { return t; }

template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return min(t, var_min(tail...)); }

template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return max(t, var_max(tail...)); }

template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }

template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }

template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return max(low, min(high, t)); }

template <typename T> void chclamp(T &t, const T &low, const T &high) { t = clamp(t, low, high); }



namespace init__ {



struct InitIO {

    InitIO() {

        cin.tie(nullptr);

        ios_base::sync_with_stdio(false);

        cout << fixed << setprecision(30);

    }

} init_io;



}



#ifdef DEBUGGING

// #include "../debug/debug.cpp"

#include "../../debug/debug.cpp"

#else

#define DEBUG(...) 0

#define DEBUG_SEPARATOR_LINE 0

#endif



template <typename T>

T make_v(T init) { return init; }



template <typename T, typename... Tail>

auto make_v(T init, size_t s, Tail... tail) {

#define rec make_v(init, tail...)

    return V<decltype(rec)>(s, rec);

#undef rec

}



struct Solver {

    using PQ = priority_queue<ll, V<ll>, greater<ll>>;

    ll N;

    V<ll> costs;

    VV<ll> edges;



    Solver(ll arg_N) 

        : N(arg_N),

          costs(arg_N),

          edges(arg_N) 

    {

        ll M;

        cin >> M;

        for(auto &&ele : costs) cin >> ele;

        for(ll i = 0; i < M; i++) {

            ll a, b;

            cin >> a >> b;

            edges[a].push_back(b);

            edges[b].push_back(a);

        }

    }



    void dfs(ll cur, V<ll> &nodes, V<bool> &visited) {

        visited[cur] = true;

        nodes.push_back(cur);

        for(ll nxt : edges[cur]) if(!visited[nxt]) dfs(nxt, nodes, visited);

    }



    VV<ll> calc_forest() {

        V<bool> visited(N);

        VV<ll> ret;

        for(ll i = 0; i < N; i++) {

            if(visited[i]) continue;

            V<ll> tree;

            dfs(i, tree, visited);

            ret.push_back(move(tree));

        }

        return ret;

    }



    ll solve() {

        auto forest = calc_forest();

        DEBUG(forest);

        ll add_edges = 2 * (forest.size() - 1);

        if(N < add_edges) return -1;

        if(!add_edges) return 0;

        V<PQ> costs_pq;

        for(auto &&tree : forest) {

            PQ pq;

            for(ll node : tree) pq.push(costs[node]);

            costs_pq.push_back(move(pq));

        }

        ll ret = 0;

        PQ rests;

        for(auto &&pq : costs_pq) {

            ret += pq.top();

            pq.pop();

            add_edges--;

            while(pq.size()) {

                rests.push(pq.top());

                pq.pop();

            }

        }

        while(add_edges--) {

            ret += rests.top();

            rests.pop();

        }

        return ret;

    }

};



int main() {

    ll N;

    cin >> N;

    auto ans = Solver(N).solve();

    if(ans == -1) cout << "Impossible";

    else cout << ans;

    cout << endl;

    return 0;

}


// Fastest known solution for this problem: