Problem:
Score : 600 points

Problem Statement

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.

Sample Input 1

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

Sample Output 1

7

If we connect vertices 0 and 5, the graph becomes connected, for the cost of 1 + 6 = 7 dollars.

Sample Input 2

5 0
3 1 4 1 5

Sample Output 2

Impossible

We can't make the graph connected.

Sample Input 3

1 0
5

Sample Output 3

0

The graph is already connected, so we do not need to add any edges.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program{
	const int mod=1000000007;
	const long o=1;
	static void Main(){
		Sc sc=new Sc();
		int[] s=sc.Ia;
		long ans=0;
		int m=0;
		int[] a=sc.Ia;
		Uf uf=new Uf(s[0]);
		for(int i=0;i<s[1];i++){
			int[] q=sc.Ia;
			uf.Union(q[0],q[1]);
		}
		int[] rt=new int[s[0]];
		int[] h=new int[uf.all+1];
		int[] c=new int[uf.all+1];
		for(int i=0;i<s[0];i++){
			int q=uf.Root(i);
			if(rt[q]==0){
				m++;
				h[m]=a[i];
				rt[q]=m;
				c[m]=i;
			}
			else if(h[rt[q]]>a[i]){
				h[rt[q]]=a[i];
				c[rt[q]]=i;
			}
		}
		for(int i=1;i<=m;i++){
			a[c[i]]=int.MaxValue;
			ans+=h[i];
		}
		Array.Sort(a);
		m=(m-1)*2-m;
		for(int i=0;i<m;i++){
			if(a[i]==int.MaxValue){m=-1;break;}
			ans+=a[i];
		}
		if(uf.all==1){m=0;ans=0;}
		Console.WriteLine("{0}",m!=-1?ans.ToString():"Impossible");
	}
}
public class Uf{
	private int[] arr,hi;
	public int all;
	public Uf(int n){
		arr=new int[n];
		hi=new int[n];
		all=n;
		for(int i=0;i<n;i++){arr[i]=-1;}
	}
	public void Union(int a,int b){
		a=Root(a);
		b=Root(b);
		if(a!=b){
			if(hi[a]<hi[b]){
				int v=b;
				b=a;
				a=v;
			}
			arr[a]+=arr[b];
			hi[a]=Math.Max(hi[a],hi[b]+1);
			arr[b]=a;
			all--;
		}
	}
	public bool Same(int a,int b){return Root(a)==Root(b);}
	public int Total(int a){return -arr[Root(a)];}
	public int Root(int a){return arr[a]<0?a:arr[a]=Root(arr[a]);}
}

public class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
}