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

using namespace std;



const int N = 1e5 + 7;



long long a[N];

vector <int> ad[N];

int n, m;

int cnt;

bool mrk[N];

set < pair<long long, int> > s[N];

set < pair<long long, int> > can;

void dfs(int v) {

	mrk[v] = 1;

	s[cnt].insert({a[v], v});

	for (auto u: ad[v]) {

		if (!mrk[u])

			dfs(u);

	}

}



int main() {	

	cin >> n >> m;

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

		cin >> a[i];	

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

		int x, y;

		cin >> x >> y;

		x++, y++;

		ad[x].push_back(y);

		ad[y].push_back(x);

	}

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

		if (!mrk[i]) {

			cnt++;

			dfs(i);

		}

	}

	if (cnt == 1) {

		cout << 0;

		return 0;

	}

	long long res = 0;

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

		res += s[i].begin()->first;

		s[i].erase(s[i].begin());

		while(s[i].size()) {

			can.insert({s[i].begin()->first, s[i].begin()->second});

			s[i].erase(s[i].begin());

		}

	}

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

	if ((tt + cnt) % 2)

		tt++;

	if (can.size() < tt) {

		cout << "Impossible";

		return 0;

	}	

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

		res += can.begin()->first;

		can.erase(can.begin());

	}

	cout << res;

	}

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

using namespace std;



typedef long long ll;



const int N = 1e5 + 10;

int a[N], mark[N];

vector<int> adj[N], v[N];



void dfs(int root, int col) {

    mark[root] = col;

    for (int i = 0; i < adj[root].size(); i++) {

        int u = adj[root][i];

        if (!mark[u])

            dfs(u, col);

    }

}



int main() {

    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    int n, m, x, y;

    cin >> n >> m;

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

        cin >> a[i];

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

        cin >> x >> y;

        adj[x].push_back(y);

        adj[y].push_back(x);

    }

    int cnt = 0;

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

        if (!mark[i]) {

            cnt++;

            dfs(i, cnt);

        }

    if (n < 2 * cnt - 2) {

        cout << "Impossible\n";

        return 0;

    }

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

        v[mark[i]].push_back(a[i]);

    }

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

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

    ll ans = 0;

    if (cnt > 1) {

        vector<int> u;

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

            ans += v[i][0];

            for (int j = 1; j < v[i].size(); j++)

                u.push_back(v[i][j]);

        }

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

        for (int i = 0; i < cnt - 2; i++)

            ans += u[i];

    }

    cout << ans << "\n";

    return 0;

}
// Slower C++ solution:
//IOI 2021



#include <bits/stdc++.h>

using namespace std;



#define pb push_back

#define ff first

#define ss second

typedef long long ll;

typedef pair<int, int> pii;



const int MAXSU = 1000 * 1000 + 17;



struct DSU {

	int par[MAXSU];

	DSU () {

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

	}

	int find_root(int x) {

		return (par[x] == -1? x: par[x] = find_root(par[x]));

	}

	bool set_union(int x, int y) {

		int p1 = find_root(x), p2 = find_root(y);

		return (p1 == p2? false: (par[p1] = p2) | 1);

	}

};



const int MAXN = 100 * 1000 + 17;



int n, m, a[MAXN], cnt;

ll ans;

multiset<int> cmp[MAXN];

vector<int> t;

DSU gr;



int main() {

	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	cin >> n >> m;

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

		cin >> a[i];

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

		int v, u;

		cin >> v >> u;

		v++;

		u++;

		gr.set_union(v, u);

	}

	if (m == n - 1)

		return cout << 0 << endl, 0;



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

		cmp[gr.find_root(i)].insert(a[i]);

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

		if (cmp[i].size())

			cnt++;

		else

			continue;

		ans += (*cmp[i].begin());

		cmp[i].erase(cmp[i].begin());

		for (auto j : cmp[i])

			t.pb(j);

	}

	if ((int)t.size() < cnt - 2)

		return cout << "Impossible" << endl, 0;



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

	for (int i = 0; i < cnt - 2; i++)

		ans += t[i];

	cout << ans << endl;

	return 0;



}

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

using namespace std;



typedef long long ll;



const int N = 1e5 + 10;

int a[N], mark[N];

vector<int> adj[N], v[N];



