stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;



const int maxn = 1e5 + 5;



int n, m, k;

int w[maxn], f[maxn];

ll ans;

priority_queue <int, vector<int>, greater<int>> q[maxn];

multiset <int> s;



int find(int x)

{

	return f[x] == x ? x : f[x] = find(f[x]);

}



void merge(int x, int y)

{

	int fx = find(x);

	int fy = find(y);

	if(fx != fy)

		f[fx] = fy;

}



int main()

{

	int u, v;

	scanf("%d%d", &n, &m);

	k = n - m;

	if(2 * k - 2 > n)

	{

		puts("Impossible");

		return 0;

	}

	if(k == 1)

	{

		puts("0");

		return 0;

	}

	for(int i = 1; i <= n; i++)

	{

		scanf("%d", &w[i]);

		f[i] = i;

	}

	for(int i = 1; i <= m; i++)

	{

		scanf("%d%d", &u, &v);

		u++, v++;

		merge(u, v);

	}

	for(int i = 1; i <= n; i++)

	{

		find(i);

		q[f[i]].push(w[i]);

	}

	for(int i = 1; i <= n; i++)

		if(!q[i].empty())

		{

			ans += q[i].top();

			q[i].pop();

	//		printf("val = %lld\n", val);

		}

	for(int i = 1; i <= n; i++)

		while(!q[i].empty())

		{

			s.insert(q[i].top());

			q[i].pop();

		}	

//	for(auto it = s.begin(); it != s.end(); it++)

//		printf("%d\n", *it);

	auto it = s.begin();

	for(int i = 1; i <= k - 2; i++, it++)

	{

		ans += *it;

	//	printf("%lld\n", ans);

	}

	printf("%lld\n", ans);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.347109935869116x):
#include<iostream>

#include<algorithm>

#include<cstdio>

using namespace std;

int t[101000];

int val[101000],b[101000],c[101000],k2=0;

int h[101000],nxt[201000],K=0,to[201000];

void ins(int u,int v){nxt[++K]=h[u];h[u]=K;to[K]=v;}

int Min;

void dfs(int x,int o)

{

	t[x]=o;Min=min(Min,val[x]);c[++k2]=x;

	for(int i=h[x];i;i=nxt[i])if(!t[to[i]])dfs(to[i],o);

}

int main()

{

	int n,m;scanf("%d%d",&n,&m);

	for(int i=1;i<=n;i++)scanf("%d",&val[i]);

	for(int i=1;i<=m;i++)

	{

		int u,v;scanf("%d%d",&u,&v);u++;v++;ins(u,v);ins(v,u);

	}

	int cnt=0,s=0;long long ans=0;

	for(int i=1;i<=n;i++)

	{

		if(!t[i])

		{

			Min=1e9;k2=0;

			dfs(i,++s);

			for(int j=1;j<=k2;j++)if(val[c[j]]==Min){ans+=Min;Min=1e9;}else b[++cnt]=val[c[j]];

		}

	}

	if(s==1)return 0*puts("0");

	int lst=(s-1)*2-s;

	sort(b+1,b+cnt+1);

	if(lst>cnt)return 0*puts("Impossible");

	for(int i=1;i<=lst;i++)ans+=b[i];

	printf("%lld",ans);return 0;

 }
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



const int MAXN = 101010;



int a[MAXN];



class Node {

public:

	int v;

	Node *l, *r;

	int key;

	

	Node(int x) {

		v = a[x];

		l = r = 0;

		key = 1;

	}

};



//set<pair<int,int> > s;



class Road {

public:

	int t, next;

}e[MAXN * 2];

int p[MAXN];

int z = -1;



int vis[MAXN];



void add(int u, int v) {

	++z;

	e[z].t = v;

	e[z].next = p[u];

	p[u] = z;

}



Node *root[MAXN];



int getkey(Node *now) {

	return now ? now->key : 0;

}



void update(Node *now) {

	now->key = getkey(now->r) + 1;

}



Node* merge(Node *&l, Node *&r) {

	if(!l)

		return r;

	if(!r)

		return l;

//	cout<<l->v<<" "<<r->v<<endl;

	if(l->v < r->v) {

		l->r = merge(l->r, r);

		if(getkey(l->l) < getkey(l->r))

			swap(l->l, l->r);

		update(l);

		return l;

	}

	else {

		r->r = merge(l, r->r);

		if(getkey(r->l) < getkey(r->r))

			swap(r->l, r->r);

		update(r);

		return r;

	}

}



