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)

/*{{{*/
//#define HOME
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;

#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define F first
#define S second

template<class T> void _R(T &_x) { cin >> _x; }
void _R(int &_x) { scanf("%d", &_x); }
void _R(int64_t &_x) { scanf("%" SCNd64, &_x); }
void _R(double &_x) { scanf("%lf", &_x); }
void _R(char &_x) { scanf(" %c", &_x); }
void _R(char *_x) { scanf("%s", _x); }
template<class T, class U> void _R(pair<T, U> &_x) {_R(_x.F); _R(_x.S);}
void R() {}
template<class T, class... U> void R(T &_head, U &... _tail) { _R(_head); R(_tail...); }

template<class T> void _W(const T &_x) { cout << _x; }
void _W(const int &_x) { printf("%d", _x); }
void _W(const int64_t &_x) { printf("%" PRId64, _x); }
void _W(const double &_x) { printf("%.16f", _x); }
void _W(const char &_x) { putchar(_x); }
void _W(const char *_x) { printf("%s", _x); }
template<class T, class U> void _W(const pair<T, U> &_x) {_W(_x.F); putchar(' '); _W(_x.S);}
template<class T> void _W(const vector<T> &_x) { for (auto i = _x.begin(); i != _x.end(); _W(*i++)) if (i != _x.cbegin()) putchar(' '); }
void W() {}
template<class T, class... U> void W(const T &_head, const U &... _tail) { _W(_head); putchar(sizeof...(_tail) ? ' ' : '\n'); W(_tail...); }

template<class T, class... U> void DB(const T &_head, const U &... _tail) {
#ifdef HOME
    W('#', _head, _tail...);
#endif
}

#define SZ(x) int((x).size())
#define ALL(x) (x).begin(), (x).end()
#define RAN(x,n) (x).begin(), (x).begin()+(n)
#define UNIQUE(x) {sort(ALL(x)); (x).erase(unique(ALL(x)), (x).end());}

#define REP(i,a,b) for (int i = (a); i <= (b); ++i)
#define REPD(i,a,b) for (int i = (a); i >= (b); --i)
#define FORI(i,n) REP(i,1,n)
#define FOR(i,n) REP(i,0,int(n)-1)
//#define ITER(i,t) for (auto i = t.begin(); i != t.end(); ++i)
#define IT3(i,st,ed) for (auto i = (st); i != (ed); ++i)
#define IT2(i,range) IT3(i,range)

#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define MS(X, v) memset((X), (v), sizeof((X)))

template<class T> using MaxHeap = priority_queue<T>;
template<class T> using MinHeap = priority_queue<T, vector<T>, greater<T>>;

typedef int64_t ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

inline int LG (const unsigned int &_x) { return 31-__builtin_clz(_x); } // floor: LG(x), ceil: LG(x-1)+1
/*}}}*/

const int N = 100000+10;

int n, m;
vi a;

vi fa, used;
//vector< *set<pii> > ss; // (a[i], i)
set<pii> *ss[N];
MinHeap<pair<pii,int>> he;

pair<pii, int> get_top(){
	//if(he.empty()) return {-1, -1};
	while(!he.empty()){
		auto v = he.top(); he.pop();
		DB("get top", v);
		if(fa[v.S] != v.S) continue;
		pii u = *begin(*ss[v.S]);
		if(u != v.F) continue;
		if(used[u.S] == 1) continue;
		used[u.S] = 1;
		return v;
	}
	return {{-1, -1}, -1};
}

int get_fat(int v){
	if(fa[v] == v) return v;
	else return fa[v] = get_fat(fa[v]);
}

void uni(int u, int v){
	//DB("uni:", u, v);
	u = get_fat(u), v = get_fat(v);
	if(u == v) return;
    if(SZ(*ss[u]) < SZ(*ss[v])) swap(u, v);
    fa[v] = u;
    DB(u, v);
    DB(SZ(*ss[u]), SZ(*ss[v]));
    //for(auto x: *ss[u]) DB("set u", x);
    //for(auto x: *ss[v]) DB("set v", x);
    if(SZ(*ss[v]) != 0)
		for(auto x: *ss[v]){
			//DB("set[v]", x);
			ss[u]->insert(x);
		}
    //if(SZ(*ss[u]) != 0)
		//he.emplace(*begin(*ss[u]), u);
}

int main(){
    R(n, m);
	a = vi(n);
	FOR(i, n) R(a[i]);

	fa = used = vi(n);//, ss.assign(n, new set<pii>());
	FOR(i, n){
		fa[i] = i;
        ss[i] = new set<pii>;
        ss[i]->insert(MP(a[i], i));
		//he.emplace(*begin(*ss[i]), i);
	}

	FOR(_m, m){
		int u, v;
        R(u, v);
        uni(u, v);
	}

	FOR(i, n) if(get_fat(i) == i){
		he.emplace(*begin(*ss[i]), i);
	}

	//DB(fa);

	ll ans = 0;
    int mm = n-1-m;
    while(mm && !he.empty()){
        auto v0 = get_top();
        auto v1 = get_top();
        DB(v0, v1);
        if(v1.S == -1) break; // he is empty
        ans += v0.F.F+v1.F.F;
        ss[v0.S]->erase(begin(*ss[v0.S]));
        ss[v1.S]->erase(begin(*ss[v1.S]));
        uni(v0.S, v1.S);
        if(get_fat(v0.S) == v0.S){
			if(SZ(*ss[v0.S])){
				he.emplace(*begin(*ss[v0.S]), v0.S);
			}
        }
		else{
			if(SZ(*ss[v1.S])){
				he.emplace(*begin(*ss[v1.S]), v1.S);
			}
		}
        --mm;
    }

    if(mm == 0) W(ans);
    else W("Impossible");

    return 0;
}