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

# include <algorithm>

# include <vector>

# include <string>

# include <set>

# include <map>

# include <cmath>

# include <iomanip>

# include <functional>

# include <utility>

# include <stack>

# include <queue>

# include <list>

# include <tuple>

# include <unordered_map>

# include <numeric>

# include <complex>

# include <bitset>

# include <random>

# include <chrono>

using namespace std;

using LL = long long;

using ULL = unsigned long long;

typedef pair<LL, LL> P;

constexpr int INF = 2000000000;

constexpr int HINF = INF / 2;

constexpr double DINF = 100000000000000000.0;

constexpr long long LINF = 9223372036854775807;

constexpr long long HLINF = 4500000000000000000;

const double PI = acos(-1);

int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };

# define ALL(x)      (x).begin(),(x).end()

# define UNIQ(c)     (c).erase(unique(ALL((c))),(c).end())

# define mp          make_pair

# define eb          emplace_back

# define FOR(i,a,b)  for(int i=(a);i<(b);i++)

# define RFOR(i,a,b) for(int i=(a);i>=(b);i--)

# define REP(i,n)    FOR(i,0,n)

# define INIT        std::ios::sync_with_stdio(false);std::cin.tie(0)



int n, m;

int a[101010];

vector<int> G[101010];

bool used[101010];





int minl, minpos;



void serch(int pos) {

	queue<int> rue;

	rue.push(pos);

	while (rue.size()) {

		int que = rue.front();

		rue.pop();

		used[que] = true;

		if (minl > a[que]) {

			minl = a[que];

			minpos = que;

		}

		REP(i, G[que].size()) {

			if (!used[G[que][i]])rue.push(G[que][i]);

		}

	}

}





int main() {

	cin >> n >> m;

	REP(i, n)cin >> a[i];

	REP(i, m) {

		int x, y;

		cin >> x >> y;

		G[x].emplace_back(y);

		G[y].emplace_back(x);

	}

	if (n == 1) {

		cout << 0 << endl;

		return 0;

	}

	LL ans = 0;

	int cnt = 0;

	REP(i, n) {

		if (!used[i]) {

			cnt++;

			minl = INF;

			minpos = -1;

			serch(i);

			ans += a[minpos];

			a[minpos] = INF;

		}

	}

	if (cnt == 1) {

		cout << 0 << endl;

		return 0;

	}

	sort(a, a + n);

	REP(i, cnt - 2) {

		if (a[i] == INF) {

			cout << "Impossible" << endl;

			return 0;

		}

		ans += a[i];

	}

	cout << ans << endl;

}

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

using namespace std;

using LL = long long;

using ULL = unsigned long long;

const double PI = acos(-1);

template<class T>constexpr T INF() { return ::std::numeric_limits<T>::max(); }

template<class T>constexpr T HINF() { return INF<T>() / 2; }

template <typename T_char>T_char TL(T_char cX) { return tolower(cX); };

template <typename T_char>T_char TU(T_char cX) { return toupper(cX); };

const int vy[] = { -1, -1, -1, 0, 1, 1, 1, 0 }, vx[] = { -1, 0, 1, 1, 1, 0, -1, -1 };

const int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };

int popcnt(unsigned long long n) { int cnt = 0; for (int i = 0; i < 64; i++)if ((n >> i) & 1)cnt++; return cnt; }

int d_sum(LL n) { int ret = 0; while (n > 0) { ret += n % 10; n /= 10; }return ret; }

int d_cnt(LL n) { int ret = 0; while (n > 0) { ret++; n /= 10; }return ret; }

LL gcd(LL a, LL b) { if (b == 0)return a; return gcd(b, a%b); };

LL lcm(LL a, LL b) { LL g = gcd(a, b); return a / g*b; };

# define ALL(qpqpq)           (qpqpq).begin(),(qpqpq).end()

# define UNIQUE(wpwpw)        sort(ALL((wpwpw)));(wpwpw).erase(unique(ALL((wpwpw))),(wpwpw).end())

# define LOWER(epepe)         transform(ALL((epepe)),(epepe).begin(),TL<char>)

# define UPPER(rprpr)         transform(ALL((rprpr)),(rprpr).begin(),TU<char>)

# define FOR(i,tptpt,ypypy)   for(LL i=(tptpt);i<(ypypy);i++)

# define REP(i,upupu)         FOR(i,0,upupu)



struct INIT{

    INIT(){

        std::ios::sync_with_stdio(false);

        std::cin.tie(0);

        cout << fixed << setprecision(13);

    }

}INIT;



struct UnionFind {

	UnionFind(size_t size){

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

            par.emplace_back(i);

            rnk.emplace_back(0);

        }

    }

	vector<int> par, rnk;



    int root(int x){

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

        else return par[x] = root(par[x]);

    }



    bool is_root(int x){

        return root(x) == x;

    }



    void unite(int x, int y){

        x = root(x);

        y = root(y);

        if(x == y)return;

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

            par[x] = y;

        }else{

            par[y] = x;

            if(rnk[x] == rnk[y])rnk[x]++;

        }

    }

    bool same(int x,int y){

        return root(x) == root(y);

    }

};



int n, m;

LL a[101010];

int main(){

    cin >> n >> m;

    int group = n;

    UnionFind forest(n);

    REP(i, n)cin >> a[i];

    REP(i, m){

        int x, y;

        cin >> x >> y;

        if(forest.same(x, y))continue;

        forest.unite(x, y);

        group--;

    }

    if(group == 1){

        cout << 0 << endl;

        return 0;

    }

    vector<LL> v[101010];

    REP(i, n)v[forest.root(i)].emplace_back(a[i]);

    REP(i, n)sort(ALL(v[i]));

    LL ans = 0;

    vector<LL> vec;

    REP(i, n)if((int)v[i].size()){

        ans += v[i][0];

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

            vec.emplace_back(v[i][j]);

        }

    }

    sort(ALL(vec));

    if((int)vec.size() < (group - 1) * 2 - group){

        cout << "Impossible" << endl;

        return 0;

    }

    REP(i, (group - 1) * 2 - group)ans += vec[i];

    cout << ans << endl;

}