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



using namespace std;



const int N = 100010;



struct Heap{

	Heap *l, *r;

	int val, len, size;

}*root[N], Pool[N * 2], *cur = Pool;



int fa[N];

priority_queue<pair<int, int> >Q;



Heap *newnode(int val_)

{

	cur++;

	cur -> len = 0;

	cur -> size = 1;

	cur -> val = val_;

	cur -> l = cur -> r = NULL;

	return cur;

}



Heap *Merge(Heap *A, Heap *B)

{

	if(!A)return B;

	if(!B)return A;

	if(A -> val > B -> val)swap(A, B);

	A -> r = Merge(A -> r, B);

	A -> size = (A -> l ? A -> l -> size : 0) + (A -> r ? A -> r -> size : 0) + 1;

	if(!(A -> l))swap(A -> l, A -> r);

	if(A -> l && A -> r && A -> l -> len < A -> r -> len)swap(A -> l, A -> r);

	if(A -> r)A -> len = A -> r -> len + 1;

	else A -> len = 0;

	return A;

}



int getf(int u)

{

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

	return fa[u] = getf(fa[u]);

}



int main()

{

	int n, m;

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

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

	{

		int val;

		scanf("%d", &val);

		root[i] = newnode(val);

		fa[i] = i;

	}

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

	{

		int x, y;

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

		x++; y++;

		int u, v;

		u = getf(x), v = getf(y);

		if(u > v)swap(u, v);

		fa[v] = u;

		root[u] = Merge(root[u], root[v]);

	}

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

		if(getf(i) == i)

		{

			Q.push(make_pair(root[i] -> size, i));

		}

	long long ans = 0;

	while(Q.size() > 1)

	{

		pair<int, int> v1 = Q.top();

		Q.pop();

		pair<int, int> v2 = Q.top();

		Q.pop();

		int u = v1.second, v = v2.second;

		if(!root[u] || !root[v])

		{

			puts("Impossible");

			return 0;

		}

		ans += (root[u] -> val + root[v] -> val);

		if(u > v)swap(u, v);

		fa[v] = u;

		root[u] = Merge(Merge(root[u] -> l, root[u] -> r), Merge(root[v] -> l, root[v] -> r));

		if(root[u])Q.push(make_pair(root[u] -> size, u));

		else Q.push(make_pair(0, u));

	}

	cout << ans << endl;

}