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: Runtime Error)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
static string[] input = Console.ReadLine().Split(' ');
static int n = int.Parse(input[0]);
static int m = int.Parse(input[1]);
static long[] parents = new long[n];//親

	static void Main()
	{
		long[] nums = Array.ConvertAll(Console.ReadLine().Split(' '),long.Parse);
    long[][] vertexes = new long[n][];//コストと番号
    int lowVertex = 0;
    int nextVertex = 1;
    bool[] usedVertexes = new bool[n];
    long answer = 0;
    
    for(int i = 0; i < n; i++)
    {
      vertexes[i] = new long[2];
      vertexes[i][0] = nums[i];
      vertexes[i][1] = i;
    }
    Array.Sort(vertexes, (a, b) => a[0].CompareTo(b[0]));

    for(long i = 0; i < n; i++)
    {
      parents[i] = i;
    }
    
    for(long i = 0; i < m; i++)
    {
      long[] numsa = Array.ConvertAll(Console.ReadLine().Split(' '),long.Parse);
      if(numsa[0] < numsa[1])
      {
        long swapMemo = numsa[0];
        numsa[0] = numsa[1];
        numsa[1] = swapMemo;
      }
      if(whatParent(numsa[0]) != whatParent(numsa[1]))
      {//辺の頂点の順番はnumsa[0]<numsa[1]に直す。0-indexに注意。
        parents[whatParent(numsa[0])] = whatParent(numsa[1]);//親を結合して統一。親が2人できることはない。
      }
    }

    /*
    for(int i = 0; i < n; i++)
    {
      Console.WriteLine(i+" "+whatParent(i));
    }
    */
    
    while(true)
    {
      if(nextVertex >= n) break;
      
      int aa = (int)vertexes[lowVertex][1];
      int bb = (int)vertexes[nextVertex][1];
      if(aa < bb)
      {
        int swapMemoa = aa;
        aa = bb;
        bb = swapMemoa;
      }
    
      if(whatParent(aa) != whatParent(bb))
      {
        parents[aa] = whatParent(bb);
        usedVertexes[aa] = true;
        usedVertexes[bb] = true;
        answer += vertexes[aa][0] + vertexes[bb][0];

        while(true)
        {
          if(usedVertexes[lowVertex]) lowVertex++;
          else break;
        }
        if(lowVertex == n) break;

        nextVertex++;
        if(nextVertex == lowVertex) nextVertex++;
        if(nextVertex >= n) break;
      }else
      {
        nextVertex++;
        if(nextVertex == n) break;
      }
    }

    for(int i = 1; i < n; i++)
    {
      //Console.WriteLine(i+" "+whatParent(0)+" "+whatParent(i));
      if(whatParent(0) != whatParent(i))
      {
        answer = -1;
      }
    }

		Console.WriteLine((answer == -1)?"Impossible":answer.ToString());
	}

  static long whatParent(long child)
  {
    if(parents[child] == child) return child;
    else return parents[child] = whatParent(parents[child]);
  }
  
}