void dfs(int u, int fa, int tag) {

	vis[u] = tag;

	if(u != tag) {

		root[tag] = merge(root[tag], root[u]);

		root[u] = 0;

	}

	for(int tmp = p[u]; tmp != -1; tmp = e[tmp].next) {

		if(e[tmp].t != fa) {

			dfs(e[tmp].t, u, tag);

		}

	}

} 



void del(Node *&now) {

	//print(now);

	now = merge(now->l, now->r);

}





int n, m;



int main() {

	scanf("%d%d", &n, &m);

	for(int i = 0; i < n; ++i) {

		scanf("%d", &a[i]);

		root[i] = new Node(i);

	}

	int u, v;

	memset(p, -1, sizeof(p));

	

	for(int i = 1; i <= m; ++i) {

		scanf("%d%d", &u, &v);

		add(u, v);

		add(v, u);

	}

	memset(vis, -1, sizeof(vis));

	

	int cnt = 0;

	long long ss = 0;

	Node *tmp = 0;

	for(int i = 0; i < n; ++i) {

		if(vis[i] == -1) {

			++cnt;

			dfs(i, -1, i);

			ss += root[i]->v;

			del(root[i]);

			tmp = merge(tmp, root[i]);

		}

	}

	if((n - 1 - m) * 2 > n) {

		puts("Impossible");

		return 0;

	}

	if(m == n - 1) {

		puts("0");

		return 0;

	}

	

	int need = (n - 1 - m) * 2 - cnt;

	for(int i = 1; i <= need; ++i) {

		ss += tmp->v;

		del(tmp);

	}

	

	//if(cnt >= n - 1) {

		printf("%lld\n", ss);

	//}

	/*else {

		puts("Impossible");

	}*/



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.8145254148309535x):
#include<iostream>

#include<algorithm>

#include<cstdio>

using namespace std;

int t[101000];

int val[101000],b[101000],c[101000],k2=0;

int h[101000],nxt[201000],K=0,to[201000];

void ins(int u,int v){nxt[++K]=h[u];h[u]=K;to[K]=v;}

int Min;

void dfs(int x,int o)

{

	t[x]=o;Min=min(Min,val[x]);c[++k2]=x;

	for(int i=h[x];i;i=nxt[i])if(!t[to[i]])dfs(to[i],o);

}

int main()

{

	int n,m;scanf("%d%d",&n,&m);

	for(int i=1;i<=n;i++)scanf("%d",&val[i]);

	for(int i=1;i<=m;i++)

	{

		int u,v;scanf("%d%d",&u,&v);u++;v++;ins(u,v);ins(v,u);

	}

	int cnt=0,s=0;long long ans=0;

	for(int i=1;i<=n;i++)

	{

		if(!t[i])

		{

			Min=1e9;k2=0;

			dfs(i,++s);

			for(int j=1;j<=k2;j++)if(val[c[j]]==Min){ans+=Min;Min=1e9;}else b[++cnt]=val[c[j]];

		}

	}

	if(s==1)return 0*puts("0");

	int lst=(s-1)*2-s;

	sort(b+1,b+cnt+1);

	if(lst>cnt)return 0*puts("Impossible");

	for(int i=1;i<=lst;i++)ans+=b[i];

	printf("%lld",ans);return 0;

 }
// Slower C++ solution:
#include <iostream>

#include <cassert>

#include <algorithm>

#include <vector>

#include <queue>

#include <set>

using namespace std;

int N,M;

int T[100005];

int A[100005];

long long rez;

multiset<int> G[100005];

int fi(int nod){

    if(T[nod] <= 0){

        return nod;

    }

    return T[nod] = fi(T[nod]);

}

void u(int x,int y,bool baga){

    x = fi(x);

    y = fi(y);

    if(baga){

        rez += *G[x].begin();G[x].erase(G[x].begin());

        rez += *G[y].begin();G[y].erase(G[y].begin());

        T[x]++;

        T[y]++;

    }

    if(T[x] < T[y]){

        for(auto it:G[y]){

            G[x].insert(it);

        }

        T[x] += T[y];

        T[y] = x;

    }

    else{

        for(auto it:G[x]){

            G[y].insert(it);

        }

        T[y] += T[x];

        T[x] = y;

    }

}

