#include <cstring>
#include <vector>
using namespace std;
class Dinic {
static const int MAXN = 1000 , INF = 1e9 ;
private :
struct edge {
int a, b, cap, flow;
} ;
int n, s, t, d[ MAXN] , ptr[ MAXN] , q[ MAXN] ;
vector< edge> e;
vector< int > g[ MAXN] ;
public :
//takes in number of nodes source and sink
Dinic( int a, int b, int c) : n( a) , s( b) , t( c) { }
void add_edge ( int a, int b, int cap) {
edge e1 = { a, b, cap, 0 } ;
edge e2 = { b, a, 0 , 0 } ;
g[ a] .push_back ( ( int ) e.size ( ) ) ;
e.push_back ( e1) ;
g[ b] .push_back ( ( int ) e.size ( ) ) ;
e.push_back ( e2) ;
}
bool bfs( ) {
int qh= 0 , qt= 0 ;
q[ qt++ ] = s;
memset ( d, - 1 , n * sizeof d[ 0 ] ) ;
d[ s] = 0 ;
while ( qh < qt && d[ t] == - 1 ) {
int v = q[ qh++ ] ;
for ( size_t i= 0 ; i< g[ v] .size ( ) ; ++ i) {
int id = g[ v] [ i] ,
to = e[ id] .b ;
if ( d[ to] == - 1 && e[ id] .flow < e[ id] .cap ) {
q[ qt++ ] = to;
d[ to] = d[ v] + 1 ;
}
}
}
return d[ t] ! = - 1 ;
}
int dfs ( int v, int flow) {
if ( ! flow) return 0 ;
if ( v == t) return flow;
for ( ; ptr[ v] < ( int ) g[ v] .size ( ) ; ++ ptr[ v] ) {
int id = g[ v] [ ptr[ v] ] ,
to = e[ id] .b ;
if ( d[ to] ! = d[ v] + 1 ) continue ;
int pushed = dfs ( to, min ( flow, e[ id] .cap - e[ id] .flow ) ) ;
if ( pushed) {
e[ id] .flow + = pushed;
e[ id^ 1 ] .flow - = pushed;
return pushed;
}
}
return 0 ;
}
int dinic( ) {
int flow = 0 ;
for ( ;; ) {
if ( ! bfs( ) ) break ;
memset ( ptr, 0 , n * sizeof ptr[ 0 ] ) ;
while ( int pushed = dfs ( s, INF) )
flow + = pushed;
}
return flow;
}
} ;
I2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CmNsYXNzIERpbmljIHsKICAgIHN0YXRpYyBjb25zdCBpbnQgTUFYTiA9IDEwMDAsIElORiA9IDFlOTsKCXByaXZhdGU6CgkJc3RydWN0IGVkZ2UgewoJCQlpbnQgYSwgYiwgY2FwLCBmbG93OwoJCX07CgkJaW50IG4sIHMsIHQsIGRbTUFYTl0sIHB0cltNQVhOXSwgcVtNQVhOXTsKCQl2ZWN0b3I8ZWRnZT4gZTsKCQl2ZWN0b3I8aW50PiBnW01BWE5dOwoJcHVibGljOgoJCS8vdGFrZXMgaW4gbnVtYmVyIG9mIG5vZGVzIHNvdXJjZSBhbmQgc2luawoJCURpbmljKGludCBhLCBpbnQgYiwgaW50IGMpOiBuKGEpLCBzKGIpLCB0KGMpIHsJfQoJCXZvaWQgYWRkX2VkZ2UgKGludCBhLCBpbnQgYiwgaW50IGNhcCkgewoJCQllZGdlIGUxID0geyBhLCBiLCBjYXAsIDAgfTsKCQkJZWRnZSBlMiA9IHsgYiwgYSwgMCwgMCB9OwoJCQlnW2FdLnB1c2hfYmFjayAoKGludCkgZS5zaXplKCkpOwoJCQllLnB1c2hfYmFjayAoZTEpOwoJCQlnW2JdLnB1c2hfYmFjayAoKGludCkgZS5zaXplKCkpOwoJCQllLnB1c2hfYmFjayAoZTIpOwoJCX0KCQlib29sIGJmcygpIHsKCQkJaW50IHFoPTAsIHF0PTA7CgkJCXFbcXQrK10gPSBzOwoJCQltZW1zZXQgKGQsIC0xLCBuICogc2l6ZW9mIGRbMF0pOwoJCQlkW3NdID0gMDsKCQkJd2hpbGUgKHFoIDwgcXQgJiYgZFt0XSA9PSAtMSkgewoJCQkJaW50IHYgPSBxW3FoKytdOwoJCQkJZm9yIChzaXplX3QgaT0wOyBpPGdbdl0uc2l6ZSgpOyArK2kpIHsKCQkJCQlpbnQgaWQgPSBnW3ZdW2ldLAoJCQkJCQl0byA9IGVbaWRdLmI7CgkJCQkJaWYgKGRbdG9dID09IC0xICYmIGVbaWRdLmZsb3cgPCBlW2lkXS5jYXApIHsKCQkJCQkJcVtxdCsrXSA9IHRvOwoJCQkJCQlkW3RvXSA9IGRbdl0gKyAxOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gZFt0XSAhPSAtMTsKCQl9CgkJaW50IGRmcyAoaW50IHYsIGludCBmbG93KSB7CgkJCWlmICghZmxvdykgIHJldHVybiAwOwoJCQlpZiAodiA9PSB0KSAgcmV0dXJuIGZsb3c7CgkJCWZvciAoOyBwdHJbdl08KGludClnW3ZdLnNpemUoKTsgKytwdHJbdl0pIHsKCQkJCWludCBpZCA9IGdbdl1bcHRyW3ZdXSwKCQkJCQl0byA9IGVbaWRdLmI7CgkJCQlpZiAoZFt0b10gIT0gZFt2XSArIDEpICBjb250aW51ZTsKCQkJCWludCBwdXNoZWQgPSBkZnMgKHRvLCBtaW4gKGZsb3csIGVbaWRdLmNhcCAtIGVbaWRdLmZsb3cpKTsKCQkJCWlmIChwdXNoZWQpIHsKCQkJCQllW2lkXS5mbG93ICs9IHB1c2hlZDsKCQkJCQllW2lkXjFdLmZsb3cgLT0gcHVzaGVkOwoJCQkJCXJldHVybiBwdXNoZWQ7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoJCWludCBkaW5pYygpIHsKCQkJaW50IGZsb3cgPSAwOwoJCQlmb3IgKDs7KSB7CgkJCQlpZiAoIWJmcygpKSAgYnJlYWs7CgkJCQltZW1zZXQgKHB0ciwgMCwgbiAqIHNpemVvZiBwdHJbMF0pOwoJCQkJd2hpbGUgKGludCBwdXNoZWQgPSBkZnMgKHMsIElORikpCgkJCQkJZmxvdyArPSBwdXNoZWQ7CgkJCX0KCQkJcmV0dXJuIGZsb3c7CgkJfQp9Owo=