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.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static int n;
    static int[] val, par, rank, min, num;
    static boolean[] use;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        int m = sc.nextInt();
        val = new int[n];
        par = new int[n];
        rank = new int[n];
        min = new int[n];
        use = new boolean[n];
        num = new int[n];
        long ans = 0;
        int ntree = 0;
        int none = 0;
        int neda = 0;

        for(int i=0; i<n; i++){
            val[i] = sc.nextInt();
            par[i] = i;
            rank[i] = 0;
            min[i] = i;
            use[i] = false;
            num[i] = 1;
        }

        for(int i=0; i<m; i++){
            int mx = sc.nextInt();
            int my = sc.nextInt();
            unite(mx, my);
        }

        for(int i=0; i<n; i++){
            find(i);
        }

        for(int i=0; i<n; i++){
            if(val[i] < val[min[find(i)]]) min[find(i)] = i;
        }

        for(int i=0; i<n; i++){
            if(find(i) == i){
                ans += val[min[i]];
                use[min[i]] = true;
                ntree++;
                if(num[i] == 1){
                    none++;
                }else if(num[i] > 2){
                    neda += num[i] - 2;
                }
            }
        }

        if(none - 2 > neda){
            System.out.println("Impossible");
            return;
        }

        if(ntree == 1){
            System.out.println(0);
            return;
        }

        int[] rem = new int[n - ntree];
        int c = 0;
        for(int i=0; i<n; i++){
            if(!use[i]){
                rem[c] = val[i];
                c++;
            }
        }

        Arrays.sort(rem);

        for(int i=0; i<ntree-2; i++){
            ans += rem[i];
        }

        System.out.println(ans);
    }

    public static int find(int x){
        if(par[x] == x){
            return x;
        }else{
            return par[x] = find(par[x]);
        }
    }

    public static void unite(int x, int y){
        x = find(x);
        y = find(y);
        if(x == y) return;

        if(rank[x] < rank[y]){
            par[x] = y;
            num[find(y)] += num[x];
        }else{
            par[y] = x;
            if(rank[x] == rank[y]) rank[x]++;
            num[find(x)] += num[y];        
        }        
    }

    public static boolean same(int x, int y){
        return find(x) == find(y);
    }
}