// 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: 6.32565969315789x):
#include <bits/stdc++.h>



using namespace std;



class dsu {

  public:

  vector<int> p;

  int n;



  dsu(int _n) : n(_n) {

    p.resize(n);

    iota(p.begin(), p.end(), 0);

  }



  inline int get(int x) {

    return (x == p[x] ? x : (p[x] = get(p[x])));

  }



  inline bool unite(int x, int y) {

    x = get(x);

    y = get(y);

    if (x != y) {

      p[x] = y;

      return true;

    }

    return false;

  }

};



int main() {

  int n, m;

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

  vector<int> a(n);

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

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

  }

  dsu d(n);

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

    int x, y;

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

    d.unite(x, y);

  }

  vector< vector<int> > comp(n);

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

    comp[d.get(i)].push_back(a[i]);

  }

  int cnt = 0;

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

    if (!comp[i].empty()) {

      cnt++;

    }

  }

  if (cnt == 1) {

    puts("0");

    return 0;

  }

  int choose = 2 * cnt - 2;

  long long ans = 0;

  vector<int> other;

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

    if (!comp[i].empty()) {

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

      ans += comp[i][0];

      choose--;

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

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

      }

    }

  }

  if (choose > (int) other.size()) {

    puts("Impossible");

    return 0;

  }

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

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

    ans += other[i];

  }

  cout << ans << endl;

  return 0;

}