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;

class P
{
    static void Main()
    {
        int[] nm = Console.ReadLine().Split().Select(int.Parse).ToArray();
        long[] a = Console.ReadLine().Split().Select(long.Parse).ToArray();
        MaxUnionFind muf = new MaxUnionFind(nm[0], a);
        for (long i = 0; i < nm[1]; i++)
        {
            long[] xy = Console.ReadLine().Split().Select(long.Parse).ToArray();
            muf.Union(xy[0],xy[1]);
        }
        long[] min = muf.Min;
        long res = 0;
        if (min.Length == 1)
        {
            res = 0;
        }
        else if (a.Length - min.Length < min.Length - 2)
        {
            res = -1;
        }
        else
        {
            long[] q = min.OrderBy(x => x).ToArray();
            long[] p = a.OrderBy(x => x).ToArray();
            long[] r = new long[p.Length - q.Length];

            int index = 0;
            for (int i = 0; i < min.Length - 2; i++)
            {
                while (p[i + index] == q[index]) index++;
                r[i] = p[i + index];
            }
            res = r.Sum() + min.Sum();
        }
        Console.WriteLine(res != -1 ? $"{res}" : "Impossible");
    }
    static void e()
    {
        throw new ArgumentException();
    }
}
class MaxUnionFind
{
    ufData[] data;
    public long[] Min => data.Where((x, y) => x.Parent == y).Select(x => x.Data).ToArray();
    public MaxUnionFind(int count,long[] d)
    {
        data = Enumerable.Range(0, count).Select(x => new ufData(x, d[x])).ToArray();
    }
    public void Union(long x, long y)
    {
        long xp = Parent(x);
        long yp = Parent(y);
        long xd = data[xp].Data;
        long yd = data[yp].Data;
        if (xp != yp)
        {
            data[yp].Parent = xp;
            data[xp].Data = Math.Min(xd,yd);
        }
        data[yp].Parent = xp;
    }
    public bool IsSameGroup(long x, long y) => Parent(x) == Parent(y);
    public long Parent(long x)
    {
        form(x);
        return data[x].Parent;
    }
    public long Data(long x)
    {
        form(x);
        return data[data[x].Parent].Data;
    }
    private void form(long x)
    {
        while (data[data[x].Parent].Parent != data[x].Parent)
        {
            data[x].Parent = data[data[x].Parent].Parent;
        }
    }
    struct ufData
    {
        public long Parent { get; set; }
        public long Data { get; set; }
        public ufData(long parents, long data)
        {
            Parent = parents;
            Data = data;
        }
    }
}