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 Pascal (FPC 2.6.2) (judge verdict: Runtime Error)

type
  node=record
      num,id:longint;
  end;
var father,num,now,first:array[0..10000]of longint;
    p:array[0..10000]of node;
    heap:array[0..10000,0..2]of longint;
    i:longint;
    x,y:longint;
    n,m:longint;
    totin,totout:longint;
    qwq,ans,have:int64;

function getfather(x:longint):longint;
begin
  if father[x]=x then exit(x) else
  begin
    father[x]:=getfather(father[x]);
    getfather:=father[x];
  end;
end;
procedure adde(x,y:longint);
var fx,fy:longint;
begin
  fx:=getfather(x);
  fy:=getfather(y);
  if fx<>fy then
  begin
    father[fx]:=fy;
    inc(num[fy],num[fx]);
  end;
end;
procedure qs(l,r:longint);
var i,j:longint;
    t,m:node;
begin
  i:=l;
  j:=r;
  m:=p[(l+r)>>1];
  repeat
    while (p[i].id<m.id)or((p[i].id=m.id)and(p[i].num<m.num)) do inc(i);
    while (p[j].id>m.id)or((p[j].id=m.id)and(p[j].num>m.num)) do dec(j);
    if i<=j then
    begin
      t:=p[i];p[i]:=p[j];p[j]:=t;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l<j then qs(l,j);
  if i<r then qs(i,r);
end;
procedure swap(var a,b:longint);
var t:longint;
begin
  t:=a;a:=b;b:=t;
end;
procedure up(x,bool:longint);
begin
  while x>1 do
  begin
    //writeln(heap[x,bool],'qwq');
    if p[now[heap[x,bool]]].num<p[now[heap[x>>1,bool]]].num then
    begin
      swap(heap[x,bool],heap[x>>1,bool]);
      x:=x>>1;
    end else break;
  end;
end;
procedure down(x,bool:longint);
var min,tot:longint;
begin
  if bool=1 then tot:=totin else tot:=totout;
  while x*2<=tot do
  begin
    min:=x*2;
    if (x*2+1<=tot)and
    (p[now[heap[x*2+1,bool]]].num<p[now[heap[min,bool]]].num) then inc(min);
    if (p[now[heap[x,bool]]].num>p[now[heap[min,bool]]].num) then
    begin
      swap(heap[x,bool],heap[min,bool]);
      x:=min;
    end else break;
  end;
end;
begin
  read(n,m);
  for i:=1 to n do
  begin
    read(p[i].num);
    father[i]:=i;
    num[i]:=1;
  end;
  for i:=1 to m do
  begin
    read(x,y);
    inc(x);
    inc(y);
    adde(x,y);
  end;
  for i:=1 to n do
  p[i].id:=getfather(i);
  qs(1,n);
  p[0].num:=maxlongint;
  i:=1;
  while i<=n do
  begin
    inc(ans,p[i].num);
    if num[p[i].id]>1 then
    begin
      now[p[i].id]:=i+1;
      inc(have,num[p[i].id]);
      dec(have);
    end else
    begin
      now[p[i].id]:=0;
      dec(have);
    end;
    inc(totout);
    heap[totout,0]:=p[i].id;
    up(totout,0);
    first[p[i].id]:=i;
    i:=i+num[p[i].id];
  end;
  if totout=1 then
  begin
    writeln(0);
    exit;
  end;
  inc(have);
  if have<0 then
  begin
    writeln('Impossible');
    exit;
  end;
  while totout>0 do
  begin
    inc(qwq);
    x:=heap[1,0];
    //writeln(x);
    if now[x]<>0 then
    begin
      inc(totin);
      heap[totin,1]:=x;
      up(totin,1);
    end else
    if (qwq>1)and(totin>0) then
    begin
      x:=heap[1,1];
      inc(ans,p[now[x]].num);
    end;
    if totin>0 then
    begin
      x:=heap[1,1];
      if qwq>2 then inc(ans,p[now[x]].num);
      inc(now[x]);
      if (now[x]>=first[x]+num[x]) then
      begin
        now[x]:=0;
        heap[1,1]:=heap[totin,1];
        dec(totin);
      end;
      if totin>0 then down(1,1);
    end;
    heap[1,0]:=heap[totout,0];
    dec(totout);
    down(1,0);
  end;
  writeln(ans);
end.