#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <utility>
/*
 
template<typename T, bool P = false>
class PairingHeap;
 
PairingHeapは融合可能なヒープ(優先度付きキュー)です
空間計算量 O(N)
 
 
テンプレートパラメータ
-typename T
operator< によって大小が定義された構造体
要素の型になります
 
-bool P
true を与えると最大ヒープになります
デフォルトでは false で最小ヒープです
 
 
メンバ関数
-(constructor) ()
空のヒープを構築します
時間計算量 O(1)
 
-top (void)->const T &
先頭の要素のconst参照を返します
時間計算量 O(1)
 
-pop (void)->const T &
先頭の要素を削除し、そのconst参照を返します
時間計算量 償却 O(logN)
 
-push (T data)->node_t *
data を要素としてヒープに追加します
追加された要素へのポインタを返します
時間計算量 O(1)
 
-empty ()->bool
ヒープが空かどうかを返します
時間計算量 O(1)
 
-size ()->uint32
要素数を返します
時間計算量 O(1)
 
-meld (ParingHeap<T, P> &other)
other の持つ要素全てをヒープに追加します
otherは空になります
時間計算量 O(1)
 
-decrease (node_t *x, T data)
x のキーの値を data に変更します
data は変更前の値以下(P=true ならば以上)である必要があります
時間計算量 O(1)
 
 
メンバ型
-node_t
要素を格納しているノードの型
push の返り値として与えられ、decrease の際に使用する
 
 
※N:要素数
※T の比較に掛かる時間計算量を O(1) と仮定
 
*/
 
template <typename T, bool P = false> class PairingHeap {
	static constexpr std::uint_fast64_t ALLOCSIZE = (std::uint_fast64_t)1 << 10;
 
public:
	struct node_t {
		T data;
		node_t *left, *right, *per;
	};
 
private:
	node_t *root;
	std::uint_fast32_t size_;
	static node_t *merge(node_t *x, node_t *y) {
		if (P ^ (x->data < y->data))
			std::swap(x, y);
		if (x->right = y->left)
			y->left->per = x;
		y->left = x;
		x->per = y;
		return y;
	}
 
public:
	PairingHeap() : root(nullptr), size_(0) {}
	const T &top() const {
		assert(root);
		return root->data;
	}
	const T &pop() {
		assert(root);
		--size_;
		const T &ret = root->data;
		node_t *n = nullptr, *x = root->left, *y;
		while (x) {
			y = x;
			if (x->right) {
				x = x->right->right;
				y = merge(y, y->right);
			}
			else {
				x = nullptr;
			}
			y->right = n;
			n = y;
		}
		if (!n) {
			root = nullptr;
			return ret;
		}
		root = n;
		n = n->right;
		while (n) {
			x = n;
			n = n->right;
			root = merge(root, x);
		}
		root->per = nullptr;
		root->right = nullptr;
		return ret;
	}
	node_t *push(const T &data) {
		static node_t *pool = nullptr;
		static std::uint_fast64_t it = ALLOCSIZE;
		if (it == ALLOCSIZE) {
			pool = (node_t *)malloc(ALLOCSIZE * sizeof(node_t));
			it = 0;
		}
		node_t *top = &pool[it++];
		top->data = data;
		top->left = top->right = top->per = nullptr;
		root = root ? merge(root, top) : top;
		++size_;
		return top;
	}
	bool empty() { return !root; }
	std::uint_fast32_t size() { return size_; }
	void meld(PairingHeap<T, P> &other) {
		size_ += other.size_;
		other.size_ = 0;
		if (other.root) {
			root = root ? merge(root, other.root) : other.root;
			other.root = nullptr;
		}
	}
	void decrease(node_t * x, const T &data) {
		assert(x);
		assert(!(P ^ (x->data < data)));
		if (!x->per) {
			x->data = data;
			return;
		}
		if (x->right)
			x->right->per = x->per;
		if (x->per->right != x)
			x->per->left = x->right;
		else
			x->per->right = x->right;
		x->per = nullptr;
		x->right = nullptr;
		root = merge(root, x);
	}
};
//#define NDEBUG
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
static constexpr double PI = 3.1415926535897932;
 