class cmp{

    public:

    bool operator() (int a,int b){

        return T[a] > T[b];

    }

};

priority_queue<int,vector<int>,cmp> H;

int main(){

    cin >> N >> M;

    for(int i = 1;i <= N;i++){

        cin >> A[i];

        T[i] = -1;

        G[i].insert(A[i]);

    }

    for(int i = 1;i <= M;i++){

        int x,y;

        cin >> x >> y;

        x++;

        y++;

        u(x,y,0);

    }

    for(int i = 1;i <= N;i++){

        if(T[i] <= 0){

            H.push(i);

        }

    }

    rez = 0;

    while(M < N - 1){

        if(H.size() < 2){

            cout << "Impossible";

            return 0;

        }

        int a = H.top();H.pop();

        int b = H.top();H.pop();

        if(T[b] == 0){

            cout << "Impossible";

            return 0;

        }

        u(a,b,1);

        H.push(fi(a));

        M++;

    }

    cout << rez;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.841947235611904x):
#include <cstdio>

#include <vector>

#include <algorithm>



using namespace std;



const int NMAX = 1e5;



int n,m;

vector<int> graph[NMAX + 5];

int val[NMAX + 5];

bool viz[NMAX + 5];



int dfs(int nod){

	viz[nod] = 1;

	int ans = nod;

	for(auto it:graph[nod]){

		if(!viz[it]){

			int tmp = dfs(it);

			if(val[tmp] < val[ans]){

				ans = tmp;

			}

		}

	}

	return ans;

}



