dinic:
const int maxn=55;
const int maxm=4005;
int first[maxn],iter[maxn],lvl[maxn],q[maxm];
int nex[maxm],u[maxm],v[maxm],w[maxm];
int n,m,ecnt;
void dinic_bfs(int s)
{
int f,r,x,e;
clr(lvl,-1);
f=r=0;
q[r++]=s;lvl[s]=0;
while(f<r)
{
x=q[f++];
for(e=first[x];~e;e=nex[e])
if(w[e]&&lvl[v[e]]==-1){
lvl[v[e]]=lvl[x]+1;
q[r++]=v[e];
}
}
}
int dinic_dfs(int s,int t,int maxf)
{
if(s==t)return maxf;
int ret=maxf;
for(int &e=iter[s];~e;e=nex[e])
if(w[e]&&lvl[s]<lvl[v[e]]){
int f=dinic_dfs(v[e],t,min(ret,w[e]));
w[e]-=f;
w[e^1]+=f;
ret-=f;
}
return maxf-ret;
}
int max_flow(int s,int t)
{
int f,sum=0;
while(dinic_bfs(s),lvl[t]!=-1)
{
memcpy(iter,first,sizeof iter);
while(f=dinic_dfs(s,t,INF))
sum+=f;
}
return sum;
}
void add_(int a,int b,int cc)
{
u[ecnt]=a;
v[ecnt]=b;
w[ecnt]=cc;
nex[ecnt]=first[a];
first[a]=ecnt++;
u[ecnt]=b;
v[ecnt]=a;
w[ecnt]=0;
nex[ecnt]=first[b];
first[b]=ecnt++;
}
void min_cut()
{
for(int i=0;i<ecnt;i+=2)
{
if(!w[i])w[i]=1;
else w[i]=INF;
w[i^1]=0;
}
}