using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;
using intl32 = std::int_least32_t;
using intl64 = std::int_least64_t;
using uintl32 = std::uint_least32_t;
using uintl64 = std::uint_least64_t;
 
namespace n91 {
	template <typename T>
	auto scan(T &d) ->
		typename std::enable_if<std::is_same<T, std::string>::value>::type {
		d = std::string();
		int c = 0;
		while (c < 'a' || 'z' < c)
			c = fgetc(stdin);
		while ('a' <= c && c <= 'z') {
			d.push_back(c);
			c = fgetc(stdin);
		}
	}
	template <typename T>
	auto scan(T &d) ->
		typename std::enable_if<std::is_same<T, double>::value>::type {
		scanf("%lf", &d);
	}
	template <typename T>
	auto scan(T &d) ->
		typename std::enable_if<std::is_signed<T>::value ==
		std::is_same<T, std::string>::value>::type {
		d = 0;
		int c = 0;
		while (c < '0' || '9' < c)
			c = fgetc(stdin);
		while ('0' <= c && c <= '9') {
			d = d * 10 + c - '0';
			c = fgetc(stdin);
		}
	}
	template <typename T>
	auto scan(T &d) ->
		typename std::enable_if<std::is_signed<T>::value !=
		std::is_same<T, double>::value>::type {
		d = 0;
		int c = 0;
		bool f = 0;
		while (c < '0' || '9' < c) {
			if (c == '-')
				f = 1;
			c = fgetc(stdin);
		}
		while ('0' <= c && c <= '9') {
			d = d * 10 + c - '0';
			c = fgetc(stdin);
		}
		if (f)
			d = -d;
	}
} // namespace n91
class UnionFindTree {
	using int32 = std::int_fast32_t;
	using uint32 = std::uint_fast32_t;
	std::vector<int32> tree;
 
public:
	UnionFindTree(uint32 size) : tree(size, -1) {}
	uint32 find(const uint32 x) {
		if (tree[x] < 0)
			return x;
		return tree[x] = (int32)find((uint32)tree[x]);
	}
	bool unite(uint32 x, uint32 y) {
		x = find(x);
		y = find(y);
		if (x == y)
			return false;
		if (tree[x] > tree[y])
			std::swap(x, y);
		tree[x] += tree[y];
		tree[y] = (int32)x;
		return true;
	}
	uint32 size(const uint32 x) { return (uint32)(-tree[find(x)]); }
	bool same(const uint32 x, const uint32 y) { return find(x) == find(y); }
};
 
int main(void) {
	uint32 n, m;
	n91::scan(n);n91::scan(m);
#define SIZ 100001
	PairingHeap<uint32> Q[SIZ], P;
	std::vector<uint32> r(n, 0), c(n);
	UnionFindTree U(n);
	for (uint32 i = 0;i < n;++i) {
		n91::scan(c[i]);
	}
	uint32 x, y;
	for (uint32 i = 0;i < m;++i) {
		n91::scan(x);n91::scan(y);
		U.unite(x, y);
	}
	for (uint32 i = 0;i < n;++i) {
		Q[U.find(i)].push(c[i]);
	}
	uint64 cost = 0, node = 0;
	for (uint32 i = 0;i < n;++i) {
		if (r[U.find(i)]) continue;
		r[U.find(i)] = 1;
		++node;
		cost += Q[U.find(i)].top();
		Q[U.find(i)].pop();
		P.meld(Q[U.find(i)]);
	}
	if (node == 1) {
		puts("0");
		return 0;
	}
	if (P.size() + 2 < node) {
		puts("Impossible");
		return 0;
	}
	for (uint32 i = 2;i < node;++i) {
		cost += P.top();
		P.pop();
	}
	printf("%lu\n", cost);
	return 0;
}

Measured memory_bytes: 7296