//拆点后就是一个最小割问题,直接用最大流来做;
//第一次写,代码效率不高没有任何优化,dinic版代码如下:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int Map[410][410],n;
int pre[410],vis[410];
int dinic(int start,int end)
{
int sum=0;
while(1)
{
queue <int> que;
memset(vis,0,sizeof(vis));
memset(pre,0,sizeof(pre));
que.push(start);
vis[start]=1;
while(!que.empty())
{
int i,u=que.front();
que.pop();
if(u==end)break;
for(i=1;i<=n;i++)
{
if(Map[u][i]>0&&!vis[i])
{
vis[i]=1;
pre[i]=u;
que.push(i);
}
}
}
if(!vis[end])break;
int Min=100000000;
int u=end;
while(1)
{
if(u==start)break;
if(Min>Map[pre[u]][u])
Min=Map[pre[u]][u];
u=pre[u];
}
sum+=Min;
u=end;
while(1)
{
if(u==start)break;
Map[pre[u]][u]-=Min;
Map[u][pre[u]]+=Min;
u=pre[u];
}
}
return sum;
}
int main()
{
int m,start,end,ans,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(Map,0,sizeof(Map));
scanf("%d%d",&start,&end);
end+=n;
int x,y;
for(i=1;i<=n;i++){
scanf("%d",&x);
Map[i][i+n]=x;
}
while(m--){
scanf("%d%d",&x,&y);
Map[x+n][y]=100000000;
Map[y+n][x]=100000000;
}
n+=n;
ans=dinic(start,end);
printf("%d\n",ans);
}
return 0;
}
//优化了一下,sap版代码如下:
#include<stdio.h>
#include<string.h>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
struct edge
{
int from,to,c,next;
}edge[110000];
int ant,head[500],dep[500],gap[500],n;
void add(int a,int b,int c)
{
edge[ant].from=a;
edge[ant].to=b;
edge[ant].c=c;
edge[ant].next=head[a];
head[a]=ant++;
edge[ant].from=b;
edge[ant].to=a;
edge[ant].c=0;
edge[ant].next=head[b];
head[b]=ant++;
}
void BFS(int start,int end)
{
int i,to,u;
memset(dep,-1,sizeof(dep));
memset(gap,0,sizeof(gap));
queue < int > que ;
dep[end]=0;
gap[0]=1;
que.push(end);
while(!que.empty())
{
u=que.front();
que.pop();
for(i=head[u];i!=-1;i=edge[i].next)
{
to=edge[i].to;
if(dep[to]!=-1||edge[i].c!=0)continue;
que.push(to);
dep[to]=dep[u]+1;
++gap[dep[to]];
}
}
}
int s[500],cur[500];
int Sap(int start,int end)
{
int res=0;
BFS(start,end);
int u=start,top=0;
memcpy(cur,head,sizeof(head));
while(dep[start]<n)
{
int i;
if(u==end)
{
int Min=INF,flag;
for(i=0;i<top;i++)
{
if(edge[s[i]].c<Min)
{
Min=edge[s[i]].c;
flag=i;
}
}
res+=Min;
for(i=0;i<top;i++)
{
edge[s[i]].c-=Min;
edge[s[i]^1].c+=Min;
}
top=flag;
u=edge[s[top]].from;
}
if(u!=end&&gap[dep[u]-1]==0)break;
for(i=cur[u];i!=-1;i=edge[i].next)
{
if(edge[i].c>0&&dep[edge[i].to]+1==dep[u])
break;
}
if(i!=-1)
{
cur[u]=i;
s[top++]=i;
u=edge[i].to;
}
else
{
int Min=n;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].c<=0)continue;
if(Min>dep[edge[i].to])
{
cur[u]=i;
Min=dep[edge[i].to];
}
}
--gap[dep[u]];
dep[u]=Min+1;
++gap[dep[u]];
if(u!=start)u=edge[s[--top]].from;
}
}
return res;
}
int main()
{
int m,start,end,ans;
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%d%d",&start,&end);
end+=n;
ant=0;
memset(head,-1,sizeof(head));
int x,y;
for(int i=1;i<=n;i++){
scanf("%d",&x);
add(i,i+n,x);
}
while(m--){
scanf("%d%d",&x,&y);
add(x+n,y,INF);
add(y+n,x,INF);
}
n+=n;
ans=Sap(start,end);
printf("%d\n",ans);
}
return 0;
}