Problem:
Score : 600 points

Problem Statement

You are given a forest with N vertices and M edges. The vertices are numbered 0 through N-1.
The edges are given in the format (x_i,y_i), which means that Vertex x_i and y_i are connected by an edge.

Each vertex i has a value a_i.
You want to add edges in the given forest so that the forest becomes connected.
To add an edge, you choose two different vertices i and j, then span an edge between i and j.
This operation costs a_i + a_j dollars, and afterward neither Vertex i nor j can be selected again.

Find the minimum total cost required to make the forest connected, or print Impossible if it is impossible.

Constraints

1 ≤ N ≤ 100,000

0 ≤ M ≤ N-1

1 ≤ a_i ≤ 10^9

0 ≤ x_i,y_i ≤ N-1

The given graph is a forest.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N M
a_0 a_1 .. a_{N-1}
x_1 y_1
x_2 y_2
:
x_M y_M

Output

Print the minimum total cost required to make the forest connected, or print Impossible if it is impossible.

Sample Input 1

7 5
1 2 3 4 5 6 7
3 0
4 0
1 2
1 3
5 6

Sample Output 1

7

If we connect vertices 0 and 5, the graph becomes connected, for the cost of 1 + 6 = 7 dollars.

Sample Input 2

5 0
3 1 4 1 5

Sample Output 2

Impossible

We can't make the graph connected.

Sample Input 3

1 0
5

Sample Output 3

0

The graph is already connected, so we do not need to add any edges.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template<class T> using vc = vector<T>;
template<class T> using vvc = vector<vector<T>>;

const ll MOD = 1e9 + 7;
const ll INF = 1e14;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

void init() {cin.tie(0);ios::sync_with_stdio(false);cout << fixed << setprecision(15);}
//--------------------------------------------------------------------------------//
struct UnionFind {
    vector<int> par;
    vector<int> count;
    vector<int> rank;

    UnionFind(int N) {
        count.assign(N, 1);
        rank.assign(N, 0);
        par.assign(N, 0);
        rep(i, N) par[i] = i;
    }

    int find(int x) {
        if (par[x] == x)
            return x;
        else {
            par[x] = find(par[x]);
            return par[x];
        }
    }

    void unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return;
        if (rank[x] < rank[y])
            swap(x, y);
        else if (rank[x] == rank[y])
            rank[y]++;
        par[y] = x;
        count[x] += count[y];
        return;
    }

    int size(int x) {
        return count[find(x)];
    }

    bool issame(int x, int y) {
        return find(x) == find(y);
    }
};
using UF = struct UnionFind;

int main() {
    init();
    ll N, M;
    cin >> N >> M;
    priority_queue<pair<ll,ll>, vc<pair<ll,ll>>, greater<pair<ll,ll>>> pq;
    rep(i,N){
        ll a;
        cin >> a;
        pq.emplace(a, i);
    }

    UF uf(N);
    rep(i,M){
        ll x, y;
        cin >> x >> y;
        uf.unite(x, y);
    }

    ll ans = 0;
    ll pi = -1, pv = INF;
    queue<pair<ll, ll>> q;
    while(!pq.empty()){
        if(pi==-1){
            tie(pv, pi) = pq.top();
            pq.pop();
            continue;
        }

        ll ci, cv;
        tie(cv, ci) = pq.top();
        pq.pop();
        if(uf.issame(ci,pi)){
            q.emplace(cv, ci);
            continue;
        }

        ans += cv + pv;
        uf.unite(ci, pi);
        // cout << pi << " " << ci << " " << ans << endl;

        if(!q.empty()){
            tie(pv, pi) = q.front();
            q.pop();
        }
        else{
            pi = -1;
        }
    }

    bool isLinked = true;
    ll root = uf.find(0);
    rep(i,N){
        if(uf.find(i)!=root){
            isLinked = false;
            break;
        }
    }

    if(isLinked)
        cout << ans << endl;
    else
        cout << "Impossible" << endl;
}