#include <cassert>
#include <cstdint>
#include <utility>
#include <vector>

class UnionFind {

public:
	using size_type = std::uint_fast32_t;

private:
	std::vector<std::pair<bool, size_type>> tree;

public:
	UnionFind(const size_type size) : tree(size, std::make_pair(1, 1)) {}
	size_type find(const size_type x) {
		assert(x < tree.size());
		if (tree[x].first)
			return x;
		return tree[x].second = find(tree[x].second);
	}
	bool unite(size_type x, size_type y) {
		assert(x < tree.size());
		assert(y < tree.size());
		x = find(x);
		y = find(y);
		if (x == y)
			return false;
		if (tree[x].second < tree[y].second)
			std::swap(x, y);
		tree[x].second += tree[y].second;
		tree[y] = std::make_pair(0, x);
		return true;
	}
	bool same(const size_type x, const size_type y) {
		assert(x < tree.size());
		assert(y < tree.size());
		return find(x) == find(y);
	}
	size_type size(const size_type x) {
		assert(x < tree.size());
		return tree[find(x)].second;
	}
	std::vector<size_type> roots() const {
		std::vector<size_type> ret;
		for (size_type i = 0; i < tree.size(); ++i) {
			if (tree[i].first)
				ret.push_back(i);
		}
		return ret;
	}
};

#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <utility>

template <typename T, class Compare = std::greater<T>> class PairingHeap {
	static constexpr std::uint_fast64_t ALLOCSIZE = (std::uint_fast64_t)1 << 10;

public:
	using value_type = T;
	using reference = value_type &;
	using const_reference = const value_type &;
	using size_type = std::uint_fast32_t;

private:
	struct node_t {
		value_type data;
		node_t *left, *right;
	};
	node_t *root;
	size_type size_;
	static node_t *merge(node_t *x, node_t *y) {
		static const Compare comp = Compare();
		if (comp(y->data, x->data))
			std::swap(x, y);
		x->right = y->left;
		y->left = x;
		return y;
	}

public:
	PairingHeap() : root(nullptr), size_(0) {}
	const_reference top() const {
		assert(root);
		return root->data;
	}
	const_reference pop() {
		assert(root);
		--size_;
		const_reference 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);
		}
		return ret;
	}
	void push(const_reference 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 = nullptr;
		root = root ? merge(root, top) : top;
		++size_;
	}
	bool empty() const { return !root; }
	size_type size() const { return size_; }
	void meld(PairingHeap<T, Compare> &other) {
		size_ += other.size_;
		other.size_ = 0;
		if (other.root) {
			root = root ? merge(root, other.root) : other.root;
			other.root = nullptr;
		}
	}
};


#include<iostream>
#include<vector>
int main(void) {
	int n, m;
	std::cin >> n >> m;
	std::vector<PairingHeap<int>> Q(n);
	UnionFind T(n);
	for (int i = 0; i < n; ++i) {
		int a;
		std::cin >> a;
		Q[i].push(a);
	}
	for (int i = 0; i < m; ++i) {
		int x, y;
		std::cin >> x >> y;
		int xr = T.find(x), yr = T.find(y);
		if (T.unite(x, y)) {
			if (xr == T.find(x))
				Q[xr].meld(Q[yr]);
			else
				Q[yr].meld(Q[xr]);
		}
	}
	std::vector<UnionFind::size_type> R = T.roots();
	if (R.size() == 1) {
		std::cout << "0" << std::endl;
		return 0;
	}
	long long cost = 0;
	PairingHeap<int> P;
	for (const auto i : R) {
		cost += Q[i].pop();
		P.meld(Q[i]);
	}
	if (P.size() + 2 < R.size()) {
		std::cout << "Impossible" << std::endl;
		return 0;
	}
	for (int i = 2; i < R.size(); ++i)
		cost += P.pop();
	std::cout << cost << std::endl;
	return 0;
}

Measured memory_bytes: 6908