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 Go (1.6) (judge verdict: Accepted)

package main

import (
  "fmt"
  "sort"
)

type Node struct {
  Cost int
  Index int
}
type Forest []Node
func (f Forest) Len() int {
  return len(f)
}
func (f Forest) Less(i, j int) bool {
  return f[i].Cost < f[j].Cost
}
func (f Forest) Swap(i, j int) {
  f[i], f[j] = f[j], f[i]
}

func find(R *[]int, i int) int {
  if (*R)[i] == i {
    return i
  }
  (*R)[i] = find(R, (*R)[i])
  return (*R)[i]
}

func union(R *[]int, i, j int) {
  ri := find(R, i)
  rj := find(R, j)
  if ri <= rj {
    (*R)[rj] = ri
  } else {
    (*R)[ri] = rj
  }
}

func main() {
  var N, M int
  fmt.Scan(&N, &M)
  A := make([]int, N)
  R := make([]int, N)
  var x, y int
  for i := 0; i < N; i++ {
    fmt.Scan(&x)
    A[i] = x
    R[i] = i
  }
  for i := 0; i < M; i++ {
    fmt.Scan(&x, &y)
    union(&R, x, y)
  }
  for i := 0; i < N; i++ {
    find(&R, i)
  }
  if N < 2 * (N - M - 1) {
    fmt.Println("Impossible")
  } else if M == N - 1 {
    fmt.Println(0)
  } else {
    cnt := 0
    C := make([]int, N)
    var F Forest = make([]Node, N)
    for i := 0; i < N; i++ {
      F[i] = Node{A[i], R[i]}
      C[i] = 0
    }
    sort.Sort(F)
    L := N - M - 2
    for _, node := range F {
      if C[node.Index] == 0 {
        C[node.Index] = node.Cost
        cnt += node.Cost
      } else if L > 0 {
        cnt += node.Cost
        L -= 1
      }
    }
    fmt.Println(cnt)
  }
}