/*
    題意:給出一些點,有值,給出一些邊,然后求去掉一條邊后將分成連通的兩部分,且兩部分的差值最小
    先將雙連通分量縮點,成為一棵樹,樹邊即橋,然后再遞歸一下就行
    注意,這里的重邊當成兩條路!!!
    如 1-0  1-0  則他們屬雙連通


    與poj 3140類似,不過那道簡單點,給出的是樹,就注意下__int64
    還有,如果stack overflow的話,試試在代碼最前面加
    #pragma comment(linker, "/STACK:102400000,102400000")
    還是有問題的話,那就是代碼問題了
*/

#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<vector>
using namespace std;

const int MAXN=10010;
const int  INF=2000000000;

struct  Node{
    
int v,next;
}
nodes[MAXN*2];

int G[MAXN],low[MAXN],level[MAXN];
int color[MAXN];
int sum[MAXN],A[MAXN];
int ans,N;
int vi[MAXN];
vector
<pair<int,int> >Bridge;//存橋,方便重新建圖
int alloc,n,m,ID;

void add(int a,int b){
    nodes[alloc].v
=b;nodes[alloc].next=G[a];
    G[a]
=alloc++;
}


void dfs(int u,int p,int dep){
    vi[u]
=1;
    level[u]
=low[u]=dep;
    
bool flag=true;//因為可能有重邊v->u,但第一條不算有效的(屬u->v),所以標記一下flag即可,很重要!
    for(int son=G[u];son!=-1;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(v==p&&flag){
            flag
=false;
            
continue;
        }

        
if(vi[v]==1)low[u]=min(low[u],level[v]);
        
else if(vi[v]==0){
            dfs(v,u,dep
+1);
            low[u]
=min(low[u],low[v]);
            
if(low[v]>level[u])
                Bridge.push_back(make_pair(u,v));
        }

        
    }

    vi[u]
=2;
}


void setColor(int u,int p){
    sum[color[u]]
+=A[u];
    
for(int son=G[u];son!=-1;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(color[v])continue;
        
if(low[v]>level[u])color[v]=++ID;
        
else color[v]=color[u];
        setColor(v,u);
    }

}


int  DP(int u,int p){
    A[u]
=sum[u];
    
for(int son=G[u];son!=-1;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(v==p)continue;
        
int tmp=DP(v,u);
        A[u]
+=tmp;
        ans
=min(ans,abs(N-tmp*2));
    }

    
return A[u];
}


int main(){
    
int a,b,t=1;
    
while(~scanf("%d%d",&n,&m)){
        N
=0;
        
for(int i=0;i<n;i++){
            scanf(
"%d",&A[i]);
            N
+=A[i];
        }

        alloc
=0;
        memset(G,
-1,sizeof(int)*n);
        
for(int i=1;i<=m;i++){
            scanf(
"%d%d",&a,&b);
            add(a,b);add(b,a);
        }
        
        Bridge.clear();
        memset(vi,
0,sizeof(int)*n);
        dfs(
0,0,0);

        memset(color,
0,sizeof(int)*n);
        memset(sum
+1,0,sizeof(int)*n);
        color[
0]=ID=1;
        setColor(
0,0);
        
        
//build again
        memset(G+1,-1,sizeof(int)*ID);
        alloc
=0;
        
for(int i=0;i<Bridge.size();i++){
            
int u=Bridge[i].first,v=Bridge[i].second;
            
//是add color[u],不是u
            add(color[u],color[v]);add(color[v],color[u]);
        }

        
if(ID==1)puts("impossible");//只有一個點時就是impossible
        else {
            ans
=INF;
            DP(
1,1);//這里是1開始,前面是0開始
            printf("%d\n",ans);
        }

    }

    
return 0;
}