对于同意午睡的,源点到该点权值为1,该点到源点权值为0.
而对于好朋友,则两点建立双向边,权值均为1
对于多对好朋友冲突,我们贪心地取最少的那一边使得总冲突数最少,对于此即为最小割最大流。
const int N=5e5+86;
struct egdes{
int to,nxt,w;
}e[N*2];int hd[N*2],cur[N*2],tot=1,st,en;
vi lv;
void add(int x,int y,int w){
e[++tot]=(egdes){y,hd[x],w};
hd[x]=tot;
}
int bfs(){
lv.assign(N,0);
memcpy(cur,hd,sizeof(hd));
queue<int> q;
q.push(st);
lv[st]=1;
while(!q.empty()){
int p=q.front();
q.pop();
for(int eg=hd[p];eg;eg=e[eg].nxt){
int to=e[eg].to,vol=e[eg].w;
if(vol&&!lv[to]){
lv[to]=lv[p]+1;
q.push(to);
}
}
}
return lv[en];
}
int dfs(int ss,int flow){
if(ss==en)
return flow;
int r=flow;
for(int eg=cur[ss];eg&&r;eg=e[eg].nxt){
cur[ss]=eg;
int to=e[eg].to,vol=e[eg].w;
if(vol&&lv[to]==lv[ss]+1){
int c=dfs(to,min(r,vol));
r-=c;
e[eg].w-=c;
e[eg^1].w+=c;
}
}
return flow-r;
}
int nn,mm;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>nn>>mm;
st=nn+11,en=st+1;
f(i,1,nn){
int x;
cin>>x;
if(x){
add(st,i,1);
add(i,st,0);
add(i,en,0);
add(en,i,0);
}
else {
add(st,i,0);
add(i,st,0);
add(i,en,1);
add(en,i,0);
}
}
f(i,1,mm){
int x,y;
cin>>x>>y;
add(x,y,1);
add(y,x,1);
}
LL ans=0;
while(bfs()){
ans+=dfs(st,3e8);
}
cout<<ans;
return 0;
}