void dfs(int root, int col) {

    mark[root] = col;

    for (int i = 0; i < adj[root].size(); i++) {

        int u = adj[root][i];

        if (!mark[u])

            dfs(u, col);

    }

}



int main() {

    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    int n, m, x, y;

    cin >> n >> m;

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

        cin >> a[i];

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

        cin >> x >> y;

        adj[x].push_back(y);

        adj[y].push_back(x);

    }

    int cnt = 0;

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

        if (!mark[i]) {

            cnt++;

            dfs(i, cnt);

        }

    if (n < 2 * cnt - 2) {

        cout << "Impossible\n";

        return 0;

    }

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

        v[mark[i]].push_back(a[i]);

    }

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

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

    ll ans = 0;

    if (cnt > 1) {

        vector<int> u;

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

            ans += v[i][0];

            for (int j = 1; j < v[i].size(); j++)

                u.push_back(v[i][j]);

        }

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

        for (int i = 0; i < cnt - 2; i++)

            ans += u[i];

    }

    cout << ans << "\n";

    return 0;

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

using namespace std;

vector <long long> l,q[100005];

long long n,m,x,y,ans,tot,w[100005],f[100005],cnt[100005];

long long find(long long x)

{

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

}

int main()

{

	cin>>n>>m;

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

	{

		f[i]=i;

		cin>>w[i];

	}

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

	{

		cin>>x>>y;

		f[find(x+1)]=f[find(x+1)]==find(y+1)?f[find(x+1)]:f[find(x+1)]=find(y+1);

	}

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

	{

		q[(cnt[find(i)]=cnt[find(i)]?cnt[find(i)]:++tot)].push_back(w[i]);

	}

	if(tot==1)

	{

		cout<<0<<endl;

		return 0;

	}

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

	{

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

		ans+=q[i][0];

		for(int j=1;j<q[i].size();j++)

		{

			l.push_back(q[i][j]);

		}

	}

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

	if(l.size()<tot-2)

	{

		cout<<"Impossible"<<endl;

		return 0;

	}

	for(int i=0;i<tot-2;i++)

	{

		ans+=l[i];

	}

	cout<<ans<<endl;

	return 0;

}


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

#define ri register int

using namespace std;

int n,m,a[100005],f[100005],b[100005],t,c;

long long ans;

inline int read()

{

	char ch=getchar();int x=0,f=1;while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return x*f;

}

inline int gf(ri x){return f[x]==x?x:f[x]=gf(f[x]);}

int main()

