int v, s, t, h[N], hn[2 * N], cur[N];
void push( int );
void relabel( int );
void build( int , int );
typef maxflow( int , int );
};
void network::push( int u) {
edge* te = net[u][cur[u]];
typef ex = minf(te->cap(u), e[u]);
int p = te->other(u);
if (e[p] == 0 && p != t) list.insert(p, h[p]);
te->addflow(u, ex); e[u] -= ex; e[p] += ex;
}
void network::relabel( int u) {
int i, p, mh = 2 * v, oh = h[u];
for (i = net[u].size()-1; i >= 0; i--) {
p = net[u][i]->other(u);
if (net[u][i]->cap(u) != 0 && mh > h[p] + 1)
mh = h[p] + 1;
}
hn[h[u]]--; hn[mh]++; h[u] = mh;
cur[u] = net[u].size()-1;
if (hn[oh] != 0 || oh >= v + 1) return ;
for (i = 0; i < v; i++)
if (h[i] > oh && h[i] <= v && i != s) {
hn[h[i]]--; hn[v+1]++; h[i] = v + 1;
}
}
typef network::maxflow( int ss, int tt) {
s = ss; t = tt;
int i, p, u; typef ec;
for (i = 0; i < v; i++) net[i].clear();
for (i = eg.size()-1; i >= 0; i--) {
net[eg[i].u].push_back(&eg[i]);
net[eg[i].v].push_back(&eg[i]);
}
memset(h, 0, sizeof (h)); memset(hn, 0, sizeof (hn));
memset(e, 0, sizeof (e)); e[s] = inf;
for (i = 0; i < v; i++) h[i] = v;
queue< int > q; q.push(t); h[t] = 0;
while (!q.empty()) {
p = q.front(); q.pop();
for (i = net[p].size()-1; i >= 0; i--) {
u = net[p][i]->other(p);
ec = net[p][i]->cap(u);
if (ec != 0 && h[u] == v && u != s) {
h[u] = h[p] + 1; q.push(u);
}
}
}
for (i = 0; i < v; i++) hn[h[i]]++;
for (i = 0; i < v; i++) cur[i] = net[i].size()-1;
list.clear(v);
for (; cur[s] >= 0; cur[s]--) push(s);
while (!list.empty()) {
for (u = list.remove(); e[u] > 0; ) {
if (cur[u] < 0) relabel(u);
else if (net[u][cur[u]]->cap(u) > 0 &&
h[u] == h[net[u][cur[u]]->other(u)]+1)
push(u);
else cur[u]--;
}
}
return e[t];
}
void network::build( int n, int m) {
v = n; eg.clear();
int a, b, i; typef l;
for (i = 0; i < m; i++) {
cin >> a >> b >> l;
eg.push_back(edge(a, b, l, 0)); // vertex: 0 ~ n-1
}
}