int cnt;
int h[maxn];
int prep[maxn];
int pree[maxm];
int dis[maxn];
int st = maxn - 2;
int ed = maxn - 1;
struct Edge
{
int v, nxt;
int w, f;
}e[maxm];
int head[maxn];
inline void init()
{
memset(head, -1, sizeof(head));
cnt = 1;
}
inline void add(int u, int v, int w, int f)
{
e[++cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt;
e[cnt].f = f;
e[cnt].w = w;
e[++cnt].v = u;
e[cnt].nxt = head[v];
head[v] = cnt;
e[cnt].f = -f;
e[cnt].w = 0;
}
inline pair<int, int> dijstra()
{
int maxf = 0;
int minc = 0;
while (1)
{
priority_queue<pair<int, int>>heap;
memset(dis, 0x3f, sizeof(dis));
dis[st] = 0;
heap.push(make_pair(0, st));
while (!heap.empty())
{
pair<int, int> x = heap.top();
heap.pop();
if (-x.first != dis[x.second]) continue;
if (x.second == ed) break;
for (int i = head[x.second]; i != -1; i = e[i].nxt)
{
int now = e[i].f + h[x.second] - h[e[i].v];
if (e[i].w > 0 && dis[e[i].v] > dis[x.second] + now)
{
dis[e[i].v] = dis[x.second] + now;
heap.push(make_pair(-dis[e[i].v], e[i].v));
prep[e[i].v] = x.second;
pree[e[i].v] = i;
}
}
}
if (dis[ed] >= 0x3f3f3f3f) break;
for (int i = 0; i <= n; i++) h[i] += dis[i];
int now = 0x3f3f3f3f;
for (int i = ed; i != st; i = prep[i])
now = min(now, e[pree[i]].w);
for (int i = ed; i != st; i = prep[i])
{
e[pree[i]].w -= now;
e[pree[i] ^ 1].w += now;
}
maxf += now;
minc += now * h[ed];
}
return make_pair(maxf, minc);
}