/**/ /*
    题意:给出一些点,有值,给出一些边,然后求去掉一条边后将分成连通的两部分,且两部分的差值最小
    先将双连通分量缩点,成为一棵树,树边即桥,然后再递归一下就行
    注意,这里的重边当成两条路!!!
    如 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;
}