You are given a forest with N vertices and M edges. The vertices are numbered 0 through N-1. The edges are given in the format (x_i,y_i), which means that Vertex x_i and y_i are connected by an edge.

Each vertex i has a value a_i. You want to add edges in the given forest so that the forest becomes connected. To add an edge, you choose two different vertices i and j, then span an edge between i and j. This operation costs a_i + a_j dollars, and afterward neither Vertex i nor j can be selected again.

Find the minimum total cost required to make the forest connected, or print `Impossible` if it is impossible.

Constraints

* 1 ≤ N ≤ 100,000
* 0 ≤ M ≤ N-1
* 1 ≤ a_i ≤ 10^9
* 0 ≤ x_i,y_i ≤ N-1
* The given graph is a forest.
* All input values are integers.

Input

Input is given from Standard Input in the following format:


N M
a_0 a_1 .. a_{N-1}
x_1 y_1
x_2 y_2
:
x_M y_M


Output

Print the minimum total cost required to make the forest connected, or print `Impossible` if it is impossible.

Examples

Input

7 5
1 2 3 4 5 6 7
3 0
4 0
1 2
1 3
5 6


Output

7


Input

5 0
3 1 4 1 5


Output

Impossible


Input

1 0
5


Output

0
import java.util.*;
import java.io.*;

public class Main {

	class DSU {
		int[] p;

		public DSU(int n) {
			p = new int[n];
			for (int i = 0; i < n; i++) {
				p[i] = i;
			}
		}

		int get(int i) {
			if (p[i] == i) {
				return i;
			}
			return p[i] = get(p[i]);
		}

		void union(int a, int b) {
			p[get(b)] = get(a);
		}
	}

	void solve() {
		int n = in.nextInt(), m = in.nextInt();
		int[] cost = new int[n];
		for (int i = 0; i < n; i++) {
			cost[i] = in.nextInt();
		}
		DSU dsu = new DSU(n);
		for (int i = 0; i < m; i++) {
			dsu.union(in.nextInt(), in.nextInt());
		}
		int edges = n - m - 1;
		int needTake = 2 * edges;
		int[] count = new int[n];

		Integer[] a = new Integer[n];
		for (int i = 0; i < n; i++) {
			a[i] = i;
		}
		Arrays.sort(a, (i, j) -> Integer.compare(cost[i], cost[j]));
		long ans = 0;
		if (needTake == 0){ 
			out.println(0);
			return;
		}
		boolean[] used = new boolean[n];
		for (int i : a) {
			if (count[dsu.get(i)] == 0) {
				ans += cost[i];
				needTake--;
				count[dsu.get(i)]++;
				used[i] = true;
			}
		}
		for (int i : a) {
			if (used[i]) {
				continue;
			}
			if (count[dsu.get(i)] < edges && needTake > 0) {
				ans += cost[i];
				needTake--;
				count[dsu.get(i)]++;
				used[i] = true;
			}
		}
		out.println(needTake == 0 ? ans : "Impossible");
	}

	FastScanner in;
	PrintWriter out;

	void run() {
		in = new FastScanner();
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public FastScanner(String s) {
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public String nextToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(nextToken());
		}

		public long nextLong() {
			return Long.parseLong(nextToken());
		}

		public double nextDouble() {
			return Double.parseDouble(nextToken());
		}
	}

	public static void main(String[] args) {
		new Main().run();
	}
}