{

	n=read();m=read();for(ri i=1;i<=n;++i)a[i]=read(),f[i]=i;

	for(ri i=1,x,y;i<=m;++i)

	x=gf(read()+1),y=gf(read()+1),b[++t]=max(a[x],a[y]),a[x]=min(a[x],a[y]),f[y]=x;

	for(ri i=1;i<=n;++i)if(f[i]==i)ans+=a[i],c++;if(c==1){puts("0");return 0;}

	if(2*(c-1)>n){puts("Impossible");return 0;}sort(b+1,b+1+t);

	//for(ri i=1;i<=t;++i)cout<<b[i]<<" ";

	for(ri i=1;i<=c-2;++i)ans+=b[i];printf("%lld",ans);

	return 0;

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

#include<cstring>

#include<algorithm>

using namespace std;

const long long MAXN=100005;



namespace DSU

{

	long long fa[MAXN];

	void Clear()

	{memset(fa,-1,sizeof fa);}

	long long Root(long long x)

	{return fa[x]==-1?x:(fa[x]=Root(fa[x]));}

	void Union(long long x,long long y)

	{

		long long r1=Root(x),r2=Root(y);

		if(r1!=r2)

			fa[r1]=r2;

	}

}



struct Vertice

{

	long long val,id;

	Vertice(){val=0x3F3F3F3F3F3F3F3FLL;}

	Vertice(long long v,long long i){val=v;id=i;}

	bool operator < (const Vertice &t)const

	{return val<t.val;}

};



Vertice V[MAXN],tr[MAXN];

bool used[MAXN];

bool mk[MAXN];



int main()

{

	long long n,m;

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

	for(long long i=0,a;i<n;i++)

	{

		scanf("%lld",&a);

		V[i]=Vertice(a,i);

	}

	DSU::Clear();

	for(long long i=0,u,v;i<m;i++)

	{

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

		DSU::Union(u,v);

	}

	int cc=0;

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

		if(!mk[DSU::Root(i)])

		{

			mk[DSU::Root(i)]=true;

			cc++;

		}

	if(cc==1)

	{

		puts("0");

		return 0;

	}

	if(2*cc-2>n)

	{

		puts("Impossible");

		return 0;

	}

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

	{

		int r=DSU::Root(i);

		tr[r]=min(tr[r],V[i]);

	}

	long long ans=0,cnt=2*cc-2;

	for(long long i=0;i<n&&cnt;i++)

	{

		int r=DSU::Root(i);

		if(!used[tr[r].id])

		{

			ans+=tr[r].val;

			used[tr[r].id]=true;

			cnt--;

		}

	}

	sort(V,V+n);

	for(long long i=0;i<n&&cnt;i++)

		if(!used[V[i].id])

		{

			ans+=V[i].val;

			cnt--;

		}

	

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

	return 0;

}


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

#include<algorithm>

#define maxn 100005

#define LL long long

using namespace std;

int n,m,fa[maxn],use[maxn],cnt;

LL ans;

struct node { int w;bool vis; } a[maxn];

bool cmp(node p,node q) 

{

	if(p.vis) return false;

	if(q.vis) return true;

	return p.w<q.w; 

}

int find(int x)

{

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

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

}

int main()

{

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

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

	{

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

		fa[i]=i;use[i]=i;

		a[i].vis=true;

	}

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

	{

		int u,v;

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

		u++,v++;

		int r1=find(u),r2=find(v);

		if(r1!=r2)

		{

			if(a[use[r2]].w<a[use[r1]].w)

			{

				a[use[r1]].vis=false;

				use[r1]=use[r2];

			}

			else a[use[r2]].vis=false;

			fa[r2]=r1;

		}

	}

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

		if(find(i)==i) 

		{

			ans+=1ll*a[use[i]].w;

			cnt++;

		}

	if(cnt==1)

	{

		printf("0\n");

		return 0;

	}

	sort(a+1,a+n+1,cmp);

	for(int i=1;i<=cnt-2;i++)

		if(a[i].vis)

		{

			printf("Impossible\n");

			return 0;

		}

		else ans+=1ll*a[i].w;

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

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

#include<cstring>

#include<algorithm>

using namespace std;

const long long MAXN=100005;



namespace DSU

{

	long long fa[MAXN];

	void Clear()

	{memset(fa,-1,sizeof fa);}

	long long Root(long long x)

	{return fa[x]==-1?x:(fa[x]=Root(fa[x]));}

	void Union(long long x,long long y)

	{

		long long r1=Root(x),r2=Root(y);

		if(r1!=r2)

			fa[r1]=r2;

	}

}



struct Vertice

{

	long long val,id;

	Vertice(){val=0x3F3F3F3F3F3F3F3FLL;}

	Vertice(long long v,long long i){val=v;id=i;}

	bool operator < (const Vertice &t)const

	{return val<t.val;}

};



Vertice V[MAXN],tr[MAXN];

bool used[MAXN];

bool mk[MAXN];



int main()

{

	long long n,m;

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

	for(long long i=0,a;i<n;i++)

	{

		scanf("%lld",&a);

		V[i]=Vertice(a,i);

	}

	DSU::Clear();

	for(long long i=0,u,v;i<m;i++)

	{

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

		DSU::Union(u,v);

	}

	int cc=0;

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

		if(!mk[DSU::Root(i)])

		{

			mk[DSU::Root(i)]=true;

			cc++;

		}

	if(cc==1)

	{

		puts("0");

		return 0;

	}

	if(2*cc-2>n)

	{

		puts("Impossible");

		return 0;

	}

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

	{

		int r=DSU::Root(i);

		tr[r]=min(tr[r],V[i]);

	}

	long long ans=0,cnt=2*cc-2;

	for(long long i=0;i<n&&cnt;i++)

	{

		int r=DSU::Root(i);

		if(!used[tr[r].id])

		{

			ans+=tr[r].val;

			used[tr[r].id]=true;

			cnt--;

		}

	}

	sort(V,V+n);

	for(long long i=0;i<n&&cnt;i++)

		if(!used[V[i].id])

		{

			ans+=V[i].val;

			cnt--;

		}

	

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

	return 0;

}


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

using namespace std;

int n,m,fa[100005],a[100005],b[100005],t,x,y;

long long s;

inline int read(){

    int x=0,f=1;char ch=getchar();

    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}

    return x*f;

}

int find(int r){return fa[r]?fa[r]=find(fa[r]):r;}

int main(){

	n=read(),m=read();

	if(m==n-1) return 0*puts("0");

	for(int i=1;i<=n;++i) a[i]=read(),s+=a[i];

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

		x=read(),y=read();

		x=find(x+1),y=find(y+1);

		s-=max(a[x],a[y]);

		b[++t]=max(a[x],a[y]);

		if(a[x]>a[y]) fa[x]=y;else fa[y]=x;

	}

	if(t<n-m-2) return 0*puts("Impossible");

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

	for(int i=1;i<=n-m-2;++i) s+=b[i];

	printf("%lld",s);

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

#include<cstring>

#include<algorithm>

using namespace std;

const long long MAXN=100005;



namespace DSU

{

	long long fa[MAXN];

	void Clear()

	{memset(fa,-1,sizeof fa);}

	long long Root(long long x)

	{return fa[x]==-1?x:(fa[x]=Root(fa[x]));}

	void Union(long long x,long long y)

	{

		long long r1=Root(x),r2=Root(y);

		if(r1!=r2)

			fa[r1]=r2;

	}

}



struct Vertice

{

	long long val,id;

	Vertice(){val=0x3F3F3F3F3F3F3F3FLL;}

	Vertice(long long v,long long i){val=v;id=i;}

	bool operator < (const Vertice &t)const

	{return val<t.val;}

};



Vertice V[MAXN],tr[MAXN];

bool used[MAXN];

bool mk[MAXN];



int main()

{

	long long n,m;

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

	for(long long i=0,a;i<n;i++)

	{

		scanf("%lld",&a);

		V[i]=Vertice(a,i);

	}

	DSU::Clear();

	for(long long i=0,u,v;i<m;i++)

	{

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

		DSU::Union(u,v);

	}

	int cc=0;

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

		if(!mk[DSU::Root(i)])

		{

			mk[DSU::Root(i)]=true;

			cc++;

		}

	if(cc==1)

	{

		puts("0");

		return 0;

	}

	if(2*cc-2>n)

	{

		puts("Impossible");

		return 0;

	}

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

	{

		int r=DSU::Root(i);

		tr[r]=min(tr[r],V[i]);

	}

	long long ans=0,cnt=2*cc-2;

	for(long long i=0;i<n&&cnt;i++)

	{

		int r=DSU::Root(i);

		if(!used[tr[r].id])

		{

			ans+=tr[r].val;

			used[tr[r].id]=true;

			cnt--;

		}

	}

	sort(V,V+n);

	for(long long i=0;i<n&&cnt;i++)

		if(!used[V[i].id])

		{

			ans+=V[i].val;

			cnt--;

		}

	

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

	return 0;

}


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

using namespace std;



const int MAXN = 1e5 + 10;



bool vis[MAXN];

int n, m, k;

int u, v;

int a[MAXN];

long long ans;

vector<int> adj[MAXN];

vector<int> ret;

vector<vector<int>> b;

 

void dfs(int x, vector<int>& k) {

	k.push_back(a[x]);

	vis[x] = true;

	for (int u: adj[x]) 

		if (!vis[u]) 

			dfs(u, k);

}

 

int main() {

	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	///////////////////////////////////////////////////////////

	cin >> n >> m;

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

		cin >> a[i];

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

		cin >> u >> v;

		u++;

		v++;

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

	/////////////////////////////////////////////////////////////

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

		if (!vis[i]) {

			dfs(i, ret);

			b.push_back(ret);

			ret.clear();

		}

	}

	k = b.size();

 

	if (n < 2 * k - 2)

		return cout << "Impossible" << '\n', 0;



	if (k == 1)

		return cout << 0 << '\n', 0;

		

	vector<int> res;

	for (auto v: b) {

		sort(v.rbegin(), v.rend());

		ans += v.back();

		v.pop_back();

		copy(v.begin(), v.end(), back_inserter(res));

	}

	

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

	ans = accumulate(res.begin(), res.begin() + k - 2, ans);

	cout << ans << '\n';

	return 0;

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

#include <vector>

#include <algorithm>

using namespace std;



const int N = 100 * 1000 + 5;

int nparts = 0;



int a[N];

vector <int> adj[N];

int part[N];

vector <int> vec[N];

vector <int> rm;



void dfs(int v) {

	for (auto u : adj[v]) {

		if (!part[u]) {

			part[u] = part[v];

			dfs(u);

		}

	}

}

int main() {

	long long ans = 0;

	int n, m;

	cin >> n >> m;

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

		cin >> a[i];

	}

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

		int u, v;

		cin >> u >> v;

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

	if (m == n - 1) {

		cout << 0 << endl;

		return 0;

	}

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

		if (!part[i]) {

			nparts++;

			part[i] = nparts;

			dfs(i);

		}

	}

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

		vec[part[i]].push_back(a[i]);

	}

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

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

		ans += vec[i][0];

		for (int j = 1; j < vec[i].size(); j++) {

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

		}

	}

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

