struct edge {
int to, cap, rev;
edge ( int to, int cap, int rev) : to ( to) , cap ( cap) , rev ( rev) { }
} ;
vector< edge> G[ MAX_V] ;
int level[ MAX_V] ;
int iter[ MAX_V] ;
void add_edge ( int from, int to, int cap) {
G[ from] . push_back ( edge ( to, cap, G[ to] . size ( ) ) ) ;
G[ to] . push_back ( edge ( from, 0 , G[ from] . size ( ) - 1 ) ) ;
}
void bfs ( int s) {
memset ( level, - 1 , sizeof ( level) ) ;
level[ s] = 0 ;
queue< int > Q;
Q. push ( s) ;
while ( ! Q. empty ( ) ) {
int v = Q. front ( ) ;
Q. pop ( ) ;
for ( int i = 0 ; i < G[ v] . size ( ) ; i++ ) {
edge & e = G[ v] [ i] ;
if ( e. cap > 0 && level[ e. to] < 0 ) {
level[ e. to] = level[ v] + 1 ;
Q. push ( e. to) ;
}
}
}
}
int dfs ( int v, int t, int f) {
if ( v == t) return f;
for ( int & i = iter[ v] ; i < G[ v] . size ( ) ; i++ ) {
edge & e = G[ v] [ i] ;
if ( e. cap > 0 && level[ v] < level[ e. to] ) {
int d = dfs ( e. to, t, min ( f, e. cap) ) ;
if ( d > 0 ) {
e. cap - = d;
G[ e. to] [ e. rev] . cap + = d;
return d;
}
}
}
return 0 ;
}
int maxFlow ( int s, int t) {
int flow = 0 , f;
for ( ; ; ) {
bfs ( s) ;
if ( level[ t] < 0 ) return flow;
memset ( iter, 0 , sizeof ( iter) ) ;
while ( ( f = dfs ( s, t, INF) ) > 0 ) {
flow + = f;
}
}
}
struct edge {
int to, cap, rev;
edge ( int to, int cap, int rev) : to ( to) , cap ( cap) , rev ( rev) { }
} ;
vector< edge> G[ MAX_V] ;
bool used[ MAX_V] ;
void add_edge ( int from, int to, int cap) {
G[ from] . push_back ( edge ( to, cap, G[ to] . size ( ) ) ) ;
G[ to] . push_back ( edge ( from, 0 , G[ from] . size ( ) - 1 ) ) ;
}
int dfs ( int v, int t, int f) {
if ( v == t) return f;
used[ v] = true ;
for ( int i = 0 ; i < G[ v] . size ( ) ; i++ ) {
edge & e = G[ v] [ i] ;
if ( ! used[ e. to] && e. cap > 0 ) {
int d = dfs ( e. to, t, min ( f, e. cap) ) ;
if ( d > 0 ) {
e. cap - = d;
G[ e. to] [ e. rev] . cap + = d;
return d;
}
}
}
return 0 ;
}
int max_flow ( int s, int t) {
int flow = 0 ;
for ( ; ; ) {
memset ( used, 0 , sizeof ( used) ) ;
int f = dfs ( s, t, INF) ;
if ( f == 0 ) return flow;
flow + = f;
}
}
const int INF = 0x3f3f3f3f ;
const int N = 210000 ;
struct node {
int to, cap, next;
} p[ N * 10 ] ;
int dis[ N] ;
int head[ N] ;
int cnt;
void add ( int from, int to, int cap) {
p[ cnt] . to = to;
p[ cnt] . cap = cap;
p[ cnt] . next = head[ from] ;
head[ from] = cnt++ ;
}
bool bfs ( int s, int t) {
queue< int > q;
memset ( dis, - 1 , sizeof ( dis) ) ;
dis[ s] = 0 ;
q. push ( s) ;
while ( ! q. empty ( ) ) {
int x = q. front ( ) ;
q. pop ( ) ;
for ( int i = head[ x] ; i != - 1 ; i = p[ i] . next) {
int now = p[ i] . to;
if ( dis[ now] == - 1 && p[ i] . cap != 0 ) {
dis[ now] = dis[ x] + 1 ;
q. push ( now) ;
}
}
}
return dis[ t] != - 1 ;
}
int dfs ( int x, int t, int f) {
if ( x == t) return f;
int sum = 0 ;
for ( int i = head[ x] ; i != - 1 ; i = p[ i] . next) {
int now = p[ i] . to;
if ( dis[ now] != dis[ x] + 1 || p[ i] . cap == 0 || sum >= f) continue ;
int d = dfs ( now, t, min ( p[ i] . cap, f - sum) ) ;
p[ i] . cap - = d;
p[ i ^ 1 ] . cap + = d;
sum + = d;
}
return sum;
}
int Dinic ( int s, int t) {
int flow = 0 ;
while ( bfs ( s, t) ) {
flow + = dfs ( s, t, 1 ) ;
}
return flow;
}