#include
using namespace std;
#define N 2010
#define M 200010
#define INF 0x3f3f3f3f
inline int read()
{
int s=0,f=1;
char ch=getchar();
while(ch<'0'||'9'head,to,nxt,val;
int ht[N],ex[N],gap[N];//高度,超额流,gap优化
void join(int u,int v,int w)
{
nxt.push_back(head[u]);
head[u]=to.size();
to.push_back(v);
val.push_back(w);
}
bool bfs()
{
queueq;
for(int i=1;i<=n;++i)
{
ht[i]=INF;
}
while(!q.empty())
{
q.pop();
}
q.push(T),ht[T]=0;//汇点跑源点 反向跑所以是i^1
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=nxt[i])
{
if(val[i^1]&&ht[to[i]]>ht[u]+1)
{
ht[to[i]]=ht[u]+1;
q.push(to[i]);
}
}
}
return ht[S]!=INF;
}
struct cmp
{
bool operator()(int a,int b){return ht[a],cmp>q;
bool vis[N];
bool push(int u)
{
for(int i=head[u];i!=-1;i=nxt[i])
{
if(val[i]&&ht[u]==ht[to[i]]+1)
{
int tmp=min(val[i],ex[u]);
ex[u]-=tmp;
ex[to[i]]+=tmp;
val[i]-=tmp;
val[i^1]+=tmp;
if(to[i]!=S&&to[i]!=T&&!vis[to[i]])
{
vis[to[i]]=1;
q.push(to[i]);
}
if(!ex[u]) return 0;
}
}
return 1;
}
void relabel(int u)
{
ht[u]=INF;
for(int i=head[u];i!=-1;i=nxt[i])
{
if(val[i]) ht[u]=min(ht[u],ht[to[i]]);
}
++ht[u];
}
int hlpp()
{
if(!bfs()) return 0;
ht[S]=n;
memset(gap,0,sizeof(gap));
for(int i=1;i<=n;++i)
{
if(ht[i]!=INF) ++gap[ht[i]];
}
for(int i=head[S];i!=-1;i=nxt[i])
{
if(val[i])
{
int tmp=val[i];
ex[S]-=tmp;
ex[to[i]]+=tmp;
val[i]-=tmp;
val[i^1]+=tmp;
if(to[i]!=S&&to[i]!=T&&!vis[to[i]])
{
vis[to[i]]=1;
q.push(to[i]);
}
}
}
while(!q.empty())
{
int u=q.top();
q.pop();vis[u]=0;
while(push(u))
{
if(!--gap[ht[u]])
{
for(int i=1;i<=n;++i)
{
if(i!=S&&i!=T&&ht[i]>ht[u]&&ht[i]