//	cout << nparts << endl;

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

		cout << "Impossible" << endl;

	}

	else {

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

			ans += rm[i];

		}

		cout << ans << endl;

	}

	return 0;

}

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

using namespace std;



const int MAXN = 1e5 + 10;



bool vis[MAXN];

int n, m, k;

int u, v;

int a[MAXN];

long long ans;

vector<int> adj[MAXN];

vector<int> ret;

vector<vector<int>> b;

 

void dfs(int x, vector<int>& k) {

	k.push_back(a[x]);

	vis[x] = true;

	for (int u: adj[x]) 

		if (!vis[u]) 

			dfs(u, k);

}

 

int main() {

	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	///////////////////////////////////////////////////////////

	cin >> n >> m;

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

		cin >> a[i];

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

		cin >> u >> v;

		u++;

		v++;

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

	/////////////////////////////////////////////////////////////

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

		if (!vis[i]) {

			dfs(i, ret);

			b.push_back(ret);

			ret.clear();

		}

	}

	k = b.size();

 

	if (n < 2 * k - 2)

		return cout << "Impossible" << '\n', 0;



	if (k == 1)

		return cout << 0 << '\n', 0;

		

	vector<int> res;

	for (auto v: b) {

		sort(v.rbegin(), v.rend());

		ans += v.back();

		v.pop_back();

		copy(v.begin(), v.end(), back_inserter(res));

	}

	

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

	ans = accumulate(res.begin(), res.begin() + k - 2, ans);

	cout << ans << '\n';

	return 0;

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

