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

#include<cctype>

#include<cstring>

#include<algorithm>

#include<vector>

using std::vector;

#define max(a,b) (a>b?a:b)

#define min(a,b) (a<b?a:b)

#define reg register

typedef long long ll;

inline int read(){

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

    for(;!isdigit(ch);f=ch=='-'?-1:1,ch=getchar());

    for(;isdigit(ch);x=x*10+(ch^48),ch=getchar());

    return x*f;

}

const int MN=1e5+5;

int n,m;

class UFset{

	public:

		int par[MN];

		inline int find(int x){return x==par[x]?x:par[x]=find(par[x]);}

		inline void init(int x){for(reg int i=0;i<x;i++)par[i]=i;}

		inline void unite(int x,int y){x=find(x);y=find(y);par[y]=x;}

		inline bool isfa(int x){return find(x)==x;}

}S;

int v[MN],cnt,id[MN],a[MN];

vector<int>pts[MN];

int main(){

	n=read();m=read();S.init(n);if(n==m+1)return 0*puts("0");

	for(reg int i=0;i<n;i++)v[i]=read();

	for(reg int i=1;i<=m;i++)S.unite(read(),read());

	for(reg int i=0;i<n;i++)if(S.isfa(i))id[i]=++cnt,pts[cnt].push_back(v[i]);

	for(reg int i=0;i<n;i++)if(!S.isfa(i))pts[id[S.find(i)]].push_back(v[i]);

	if(n<((cnt-1)<<1))return 0*puts("Impossible");

	for(reg int i=1;i<=cnt;i++)std::sort(pts[i].begin(),pts[i].end());

	reg ll ans=0;reg int tot=0;

	for(reg int i=1;i<=cnt;i++)ans+=pts[i][0];

	for(reg int i=1;i<=cnt;i++)for(reg int j=1;j<pts[i].size();j++)a[++tot]=pts[i][j];

	std::sort(a+1,a+1+tot);

	for(reg int i=1;i<=cnt-2;i++)ans+=a[i];

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

    return 0;

}

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

using namespace std;



#define ll long long

#define sd(x) scanf("%d", &(x))

#define pii pair<int, int>

#define F first

#define S second

#define all(c) ((c).begin()), ((c).end())

#define sz(x) ((int)(x).size())

#define ld long double



template<class T,class U>

ostream& operator<<(ostream& os,const pair<T,U>& p){

	os<<"("<<p.first<<", "<<p.second<<")";

	return os;

}



template<class T>

ostream& operator <<(ostream& os,const vector<T>& v){

	os<<"{";

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

		if(i)os<<", ";

		os<<v[i];

	}

	os<<"}";

	return os;

}



#ifdef LOCAL

#define cerr cout

#else

#endif



#define TRACE



#ifdef TRACE

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1){

	cerr << name << " : " << arg1 << std::endl;

}

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args){

	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);

}

#else

#define trace(...)

#endif



struct dsu{

    int n;

    vector<int> par;

    vector<vector<int>> comp;

    int num;

    dsu(int n) : n(n), par(n), comp(n), num(n){

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

    }

    int root(int x){

        return x == par[x] ? x : (par[x] = root(par[x]));

    }

    bool merge(int x, int y){

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

        if(x == y) return 0;

        par[x] = y;

        num--;

        return 1;

    }

    void get(){

        for(int i = 0; i < n; i++) comp[root(i)].push_back(i);

    }

};





int a[100005];

int main(){

    int n, m; sd(n); sd(m);

    for(int i = 0; i < n; i++) sd(a[i]);

    dsu D(n);

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

        int u, v;

        sd(u); sd(v);

        D.merge(u, v);

    }

    if(D.num == 1){

        printf("0\n");

        return 0;

    }

    D.get();

    vector<int> rem;

    ll ans = 0;

    int num = 0;

    for(int i = 0; i < n; i++) if(!D.comp[i].empty()){

        vector<int> V = D.comp[i];

        sort(all(V), [&](int i, int j){

            return a[i] < a[j];

        });

        ans += a[V[0]];

        for(int j = 1; j < sz(V); j++) rem.push_back(a[V[j]]);

    }

    if(sz(rem) < D.num - 2){

        printf("Impossible\n");

        return 0;

    }

    sort(all(rem));

    for(int i = 0; i < D.num - 2; i++) ans += rem[i];

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

}