int tol,head[maxn];
struct edge
{
int to,next,cap,flow;
}es[maxm];
void addedge( int u , int v , int w )
{
es[tol].to = v;
es[tol].cap = w;
es[tol].flow = 0;
es[tol].next = head[u];
head[u] = tol++;
es[tol].to = u;
es[tol].cap = 0;
es[tol].flow = 0;
es[tol].next = head[v];
head[v] = tol++;
}
int gap[maxn],dep[maxn],cur[maxn],Q[maxn],S[maxn];
void bfs( int s , int t )
{
memset ( dep , -1 , sizeof(dep) );
memset ( gap , 0 , sizeof(gap) );
gap[0] = 1;
int front = 0,rear = 0;
dep[t] = 0;
Q[rear++] = t;
while ( front!=rear )
{
int u = Q[front++];
for ( int i=head[u] ; i!=-1 ; i=es[i].next )
{
int v = es[i].to;
if ( dep[v]!=-1 ) continue;
Q[rear++] = v;
dep[v] = dep[u]+1;
gap[dep[v]]++;
}
}
}
int sap( int s , int t , int n )
{
bfs( s , t );
memcpy( cur , head , sizeof(cur) );
int top = 0,u = s,ans = 0;
while ( dep[s]<n )
{
if ( u==t )
{
int minx = inf;
int inser;
for ( int i=0 ; i<top ; i++ )
if ( minx>es[S[i]].cap-es[S[i]].flow )
{
minx = es[S[i]].cap-es[S[i]].flow;
inser = i;
}
for ( int i=0 ; i<top ; i++ )
{
es[S[i]].flow += minx;
es[S[i]^1].flow -= minx;
}
ans += minx;
top = inser;
u = es[S[top]^1].to;
continue;
}
bool flag = false;
int v;
for ( int i=cur[u] ; i!=-1 ; i=es[i].next )
{
v = es[i].to;
if ( es[i].cap-es[i].flow&&dep[v]+1==dep[u] )
{
flag = true;
cur[u] = i;
break;
}
}
if ( flag )
{
S[top++] = cur[u];
u = v;
continue;
}
int Min = n;
for ( int i=head[u] ; i!=-1 ; i=es[i].next )
if ( es[i].cap-es[i].flow&&dep[es[i].to]<Min )
{
Min = dep[es[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if ( !gap[dep[u]] ) return ans;
dep[u] = Min+1;
gap[dep[u]]++;
if ( u!=s ) u = es[S[--top]^1].to;
}
return ans;
}