#include<iostream>

#include<vector>

#include<algorithm>

#include<cmath>

#include<set>

#include<queue>

#include<deque>

#include<map>

#include<stack>

#include<bitset>

#include<list>

#include<cassert>

#include<numeric>

#include<iomanip>



using namespace std;

 

const long long N = 1e5 + 5;



long long cnt = 0;

long long ans = 0;

long long n, m; 

long long a[N];

vector <long long> graph[N];

vector <long long> other;

vector <long long> component[N];

long long comp[N];

bool mark[N];

 

void dfs(long long v, long long cnt) 

{

	comp[v] = cnt;

	mark[v] = true;

	for (long long i = 0; i < graph[v].size(); i++)

	{

		long long u = graph[v][i];

		if (!mark[u])

		{

			dfs(u, cnt);

		}

	}

}



int main() 

{

	cin >> n >> m;

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

	{

		cin >> a[i];

	}

	for (long long i = 0; i < m; i++) 

	{

		long long u, v;

		cin >> u >> v;

		graph[u].push_back(v);

		graph[v].push_back(u);

	}

	if (m == n - 1) 

	{

		cout << 0 << endl;

		exit(0);

	}

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

	{

		if (!mark[i]) 

		{

			cnt++;

			dfs(i, cnt);

		}

	}

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

	{

		component[comp[i]].push_back(a[i]);

	}

	for (long long i = 1; i <= cnt; i++)

	{

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

	}

	for (long long i = 1; i <= cnt; i++) 

	{

		ans += component[i][0];

		for (long long j = 1; j < component[i].size(); j++) 

		{

			other.push_back(component[i][j]);

		}

	}

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

	if (2 * (cnt - 1) > n) 

	{

		cout << "Impossible" << endl;

		exit(0);

	}

	for (long long i = 0; i < cnt - 2; i++) 

	{

		ans += other[i];

	}

	cout << ans << endl;

}

	

            





 


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