int main(){

	

	scanf("%d %d",&n,&m);

	

	for(int i = 0;i < n;i++){

		scanf("%d",&val[i]);

	}

	

	for(int i = 0;i < m;i++){

		int x,y;

		scanf("%d %d",&x,&y);

		graph[x].push_back(y);

		graph[y].push_back(x);

	}

	

	if(2 * (n - m - 1) > n){

		printf("Impossible");

		return 0;

	}

	

	if(m == n - 1){

		printf("0");

		return 0;

	}

	

	long long ans = 0;

	

	for(int i = 0;i < n;i++){

		if(!viz[i]){

			int tmp = dfs(i);

			ans += val[tmp];

			val[tmp] = 1 << 30;

		}

	}

	

	sort(val,val + n);

	

	for(int i = 0;i < n - m - 2;i++){

		ans += val[i];

	}

	

	printf("%lld",ans);



	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



typedef long long LL;



const int MAXN = 1e5 + 5;



int n, m, w[MAXN];



std::multiset<int> st[MAXN];

std::set<std::pair<int, int> > spec;



int fa[MAXN], part;



int Find(int x) {

    return fa[x] == x ? x : fa[x] = Find(fa[x]);

}



void merge(int u, int v) {

    if (Find(u) == Find(v)) return;

    if (st[fa[u]].size() > st[fa[v]].size()) std::swap(u, v);

    --part;

    for (int i: st[fa[u]]) {

        st[fa[v]].insert(i);

    }

    st[fa[u]].clear();

    if (!st[fa[v]].empty()) spec.insert(std::make_pair(st[fa[v]].size(), fa[v]));

    fa[fa[u]] = fa[v];

}



int main() {

    scanf("%d%d", &n, &m); part = n;

    for (int i = 0; i < n; ++i) {

        fa[i] = i;

        scanf("%d", w + i);

        st[i].insert(w[i]);

        spec.insert(std::make_pair(1, i));

    }

    

    for (int i = 1; i <= m; ++i) {

        static int u, v;

        

        scanf("%d%d", &u, &v);

        spec.erase(spec.find(std::make_pair(st[Find(u)].size(), Find(u))));

        spec.erase(spec.find(std::make_pair(st[Find(v)].size(), Find(v))));

        merge(u, v);

    }

    

    LL ans = 0;

    

    while (part > 1) {

        if (spec.size() < 2) {

            puts("Impossible");

            return 0;

        }

        auto x = *--spec.end();

        spec.erase(--spec.end());

        

        auto y = *--spec.end();

        spec.erase(--spec.end());

        

        int u = x.second, v = y.second;

        ans += *st[Find(u)].begin() + *st[Find(v)].begin();

        

        st[Find(u)].erase(st[Find(u)].begin());

        st[Find(v)].erase(st[Find(v)].begin());

        

        merge(u, v);

    }

    

    printf("%lld\n", ans);

    

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.4872031622225534x):
#include<cmath>

#include<cstdio>

#include<algorithm>

#include<queue>

using namespace std;

typedef long long LL;

int n,m;

LL a[100000+10];

int par[100000+10];

priority_queue<LL> mini[100000+10];



int fpar(int x){

	if (par[x]==-1)return x;

	par[x]=fpar(par[x]);

	return par[x];

}

priority_queue <LL > pq1;

LL ans=0;

int main(){

	scanf("%d%d",&n,&m);

	for (int f1=0;f1<n;f1++)scanf("%lld",&a[f1]);

	for (int f1=0;f1<n;f1++){par[f1]=-1;}

	for (int f1=0;f1<m;f1++){

		int i,j;

		scanf("%d%d",&i,&j);

		i=fpar(i);

		j=fpar(j);

		par[j]=i;

	}

	for (int f1=0;f1<n;f1++){

		int j=fpar(f1);

		mini[j].push(-a[f1]);

	}

	if (n==1+m){

		printf("0\n");

		return 0;

	}

	for (int f1=0;f1<n;f1++){

		if (par[f1]==-1){

			ans-=mini[f1].top();

			mini[f1].pop();

			while (!mini[f1].empty()){

				pq1.push(mini[f1].top());

				mini[f1].pop();

			}	

		}

	}

	

	if (int(pq1.size())>=n-m-2){

		for (int f1=1;f1<=n-m-2;f1++){

			ans-=pq1.top();

			pq1.pop();

		}

		printf("%lld\n",ans);

	} else printf("Impossible\n");

}

//
// Slower C++ solution:
#include <bits/stdc++.h>



typedef long long LL;



const int MAXN = 1e5 + 5;



int n, m, w[MAXN];



std::multiset<int> st[MAXN];

std::set<std::pair<int, int> > spec;



int fa[MAXN], part;



int Find(int x) {

    return fa[x] == x ? x : fa[x] = Find(fa[x]);

}



void merge(int u, int v) {

    if (Find(u) == Find(v)) return;

    if (st[fa[u]].size() > st[fa[v]].size()) std::swap(u, v);

    --part;

    for (int i: st[fa[u]]) {

        st[fa[v]].insert(i);

    }

    st[fa[u]].clear();

    if (!st[fa[v]].empty()) spec.insert(std::make_pair(st[fa[v]].size(), fa[v]));

    fa[fa[u]] = fa[v];

}



int main() {

    scanf("%d%d", &n, &m); part = n;

    for (int i = 0; i < n; ++i) {

        fa[i] = i;

        scanf("%d", w + i);

        st[i].insert(w[i]);

        spec.insert(std::make_pair(1, i));

    }

    

    for (int i = 1; i <= m; ++i) {

        static int u, v;

        

        scanf("%d%d", &u, &v);

        spec.erase(spec.find(std::make_pair(st[Find(u)].size(), Find(u))));

        spec.erase(spec.find(std::make_pair(st[Find(v)].size(), Find(v))));

        merge(u, v);

    }

    

    LL ans = 0;

    

    while (part > 1) {

        if (spec.size() < 2) {

            puts("Impossible");

            return 0;

        }

        auto x = *--spec.end();

        spec.erase(--spec.end());

        

        auto y = *--spec.end();

        spec.erase(--spec.end());

        

        int u = x.second, v = y.second;

        ans += *st[Find(u)].begin() + *st[Find(v)].begin();

        

        st[Find(u)].erase(st[Find(u)].begin());

        st[Find(v)].erase(st[Find(v)].begin());

        

        merge(u, v);

    }

    

    printf("%lld\n", ans);

    

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.790437860691978x):
#include <bits/stdc++.h>



using namespace std;



#define SZ(x) ((int)x.size())



const int N = 100005;



int n, m;

int a[N];

int fa[N];



vector<int> val[N];



int getfa(int x) {

	return fa[x] == x ? x : fa[x] = getfa(fa[x]);

}



void merge(int x, int y) {

	x = getfa(x);

	y = getfa(y);

	if(SZ(val[x]) < SZ(val[y])) {

		swap(x, y);

	}

	for(auto v: val[y]) {

		val[x].push_back(v);

	}

	val[y].clear();

	fa[y] = x;

}



void input()

{

	scanf("%d%d", &n, &m);

	for(int i = 1; i <= n; i++) {

		scanf("%d", &a[i]);



		val[i].push_back(a[i]);

		fa[i] = i;

	}

	for(int i = 1; i <= m; i++) {

		int x, y;

		scanf("%d%d", &x, &y);

		x++, y++;

		merge(x, y);

	}

}



void solve()

{

	long long ans = 0;



	int cnt = (n - 1 - m) * 2;



	if(cnt == 0) {

		puts("0");

		return;

	}



	vector<int> vec;

	for(int i = 1; i <= n; i++) {

		if(fa[i] == i) {

			sort(val[i].begin(), val[i].end());

			ans += val[i][0];

			cnt--;

			for(int j = 1; j < SZ(val[i]); j++) {

				vec.push_back(val[i][j]);

			}

		}

	}



	if(SZ(vec) < cnt) {

		puts("Impossible");

		return;

	}



	sort(vec.begin(), vec.end());

	for(int i = 0; i < cnt; i++) {

		ans += vec[i];

	}

	cout << ans << endl;

}



int main()

{

	input();

	solve();



	return 0;

}
// Slower C++ solution:
#include<cmath>

#include<cstdio>

#include<algorithm>

#include<queue>

using namespace std;

typedef long long LL;

int n,m;

LL a[100000+10];

int par[100000+10];

priority_queue<LL> mini[100000+10];



int fpar(int x){

	if (par[x]==-1)return x;

	par[x]=fpar(par[x]);

	return par[x];

}

priority_queue <LL > pq1;

LL ans=0;

int main(){

	scanf("%d%d",&n,&m);

	for (int f1=0;f1<n;f1++)scanf("%lld",&a[f1]);

	for (int f1=0;f1<n;f1++){par[f1]=-1;}

	for (int f1=0;f1<m;f1++){

		int i,j;

		scanf("%d%d",&i,&j);

		i=fpar(i);

		j=fpar(j);

		par[j]=i;

	}

	for (int f1=0;f1<n;f1++){

		int j=fpar(f1);

		mini[j].push(-a[f1]);

	}

	if (n==1+m){

		printf("0\n");

		return 0;

	}

	for (int f1=0;f1<n;f1++){

		if (par[f1]==-1){

			ans-=mini[f1].top();

			mini[f1].pop();

			while (!mini[f1].empty()){

				pq1.push(mini[f1].top());

				mini[f1].pop();

			}	

		}

	}

	

	if (int(pq1.size())>=n-m-2){

		for (int f1=1;f1<=n-m-2;f1++){

			ans-=pq1.top();

			pq1.pop();

		}

		printf("%lld\n",ans);

	} else printf("Impossible\n");

}

//

// Faster C++ solution for the same problem (measured speedup: 1.203895947892052x):
#include <bits/stdc++.h>



using namespace std;



#define SZ(x) ((int)x.size())



const int N = 100005;



int n, m;

int a[N];

int fa[N];



vector<int> val[N];



int getfa(int x) {

	return fa[x] == x ? x : fa[x] = getfa(fa[x]);

}



void merge(int x, int y) {

	x = getfa(x);

	y = getfa(y);

	if(SZ(val[x]) < SZ(val[y])) {

		swap(x, y);

	}

	for(auto v: val[y]) {

		val[x].push_back(v);

	}

	val[y].clear();

	fa[y] = x;

}



void input()

{

	scanf("%d%d", &n, &m);

	for(int i = 1; i <= n; i++) {

		scanf("%d", &a[i]);



		val[i].push_back(a[i]);

		fa[i] = i;

	}

	for(int i = 1; i <= m; i++) {

		int x, y;

		scanf("%d%d", &x, &y);

		x++, y++;

		merge(x, y);

	}

}



void solve()

{

	long long ans = 0;



	int cnt = (n - 1 - m) * 2;



	if(cnt == 0) {

		puts("0");

		return;

	}



	vector<int> vec;

	for(int i = 1; i <= n; i++) {

		if(fa[i] == i) {

			sort(val[i].begin(), val[i].end());

			ans += val[i][0];

			cnt--;

			for(int j = 1; j < SZ(val[i]); j++) {

				vec.push_back(val[i][j]);

			}

		}

	}



	if(SZ(vec) < cnt) {

		puts("Impossible");

		return;

	}



	sort(vec.begin(), vec.end());

	for(int i = 0; i < cnt; i++) {

		ans += vec[i];

	}

	cout << ans << endl;

}



int main()

{

	input();

	solve();



	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



typedef long long LL;



const int MAXN = 1e5 + 5;



int n, m, w[MAXN];



std::multiset<int> st[MAXN];

std::set<std::pair<int, int> > spec;



int fa[MAXN], part;



int Find(int x) {

    return fa[x] == x ? x : fa[x] = Find(fa[x]);

}



void merge(int u, int v) {

    if (Find(u) == Find(v)) return;

    if (st[fa[u]].size() > st[fa[v]].size()) std::swap(u, v);

    --part;

    for (int i: st[fa[u]]) {

        st[fa[v]].insert(i);

    }

    st[fa[u]].clear();

    if (!st[fa[v]].empty()) spec.insert(std::make_pair(st[fa[v]].size(), fa[v]));

    fa[fa[u]] = fa[v];

}



int main() {

    scanf("%d%d", &n, &m); part = n;

    for (int i = 0; i < n; ++i) {

        fa[i] = i;

        scanf("%d", w + i);

        st[i].insert(w[i]);

        spec.insert(std::make_pair(1, i));

    }

    

    for (int i = 1; i <= m; ++i) {

        static int u, v;

        

        scanf("%d%d", &u, &v);

        spec.erase(spec.find(std::make_pair(st[Find(u)].size(), Find(u))));

        spec.erase(spec.find(std::make_pair(st[Find(v)].size(), Find(v))));

        merge(u, v);

    }

    

    LL ans = 0;

    

    while (part > 1) {

        if (spec.size() < 2) {

            puts("Impossible");

            return 0;

        }

        auto x = *--spec.end();

        spec.erase(--spec.end());

        

        auto y = *--spec.end();

        spec.erase(--spec.end());

        

        int u = x.second, v = y.second;

        ans += *st[Find(u)].begin() + *st[Find(v)].begin();

        

        st[Find(u)].erase(st[Find(u)].begin());

        st[Find(v)].erase(st[Find(v)].begin());

        

        merge(u, v);

    }

    

    printf("%lld\n", ans);

    

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 33.21480339008598x):
#include <cstdio>

#include <cstdlib>

#include <algorithm>



const int maxn = 1e5 + 20;



int n, m, A[maxn], F[maxn];

std::pair<int,int> M[maxn];

bool used[maxn];



int find(int x)

{

	return F[x] == x ? x : (F[x] = find(F[x]));

}

template<class TAT>void checkmin(TAT &x,const TAT &y)

{

	if(y < x) x = y;

}

int main()

{

	scanf("%d%d", &n, &m);

	for(int i = 0; i < n; i++) scanf("%d", &A[i]);

	

	for(int i = 0; i < n; i++) F[i] = i;

	

	for(int i = 0, x, y; i < m; i++)

	{

		scanf("%d%d", &x, &y);

		F[find(x)] = find(y);

	}

	

	for(int i = 0; i < n; i++)

		M[i] = std::make_pair(A[i], i);

	

	for(int i = 0; i < n; i++)

		checkmin(M[find(i)], M[i]);

	

	long long ans = 0;

	int cnt = 0;

	

	for(int i = 0; i < n; i++)

		if(find(i) == i)

		{

			ans += M[i].first, cnt++;

			used[M[i].second] = true;

		}



	if(cnt == 1)

	{

		printf("0\n");

	}

	else if(n < (cnt - 1) * 2)

	{

		printf("Impossible\n");

	}

	else

	{

		for(int i = 0; i < n; i++)

			M[i] = std::make_pair(A[i], i);

		std::sort(M, M + n);

		

		int rem = (cnt - 1) * 2 - cnt;

		

		for(int i = 0; i < n && rem; i++)

		{

			if(used[M[i].second]) continue;

			ans += M[i].first, rem--;

		}

		

		printf("%lld\n", ans);

	}

	

	return 0;

}
// Slower C++ solution:
#include <algorithm>

#include <iostream>

#include <cstdlib>

#include <cstdio>

#include <string>

#include <vector>

using namespace std;

const int MAXN = 100000;



int n, m;

int fa[MAXN+5];

int val[MAXN+5];

vector <int> blk[MAXN+5];

vector <int> ansEdge;

long long int ans;



int SetFind(int x)

{

    if(fa[x] != x)

        return fa[x] = SetFind(fa[x]);

    return fa[x];

}



void SetInit(int n)

{

    for(int i = 1; i <= n; i++)

        fa[i] = i;

}



int main()

{

    int blkcnt;



    cin >> n >> m ;

    SetInit(n);

    blkcnt = n;



    for(int i = 1; i <= n; i++)

    {

        cin >> val[i] ;

        //blk[i].push_back(val[i]);

    }





    for(int i = 1; i <= m; i++)

    {

        int u, v;

        cin >> u >> v;

        u++, v++;

        if(SetFind(u) != SetFind(v))

            fa[SetFind(u)] = SetFind(v), blkcnt--;

    }



    for(int i = 1; i <= n; i++)

        blk[SetFind(i)].push_back(val[i]);

/*

    for(int i = 1; i <= n; i++)

    {

        if(!blk[i].empty())

            cout << blk[i].size() << endl ;

    }

*/

    if(blkcnt <= 1)

    {

        cout << 0 << endl ;

        return 0;

    }



    blkcnt -= 2;



    for(int i = 1; i <= n; i++)

        if(!blk[i].empty())

        {

            sort(blk[i].begin(), blk[i].end());

            ans += blk[i][0];

            for(int k = 1; k < blk[i].size(); k++)

                ansEdge.push_back(blk[i][k]);

        }



    if(ansEdge.size() < blkcnt)

    {

        cout << "Impossible" << endl;

        return 0;

    }



    sort(ansEdge.begin(), ansEdge.end());



    for(int i = 0; i < blkcnt; i++)

        ans += ansEdge[i] ;



    cout << ans << endl ;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 18.591069952063076x):
#include <cstdio>

#include <cstdlib>

#include <algorithm>



const int maxn = 1e5 + 20;



int n, m, A[maxn], F[maxn];

std::pair<int,int> M[maxn];

bool used[maxn];



int find(int x)

{

	return F[x] == x ? x : (F[x] = find(F[x]));

}

template<class TAT>void checkmin(TAT &x,const TAT &y)

{

	if(y < x) x = y;

}

int main()

{

	scanf("%d%d", &n, &m);

	for(int i = 0; i < n; i++) scanf("%d", &A[i]);

	

	for(int i = 0; i < n; i++) F[i] = i;

	

	for(int i = 0, x, y; i < m; i++)

	{

		scanf("%d%d", &x, &y);

		F[find(x)] = find(y);

	}

	

	for(int i = 0; i < n; i++)

		M[i] = std::make_pair(A[i], i);

	

	for(int i = 0; i < n; i++)

		checkmin(M[find(i)], M[i]);

	

	long long ans = 0;

	int cnt = 0;

	

	for(int i = 0; i < n; i++)

		if(find(i) == i)

		{

			ans += M[i].first, cnt++;

			used[M[i].second] = true;

		}



	if(cnt == 1)

	{

		printf("0\n");

	}

	else if(n < (cnt - 1) * 2)

	{

		printf("Impossible\n");

	}

	else

	{

		for(int i = 0; i < n; i++)

			M[i] = std::make_pair(A[i], i);

		std::sort(M, M + n);

		

		int rem = (cnt - 1) * 2 - cnt;

		

		for(int i = 0; i < n && rem; i++)

		{

			if(used[M[i].second]) continue;

			ans += M[i].first, rem--;

		}

		

		printf("%lld\n", ans);

	}

	

	return 0;

}