// #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <cmath>
#include <climits>
#include <vector>
#include <queue>
#include <deque>
#include <array>
#include <list>
#include <stack>
#include <tuple>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <string>
#include <cstring>
#include <random>
#include <bitset>
#include <iomanip>
#include <iterator>
#include <functional>
#include <ctime>
#include <chrono>
#include <cctype>
#include <fstream>
#include <numeric>
#include <complex>
#include <cassert>
using namespace std;
// #pragma GCC optimize("Ofast")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define int long long
#define sz(x) ((int)(x).size())
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define pf push_front
#define ff first
#define ss second
#define unique(x) (x).erase(unique(all(x)), (x).end())
#define min3(a, b, c) min(a, min(b, c))
#define max3(a, b, c) max(a, max(b, c))
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define ROF(i, a, b) for (int i = (a); i >= (b); i--)
using vi = vector<int>;
using vd = vector<double>;
using vpii = vector<pair<int, int>>;
using vpdd = vector<pair<double, double>>;
using pii = pair<int, int>;
using pdd = pair<double, double>;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;
#define BIT(n) (1LL << (n))
#define HAS_BIT(x, n) (((x) >> (n)) & 1)
#define SET_BIT(x, n) ((x) | BIT(n))
template <typename Container>
void PRINT(const Container& container) {
for (const auto& e : container) {
cout << e << ' ';
} cout << '\n';
}
void print_double(double ans, int num) {
cout << fixed << setprecision(num) << ans << '\n';
}
const int inf = 1e18;
const double eps = 1e-9;
const double PI = 3.141592653589793;
string alh = "abcdefghijklmnopqrstuvwxyz";
string ALH = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
class TP {
private:
vector<vector<int>> c;
vector<int> s;
vector<int> d;
int m, n;
vector<pair<int, int>> findCyc(vector<vector<int>>& sol, int si, int sj) {
int tot = m + n;
vector<int> par(tot, -1);
vector<bool> vis(tot, false);
queue<int> q;
vis[si] = true;
q.push(si);
int tar = sj + m;
while (!q.empty()) {
int node = q.front();
q.pop();
if (node < m) {
int i = node;
for (int j = 0; j < n; j++) {
if (sol[i][j] > 0) {
int cn = j + m;
if (!vis[cn]) {
vis[cn] = true;
par[cn] = node;
q.push(cn);
if (cn == tar) {
vector<int> path;
int cur = cn;
while (cur != -1) {
path.push_back(cur);
cur = par[cur];
}
reverse(path.begin(), path.end());
vector<pair<int, int>> cyc;
cyc.push_back({ si, sj });
for (int idx = 0; idx < path.size() - 1; idx++) {
int n1 = path[idx];
int n2 = path[idx + 1];
if (n1 < m && n2 >= m) {
cyc.push_back({ n1, n2 - m });
}
else if (n1 >= m && n2 < m) {
cyc.push_back({ n2, n1 - m });
}
}
return cyc;
}
}
}
}
}
else {
int j = node - m;
for (int i = 0; i < m; i++) {
if (sol[i][j] > 0) {
int rn = i;
if (!vis[rn]) {
vis[rn] = true;
par[rn] = node;
q.push(rn);
}
}
}
}
}
return {};
}
void redist(vector<vector<int>>& sol, vector<pair<int, int>>& cyc) {
if (cyc.size() < 4) return;
int theta = INT_MAX;
for (int i = 1; i < cyc.size(); i += 2) {
int x = cyc[i].first, y = cyc[i].second;
if (sol[x][y] < theta) {
theta = sol[x][y];
}
}
for (int i = 0; i < cyc.size(); i++) {
int x = cyc[i].first, y = cyc[i].second;
if (i % 2 == 0) {
sol[x][y] += theta;
}
else {
sol[x][y] -= theta;
}
}
}
public:
TP(vector<vector<int>> c, vector<int> s, vector<int> d)
: c(c), s(s), d(d) {
m = s.size();
n = d.size();
}
vector<vector<int>> NW() {
vector<vector<int>> sol(m, vector<int>(n, 0));
vector<int> sup = s, dem = d;
int i = 0, j = 0;
while (i < m && j < n) {
int amt = min(sup[i], dem[j]);
sol[i][j] = amt;
sup[i] -= amt;
dem[j] -= amt;
if (sup[i] == 0) i++;
if (dem[j] == 0) j++;
}
return sol;
}
vector<vector<int>> solve() {
auto sol = NW();
int iter = 0;
const int MAX_ITER = 100;
while (iter++ < MAX_ITER) {
vector<int> u(m, INT_MAX), v(n, INT_MAX);
u[0] = 0;
bool ch;
do {
ch = false;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (sol[i][j] > 0) {
if (u[i] != INT_MAX && v[j] == INT_MAX) {
v[j] = c[i][j] - u[i];
ch = true;
}
else if (v[j] != INT_MAX && u[i] == INT_MAX) {
u[i] = c[i][j] - v[j];
ch = true;
}
}
}
}
} while (ch);
int minD = 0;
int bestI = -1, bestJ = -1;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (sol[i][j] == 0) {
if (u[i] == INT_MAX || v[j] == INT_MAX) continue;
int delta = c[i][j] - (u[i] + v[j]);
if (delta < minD) {
minD = delta;
bestI = i;
bestJ = j;
}
}
}
}
if (minD >= 0) break;
auto cyc = findCyc(sol, bestI, bestJ);
if (cyc.empty()) {
cout << "Cycle not found for cell (" << bestI << "," << bestJ << ")" << endl;
break;
}
redist(sol, cyc);
}
return sol;
}
int calcCost(const vector<vector<int>>& sol) {
int tot = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
tot += sol[i][j] * c[i][j];
}
}
return tot;
}
void printSol(const vector<vector<int>>& sol) {
cout << " ";
for (int j = 0; j < n; j++) cout << setw(3) << "B" << j + 1;
cout << setw(6) << "Sup" << endl;
for (int i = 0; i < m; i++) {
cout << "A" << i + 1 << " ";
int rs = 0;
for (int j = 0; j < n; j++) {
cout << setw(4) << sol[i][j];
rs += sol[i][j];
}
cout << setw(6) << rs << endl;
}
cout << "Dem ";
for (int j = 0; j < n; j++) {
int cs = 0;
for (int i = 0; i < m; i++) {
cs += sol[i][j];
}
cout << setw(4) << cs;
}
cout << endl;
}
};
void Solve() {
vector<int> s = { 120, 90, 150 };
vector<int> d = { 50, 60, 40, 70, 30, 20, 90 };
vector<vector<int>> c = {
{4, 7, 2, 5, 8, 3, 6},
{9, 1, 6, 4, 2, 7, 5},
{3, 8, 5, 9, 1, 4, 2}
};
TP tp(c, s, d);
auto nw = tp.NW();
int nwCost = tp.calcCost(nw);
cout << "North-West corner cost: " << nwCost << endl;
auto opt = tp.solve();
int optCost = tp.calcCost(opt);
cout << "Optimal solution cost: " << optCost << endl;
tp.printSol(opt);
bool ok = true;
for (int i = 0; i < s.size(); i++) {
int rs = 0;
for (int j = 0; j < d.size(); j++) {
rs += opt[i][j];
}
if (rs != s[i]) {
cout << "R " << i << " error: " << rs << " != " << s[i] << endl;
ok = false;
}
}
for (int j = 0; j < d.size(); j++) {
int cs = 0;
for (int i = 0; i < s.size(); i++) {
cs += opt[i][j];
}
if (cs != d[j]) {
cout << "C " << j << " error: " << cs << " != " << d[j] << endl;
ok = false;
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
/*
________________
/ Just solved it \
| in my mind |
\________________/
/
/
/> フ ___________
| _ _| | |
/`ミ _x 彡 | WA 2 |
/ | |__________|
/ ヽ ノ / /
/ ̄| | | | /_________ /
| ( ̄ヽ__ヽ_)_)
\二つ
*/
/*
freopen("task.in", "r", stdin);
freopen("task.out", "w", stdout);
*/
// auto start = chrono::high_resolution_clock::now();
int multitest = false;
if (multitest == true) {
int ctt; cin >> ctt;
for (int i = 0; i < ctt; i++) {
Solve();
}
}
else {
Solve();
}
// auto end = chrono::high_resolution_clock::now();
/*
cout << "Time taken: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count()
<< " milliseconds" << endl;
*/
return 0;
}
Ly8gI2RlZmluZSBfQ1JUX1NFQ1VSRV9OT19XQVJOSU5HUyAKCiNpbmNsdWRlIDxpb3N0cmVhbT4gCiNpbmNsdWRlIDxhbGdvcml0aG0+IAojaW5jbHVkZSA8Y21hdGg+IAojaW5jbHVkZSA8Y2xpbWl0cz4gCiNpbmNsdWRlIDx2ZWN0b3I+IAojaW5jbHVkZSA8cXVldWU+IAojaW5jbHVkZSA8ZGVxdWU+IAojaW5jbHVkZSA8YXJyYXk+IAojaW5jbHVkZSA8bGlzdD4gCiNpbmNsdWRlIDxzdGFjaz4gCiNpbmNsdWRlIDx0dXBsZT4gCiNpbmNsdWRlIDxzZXQ+IAojaW5jbHVkZSA8dW5vcmRlcmVkX3NldD4gCiNpbmNsdWRlIDxtYXA+IAojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4gCiNpbmNsdWRlIDxzdHJpbmc+IAojaW5jbHVkZSA8Y3N0cmluZz4gCiNpbmNsdWRlIDxyYW5kb20+IAojaW5jbHVkZSA8Yml0c2V0PiAKI2luY2x1ZGUgPGlvbWFuaXA+IAojaW5jbHVkZSA8aXRlcmF0b3I+IAojaW5jbHVkZSA8ZnVuY3Rpb25hbD4gCiNpbmNsdWRlIDxjdGltZT4gCiNpbmNsdWRlIDxjaHJvbm8+IAojaW5jbHVkZSA8Y2N0eXBlPiAKI2luY2x1ZGUgPGZzdHJlYW0+IAojaW5jbHVkZSA8bnVtZXJpYz4gCiNpbmNsdWRlIDxjb21wbGV4PiAKI2luY2x1ZGUgPGNhc3NlcnQ+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vICNwcmFnbWEgR0NDIG9wdGltaXplKCJPZmFzdCIpCi8vICNwcmFnbWEgR0NDIHRhcmdldCgiYXZ4MixibWksYm1pMixsemNudCxwb3BjbnQiKQoKI2RlZmluZSBpbnQgICAgICAgICAgICAgICBsb25nIGxvbmcgCiNkZWZpbmUgc3ooeCkgICAgICAgICAgICAgKChpbnQpKHgpLnNpemUoKSkgCiNkZWZpbmUgbXAgICAgICAgICAgICAgICAgbWFrZV9wYWlyIAojZGVmaW5lIGFsbCh4KSAgICAgICAgICAgICh4KS5iZWdpbigpLCAoeCkuZW5kKCkgCiNkZWZpbmUgcGIgICAgICAgICAgICAgICAgcHVzaF9iYWNrIAojZGVmaW5lIHBmICAgICAgICAgICAgICAgIHB1c2hfZnJvbnQgCiNkZWZpbmUgZmYgICAgICAgICAgICAgICAgZmlyc3QgCiNkZWZpbmUgc3MgICAgICAgICAgICAgICAgc2Vjb25kIAojZGVmaW5lIHVuaXF1ZSh4KSAgICAgICAgICh4KS5lcmFzZSh1bmlxdWUoYWxsKHgpKSwgKHgpLmVuZCgpKSAKI2RlZmluZSBtaW4zKGEsIGIsIGMpICAgICBtaW4oYSwgbWluKGIsIGMpKSAKI2RlZmluZSBtYXgzKGEsIGIsIGMpICAgICBtYXgoYSwgbWF4KGIsIGMpKSAKI2RlZmluZSBGT1IoaSwgYSwgYikgICAgICBmb3IgKGludCBpID0gKGEpOyBpIDw9IChiKTsgaSsrKSAKI2RlZmluZSBST0YoaSwgYSwgYikgICAgICBmb3IgKGludCBpID0gKGEpOyBpID49IChiKTsgaS0tKSAKCnVzaW5nIHZpID0gdmVjdG9yPGludD47CnVzaW5nIHZkID0gdmVjdG9yPGRvdWJsZT47CnVzaW5nIHZwaWkgPSB2ZWN0b3I8cGFpcjxpbnQsIGludD4+Owp1c2luZyB2cGRkID0gdmVjdG9yPHBhaXI8ZG91YmxlLCBkb3VibGU+PjsKdXNpbmcgcGlpID0gcGFpcjxpbnQsIGludD47CnVzaW5nIHBkZCA9IHBhaXI8ZG91YmxlLCBkb3VibGU+OwoKLy8gI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPgovLyAjaW5jbHVkZSA8ZXh0L3BiX2RzL3RyZWVfcG9saWN5LmhwcD4KLy8gdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7Ci8vIHR5cGVkZWYgdHJlZTxpbnQsIG51bGxfdHlwZSwgbGVzczxpbnQ+LCByYl90cmVlX3RhZywgdHJlZV9vcmRlcl9zdGF0aXN0aWNzX25vZGVfdXBkYXRlPiBvcmRlcmVkX3NldDsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHVzaW5nIG1pbl9oZWFwID0gcHJpb3JpdHlfcXVldWU8VCwgdmVjdG9yPFQ+LCBncmVhdGVyPFQ+PjsKdGVtcGxhdGU8dHlwZW5hbWUgVD4gdXNpbmcgbWF4X2hlYXAgPSBwcmlvcml0eV9xdWV1ZTxUPjsKCiNkZWZpbmUgQklUKG4pICgxTEwgPDwgKG4pKQojZGVmaW5lIEhBU19CSVQoeCwgbikgKCgoeCkgPj4gKG4pKSAmIDEpCiNkZWZpbmUgU0VUX0JJVCh4LCBuKSAoKHgpIHwgQklUKG4pKQoKdGVtcGxhdGUgPHR5cGVuYW1lIENvbnRhaW5lcj4Kdm9pZCBQUklOVChjb25zdCBDb250YWluZXImIGNvbnRhaW5lcikgewogICAgZm9yIChjb25zdCBhdXRvJiBlIDogY29udGFpbmVyKSB7CiAgICAgICAgY291dCA8PCBlIDw8ICcgJzsKICAgIH0gY291dCA8PCAnXG4nOwp9Cgp2b2lkIHByaW50X2RvdWJsZShkb3VibGUgYW5zLCBpbnQgbnVtKSB7CiAgICBjb3V0IDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbihudW0pIDw8IGFucyA8PCAnXG4nOwp9Cgpjb25zdCBpbnQgaW5mID0gMWUxODsKY29uc3QgZG91YmxlIGVwcyA9IDFlLTk7CmNvbnN0IGRvdWJsZSBQSSA9IDMuMTQxNTkyNjUzNTg5NzkzOwoKc3RyaW5nIGFsaCA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CnN0cmluZyBBTEggPSAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiOwoKY2xhc3MgVFAgewpwcml2YXRlOgogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBjOwogICAgdmVjdG9yPGludD4gczsKICAgIHZlY3RvcjxpbnQ+IGQ7CiAgICBpbnQgbSwgbjsKCiAgICB2ZWN0b3I8cGFpcjxpbnQsIGludD4+IGZpbmRDeWModmVjdG9yPHZlY3RvcjxpbnQ+PiYgc29sLCBpbnQgc2ksIGludCBzaikgewogICAgICAgIGludCB0b3QgPSBtICsgbjsKICAgICAgICB2ZWN0b3I8aW50PiBwYXIodG90LCAtMSk7CiAgICAgICAgdmVjdG9yPGJvb2w+IHZpcyh0b3QsIGZhbHNlKTsKICAgICAgICBxdWV1ZTxpbnQ+IHE7CgogICAgICAgIHZpc1tzaV0gPSB0cnVlOwogICAgICAgIHEucHVzaChzaSk7CiAgICAgICAgaW50IHRhciA9IHNqICsgbTsKCiAgICAgICAgd2hpbGUgKCFxLmVtcHR5KCkpIHsKICAgICAgICAgICAgaW50IG5vZGUgPSBxLmZyb250KCk7CiAgICAgICAgICAgIHEucG9wKCk7CgogICAgICAgICAgICBpZiAobm9kZSA8IG0pIHsKICAgICAgICAgICAgICAgIGludCBpID0gbm9kZTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNvbFtpXVtqXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNuID0gaiArIG07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlzW2NuXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzW2NuXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJbY25dID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHEucHVzaChjbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY24gPT0gdGFyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4gcGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY3VyID0gY247CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGN1ciAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoLnB1c2hfYmFjayhjdXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgPSBwYXJbY3VyXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZShwYXRoLmJlZ2luKCksIHBhdGguZW5kKCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8cGFpcjxpbnQsIGludD4+IGN5YzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWMucHVzaF9iYWNrKHsgc2ksIHNqIH0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpZHggPSAwOyBpZHggPCBwYXRoLnNpemUoKSAtIDE7IGlkeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuMSA9IHBhdGhbaWR4XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG4yID0gcGF0aFtpZHggKyAxXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4xIDwgbSAmJiBuMiA+PSBtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWMucHVzaF9iYWNrKHsgbjEsIG4yIC0gbSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChuMSA+PSBtICYmIG4yIDwgbSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljLnB1c2hfYmFjayh7IG4yLCBuMSAtIG0gfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN5YzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGludCBqID0gbm9kZSAtIG07CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG07IGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChzb2xbaV1bal0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBybiA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmlzW3JuXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzW3JuXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJbcm5dID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHEucHVzaChybik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHt9OwogICAgfQoKICAgIHZvaWQgcmVkaXN0KHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIHNvbCwgdmVjdG9yPHBhaXI8aW50LCBpbnQ+PiYgY3ljKSB7CiAgICAgICAgaWYgKGN5Yy5zaXplKCkgPCA0KSByZXR1cm47CgogICAgICAgIGludCB0aGV0YSA9IElOVF9NQVg7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBjeWMuc2l6ZSgpOyBpICs9IDIpIHsKICAgICAgICAgICAgaW50IHggPSBjeWNbaV0uZmlyc3QsIHkgPSBjeWNbaV0uc2Vjb25kOwogICAgICAgICAgICBpZiAoc29sW3hdW3ldIDwgdGhldGEpIHsKICAgICAgICAgICAgICAgIHRoZXRhID0gc29sW3hdW3ldOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGN5Yy5zaXplKCk7IGkrKykgewogICAgICAgICAgICBpbnQgeCA9IGN5Y1tpXS5maXJzdCwgeSA9IGN5Y1tpXS5zZWNvbmQ7CiAgICAgICAgICAgIGlmIChpICUgMiA9PSAwKSB7CiAgICAgICAgICAgICAgICBzb2xbeF1beV0gKz0gdGhldGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBzb2xbeF1beV0gLT0gdGhldGE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgpwdWJsaWM6CiAgICBUUCh2ZWN0b3I8dmVjdG9yPGludD4+IGMsIHZlY3RvcjxpbnQ+IHMsIHZlY3RvcjxpbnQ+IGQpCiAgICAgICAgOiBjKGMpLCBzKHMpLCBkKGQpIHsKICAgICAgICBtID0gcy5zaXplKCk7CiAgICAgICAgbiA9IGQuc2l6ZSgpOwogICAgfQoKICAgIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gTlcoKSB7CiAgICAgICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBzb2wobSwgdmVjdG9yPGludD4obiwgMCkpOwogICAgICAgIHZlY3RvcjxpbnQ+IHN1cCA9IHMsIGRlbSA9IGQ7CiAgICAgICAgaW50IGkgPSAwLCBqID0gMDsKCiAgICAgICAgd2hpbGUgKGkgPCBtICYmIGogPCBuKSB7CiAgICAgICAgICAgIGludCBhbXQgPSBtaW4oc3VwW2ldLCBkZW1bal0pOwogICAgICAgICAgICBzb2xbaV1bal0gPSBhbXQ7CiAgICAgICAgICAgIHN1cFtpXSAtPSBhbXQ7CiAgICAgICAgICAgIGRlbVtqXSAtPSBhbXQ7CgogICAgICAgICAgICBpZiAoc3VwW2ldID09IDApIGkrKzsKICAgICAgICAgICAgaWYgKGRlbVtqXSA9PSAwKSBqKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzb2w7CiAgICB9CgogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBzb2x2ZSgpIHsKICAgICAgICBhdXRvIHNvbCA9IE5XKCk7CiAgICAgICAgaW50IGl0ZXIgPSAwOwogICAgICAgIGNvbnN0IGludCBNQVhfSVRFUiA9IDEwMDsKCiAgICAgICAgd2hpbGUgKGl0ZXIrKyA8IE1BWF9JVEVSKSB7CiAgICAgICAgICAgIHZlY3RvcjxpbnQ+IHUobSwgSU5UX01BWCksIHYobiwgSU5UX01BWCk7CiAgICAgICAgICAgIHVbMF0gPSAwOwoKICAgICAgICAgICAgYm9vbCBjaDsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgY2ggPSBmYWxzZTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvbFtpXVtqXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1W2ldICE9IElOVF9NQVggJiYgdltqXSA9PSBJTlRfTUFYKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdltqXSA9IGNbaV1bal0gLSB1W2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZbal0gIT0gSU5UX01BWCAmJiB1W2ldID09IElOVF9NQVgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1W2ldID0gY1tpXVtqXSAtIHZbal07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IHdoaWxlIChjaCk7CgogICAgICAgICAgICBpbnQgbWluRCA9IDA7CiAgICAgICAgICAgIGludCBiZXN0SSA9IC0xLCBiZXN0SiA9IC0xOwoKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNvbFtpXVtqXSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1W2ldID09IElOVF9NQVggfHwgdltqXSA9PSBJTlRfTUFYKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlbHRhID0gY1tpXVtqXSAtICh1W2ldICsgdltqXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWx0YSA8IG1pbkQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbkQgPSBkZWx0YTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RJID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RKID0gajsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1pbkQgPj0gMCkgYnJlYWs7CgogICAgICAgICAgICBhdXRvIGN5YyA9IGZpbmRDeWMoc29sLCBiZXN0SSwgYmVzdEopOwogICAgICAgICAgICBpZiAoY3ljLmVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkN5Y2xlIG5vdCBmb3VuZCBmb3IgY2VsbCAoIiA8PCBiZXN0SSA8PCAiLCIgPDwgYmVzdEogPDwgIikiIDw8IGVuZGw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVkaXN0KHNvbCwgY3ljKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzb2w7CiAgICB9CgogICAgaW50IGNhbGNDb3N0KGNvbnN0IHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIHNvbCkgewogICAgICAgIGludCB0b3QgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgICAgICB0b3QgKz0gc29sW2ldW2pdICogY1tpXVtqXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdG90OwogICAgfQoKICAgIHZvaWQgcHJpbnRTb2woY29uc3QgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgc29sKSB7CiAgICAgICAgY291dCA8PCAiICAgICI7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIGNvdXQgPDwgc2V0dygzKSA8PCAiQiIgPDwgaiArIDE7CiAgICAgICAgY291dCA8PCBzZXR3KDYpIDw8ICJTdXAiIDw8IGVuZGw7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICAgICAgICAgIGNvdXQgPDwgIkEiIDw8IGkgKyAxIDw8ICIgICI7CiAgICAgICAgICAgIGludCBycyA9IDA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbjsgaisrKSB7CiAgICAgICAgICAgICAgICBjb3V0IDw8IHNldHcoNCkgPDwgc29sW2ldW2pdOwogICAgICAgICAgICAgICAgcnMgKz0gc29sW2ldW2pdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvdXQgPDwgc2V0dyg2KSA8PCBycyA8PCBlbmRsOwogICAgICAgIH0KCiAgICAgICAgY291dCA8PCAiRGVtICI7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgaW50IGNzID0gMDsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtOyBpKyspIHsKICAgICAgICAgICAgICAgIGNzICs9IHNvbFtpXVtqXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb3V0IDw8IHNldHcoNCkgPDwgY3M7CiAgICAgICAgfQogICAgICAgIGNvdXQgPDwgZW5kbDsKICAgIH0KfTsKCnZvaWQgU29sdmUoKSB7CiAgICB2ZWN0b3I8aW50PiBzID0geyAxMjAsIDkwLCAxNTAgfTsKICAgIHZlY3RvcjxpbnQ+IGQgPSB7IDUwLCA2MCwgNDAsIDcwLCAzMCwgMjAsIDkwIH07CiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IGMgPSB7CiAgICAgICAgezQsIDcsIDIsIDUsIDgsIDMsIDZ9LAogICAgICAgIHs5LCAxLCA2LCA0LCAyLCA3LCA1fSwKICAgICAgICB7MywgOCwgNSwgOSwgMSwgNCwgMn0KICAgIH07CgogICAgVFAgdHAoYywgcywgZCk7CgogICAgYXV0byBudyA9IHRwLk5XKCk7CiAgICBpbnQgbndDb3N0ID0gdHAuY2FsY0Nvc3QobncpOwogICAgY291dCA8PCAiTm9ydGgtV2VzdCBjb3JuZXIgY29zdDogIiA8PCBud0Nvc3QgPDwgZW5kbDsKCiAgICBhdXRvIG9wdCA9IHRwLnNvbHZlKCk7CiAgICBpbnQgb3B0Q29zdCA9IHRwLmNhbGNDb3N0KG9wdCk7CiAgICBjb3V0IDw8ICJPcHRpbWFsIHNvbHV0aW9uIGNvc3Q6ICIgPDwgb3B0Q29zdCA8PCBlbmRsOwoKICAgIHRwLnByaW50U29sKG9wdCk7CgogICAgYm9vbCBvayA9IHRydWU7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHMuc2l6ZSgpOyBpKyspIHsKICAgICAgICBpbnQgcnMgPSAwOwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZC5zaXplKCk7IGorKykgewogICAgICAgICAgICBycyArPSBvcHRbaV1bal07CiAgICAgICAgfQogICAgICAgIGlmIChycyAhPSBzW2ldKSB7CiAgICAgICAgICAgIGNvdXQgPDwgIlIgIiA8PCBpIDw8ICIgZXJyb3I6ICIgPDwgcnMgPDwgIiAhPSAiIDw8IHNbaV0gPDwgZW5kbDsKICAgICAgICAgICAgb2sgPSBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChpbnQgaiA9IDA7IGogPCBkLnNpemUoKTsgaisrKSB7CiAgICAgICAgaW50IGNzID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMuc2l6ZSgpOyBpKyspIHsKICAgICAgICAgICAgY3MgKz0gb3B0W2ldW2pdOwogICAgICAgIH0KICAgICAgICBpZiAoY3MgIT0gZFtqXSkgewogICAgICAgICAgICBjb3V0IDw8ICJDICIgPDwgaiA8PCAiIGVycm9yOiAiIDw8IGNzIDw8ICIgIT0gIiA8PCBkW2pdIDw8IGVuZGw7CiAgICAgICAgICAgIG9rID0gZmFsc2U7CiAgICAgICAgfQogICAgfQp9CgpzaWduZWQgbWFpbigpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogICAgY2luLnRpZSgwKTsKICAgIGNvdXQudGllKDApOwoKICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICBfX19fX19fX19fX19fX19fCiAgICAgICAgICAgICAgICAgICAgIC8gSnVzdCBzb2x2ZWQgaXQgXAogICAgICAgICAgICAgICAgICAgICB8ICAgaW4gbXkgbWluZCAgIHwKICAgICAgICAgICAgICAgICAgICAgXF9fX19fX19fX19fX19fX18vCiAgICAgICAgICAgICAgICAgICAgLwogICAgICAgICAgICAgICAgICAgLwrjgIDjgIDjgIDjgIDjgIDvvI/vvJ7jgIAg44OVICAgICAgICAgX19fX19fX19fX18K44CA44CA44CA44CA44CAfCDjgIBf44CAIF98ICAgICAgIHwgICAgICAgICAgfArjgIAg44CA44CA44CA77yPYOODnyBfeCDlvaEgICAgICAgfCAgIFdBIDIgICB8CuOAgOOAgCDjgIAgL+OAgOOAgOOAgCDjgIAgfCAgICAgICB8X19fX19fX19fX3wK44CA44CA44CAIC/jgIAg44O944CA44CAIO++iSAgICAgICAgLyAgICAgICAgICAvCuOAgO+8j++/o3zjgIDjgIAgfOOAgHzjgIB8ICAgICAgIC9fX19fX19fX18gLwrjgIB8ICjvv6Pjg73vvL9f44O9XylfKQrjgIDvvLzkuozjgaQKCiAgICAqLwoKICAgIC8qCiAgICBmcmVvcGVuKCJ0YXNrLmluIiwgInIiLCBzdGRpbik7CiAgICBmcmVvcGVuKCJ0YXNrLm91dCIsICJ3Iiwgc3Rkb3V0KTsKICAgICovCgogICAgLy8gYXV0byBzdGFydCA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKCiAgICBpbnQgbXVsdGl0ZXN0ID0gZmFsc2U7CiAgICBpZiAobXVsdGl0ZXN0ID09IHRydWUpIHsKICAgICAgICBpbnQgY3R0OyBjaW4gPj4gY3R0OwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGN0dDsgaSsrKSB7CiAgICAgICAgICAgIFNvbHZlKCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgU29sdmUoKTsKICAgIH0KCiAgICAvLyBhdXRvIGVuZCA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKCiAgICAvKgogICAgY291dCA8PCAiVGltZSB0YWtlbjogIgogICAgICAgICA8PCBjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8Y2hyb25vOjptaWxsaXNlY29uZHM+KGVuZCAtIHN0YXJ0KS5jb3VudCgpCiAgICAgICAgIDw8ICIgbWlsbGlzZWNvbmRzIiA8PCBlbmRsOwogICAgKi8KCiAgICByZXR1cm4gMDsKfQ==