using namespace std;



const int MAXN = 1e5 + 10;



bool vis[MAXN];

int n, m, k;

int u, v;

int a[MAXN];

long long ans;

vector<int> adj[MAXN];

vector<int> ret;

vector<vector<int>> b;

 

void dfs(int x, vector<int>& k) {

	k.push_back(a[x]);

	vis[x] = true;

	for (int u: adj[x]) 

		if (!vis[u]) 

			dfs(u, k);

}

 

int main() {

	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	///////////////////////////////////////////////////////////

	cin >> n >> m;

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

		cin >> a[i];

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

		cin >> u >> v;

		u++;

		v++;

		adj[u].push_back(v);

		adj[v].push_back(u);

	}

	/////////////////////////////////////////////////////////////

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

		if (!vis[i]) {

			dfs(i, ret);

			b.push_back(ret);

			ret.clear();

		}

	}

	k = b.size();

 

	if (n < 2 * k - 2)

		return cout << "Impossible" << '\n', 0;



	if (k == 1)

		return cout << 0 << '\n', 0;

		

	vector<int> res;

	for (auto v: b) {

		sort(v.rbegin(), v.rend());

		ans += v.back();

		v.pop_back();

		copy(v.begin(), v.end(), back_inserter(res));

	}

	

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

	ans = accumulate(res.begin(), res.begin() + k - 2, ans);

	cout << ans << '\n';

	return 0;

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

#include <algorithm>

#include <vector>

#define fs first

#define sc second

using namespace std;

const int maxn = 1e5+10;

using pii = pair<int,int>;



int N;

int main(){

    cin>>N;

    cout<<(N+2-1)/2<<endl;





    return 0;

}

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



int main()

{

	int N;

	scanf("%d", &N);

	

	

	if(N%2==0)

	{

		printf("%d", N/2);

	}	

	else if(N%2!=0)

	{

		printf("%d", N/2 + 1);

	}

	return 0;

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

using namespace std;

main()

{



int n;

cin>>n;

if(n%2==0)

{

    cout<<""<<n/2;

}

else

{

    cout<<""<<(n/2)+1;

}



}


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



int main()

{

	int N;

	scanf("%d", &N);

	

	

	if(N%2==0)

	{

		printf("%d", N/2);

	}	

	else if(N%2!=0)

	{

		printf("%d", N/2 + 1);

	}

	return 0;

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

#include <algorithm>

#include <vector>

#define fs first

#define sc second

using namespace std;

const int maxn = 1e5+10;

using pii = pair<int,int>;



int N;

int main(){

    cin>>N;

    cout<<(N+2-1)/2<<endl;





    return 0;

}

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

int main(){

	int pages;

	scanf("%d", &pages);

	(pages % 2 == 0) ? printf("%d", pages / 2) : printf("%d", pages / 2 + 1);

	return 0;

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

using namespace std;

main()

{



int n;

cin>>n;

if(n%2==0)

{

    cout<<""<<n/2;

}

else

{

    cout<<""<<(n/2)+1;

}



}


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

int main(){

	int pages;

	scanf("%d", &pages);

	(pages % 2 == 0) ? printf("%d", pages / 2) : printf("%d", pages / 2 + 1);

	return 0;

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

#include <algorithm>

#include <vector>

#define fs first

#define sc second

using namespace std;

const int maxn = 1e5+10;

using pii = pair<int,int>;



int N;

int main(){

    cin>>N;

    cout<<(N+2-1)/2<<endl;





    return 0;

}

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

 

int main()

{

	int N;

	scanf("%d", &N);

	

	

	if(N%2==0)

	{

		printf("%d", N/2);

	}	

	if(N%2!=0)

	{

		printf("%d", N/2 + 1);

	}

	return 0;

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

using namespace std;

main()

{



int n;

cin>>n;

if(n%2==0)

{

    cout<<""<<n/2;

}

else

{

    cout<<""<<(n/2)+1;

}



}


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

 

int main()

{

	int N;

	scanf("%d", &N);

	

	

	if(N%2==0)

	{

		printf("%d", N/2);

	}	

	if(N%2!=0)

	{

		printf("%d", N/2 + 1);

	}

	return 0;

}