/*input
4 1
1 10 20 2
1 2
*/
#include <bits/stdc++.h>

using namespace std;

#define rep(i,a,b) for(int (i) = (a); (i) < (b); ++(i))
#define per(i,a,b) for(int (i) = (n-1); (i) >= (a); --(i))
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define mp make_pair
#define mt make_tuple
#define all(v) (v).begin(), (v).end()
#define sz(v) (int) (v).size()
#define fast() ios::sync_with_stdio(0);cin.tie(0);

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> ii;
typedef tuple<int, int, int> iii;
typedef vector<int> vi;
typedef vector<vi> vvi;

const int inf = 0x3f3f3f3f;
const int neginf = 0xc0c0c0c0;
const int mod = 1000000007;

// 0 -> eq, 1 ( a > b), -1 ( a < b)
bool cmp(const double& a, const double& b, const double TOL = 1e-9){
	return (a + TOL > b)? (b + TOL > a)? 0 : 1 : -1;
}

ll powmod(ll a, ll b){
	ll res = 1;
	a %= mod;
	assert(b >= 0);
	for(;b;b>>=1){
		if(b&1) res = (res*a)%mod;
		a = (a*a)%mod;
	} 
	return res;
}

int n, m;

const int ms = 1e5 + 100;

// struct UF {
//   vi p, rank;
//   UF(int n) {
//     p = vi(n);
//     rank = vi(n, 0);
//     fu(i, n) p[i] = i;
//   }
//   int fk(int v) {
//     if (p[v] != v) p[v] = fk(p[v]);
//     return p[v];
//   }
//   bool unio(int a, int b) { // returns false if a and b are already joined
//     a = fk(a); b = fk(b);
//     if (a == b) return false;
//     if (rank[a] < rank[b]) p[a] = b;
//     else p[b] = a;
//     if (rank[a] == rank[b]) rank[a]++;
//     return true;
//   }
// };

vi g[ms];
ll price[ms];
int visited[ms] = {0};

// visitando as cc's ... muito provavelmente esta certo
vi find_cc(int v){
	vi cc;
	queue<int> nodes;
	nodes.push(v);
	visited[v] = 1;
	while(!nodes.empty()){
		int top = nodes.front();
		//cout << "top = " << top << endl;
		cc.pb(top);
		nodes.pop();
		for(const int& u : g[top]){
			if(!visited[u]){
				visited[u] = 1;
				nodes.push(u);
			}
		}
	}
	//for(const int x : cc) cout << x << " ";
	//cout << endl;
	//sort(all(cc));
	return cc;
}

vector<vi> ccs;

bool jaFoi[ms];
int meuGrupo[ms];

int main(){
	fast();
	cin >> n >> m;
	memset(meuGrupo, -1, sizeof meuGrupo);
	rep(i,0,n) cin >> price[i];
	rep(i,0,m){
		int a, b;
		cin >> a >> b;
		g[a].pb(b);
		g[b].pb(a);
	}
	rep(i,0,n){
		if(!visited[i]){
			vi x = find_cc(i);
			ccs.pb(x);
		}
	}
	rep(i,0,sz(ccs)){
		for(const int& x : ccs[i]){
			meuGrupo[x] = i;
		}
	}

	int edgesMade = 0;
	// vamos comecar com o primeiro cc no Prim
	priority_queue<ll, vector<ll> , greater<ll> > taPreso;
	priority_queue<pair<ll, ll> , vector<pair<ll, ll> >, greater<pair<ll, ll> > > taLivre;
	if(sz(ccs) == 1){
		cout << 0 << endl;
		return 0;
	}

	int maior = 0;
	int xx;
	rep(i,0,sz(ccs)){
		if(sz(ccs[i]) > xx){
			xx = sz(ccs[i]);
			maior = i;
		}
	}
	for(int v : ccs[maior]) taPreso.push(price[v]);
	rep(i,0, sz(ccs)){
		if(i == maior) continue;
		for(const int& v : ccs[i]){
			taLivre.push(mp(price[v], v)); // preco menor, depois o idx
		}
	}

	ll cost = 0;
	jaFoi[maior] = 1;

	while(edgesMade < sz(ccs) - 1){
		// se nao tem ngm disponivel pra ligar da ruim
		if(taPreso.empty()){
			cout << "Impossible" << endl;
			return 0;
		}
		ll u = taPreso.top();
		taPreso.pop();


		pair<ll, ll> topo = taLivre.top();
		while(jaFoi[meuGrupo[topo.se]]){
			taLivre.pop();
			if(taLivre.empty()){
				cout << "Impossible" << endl;
				return 0;
			}
			topo = taLivre.top();
		}
		taLivre.pop();
		
		jaFoi[meuGrupo[topo.se]] = 1;

		for(const int& v : ccs[meuGrupo[topo.se]]) if(v != topo.se) taPreso.push(price[v]);

		//taPreso.erase(taPreso.find(topo.fi));
		cost += u;
		cost += topo.fi;
		edgesMade++;
	}
	// bool ok = true;
	// rep(i,0,sz(ccs)) ok &= jaFoi[i];
	if(edgesMade < sz(ccs) - 1){
		cout << "Impossible" << endl;
		return 0;
	}
	cout << cost << endl;
	//else cout << "Impossible" << endl;
	return 0;
}




Measured memory_bytes: 13872