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

using namespace std;



typedef long long ll;

const int maxn=100010;

multiset<int> S[maxn];

set<pair<int,int> > S2;

struct Edge

{

	int v,next;

}	e[maxn<<1];

int g[maxn],tot;

void addedge(int x,int y)

{

	tot++;

	e[tot].v=y;

	e[tot].next=g[x];

	g[x]=tot;

}

int n,m;

bool vis[maxn];

int a[maxn];



void dfs(int t,int ha)

{

	S[ha].insert(a[t]);

	vis[t]=true;

	for (int i=g[t];i;i=e[i].next)

	if (!vis[e[i].v])

		dfs(e[i].v,ha);

}

int Union(pair<int,int> x,pair<int,int> y)

{

	multiset<int>::iterator it=S[x.second].lower_bound(x.first);

	S[x.second].erase(it);

	it=S[y.second].lower_bound(y.first);

	S[y.second].erase(it);

	int l=x.second,r=y.second;

	if (S[l].size()>S[r].size())	swap(l,r);

	for (auto i:S[l])

		S[r].insert(i);

	S[l].clear();

	return r;

}

int main()

{

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

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

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

	{

		int x,y;

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

		x++;y++;

		addedge(x,y);

		addedge(y,x);

	}

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

	if (!vis[i])

		dfs(i,i);

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

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

			S2.insert(make_pair(S[i].size(),i));

	ll ans=0;

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

	{

		if (S2.empty())

		{

			printf("Impossible\n");

			return 0;

		}

		pair<int,int> tmp1=*--S2.end();

		S2.erase(--S2.end());

		if (S2.empty())

		{

			printf("Impossible\n");

			return 0;

		}

		pair<int,int> tmp2=*--S2.end();

		S2.erase(--S2.end());

		tmp1.first=*S[tmp1.second].begin();

		tmp2.first=*S[tmp2.second].begin();

		ans+=tmp1.first+tmp2.first;

		int q=Union(tmp1,tmp2);

		if (!S[q].empty())	S2.insert(make_pair(S[q].size(),q));

	}

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

	return 0;

}

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

using namespace std;

const int maxn = 1e5+100;

typedef long long LL;

int val[maxn],First[maxn],cnt,N,M;

int tot,pre[maxn];

LL ans = 0;

struct node{

    int to,Next;

}Tree[maxn*2];

void init(){

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

    cnt = 0;

}

void addedge(int from,int to){

    Tree[cnt].to = to;

    Tree[cnt].Next = First[from];

    First[from] = cnt++;

}

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

void dfs(int u,int fa){

    pre[u] = 1;

    Q[tot].push(val[u]);

    for(int i = First[u];i!=-1;i=Tree[i].Next){

        int to = Tree[i].to;

        if(to==fa)continue;

        dfs(to,u);

    }

}

vector<int> ac,bc;

int main(){

    init();

    scanf("%d%d",&N,&M);

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

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

        int a,b;

        scanf("%d%d",&a,&b);

        addedge(a,b);

        addedge(b,a);

    }

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

        if(!pre[i]){

            tot++;

            dfs(i,-1);

            ac.push_back(tot);

        }

    }

    if(tot==1){

        printf("%d\n",0);

        return 0;

    }

    bool flag = 0;

    priority_queue<int,vector<int>,greater<int> >QQ;

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

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

       Q[i].pop();

       while(!Q[i].empty()){

        QQ.push(Q[i].top());

        Q[i].pop();

       }

    }

    int my =tot-2;

    if(QQ.size()<my){

        printf("Impossible\n");

        return 0;

    }

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

        ans+=QQ.top();

        QQ.pop();

    }

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

    return 0;

}

/*

7 4

1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000

0 1

1 2

3 4

5 6

6 3

1 1 1 3 7 8

0 4

1 5

2 3

*/