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 (GCC 5.4.1) (judge verdict: Runtime Error)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

//for
#define REP(i,n) for(int i=0,i##_len=(int)(n);i<i##_len;i++)
#define REPS(i,n) for(int i=1,i##_len=(int)(n);i<=i##_len;i++)
#define RREP(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define RREPS(i,n) for(int i=(int)(n);i>0;i--)

//printf
#define PRINTD(d) printf("%d\n",(d))
#define PRINTS(s) printf("%s\n",(s))

//memset
#define m0(s) memset(s,0,sizeof(s))
#define ml(s) memset(s,63,sizeof(s))
#define fill(s,c) memset(s,c,sizeof(s))

typedef long long ll;

int Min(int a, int b) {
	return (a)<(b) ? (a) : (b);
}
int Max(int a, int b) {
	return (a) > (b) ? (a) : (b);
}

int a[10000];
int g[10000];
int m[10000];
int f[10000] = { 0 };
ll sum = 0;

int dfs(int i) {
	if (g[i] != i) {
		return g[i] = dfs(g[i]);
	}
	else {
		return i;
	}
}

int main() {
	int N, M;
	scanf("%d %d", &N, &M);
	REP(i, N) g[i] = i;
	REP(i, N) m[i] = 1000000001;
	REP(i, N) scanf("%d", &a[i]);
	REP(i,M) {
		int x,y;
		scanf("%d %d", &x, &y);
		f[x] = f[y] = 1;
		int g1 = dfs(x);
		int g2 = dfs(y);
		if (a[g1] <= g2) {
			g[g2] = g1;
			m[g2] = 0;
			if (a[y] < m[g1])m[g1] = a[y];
		}
		else {
			g[g1] = g2;
			m[g1] = 0;
			if (a[x] < m[g2])m[g2] = a[x];
		}
	}
	int cnt = 0;
	REP(i, N) {
		if (f[i]==0)cnt++;
	}
	if (cnt > 2) {
		PRINTS("Impossible");
		return 0;
	}
	int max[2] = {0};
	int flag = 0;
	REP(i, N) {
		if (g[i] == i) {
			flag++;
			sum += a[i];
			//printf("%d sum=%lld\n", i, sum);
			if (m[i] <= 1000000000) {
				REP(j, 2) {
					if (max[j] < m[i]) {
						sum -= max[1];
						if (j == 0) {
							max[1] = max[0];
						}
						max[j] = m[i];
						//printf("max=%d %d\n", max[0], max[1]);
						break;
					}
				}
			}
		}
	}
	/*
	REP(i, N) {
		printf("%d ", g[i]);
	}
	PRINTS("");
	REP(i, N) {
		printf("%d ", m[i]);
	}
	PRINTS("");
	*/
	if (flag==1) {
		PRINTD(0);
	}
	else if (flag) {
		printf("%lld\n", sum);
	}
}