const int Maxn = 1e4;
const int Maxm = 1e5;
const int Maxq = 1e7;
const LL Limit = 1e14;
const LL Inf = 0x3f3f3f3f3f3f3f;
struct Date {
int x, y; LL flux, val;
Date () {}
Date (int _x, int _y, LL _flux, LL _val) {
x = _x; y = _y; flux = _flux; val = _val;
}
};
struct edge {
int to[Maxm * 2 + 5], Next[Maxm * 2 + 5]; LL flux[Maxm * 2 + 5], val[Maxm * 2 + 5];
int len, Head[Maxn + 5];
edge () { len = 1; memset (Head, 0, sizeof Head); }
void Init () { len = 1; memset (Head, 0, sizeof Head); }
void plus (int x, int y, LL _flux, LL _val) {
to[++len] = y;
flux[len] = _flux;
val[len] = _val;
Next[len] = Head[x];
Head[x] = len;
}
void add (int x, int y, LL _flux, LL _val) {
plus (x, y, _flux, _val);
plus (y, x, 0, -_val);
}
void rev_add (int x, int y, LL _flux, LL _val) {
plus (x, y, 0, _val);
plus (y, x, _flux, -_val);
}
};
struct Max_Flow {
edge mp;
Date e[Maxm + 5];
int n, m, s, t;
void add (int x, int y, LL _flux, LL _val) {
e[++m] = Date (x, y, _flux, _val);
}
bool vis[Maxn + 5];
int hh, tt, q[Maxq + 5];
LL dist[Maxn + 5]; int fa[Maxn + 5];
void Init () {
mp.Init ();
hh = 1; tt = 0;
n = m = s = t = 0;
memset (vis, 0, sizeof vis);
memset (dist, 0x3f, sizeof dist);
}
bool Spfa () {
memset (vis, 0, sizeof vis);
memset (dist, 0x3f, sizeof dist);
hh = 1; tt = 0; q[++tt] = s; dist[s] = 0;
while (hh <= tt) {
int u = q[hh++];
vis[u] = 0;
for (int i = mp.Head[u]; i; i = mp.Next[i]) {
int v = mp.to[i]; LL flux = mp.flux[i], w = mp.val[i];
if (flux == 0) continue;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
fa[v] = i;
if (!vis[v]) {
q[++tt] = v;
vis[v] = 1;
}
}
}
}
return dist[t] <= Limit;
}
LL Update () {
int p = t; LL cost = 0, flow = Inf;
while (p != s) {
cost += mp.val[fa[p]];
flow = Min (flow, mp.flux[fa[p]]);
p = mp.to[fa[p] ^ 1];
}
p = t;
while (p != s) {
mp.flux[fa[p]] -= flow;
mp.flux[fa[p] ^ 1] += flow;
p = mp.to[fa[p] ^ 1];
}
return cost * flow;
}
void Build_Positive () {
mp.Init ();
rep (i, 1, m)
mp.add (e[i].x, e[i].y, e[i].flux, e[i].val);
}
LL Cost_Positive () {
Build_Positive ();
LL res = 0;
while (Spfa ()) {
res += Update ();
}
return res;
}
int depth[Maxn + 5], cur[Maxn + 5];
bool BFS () {
memset (depth, 0, sizeof depth);
hh = 1; tt = 0; q[++tt] = s;
depth[s] = 1; cur[s] = mp.Head[s];
while (hh <= tt) {
int u = q[hh++];
for (int i = mp.Head[u]; i; i = mp.Next[i]) {
int v = mp.to[i]; LL flux = mp.flux[i];
if (flux == 0) continue;
if (depth[v]) continue;
depth[v] = depth[u] + 1;
cur[v] = mp.Head[v];
q[++tt] = v;
if (v == t) return 1;
}
}
return 0;
}
LL DFS (int u, LL Up) {
if (u == t) return Up;
if (Up == 0) return 0;
LL flow = 0;
while (cur[u] && flow < Up) {
int i = cur[u]; cur[u] = mp.Next[cur[u]];
int v = mp.to[i]; LL flux = mp.flux[i];
if (flux == 0) continue;
if (depth[v] != depth[u] + 1) continue;
LL tmp = DFS (v, Min (Up - flow, flux));
if (tmp == 0) depth[v] = -1;
flow += tmp; mp.flux[i] -= tmp; mp.flux[i ^ 1] += tmp;
if (mp.flux[i] && flow >= Up) cur[u] = i;
}
return flow;
}
LL Dinic () {
Build_Positive ();
LL flow = 0;
while (BFS ()) {
flow += DFS (s, Inf);
}
return flow;
}
LL h[Maxn + 5];
void Spfa_For_Dijkstra () {
memset (vis, 0, sizeof vis);
memset (dist, 0x3f, sizeof dist);
hh = 1; tt = 0; q[++tt] = s; dist[s] = 0;
while (hh <= tt) {
int u = q[hh++];
vis[u] = 0;
for (int i = mp.Head[u]; i; i = mp.Next[i]) {
int v = mp.to[i]; LL flux = mp.flux[i], w = mp.val[i];
if (flux == 0) continue;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
fa[v] = i;
if (!vis[v]) {
q[++tt] = v;
vis[v] = 1;
}
}
}
}
rep (i, 1, n)
if (h[i] + dist[i] < Limit)
h[i] += dist[i];
}
bool Dijkstra () {
memset (vis, 0, sizeof vis);
memset (dist, 0x3f, sizeof dist);
priority_queue <PII, vector <PII>, greater <PII> > p;
p.push (MP (0, s)); dist[s] = 0;
while (p.size ()) {
PII tmp = p.top (); p.pop ();
int u = tmp.se;
if (vis[u]) continue; vis[u] = 1;
for (int i = mp.Head[u]; i; i = mp.Next[i]) {
int v = mp.to[i]; LL flux = mp.flux[i], w = mp.val[i] + h[u] - h[v];
if (flux == 0) continue;
if (vis[v]) continue;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
fa[v] = i;
p.push (MP (dist[v], v));
}
}
}
rep (i, 1, n)
if (h[i] + dist[i] < Limit)
h[i] += dist[i];
return dist[t] <= Limit;
}
LL Cost_Positive_Dijkstra () {
Build_Positive ();
Spfa_For_Dijkstra ();
LL res = 0;
while (Dijkstra ()) {
res += Update ();
}
return res;
}
int S, T;
LL d[Maxn + 5];
LL Build_Negative () {
mp.Init (); S = s; T = t; s = Maxn - 2; t = Maxn - 1;
LL res = 0;
rep (i, 1, m) {
if (e[i].val < 0) {
mp.rev_add (e[i].x, e[i].y, e[i].flux, e[i].val);
res += e[i].flux * e[i].val;
d[e[i].y] += e[i].flux;
d[e[i].x] -= e[i].flux;
}
else mp.add (e[i].x, e[i].y, e[i].flux, e[i].val);
}
rep (i, 1, n)
if (d[i] > 0) mp.add (s, i, d[i], 0);
else if (d[i] < 0) mp.add (i, t, -d[i], 0);
while (Spfa ()) {
res += Update ();
}
return res;
}
LL Cost_Negative () {
LL flow = Build_Negative ();
s = S; t = T;
while (Spfa ()) {
flow += Update ();
}
return flow;
}
}G;