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 <iostream>
# include <algorithm>
#include <array>
# include <cassert>
#include <cctype>
#include <climits>
#include <numeric>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <tuple>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <chrono>
# include <random>
# include <limits.h>
# include <unordered_map>
# include <unordered_set>
# include <deque>
# include <cstdio>
# include <cstring>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
constexpr long long MOD = 1000000000 + 7;
constexpr long long INF = 1e17 - 10;
const double PI = acos(-1);
typedef pair<LL, LL> Pll;
typedef pair<LL, pair<LL, LL>> Ppll;
typedef pair<LL, pair<LL, bitset<100001>>> Pbll;
typedef pair<LL, pair<LL, vector<LL>>> Pvll;
typedef pair<LL, LL> Vec2;
struct Tll { LL first, second, third; };
typedef pair<LL, Tll> Ptll;
#define rep(i,rept) for(LL i=0;i<rept;i++)
#define Mfor(i,mf) for(LL i=mf-1;i>=0;i--)
struct Edge { LL to, cost; };
LL par[1000000];
LL h, w, n, m, s, t, k, p, q, ans = 0,a[1000000], d[1000000];
int find(int x) { if (par[x] == x)return x; 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 (a[x] < a[y])swap(x, y);par[x] = y; }
bool same(int x, int y) { return find(x) == find(y); }
vector<LL>tree[1000000];
bool f[1000000];
int main() {
	cin >> n >> m;
	rep(i, n)
		cin >> a[i];
	for (LL i = 0; i < n; i++)par[i] = i;
	rep(i, m) {
		LL x, y;
		cin >> x >> y;
		unite(x, y);
	}
	rep(i, n) {
		tree[find(i)].push_back(a[i]);
	}
	rep(i, n) {
		if (f[find(i)] == 0) {
			f[find(i)] = 1;
			sort(tree[find(i)].begin(), tree[find(i)].end());
		}
	}
	rep(i, n - 1) {
		if (!same(i, i + 1)) {
			if (tree[find(i)][0] + tree[find(i + 1)][0] >= INF) {
				cout << "Impossible" << endl;
				return 0;
			}
			ans += tree[find(i)][0] + tree[find(i + 1)][0];
			tree[find(i)][0] = INF;
			tree[find(i+1)][0] = INF;
			rep(j, tree[find(i + 1)].size())
				tree[find(i)].push_back(tree[find(i + 1)][j]);
			sort(tree[find(i)].begin(), tree[find(i)].end());
			unite(i, i + 1);
		}
	}
	cout <<ans<< endl;
	return 0;
}