{
"WrongAwnser": {
"prefix": "WrongAwnser",
"body": [
"#include <bits/stdc++.h>",
"using namespace std;",
"mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());",
"",
"using i16 = short int;",
"using i32 = int32_t;",
"using i64 = int64_t;",
"using ui16 = unsigned short int;",
"using ui32 = uint32_t;",
"using ui64 = uint64_t;",
"",
"template<class T>",
"using v = vector<T>;",
"",
"#define all(a) (a).begin(), (a).end()",
"#define open(x) freopen(#x \".inp\", \"r\", stdin), freopen(#x \".out\", \"w\", stdout)",
"",
"template<class X, class Y> bool mimi(X &x, const Y &y) {if(x > y) {x = y; return 1;} return 0;}",
"template<class X, class Y> bool mama(X &x, const Y &y) {if(x < y) {x = y; return 1;} return 0;}",
"",
"const i32 N = 2 * 1e5;",
"const i32 M = 1000000007;",
"const i32 inf = 1000000009;",
"const i64 infll = (i64)1000000000000000018;",
"",
"void sad(i32 testID) {",
" $0",
"}",
"",
"i32 main() {",
" auto begin = std::chrono::high_resolution_clock::now();",
" ios_base::sync_with_stdio(false);",
" cin.tie(NULL); cout.tie(NULL);",
"",
" i32 t = 1;",
" cin >> t;",
" for(i32 testID = 1; testID <= t; testID++) {",
" // cout << \"Case #\" << testID << \":\\n\";",
" sad(testID);",
" }",
" auto end = std::chrono::high_resolution_clock::now();",
" auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);",
" cerr << endl << \"Time measured: \" << elapsed.count() * 1e-9 << \" seconds.\" << endl; ",
" return 0;",
"}",
""
],
"description": "WrongAwnser"
}
"Accepted": {
"prefix": "Accepted",
"body": [
"#include <bits/stdc++.h>",
"using namespace std;",
"mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());",
"",
"#define i32 int",
"#define i64 long long int",
"#define ui32 unsigned int",
"#define ui64 unsigned long long int",
"",
"#define all(a) (a).begin(), (a).end()",
"#define open(x) freopen(#x \".inp\", \"r\", stdin), freopen(#x \".out\", \"w\", stdout)",
"",
"const i32 N = 2 * 1e5;",
"const i32 M = 1000000007;",
"const i32 inf = 1000000009;",
"const i64 infll = (i64)1000000000000000018;",
"",
"void sad(i32 testID) {",
" ",
"}",
"",
"i32 main() {",
" auto begin = std::chrono::high_resolution_clock::now();",
" ios_base::sync_with_stdio(false);",
" cin.tie(NULL); cout.tie(NULL);",
"",
" i32 t = 1;",
" cin >> t;",
" for(i32 testID = 1; testID <= t; testID++) {",
" // cout << \"Case #\" << testID << \":\\n\";",
" sad(testID);",
" }",
" auto end = std::chrono::high_resolution_clock::now();",
" auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);",
" cerr << endl << \"Time measured: \" << elapsed.count() * 1e-9 << \" seconds.\" << endl; ",
" return 0;",
"}",
""
],
"description": "Accepted"
}
"Power": {
"prefix": "Power",
"body": [
"i64 power(i64 base, i64 exp, i64 mod) {",
" i64 result = 1;",
" for(; exp; exp >>= 1, base = (base * base) % mod) if(exp & 1) result = (result * base) % mod;",
" return result;",
"}"
],
"description": "Power"
}
"Sieve": {
"prefix": "Sieve",
"body": [
"vector<i32> p(maxn + 1, 0);",
"void Sieve() {",
" for (i32 i = 2; i * i <= maxn; ++i) if (p[i] == 0) for (i32 j = i * i; j <= maxn; j += i) if (p[j] == 0) p[j] = i;",
" for (i32 i = 2; i <= maxn; ++i) if (p[i] == 0) p[i] = i;",
" return;",
"}"
],
"description": "Sieve"
}
"primeFactorization": {
"prefix": "primeFactorization",
"body": [
"vector<i64> factored;",
"void factor(i32 n) {",
" factored.clear();",
" while (n != 1) {",
" factored.push_back(v[n]);",
" n /= v[n];",
" }",
"}",
"",
"void sqrfactor(i64 n) {",
" factored.clear();",
" while (n % 2 == 0) {",
" factored.push_back(2);",
" n /= 2;",
" }",
"",
" for (i32 i = 3; i * i <= n; i += 2) {",
" while (n % i == 0) {",
" factored.push_back(i);",
" n /= i;",
" }",
" }",
"",
" if (n > 1) {",
" factored.push_back(n);",
" }",
"}"
],
"description": "primeFactorization"
}
"EulerTotient": {
"prefix": "EulerTotient",
"body": [
"map<i64, i64> mp;",
"i64 res = 1;",
"i64 eulerTotient(const i32& n){",
" i64 res = 1;",
" for (i32 it : factored) {",
" if(mp[it] >= 1){",
" res *= it;",
" mp[it] ++;",
" }",
" else{",
" mp[it] ++;",
" res *= it - 1;",
" }",
" }",
"",
" return res;",
"}"
],
"description": "primeFactorization"
}
"Matrix": {
"prefix": "Matrix",
"body": [
"class Matrix {",
"private:",
" i64 row, col;",
" vector<vector<i64>> data;",
"",
"pubi64c:",
" Matrix(const vector<vector<i64>>& base) : row(base.size()), col(base[0].size()), data(base) {}",
"",
" Matrix(i64 r, i64 c, i64 val) : row(r), col(c), data(vector<vector<i64>>(r, vector<i64>(c, val))) {}",
"",
" void fill(const i64& value) {",
" for(auto& row : data)",
" std::fill(row.begin(), row.end(), value);",
" }",
"",
" void fix(const i64& current, const i64& value) {",
" for(auto& row : data)",
" for(auto& cell : row)",
" if(cell == current) cell = value;",
" }",
"",
" Matrix& operator=(const Matrix& that) {",
" if (this != &that) {",
" row = that.row;",
" col = that.col;",
" data = that.data;",
" }",
" return *this;",
" }",
"",
" static i64 multiply(i64 a, i64 b) {",
" if(mod <= 1e9 + 7) return (a * b) % mod;",
" i64 res = 0;",
" a %= mod;",
" while (b > 0) {",
" if (b & 1)",
" res = (res + a) % mod;",
" a = (2 * a) % mod;",
" b >>= 1;",
" }",
" return res;",
" }",
"",
" static i64 cal(i64 a, i64 b) {",
" return (a + b % mod) % mod;",
" }",
"",
" Matrix operator*(const Matrix& that) const {",
" if (col != that.row) {",
" throw runtime_error(\"segmentation fault\");",
" }",
" Matrix res(row, that.col, 0);",
" for(i32 i = 0; i < row; i++) {",
" for(i32 j = 0; j < that.col; j++) {",
" for(i32 k = 0; k < col; k++) {",
" res.data[i][j] = cal(res.data[i][j], multiply(data[i][k], that.data[k][j]));",
" }",
" }",
" }",
" return res;",
" }",
"",
" Matrix operator^(i64 exp) const {",
" Matrix res(row, col, 0);",
" Matrix base = *this;",
" for(i32 i = 0; i < row; i++) res.data[i][i] = 1; ",
"",
" while (exp > 0) {",
" if (exp & 1) res = res * base;",
" base = base * base;",
" exp >>= 1;",
" }",
" return res;",
" }",
"",
" Matrix& operator*=(const Matrix& that) {",
" *this = *this * that;",
" return *this;",
" }",
"",
" Matrix& operator^=(i64 exp) {",
" *this = *this ^ exp;",
" return *this;",
" }",
"",
" bool operator==(const Matrix& that) const {",
" return row == that.row && col == that.col && data == that.data;",
" }",
"",
" i64 rows() const { return row; }",
" i64 cols() const { return col; }",
"",
" const vector<i64>& operator[](i32 i) const { return data[i]; }",
" vector<i64>& operator[](i32 i) { return data[i]; }",
"",
" void print() const {",
" for(const auto& row : data) {",
" for(const auto& cell : row) {",
" cout << cell << \" \";",
" }",
" cout << endl;",
" }",
" }",
"};"
],
"description": "Matrix"
}
"max_subarray_sum": {
"prefix": "max_subarray_sum",
"body": [
"vector<i32> res;",
"void max_subarray_sum(const vector<i32>& arr) {",
" i32 max_sum = -inf;",
" i32 current_sum = 0;",
" i32 start_index = 0;",
" i32 end_index = 0;",
" i32 temp_start_index = 0;",
"",
" for (i32 i = 0; i < arr.size(); ++i) {",
" current_sum += arr[i];",
"",
" if (current_sum > max_sum) {",
" max_sum = current_sum;",
" start_index = temp_start_index;",
" end_index = i;",
" }",
"",
" if (current_sum < 0) {",
" current_sum = 0;",
" temp_start_index = i + 1;",
" }",
" }",
"",
" res = vector<i32>(arr.begin() + start_index, arr.begin() + end_index + 1);",
"}"
],
"description": "max_subarray_sum"
}
"SegmentTree": {
"prefix": "SegmentTree",
"body": [
"struct STN {i32 val, lazy;};",
"struct SegmentTree {",
" vector<STN> node;",
" const STN DEADNODE = {0, 0};",
" i32 uu, vv, n;",
" SegmentTree(i32 size) : n(size) {",
" node.resize(4 * n + 10, DEADNODE);",
" this->uu = 0;",
" this->vv = n;",
" }",
" void relength(i32 size){",
" n = size;",
" node.resize(4 * n + 10, DEADNODE);",
" this->uu = 0;",
" this->vv = n;",
" }",
" STN merge(STN a, STN b) {",
" return {a.val + b.val, 0};",
" }",
" void lazy_update(i32 id, i32 l, i32 r){",
" if(node[id].lazy != 0){",
" node[id << 1].lazy += node[id].lazy;",
" node[id << 1 | 1].lazy += node[id].lazy;",
" i32 mid = (r + l) >> 1;",
" node[id << 1].val += node[id].lazy * (mid - l + 1);",
" node[id << 1 | 1].val += node[id].lazy * (r - mid);",
" node[id].lazy = 0;",
" }",
" }",
" void updateV(i32 pos, i32 val) {updateV(pos, pos, val, 1, uu, vv);}",
" void updateV(i32 u, i32 v, i32 val, i32 id, i32 l, i32 r) {",
" if (l > v || r < u) return;",
" if (u <= l && r <= v) {",
" node[id].val = val;",
" return;",
" }",
" lazy_update(id, l, r);",
" i32 mid = (l + r) >> 1;",
" updateV(u, v, val, id << 1, l, mid);",
" updateV(u, v, val, id << 1 | 1, mid + 1, r);",
" node[id] = merge(node[id << 1], node[id << 1 | 1]);",
" }",
" void update(i32 u, i32 v, i32 val) {update(u, v, val, 1, uu, vv);}",
" void update(i32 u, i32 v, i32 val, i32 id, i32 l, i32 r) {",
" if (l > v || r < u) return;",
" if (u <= l && r <= v) {",
" node[id].lazy += val;",
" node[id].val += val * (r - l + 1);",
" return;",
" }",
" lazy_update(id, l, r);",
" i32 mid = (l + r) >> 1;",
" update(u, v, val, id << 1, l, mid);",
" update(u, v, val, id << 1 | 1, mid + 1, r);",
" node[id] = merge(node[id << 1], node[id << 1 | 1]);",
" }",
" STN get(i32 u, i32 v) {return get(u, v, 1, uu, vv);}",
" STN get(i32 u, i32 v, i32 id, i32 l, i32 r) {",
" if (l > v || r < u) return DEADNODE;",
" if (u <= l && r <= v) return node[id];",
" lazy_update(id, l, r);",
" i32 mid = (l + r) >> 1;",
" return merge(get(u, v, id << 1, l, mid), get(u, v, id << 1 | 1, mid + 1, r));",
" }",
"};",
""
],
"description": "SegmentTree"
}
"FenwickTree": {
"prefix": "FenwickTree",
"body": [
"struct FenwickTree {",
" vector<i64> bit1, bit2;",
" i64 n;",
"",
" FenwickTree(i64 size) : n(size) {",
" bit1.resize(n + 1, 0);",
" bit2.resize(n + 1, 0);",
" }",
"",
" void update(vector<i64>& b, i64 u, i64 v) {",
" i64 idx = u;",
" while (idx <= n) {",
" b[idx] += v;",
" idx += (idx & (-idx));",
" }",
" }",
"",
" void update(i64 pos, i64 val){",
" update(pos, pos, val);",
" }",
"",
" void update(i64 l, i64 r, i64 val) {",
" update(bit1, l, (n - l + 1) * val);",
" update(bit1, r + 1, -(n - r + 1) * val);",
" update(bit2, l, val);",
" update(bit2, r + 1, -val);",
" }",
"",
" i64 getNode(vector<i64>& b, i64 u) {",
" i64 idx = u, ans = 0;",
" while (idx > 0) {",
" ans += b[idx];",
" idx -= (idx & (-idx));",
" }",
" return ans;",
" }",
"",
" i64 prefSum(i64 u) {",
" return getNode(bit1, u) - getNode(bit2, u) * (n - u);",
" }",
"",
" i64 get(i64 x) {",
" return prefSum(x) - prefSum(x - 1);",
" }",
"",
" i64 get(i64 l, i64 r) {",
" return prefSum(r) - prefSum(l - 1);",
" }",
"};"
],
"description": "FenwickTree"
}
"Dijkstra": {
"prefix": "Dijkstra",
"body": [
"struct Edge {i32 v; i64 c;};",
"struct Node {i32 idx; i64 val;bool operator<(const Node& other) const {return val > other.val;}};",
"void dijkstra(i32 n, i32 s, const vector<vector<Edge>>& graph, vector<i64>& dp, vector<i32>& trace) {",
" dp.resize(n, infll); dp[s] = 0;",
" trace.resize(n, -1);",
" priority_queue<Node> pq;",
" pq.push({s, 0});",
" while (!pq.empty()) {",
" Node current = pq.top();",
" pq.pop();",
" i32 u = current.idx;",
" i64 d = current.val;",
" if (d > dp[u]) continue;",
" for (const Edge& edge : graph[u]) {",
" i32 v = edge.v; i64 c = edge.c;",
" if (dp[u] + c < dp[v]) {",
" dp[v] = dp[u] + c;",
" trace[v] = u;",
" pq.push({v, dp[v]});",
" }",
" }",
" }",
"}"
],
"description": "Dijkstra"
}
"Miller_rabin": {
"prefix": "Miller_rabin",
"body": [
"bool miller_rabin(i64 n, i64 k) {",
" if (n <= 1) return false;",
" if (n == 2 || n == 3) return true;",
" if (n % 2 == 0) return false;",
"",
" i64 r = 0, d = n - 1;",
" while (!(d & 1)) {",
" r++;",
" d /= 2;",
" }",
"",
" for(i64 i = 0; i < k; i ++)",
" i64 a = rand() % (n - 4) + 2; ",
" i64 x = power(a, d, n);",
"",
" if (x == 1 || x == n - 1) continue;",
"",
" for(i64 j = 0; j < r - 1; j ++){",
" x = power(x, 2, n);",
" if (x == n - 1) break;",
" }",
"",
" if (x != n - 1) return false; ",
" }",
" ",
" return true; ",
"}"
],
"description": "Miller_rabin"
}
"SparseTable": {
"prefix": "SparseTable",
"body": [
"struct SparseTableNode{i64 val;};",
"struct SparseTable {",
" i64 n;",
" vector<vector<SparseTableNode>> dp;",
" void rebuild(const vector<i32>& a) {",
" n = a.size(); dp.clear();",
" dp.resize(n, vector<SparseTableNode>(__lg(n) + 1));",
" build(a);",
" }",
" SparseTable(const vector<i32>& a) : n(a.size()) {",
" dp.clear();",
" dp.resize(n, vector<SparseTableNode>(__lg(n) + 1));",
" build(a);",
" }",
" SparseTableNode merge(SparseTableNode a, SparseTableNode b) {",
" if(a.val < b.val) return a; return b;",
" }",
" void build(const vector<i32>& a) {",
" for(i32 i = 0; i < n; i ++) dp[i][0] = {a[i]};",
" for(i32 j = 1; j <= __lg(n); j ++)",
" for(i32 i = 0; i < n - (1 << j) + 1; i ++)",
" dp[i][j] = merge(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);",
" }",
" SparseTableNode get(i64 l, i64 r) {",
" i64 minlen = __lg(r - l + 1);",
" return merge(dp[l][minlen], dp[r - (1 << minlen) + 1][minlen]);",
" }",
"};"
],
"description": "SparseTable"
}
"Trie": {
"prefix": "Trie",
"body": [
"const i64 max_ = 26;",
"struct Trie{",
" struct Node{",
" Node *child[max_];",
" i64 exist, cnt;",
" Node() {for(i32 i = 0; i < max_; i ++) child[i] = NULL; exist = cnt = 0;}",
" };",
" ",
" i64 cur; Node *root;",
" Trie() : cur(0) {root = new Node();};",
" void add(string s) {",
" Node *p = root;",
" for (auto f : s) {",
" i64 c = f - 'a';",
" if (p->child[c] == NULL) p->child[c] = new Node();",
" p = p->child[c]; p->cnt++;",
" }",
" p->exist++;",
" }",
"",
" bool delete_str(Node *p, string& s, i64 i) {",
" if (i != (i64)s.size()) {",
" i64 c = s[i] - 'a';",
" bool is_deleted = delete_str(p->child[c], s, i + 1);",
" if (is_deleted) p->child[c] = NULL;",
" }",
" else p->exist--;",
" if (p != root) {",
" p->cnt--;",
" if (p->cnt == 0) {delete(p); return true;}",
" }",
" return false;",
" }",
" void erase(string s) {",
" if (find(s) == false) return;",
" delete_str(root, s, 0);",
" }",
" bool find(string s) {",
" Node *p = root;",
" for (auto f : s) {",
" i64 c = f - 'a';",
" if (p->child[c] == NULL) return false;",
" p = p->child[c];",
" }",
" return (p->exist != 0);",
" }",
"};"
],
"description": "Trie"
}
"LIS": {
"prefix": "LIS",
"body": [
"void tracei64S(const vector<i32>& a, const vector<i32>& dp, const vector<i32>& b, vector<i32>& trace){",
" i32 res = *max_element(dp.begin(), dp.end()) + 1;",
" for(i32 p = b.size() - 1; p >= 0; p --) if (res == dp[p] + 1) res--, trace.push_back(a[p]);",
" reverse(all(trace));",
"}",
"i64 LIS(vector<i32>& a, bool with_trace, vector<i32>& trace){",
" i64 n = a.size(); vector<i32> b(n, inf), dp(n, 0);",
" i64 res = 1;",
" for(i32 i = 0; i < n; i ++) {",
" dp[i] = lower_bound(b.begin(), b.begin() + res, a[i]) - b.begin();",
" res = max(res, dp[i] + 1);",
" b[dp[i]] = a[i];",
" }",
" if(with_trace) tracei64S(a, dp, b, trace);",
" return res;",
"}"
],
"description": "LIS"
}
"LISpair": {
"prefix": "LISpair",
"body": [
"void tracei64S(const vii& a, const vector<i32>& dp, const vector<i32>& b, vii& trace){",
" i32 res = *max_element(dp.begin(), dp.end()) + 1;",
" for(i32 p = b.size() - 1; p >= 0; p --) if (res == dp[p] + 1) res--, trace.push_back(a[p]);",
" reverse(all(trace));",
"}",
"",
"i64 LIS(vii& a, bool with_trace, vii& trace){",
" i64 n = a.size();",
" vector<i32> b(n, inf), dp(n, 0);",
" sort(all(a));",
" i64 res = 1;",
" for(i32 i = 0; i < n; i ++) {",
" dp[i] = lower_bound(b.begin(), b.begin() + res, a[i].se) - b.begin();",
" res = max(res, dp[i] + 1);",
" b[dp[i]] = a[i].se;",
" }",
" if(with_trace) tracei64S(a, dp, b, trace);",
" return res;",
"}"
],
"description": "LISpair"
}
"Matrix": {
"prefix": "Matrix",
"body": [
"class Matrix {",
"private:",
" i64 row, col;",
" vector<vector<i64>> data;",
"",
"public:",
" Matrix(const vector<vector<i64>>& base) {",
" row = base.size();",
" col = base[0].size();",
" data = base;",
" }",
" Matrix(i64 r, i64 c, i64 val) : row(r), col(c), data(vector<vector<i64>>(r, vector<i64>(c, val))) {}",
" void fill(const i64& that){for(i32 i = 0; i < data.size(); i ++) for(i32 j = 0; j < data[i].size(); j ++) data[i][j] = that;}",
" void fix(const i64& cur, const i64& that){ for(i32 i = 0; i < data.size(); i ++) for(i32 j = 0; j < data[i].size(); j ++) if(data[i][j] == cur) data[i][j] = that;}",
" Matrix& operator=(const Matrix& that) {",
" if (this != &that) {",
" row = that.row;",
" col = that.col;",
" data = that.data;",
" }",
" return *this;",
" }",
" static i64 multiply(i64 a, i64 b){",
" if(M <= 1e9 + 7) return (a * b) % M;",
" i64 res = 0;",
" a %= M;",
" while (b > 0) {",
" if (b & 1)",
" res = (res + a) % M;",
" a = (2 * a) % M;",
" b >>= 1;",
" }",
" return res;",
" }",
"",
" static i64 cal(i64 a, i64 b){return (a + b) % M;}",
" Matrix operator*(const Matrix& that) const {",
" if (col != that.row) throw std::runtime_error(\"segmentation fault\");",
" Matrix res(row, that.col, 0);",
" for(i32 i = 0; i < row; i ++) ",
" for(i32 j = 0; j < that.col; j ++) ",
" for(i32 k = 0; k < col; k ++) ",
" res.data[i][j] = cal(res.data[i][j], multiply(data[i][k], that.data[k][j]));",
" return res;",
" }",
" Matrix operator^(i64 exp){",
" i64 i = row;",
" Matrix res(i, i, 0);",
" Matrix temp = *this;",
" for(i32 j = 0; j < i; j ++) res.data[j][j] = 1;",
" while (exp) {",
" if (exp & 1) res = res * temp;",
" temp = temp * temp;",
" exp >>= 1;",
" }",
" return res;",
" }",
" Matrix& operator*=(const Matrix& that) {",
" if (col != that.row) throw std::runtime_error(\"segmentation fault\");",
" Matrix result = (*this) * that;",
" (*this) = result;",
" return *this;",
" }",
" Matrix& operator^=(i64 exp) {",
" if (exp == 0) {",
" Matrix res(row, col, 0);",
" for(i32 i = 0; i < row; i ++) res[i][i] = 1;",
" (*this) = res;",
" return *this;",
" }",
" Matrix res = *this;",
" exp--;",
" while (exp > 0) {",
" if (exp & 1) (*this) *= res;",
" res *= res;",
" exp >>= 1;",
" }",
" return *this;",
" }",
" bool operator==(const Matrix& that) const {",
" if (row != that.row || col != that.col) return false;",
" for(i32 i = 0; i < row; i ++) ",
" for(i32 j = 0; j < col; j ++) ",
" if (data[i][j] != that.data[i][j]) return false;",
" return true;",
" }",
" const vector<i64>& operator[](i32 i) const {return data[i];}",
" vector<i64>& operator[](i32 i) {return data[i];}",
" void print() const {",
" for(i32 i = 0; i < row; i ++){",
" for(i32 j = 0; j < col; j ++){",
" cout << data[i][j] << \" \";",
" }",
" cout << endl;",
" }",
" }",
"};"
],
"description": "Matrix"
}
"BerklampMassey": {
"prefix": "BerklampMassey",
"body": [
"i64 power(i64 base, i64 exp, i64 mod) {",
" i64 temp = base, res = 1;",
" while (exp) {",
" if (exp % 2) res = (res * temp) % mod;",
" temp = (temp * temp) % mod;",
" exp /= 2;",
" }",
" return res;",
"}",
"",
"template<typename T>",
"vector<T> berlekampMassey(vector<T> s) {",
" if (s.empty()) return {};",
"",
" i32 n = s.size(), L = 0, m = 0; // m = i - f",
" vector<T> C(n), D(n), oldC;",
" C[0] = D[0] = 1;",
" T df1 = 1; // d(f+1)",
" for (i32 i = 0; i < n; i++) {",
" ++m;",
" // check if C(i) == a(i)",
" // delta = s_i - sum( cj * s(i-j) ) = d(f+1)?",
" T delta = s[i];",
" for (i32 j = 1; j <= L; j++) {",
" delta += C[j] * s[i-j]; // C(j) is already multipi64ed by -1",
" delta %= mod;",
" }",
" if (delta == 0) continue; // C(i) is correct",
"",
" // Update c = c + d",
" oldC = C;",
" T coeff = delta * power(df1, mod - 2, mod) % mod;",
" for (i32 j = m; j < n; j++) {",
" C[j] -= coeff * D[j - m]; // prepend D with m zeroes, multiply by coeff and add to C",
" C[j] = (C[j] + mod * mod) % mod;",
" }",
" if (2*L > i) continue;",
" L = i + 1 - L, D = oldC, df1 = delta, m = 0;",
" }",
" C.resize(L + 1);",
" C.erase(C.begin());",
" for (auto& x : C) x = -x, x = (x + mod * mod) % mod;",
" return C;",
"}",
"",
"// Helper function",
"template<typename T>",
"vector<T> mul(const vector<T> &a, const vector<T> &b, const vector<T>& c) {",
" vector<T> ret(a.size() + b.size() - 1);",
" // ret = a * b",
" for (i32 i=0; i<(i32)a.size(); i++)",
" for (i32 j=0; j<(i32)b.size(); j++)",
" ret[i+j] += a[i] * b[j], ret[i + j] %= mod;",
"",
" i32 n = c.size();",
" // reducing ret mod f(x)",
" for (i32 i=(i32)ret.size()-1; i>=n; i--)",
" for (i32 j=n-1; j>=0; j--)",
" ret[i-j-1] += ret[i] * c[j], ret[i - j - 1] %= mod;",
" ret.resize(min((i32) ret.size(), n));",
" return ret;",
"}",
"",
"// Find k-th element in i64near recurrence: O(d^2 * logn)",
"// Need faster code? See https://j...content-available-to-author-only...o.jp/problem/kth_term_of_i64nearly_recurrent_sequence",
"// (but usually not needed since bottleneck is BerlekampMassey",
"//",
"// Params:",
"// - c: as returned by berlekampMassey",
"// - s: s0, s1, ..., s(N-1)",
"// Returns: s(k)",
"template<typename T>",
"T check(const vector<T> &c, const vector<T> &s, i64 k) {",
" i32 n = (i32) c.size();",
" assert(c.size() <= s.size());",
"",
" vector<T> a = n == 1 ? vector<T>{c[0]} : vector<T>{0, 1}, x{1};",
" for (; k>0; k/=2) {",
" if (k % 2)",
" x = mul(x, a, c); // mul(a, b) computes a(x) * b(x) mod f(x)",
" a = mul(a, a, c);",
" }",
" x.resize(n);",
"",
" T ret = 0;",
" for (i32 i=0; i<n; i++)",
" ret += x[i] * s[i], ret %= mod;",
" return ret;",
"}",
"",
"// Result for f[n]",
"template<typename T>",
"T main_cal(const vector<T> &f, i64 k) {",
" vector<i64> c = berlekampMassey(f);",
" return check(c, f, k);",
"}"
],
"description": "BerklampMassey"
}
"dptools": {
"prefix": "dptools",
"body": [
"void add(i32 &a, i32 b) {a = (a + b) % M;}",
"void gmin(i32 &a, i32 b) {a = min(a, b);}",
"void gmax(i32 &a, i32 b) {a = max(a, b);}",
"bool get(i32 mask, i32 idx){return ((mask >> idx) & 1);}",
"void print(i32 mask, string s) {bitset<3> a(mask); cout << a.to_string() << s;}"
],
"description": "dptools"
}
"Tree": {
"prefix": "Tree",
"body": [
"class Tree{",
" private:",
" vv<vv<i32>> up;",
" vv<i32> h;",
" i32 n;",
" public:",
" Tree(i32 size, vv<vv<i32>>& a) : n(size) {",
" up = vv<vv<i32>>(__lg(n) + 1, vv<i32>(n, 0));",
" h = vv<i32>(n, 0);",
" queue<i32> q; q.push(0);",
" while (!q.empty()) {",
" i32 node = q.front(); q.pop();",
" for (auto x : a[node]) {",
" if (x == up[0][node]) continue;",
" up[0][x] = node;",
" h[x] = h[node] + 1;",
" q.push(x);",
" }",
" }",
" for (i16 i = 1; i <= __lg(n); i++)",
" for (i32 j = 0; j < n; j++)",
" up[i][j] = up[i - 1][up[i - 1][j]];",
" }",
" i32 lca(i32 u, i32 v) {",
" if (h[u] > h[v]) swap(u, v);",
" if (h[u] != h[v]) {",
" i32 dif = h[v] - h[u];",
" for (i16 i = __lg(dif); i >= 0; i--)",
" if (dif >= (1 << i)) v = up[i][v], dif -= (1 << i);",
" }",
" if (u == v) return u;",
" for (i16 i = __lg(n); i >= 0; i--)",
" if (up[i][u] != up[i][v])",
" u = up[i][u], v = up[i][v];",
" return up[0][u];",
" }",
"};",
""
],
"description": "Tree"
}
"DisjointSets": {
"prefix": "DisjointSets",
"body": [
"struct Save {",
" i32 v, rnkv, u, rnku;",
" Save() {}",
" Save(i32 _v, i32 _rnkv, i32 _u, i32 _rnku)",
" : v(_v), rnkv(_rnkv), u(_u), rnku(_rnku) {}",
"};",
"struct DisjointSets {",
" vector<i32> par, rank;",
" i32 comps;",
" vector<Save> history;",
"",
" DisjointSets() {}",
" DisjointSets(i32 n) {",
" par.resize(n); rank.resize(n, 0);",
" for (i32 i = 0; i < n; i++) par[i] = i;",
" comps = n;",
" }",
"",
" i32 root(i32 v) {",
" return (v == par[v]) ? v : root(par[v]);",
" }",
"",
" bool merge(i32 v, i32 u) {",
" v = root(v); u = root(u);",
" if (v == u) return false;",
" comps--;",
" if (rank[v] > rank[u]) swap(v, u);",
" history.push_back(Save(v, rank[v], u, rank[u]));",
" par[v] = u;",
" if (rank[u] == rank[v]) rank[u] ++;",
" return true;",
" }",
"",
" void rollback() {",
" if (history.empty()) return;",
" Save x = history.back();",
" history.pop_back();",
" par[x.v] = x.v; rank[x.v] = x.rnkv;",
" par[x.u] = x.u; rank[x.u] = x.rnku;",
" comps++;",
" }",
"};"
],
"description": "DisjointSets"
}
"SqrtDecomposition": {
"prefix": "SqrtDecomposition",
"body": [
"vector<vector<i32>> blocks;",
"vector<vector<i32>> block_freq;",
"i32 block_size; i32 sq_temp[N];",
"void sqrt_decomposition(i32 n, i32 k) {",
" block_size = sqrt(n);",
" blocks.resize((n + block_size - 1) / block_size);",
" block_freq.resize(blocks.size(), vector<i32>(k));",
" for(i32 i = 0; i < n; i++) {",
" blocks[i / block_size].push_back(sq_temp[i]);",
" block_freq[i / block_size][sq_temp[i]]++;",
" }",
"}",
"i32 sqrt_query(i32 q_l, i32 q_r, i32 k) {",
" i32 block_l = q_l / block_size;",
" i32 block_r = q_r / block_size, cnt = 0;",
" if (block_l == block_r) {",
" for (i32 i = q_l; i <= q_r; i++) ",
" if(sq_temp[i] < k) cnt ++;",
" } ",
" else {",
" for (i32 i = q_l; i < (block_l + 1) * block_size; i++) ",
" if(sq_temp[i] < k) cnt++;",
" for (i32 i = block_l + 1; i < block_r; i++) ",
" for (i32 j = 0; j < k; j++) ",
" cnt += block_freq[i][j];",
" for (i32 i = block_r * block_size; i <= q_r; i++) ",
" if(sq_temp[i] < k) cnt ++;",
" }",
" return cnt;",
"}"
],
"description": "SqrtDecomposition"
}
"FenwickTree": {
"prefix": "FenwickTree",
"body": [
"struct FenwickTree {",
" vector<i64> node;",
" FenwickTree(i32 n) : node(n + 8, 0) {}",
" void update(i32 pos, i64 val) {",
" for (; pos < node.size(); pos += pos & -pos) ",
" node[pos] += val;",
" }",
" i64 getSum(i32 pos) {",
" i64 res = 0;",
" for (; pos > 0; pos -= pos & -pos) ",
" res += node[pos];",
" return res;",
" }",
" i64 get(i32 l, i32 r) {",
" return getSum(r) - getSum(l - 1);",
" }",
"};",
""
],
"description": "FenwickTree"
}
"FenwickTree2D": {
"prefix": "FenwickTree2D",
"body": [
"struct FenwickTree2D {",
" vector<vector<i64>> node;",
" FenwickTree2D(i32 n, i32 m) : node(n + 8, vector<i64>(m + 8, 0)) {}",
" void update(i32 x, i32 y, i64 val) {",
" for (i32 i = x; i < node.size(); i += i & -i) ",
" for (i32 j = y; j < node[0].size(); j += j & -j) ",
" node[i][j] += val;",
" }",
" i64 getSum(i32 x, i32 y) {",
" i64 res = 0;",
" for (i32 i = x; i > 0; i -= i & -i) ",
" for (i32 j = y; j > 0; j -= j & -j) ",
" res += node[i][j];",
" return res;",
" }",
" i64 get(i32 x1, i32 y1, i32 x2, i32 y2) {",
" return getSum(x2, y2) - getSum(x1 - 1, y2) - getSum(x2, y1 - 1) + getSum(x1 - 1, y1 - 1);",
" }",
"};",
""
],
"description": "FenwickTree2D"
}
"FenwickTree3D": {
"prefix": "FenwickTree3D",
"body": [
"struct FenwickTree3D {",
" vector<vector<vector<i64>>> node;",
" FenwickTree3D(i32 n, i32 m, i32 p) : node(n + 8, vector<vector<i64>>(m + 8, vector<i64>(p + 8, 0))) {}",
" ",
" void update(i32 x, i32 y, i32 z, i64 val) {",
" for (i32 i = x; i < node.size(); i += i & -i) ",
" for (i32 j = y; j < node[0].size(); j += j & -j) ",
" for (i32 k = z; k < node[0][0].size(); k += k & -k) ",
" node[i][j][k] += val;",
" }",
"",
" i64 getSum(i32 x, i32 y, i32 z) {",
" i64 res = 0;",
" for (i32 i = x; i > 0; i -= i & -i) ",
" for (i32 j = y; j > 0; j -= j & -j) ",
" for (i32 k = z; k > 0; k -= k & -k) ",
" res += node[i][j][k];",
" return res;",
" }",
" ",
" i64 get(i32 x1, i32 y1, i32 z1, i32 x2, i32 y2, i32 z2) {",
" return getSum(x2, y2, z2) ",
" - getSum(x1 - 1, y2, z2) - getSum(x2, y1 - 1, z2) - getSum(x2, y2, z1 - 1)",
" + getSum(x1 - 1, y1 - 1, z2) + getSum(x1 - 1, y2, z1 - 1) + getSum(x2, y1 - 1, z1 - 1)",
" - getSum(x1 - 1, y1 - 1, z1 - 1);",
" }",
"};",
""
],
"description": "FenwickTree3D"
}
"FastSet": {
"prefix": "FastSet",
"body": [
"struct FastSet {",
" static constexpr i32 BASE = 6;",
" static constexpr i32 RANGE = 1 << BASE;",
" static constexpr i32 FILTER = RANGE - 1;",
" i32 N, log;",
" vector<vector<i64>> seg;",
"",
" FastSet(i32 _N = 0, bool val = 0) { build(_N, val); }",
" ",
" void build(i32 _N = 0, bool val = 0) {",
" seg.clear(); N = _N, log = 0;",
" while(true) {",
" seg.emplace_back((_N + FILTER) >> BASE, (val ? ~0ull : 0ull)); ++log;",
" if(seg.back().size() <= 1) break;",
" _N = seg.back().size();",
" }",
" }",
" ",
" void insert(i32 k) {",
" i32 id = k >> BASE;",
" for(i32 i = 0; i < seg.size(); ++i, k >>= BASE, id >>= BASE) {",
" if(seg[i][id] >> (k & FILTER) & 1) break;",
" seg[i][id] |= i64(1) << (k & FILTER);",
" }",
" }",
"",
" void erase(i32 k) {",
" if(!(*this)[k]) return;",
" i32 id = k >> BASE;",
" for(i32 i = 0; i < seg.size(); ++i, k >>= BASE, id >>= BASE) {",
" seg[i][id] ^= i64(1) << (k & FILTER);",
" if(bool(seg[i][id])) break;",
" }",
" }",
"",
" bool operator[](i32 k) {",
" assert(0 <= k && k < N);",
" return seg[0][k >> BASE] >> (k & FILTER) & 1;",
" }",
"",
" i32 next(i32 k) {",
" i32 id = k >> BASE;",
" for(i32 i = 0; i < seg.size(); ++i) {",
" if((id = (k >> BASE)) >= seg[i].size()) break;",
" i64 x = seg[i][id] >> (k & FILTER);",
" if(!x) { k = id + 1; continue; }",
" k += __builtin_ctzll(x);",
" for(i32 j = i - 1; j >= 0; --j) k = (k << 6) | __builtin_ctzll(seg[j][k]);",
" return k;",
" }",
" return N;",
" }",
"",
" i32 prev(i32 k) {",
" k = min(k, N - 1);",
" i32 id;",
" for(i32 i = 0; i < seg.size(); ++i) {",
" if(k < 0) break;",
" i64 x = seg[i][id = (k >> BASE)] << (FILTER - (k & FILTER));",
" if(!x) { k = id - 1; continue; }",
" k -= __builtin_clz
ll(x);",
" for(i32 j = i - 1; j >= 0; --j) k = (k << BASE) | (FILTER - __builtin_clzll(seg[j][k]));",
" return k;",
" }",
" return -1;",
" }",
"};"
],
"description": "FastSet"
}
"ConvexHullTrick": {
"prefix": "ConvexHullTrick",
"body": [
"struct Line {",
" mutable i64 k, m, p;",
" bool operator<(const Line& o) const {return k < o.k;}",
" bool operator<(i64 x) const {return p < x;}",
"};",
"struct ConvexHullTrick : multiset<Line, less<>> {",
" static const i64 INF = LLONG_MAX;",
" i64 div(i64 a, i64 b) {",
" return a / b - ((a ^ b) < 0 && a % b); ",
" }",
" bool isect(iterator x, iterator y) {",
" if (y == end()) return x->p = INF, 0;",
" if (x->k == y->k) x->p = x->m > y->m ? INF : -INF;",
" else x->p = div(y->m - x->m, x->k - y->k);",
" return x->p >= y->p;",
" }",
" void push(i64 k, i64 m) {",
" auto z = insert({k, m, 0}), y = z ++, x = y;",
" while (isect(y, z)) z = erase(z);",
" if (x != begin() && isect(-- x, y)) isect(x, y = erase(y));",
" while ((y = x) != begin() && (-- x)->p >= y->p)",
" isect(x, erase(y));",
" }",
" i64 get(i64 x) {",
" assert(!empty());",
" auto l = *lower_bound(x);",
" return l.k * x + l.m;",
" }",
"};",
""
],
"description": "ConvexHullTrick"
}
"FastSegmentTree": {
"prefix": "FastSegmentTree",
"body": [
"#include <immintrin.h> ",
"const int _SIZE = 1 << 20, INF = 1e9 + 9;",
"using T = uint32_t;",
"T st[2 * _SIZE]; ",
"const T identity_element = INF; ",
"__attribute__((target(\"avx2\"))) __m256i reduce(__m256i a, __m256i b) {",
" return _mm256_min_epi32(a, b);",
"}",
"T reduce(T a, T b) {",
" return min(a, b);",
"}",
"void build(int n, const T a[]) {",
" for (int i = 0; i < n; i++) st[i + _SIZE] = a[i + 1];",
" for (int i = _SIZE - 1; i > 0; i--) {",
" st[i] = reduce(st[i << 1], st[i << 1 | 1]);",
" }",
"}",
"__attribute__((target(\"avx2\"))) T query_parallel(int l, int r) {",
" T res = identity_element;",
" l += _SIZE, r += _SIZE;",
" __m256i vec_res = _mm256_set1_epi32(res); ",
"",
" while (l <= r) {",
" if (l & 1) {",
" __m256i vec_l = _mm256_set1_epi32(st[l]);",
" vec_res = reduce(vec_res, vec_l); ",
" ++l;",
" }",
" if (!(r & 1)) {",
" __m256i vec_r = _mm256_set1_epi32(st[r]);",
" vec_res = reduce(vec_res, vec_r); ",
" --r;",
" }",
" l >>= 1, r >>= 1;",
" }",
"",
" T result[8];",
" _mm256_storeu_si256((__m256i*)result, vec_res);",
" for (int i = 0; i < 8; i++) {",
" res = reduce(res, result[i]);",
" }",
" return res;",
"}",
"void upd(int p, T val) {",
" for (st[p += _SIZE] = val; p > 1; p >>= 1) {",
" st[p >> 1] = reduce(st[p], st[p ^ 1]);",
" }",
"}",
"void update(int pos, int val) {upd(pos - 1, val);}",
"T get(int l, int r) {return query_parallel(l - 1, r - 1);}"
],
"description": "FastSegmentTree"
},
"Checker": {
"prefix": "Checker",
"body": [
"#include <bits/stdc++.h>",
"using namespace std;",
"",
"using i32 = int32_t;",
"using i64 = int64_t;",
"",
"template<class T>",
"using v = vector<T>;",
"",
"#define all(a) (a).begin(), (a).end()",
"",
"string file = \"DRAWATREE\";",
"",
"i64 rand(i64 l, i64 h) {",
" return l + (rand() % (h - l + 1));",
"}",
"",
"void check() {",
" ofstream out(file + \".inp\");",
"",
" i32 n = 600; out << n << endl;",
" for (i32 i = 0; i < n - 1; i++) {",
" for (i32 j = i + 1; j < n; j++) {",
" out << (rand(0, 2) == 0? 'N' : 'Y');",
" }",
" out << endl;",
" }",
"",
" out.close();",
"}",
"",
"void sad(i32 testID) {",
" srand(time(NULL));",
" for (i32 i = 1; i <= 100; i++) { ",
" check();",
" system((file + \".exe\").c_str()); ",
" system((file + \"_trau.exe\").c_str()); ",
" if (system((\"fc \" + (file + \".out\") + \" \" + (file + \".ans\")).c_str())) {",
" // cout << \"Test \" << i << \" failed!\\n\";",
" return;",
" }",
" }",
"}",
"",
"i32 main() {",
" ios_base::sync_with_stdio(false);",
" cin.tie(NULL); cout.tie(NULL);",
"",
" i32 t = 1;",
" for (i32 testID = 1; testID <= t; testID++) {",
" sad(testID);",
" }",
" return 0;",
"}",
""
],
"description": "Checker"
},
"mul": {
"prefix": "mul",
"body": [
"ui64 modmul(ui64 a, ui64 b, ui64 M){",
" i64 ret = a * b - M * ui64(1.L / M * a * b);",
" return ret + M * (ret < 0) - M * (ret >= (i64)M);",
"}"
],
"description": "mul"
}
"PollardRho": {
"prefix": "PollardRho",
"body": [
"ui64 PollardRho(ui64 n){",
" auto f = [n](ui64 x){return modmul(x, x, n) + 1;};",
" ui64 x=0, y=0, t=30, prd=2, i=1, q;",
" while (t++ % 40 || __gcd(prd, n) == 1){",
" if (x == y) x = ++i, y = f(x);",
" if ((q = modmul(prd, max(x, y) - min(x, y), n))) prd = q;",
" x = f(x), y = f(f(y));",
" }",
" return __gcd(prd, n);",
"}",
"vector<ui64> factor(ui64 n){",
" if (n == 1) return{};",
"}"
],
"description": "PollardRho"
}
"BetterSieve": {
"prefix": "BetterSieve",
"body": [
"vector<i32> _checkPrime(N >> 6), _prime;",
"void Sieve() {",
" #define set(n) (_checkPrime[n >> 6] |= (1<<((n & 63) >> 1)))",
" #define get(n) (_checkPrime[n >> 6] & (1 << ((n & 63) >> 1)))",
" ",
" _prime.push_back(2); i32 t = sqrt(N);",
" for (i32 i = 3; i < N; i += 2)",
" if (!get(i)) {",
" _prime.push_back(i);",
" if (i > t) continue;",
" for (i32 j = i * i; j < N; j += (i << 1)) set(j);",
" }",
"}"
],
"description": "BetterSieve"
}
"gcd_withExtendedEuclidean": {
"prefix": "gcd_withExtendedEuclidean",
"body": [
"i64 gcd_withExtendedEuclidean(i64 a, i64 b, i64 &x, i64 &y) {",
" if (b == 0) {x = 1, y = 0; return a;}",
" i64 x1, y1, g = gcd_withExtendedEuclidean(b, a % b, x1, y1);",
" x = y1; y = x1 - a / b * y1;",
" return g;",
"}"
],
"description": "gcd_withExtendedEuclidean"
}
"custom_hash ": {
"prefix": "custom_hash ",
"body": [
"// Source: http://x...content-available-to-author-only...i.it/splitmix64.c",
"struct custom_hash {",
" static uint64_t splitmix64(uint64_t x) {",
" x += 0x9e3779b97f4a7c15;",
" x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;",
" x = (x ^ (x >> 27)) * 0x94d049bb133111eb;",
" return x ^ (x >> 31);",
" }",
" size_t operator()(uint64_t x) const {",
" static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();",
" return splitmix64(x + FIXED_RANDOM);",
" }",
"};"
],
"description": "custom_hash "
}
"MergeSortTree ": {
"prefix": "MergeSortTree ",
"body": [
"struct MSTN {vector<i32> val;};",
"struct MergeSortTree {",
" vector<MSTN> node;",
" i32 uu, vv, n;",
" MergeSortTree(i32 size) : n(size) {",
" node.resize(4 * n + 10);",
" this->uu = 1;",
" this->vv = n;",
" }",
" void relength(i32 size){",
" n = size;",
" node.resize(4 * n + 10);",
" this->uu = 1;",
" this->vv = n;",
" }",
" void merge(MSTN &a, MSTN &b, MSTN &c) {",
" a.val.clear();",
" i32 p1 = 0, p2 = 0;",
" while(true) {",
" if(p1 == b.val.size()) {",
" if(p2 == c.val.size()) break;",
" else a.val.push_back(c.val[p2 ++]);",
" }",
" else {",
" if(p2 == c.val.size()) a.val.push_back(b.val[p1 ++]);",
" else if(b.val[p1] < c.val[p2]) a.val.push_back(b.val[p1 ++]);",
" else a.val.push_back(c.val[p2 ++]);",
" }",
" }",
" }",
" void build(vector<i32> &a) {build(1, 1, n, a);}",
" void build(i32 id, i32 l, i32 r, vector<i32> &a) {",
" if (l == r) {",
" node[id].val.push_back(a[l]);",
" return;",
" }",
" i32 mid = (l + r) >> 1;",
" build(id << 1, l, mid, a);",
" build(id << 1 | 1, mid + 1, r, a);",
" merge(node[id], node[id << 1], node[id << 1 | 1]);",
" }",
" void updateV(i32 pos, i32 x, i32 y) {updateV(pos, x, y, 1, uu, vv);}",
" void updateV(i32 pos, i32 x, i32 y, i32 id, i32 l, i32 r) {",
" if (l > pos || r < pos) return;",
" if (l == r) {",
" i32 ll = 0, rr = node[id].val.size() - 1, res = 0;",
" while(ll <= rr) {",
" i32 mid = (ll + rr) >> 1;",
" if(node[id].val[mid] >= x) rr = (res = mid) - 1;",
" else ll = mid + 1;",
" }",
" if(node[id].val[res] == x) node[id].val[res] = y;",
" else throw std::runtime_error(\"Value not found\");",
" sort(all(node[id].val));",
" return;",
" }",
" i32 mid = (l + r) >> 1;",
" updateV(pos, x, y, id << 1, l, mid);",
" updateV(pos, x, y, id << 1 | 1, mid + 1, r);",
" merge(node[id], node[id << 1], node[id << 1 | 1]);",
" }",
" i32 get(i32 u, i32 v, i32 k) {return get(u, v, k, 1, uu, vv);}",
" i32 get(i32 u, i32 v, i32 k, i32 id, i32 l, i32 r) {",
" if (l > v || r < u) return 0;",
" if (u <= l && r <= v) {",
" i32 ll = 0, rr = node[id].val.size() - 1, res = node[id].val.size();",
" while(ll <= rr) {",
" i32 mid = (ll + rr) >> 1;",
" if(node[id].val[mid] > k) rr = (res = mid) - 1;",
" else ll = mid + 1;",
" }",
" return node[id].val.size() - res;",
" }",
" i32 mid = (l + r) >> 1;",
" return get(u, v, k, id << 1, l, mid) + get(u, v, k, id << 1 | 1, mid + 1, r);",
" }",
"};"
],
"description": "MergeSortTree "
}
"DynamicConnectivity": {
"prefix": "DynamicConnectivity",
"body": [
"struct Connect {",
" i32 v, u;",
" bool united;",
" Connect(i32 _v, i32 _u) : v(_v), u(_u) {",
" }",
"};",
"struct DynamicConnectivity {",
" vector<vector<Connect>> t;",
" DisjointSets dsu;",
" i32 T;",
"",
" DynamicConnectivity() {}",
" DynamicConnectivity(i32 _T, i32 n) : T(_T) {",
" dsu = DisjointSets(n);",
" t.resize(4 * T + 4);",
" }",
"",
" void add(i32 v, i32 l, i32 r, i32 ul, i32 ur, Connect& q) {",
" if (ul > ur)",
" return;",
" if (l == ul && r == ur) {",
" t[v].push_back(q);",
" return;",
" }",
" i32 mid = (l + r) >> 1;",
" add(v << 1, l, mid, ul, min(ur, mid), q);",
" add(v << 1 | 1, mid + 1, r, max(ul, mid + 1), ur, q);",
" }",
" void add(Connect q, i32 l, i32 r) {",
" add(1, 0, T - 1, l, r, q);",
" }",
"",
" void dfs(i32 v, i32 l, i32 r, vector<i32>& ans) {",
" for (Connect& q : t[v]) {",
" q.united = dsu.merge(q.v, q.u);",
" }",
" if (l == r) ans[l] = dsu.comps;",
" else {",
" i32 mid = (l + r) >> 1;",
" dfs(v << 1, l, mid, ans);",
" dfs(v << 1 | 1, mid + 1, r, ans);",
" }",
" for (Connect q : t[v]) if (q.united) dsu.rollback();",
" }",
" vector<i32> compute() {",
" vector<i32> ans(T);",
" dfs(1, 0, T - 1, ans);",
" return ans;",
" }",
"};"
],
"description": "DynamicConnectivity"
}
}
ewoJIldyb25nQXduc2VyIjogewoJICAicHJlZml4IjogIldyb25nQXduc2VyIiwKCSAgImJvZHkiOiBbCgkJIiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPiIsCgkJInVzaW5nIG5hbWVzcGFjZSBzdGQ7IiwKCQkibXQxOTkzN182NCBSTkcoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsiLAoJCSIiLAoJCSJ1c2luZyBpMTYgPSBzaG9ydCBpbnQ7IiwKCQkidXNpbmcgaTMyID0gaW50MzJfdDsiLAoJCSJ1c2luZyBpNjQgPSBpbnQ2NF90OyIsCgkJInVzaW5nIHVpMTYgPSB1bnNpZ25lZCBzaG9ydCBpbnQ7IiwKCQkidXNpbmcgdWkzMiA9IHVpbnQzMl90OyIsCgkJInVzaW5nIHVpNjQgPSB1aW50NjRfdDsiLAoJCSIiLAoJCSJ0ZW1wbGF0ZTxjbGFzcyBUPiIsCgkJInVzaW5nIHYgPSB2ZWN0b3I8VD47IiwKCQkiIiwKCQkiI2RlZmluZSBhbGwoYSkgKGEpLmJlZ2luKCksIChhKS5lbmQoKSIsCgkJIiNkZWZpbmUgb3Blbih4KSBmcmVvcGVuKCN4IFwiLmlucFwiLCBcInJcIiwgc3RkaW4pLCBmcmVvcGVuKCN4IFwiLm91dFwiLCBcIndcIiwgc3Rkb3V0KSIsCgkJIiIsCgkJInRlbXBsYXRlPGNsYXNzIFgsIGNsYXNzIFk+IGJvb2wgbWltaShYICZ4LCBjb25zdCBZICZ5KSB7aWYoeCA+IHkpIHt4ID0geTsgcmV0dXJuIDE7fSByZXR1cm4gMDt9IiwKCQkidGVtcGxhdGU8Y2xhc3MgWCwgY2xhc3MgWT4gYm9vbCBtYW1hKFggJngsIGNvbnN0IFkgJnkpIHtpZih4IDwgeSkge3ggPSB5OyByZXR1cm4gMTt9IHJldHVybiAwO30iLAoJCSIiLAoJCSJjb25zdCBpMzIgTiA9IDIgKiAxZTU7IiwKCQkiY29uc3QgaTMyIE0gPSAxMDAwMDAwMDA3OyIsCgkJImNvbnN0IGkzMiBpbmYgPSAxMDAwMDAwMDA5OyIsCgkJImNvbnN0IGk2NCBpbmZsbCA9IChpNjQpMTAwMDAwMDAwMDAwMDAwMDAxODsiLAoJCSIiLAoJCSJ2b2lkIHNhZChpMzIgdGVzdElEKSB7IiwKCQkiCSQwIiwKCQkifSIsCgkJIiIsCgkJImkzMiBtYWluKCkgeyIsCgkJIiAgICBhdXRvIGJlZ2luID0gc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7IiwKCQkiICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyIsCgkJIiAgICBjaW4udGllKE5VTEwpOyBjb3V0LnRpZShOVUxMKTsiLAoJCSIiLAoJCSIgICAgaTMyIHQgPSAxOyIsCgkJIiAgICBjaW4gPj4gdDsiLAoJCSIgICAgZm9yKGkzMiB0ZXN0SUQgPSAxOyB0ZXN0SUQgPD0gdDsgdGVzdElEKyspIHsiLAoJCSIgICAgICAgIC8vIGNvdXQgPDwgXCJDYXNlICNcIiA8PCB0ZXN0SUQgPDwgXCI6XFxuXCI7IiwKCQkiICAgICAgICBzYWQodGVzdElEKTsiLAoJCSIgICAgfSIsCgkJIiAgICBhdXRvIGVuZCA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOyIsCgkJIiAgICBhdXRvIGVsYXBzZWQgPSBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxzdGQ6OmNocm9ubzo6bmFub3NlY29uZHM+KGVuZCAtIGJlZ2luKTsiLAoJCSIgICAgY2VyciA8PCBlbmRsIDw8IFwiVGltZSBtZWFzdXJlZDogXCIgPDwgZWxhcHNlZC5jb3VudCgpICogMWUtOSA8PCBcIiBzZWNvbmRzLlwiIDw8IGVuZGw7ICIsCgkJIiAgICByZXR1cm4gMDsiLAoJCSJ9IiwKCQkiIgoJICBdLAoJICAiZGVzY3JpcHRpb24iOiAiV3JvbmdBd25zZXIiCgl9CgkiQWNjZXB0ZWQiOiB7CiAgInByZWZpeCI6ICJBY2NlcHRlZCIsCiAgImJvZHkiOiBbCiAgICAiI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IiwKICAgICJ1c2luZyBuYW1lc3BhY2Ugc3RkOyIsCgkibXQxOTkzN182NCBSTkcoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsiLAogICAgIiIsCiAgICAiI2RlZmluZSBpMzIgaW50IiwKICAgICIjZGVmaW5lIGk2NCBsb25nIGxvbmcgaW50IiwKICAgICIjZGVmaW5lIHVpMzIgdW5zaWduZWQgaW50IiwKICAgICIjZGVmaW5lIHVpNjQgdW5zaWduZWQgbG9uZyBsb25nIGludCIsCiAgICAiIiwKICAgICIjZGVmaW5lIGFsbChhKSAoYSkuYmVnaW4oKSwgKGEpLmVuZCgpIiwKICAgICIjZGVmaW5lIG9wZW4oeCkgZnJlb3BlbigjeCBcIi5pbnBcIiwgXCJyXCIsIHN0ZGluKSwgZnJlb3BlbigjeCBcIi5vdXRcIiwgXCJ3XCIsIHN0ZG91dCkiLAogICAgIiIsCiAgICAiY29uc3QgaTMyIE4gPSAyICogMWU1OyIsCiAgICAiY29uc3QgaTMyIE0gPSAxMDAwMDAwMDA3OyIsCiAgICAiY29uc3QgaTMyIGluZiA9IDEwMDAwMDAwMDk7IiwKICAgICJjb25zdCBpNjQgaW5mbGwgPSAoaTY0KTEwMDAwMDAwMDAwMDAwMDAwMTg7IiwKICAgICIiLAogICAgInZvaWQgc2FkKGkzMiB0ZXN0SUQpIHsiLAogICAgIiAgICAiLAogICAgIn0iLAogICAgIiIsCiAgICAiaTMyIG1haW4oKSB7IiwKCSIgICAgYXV0byBiZWdpbiA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOyIsCiAgICAiICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyIsCiAgICAiICAgIGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOyIsCiAgICAiIiwKICAgICIgICAgaTMyIHQgPSAxOyIsCiAgICAiICAgIGNpbiA+PiB0OyIsCiAgICAiICAgIGZvcihpMzIgdGVzdElEID0gMTsgdGVzdElEIDw9IHQ7IHRlc3RJRCsrKSB7IiwKICAgICIgICAgICAgIC8vIGNvdXQgPDwgXCJDYXNlICNcIiA8PCB0ZXN0SUQgPDwgXCI6XFxuXCI7IiwKICAgICIgICAgICAgIHNhZCh0ZXN0SUQpOyIsCiAgICAiICAgIH0iLAoJIiAgICBhdXRvIGVuZCA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOyIsCgkiICAgIGF1dG8gZWxhcHNlZCA9IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0PHN0ZDo6Y2hyb25vOjpuYW5vc2Vjb25kcz4oZW5kIC0gYmVnaW4pOyIsCgkiICAgIGNlcnIgPDwgZW5kbCA8PCBcIlRpbWUgbWVhc3VyZWQ6IFwiIDw8IGVsYXBzZWQuY291bnQoKSAqIDFlLTkgPDwgXCIgc2Vjb25kcy5cIiA8PCBlbmRsOyAiLAogICAgIiAgICByZXR1cm4gMDsiLAogICAgIn0iLAogICAgIiIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJBY2NlcHRlZCIKfQoJCSAgIlBvd2VyIjogewoJICAicHJlZml4IjogIlBvd2VyIiwKCSAgImJvZHkiOiBbCgkJImk2NCBwb3dlcihpNjQgYmFzZSwgaTY0IGV4cCwgaTY0IG1vZCkgeyIsCgkJIiAgICBpNjQgcmVzdWx0ID0gMTsiLAoJCSIgICAgZm9yKDsgZXhwOyBleHAgPj49IDEsIGJhc2UgPSAoYmFzZSAqIGJhc2UpICUgbW9kKSBpZihleHAgJiAxKSByZXN1bHQgPSAocmVzdWx0ICogYmFzZSkgJSBtb2Q7IiwKCQkiICAgIHJldHVybiByZXN1bHQ7IiwKCQkifSIKCSAgXSwKCSAgImRlc2NyaXB0aW9uIjogIlBvd2VyIgoJfQoJCgkJICAiU2lldmUiOiB7CgkJCSJwcmVmaXgiOiAiU2lldmUiLAoJCQkiYm9keSI6IFsKCQkJICAidmVjdG9yPGkzMj4gcChtYXhuICsgMSwgMCk7IiwKCQkJICAidm9pZCBTaWV2ZSgpIHsiLAoJCQkgICIgICAgZm9yIChpMzIgaSA9IDI7IGkgKiBpIDw9IG1heG47ICsraSkgaWYgKHBbaV0gPT0gMCkgZm9yIChpMzIgaiA9IGkgKiBpOyBqIDw9IG1heG47IGogKz0gaSkgaWYgKHBbal0gPT0gMCkgcFtqXSA9IGk7IiwKCQkJICAiICAgIGZvciAoaTMyIGkgPSAyOyBpIDw9IG1heG47ICsraSkgaWYgKHBbaV0gPT0gMCkgIHBbaV0gPSBpOyIsCgkJCSAgIiAgICByZXR1cm47IiwKCQkJICAifSIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIlNpZXZlIgoJCSAgfQoJCgkJICAicHJpbWVGYWN0b3JpemF0aW9uIjogewoJCQkicHJlZml4IjogInByaW1lRmFjdG9yaXphdGlvbiIsCgkJCSJib2R5IjogWwoJCQkgICJ2ZWN0b3I8aTY0PiBmYWN0b3JlZDsiLAoJCQkgICJ2b2lkIGZhY3RvcihpMzIgbikgeyIsCgkJCSAgIiAgICBmYWN0b3JlZC5jbGVhcigpOyIsCgkJCSAgIiAgICB3aGlsZSAobiAhPSAxKSB7IiwKCQkJICAiICAgICAgICBmYWN0b3JlZC5wdXNoX2JhY2sodltuXSk7IiwKCQkJICAiICAgICAgICBuIC89IHZbbl07IiwKCQkJICAiICAgIH0iLAoJCQkgICJ9IiwKCQkJICAiIiwKCQkJICAidm9pZCBzcXJmYWN0b3IoaTY0IG4pIHsiLAoJCQkgICIgICAgZmFjdG9yZWQuY2xlYXIoKTsiLAoJCQkgICIgICAgd2hpbGUgKG4gJSAyID09IDApIHsiLAoJCQkgICIgICAgICAgIGZhY3RvcmVkLnB1c2hfYmFjaygyKTsiLAoJCQkgICIgICAgICAgIG4gLz0gMjsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBmb3IgKGkzMiBpID0gMzsgaSAqIGkgPD0gbjsgaSArPSAyKSB7IiwKCQkJICAiICAgICAgICB3aGlsZSAobiAlIGkgPT0gMCkgeyIsCgkJCSAgIiAgICAgICAgICAgIGZhY3RvcmVkLnB1c2hfYmFjayhpKTsiLAoJCQkgICIgICAgICAgICAgICBuIC89IGk7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgaWYgKG4gPiAxKSB7IiwKCQkJICAiICAgICAgICBmYWN0b3JlZC5wdXNoX2JhY2sobik7IiwKCQkJICAiICAgIH0iLAoJCQkgICJ9IgoJCQldLAoJCQkiZGVzY3JpcHRpb24iOiAicHJpbWVGYWN0b3JpemF0aW9uIgoJCSAgfQoJCgkJICAiRXVsZXJUb3RpZW50IjogewoJCQkicHJlZml4IjogIkV1bGVyVG90aWVudCIsCgkJCSJib2R5IjogWwoJCQkgICJtYXA8aTY0LCBpNjQ+ICBtcDsiLAoJCQkgICJpNjQgcmVzID0gMTsiLAoJCQkgICJpNjQgZXVsZXJUb3RpZW50KGNvbnN0IGkzMiYgbil7IiwKCQkJICAiICAgIGk2NCByZXMgPSAxOyIsCgkJCSAgIiAgICBmb3IgKGkzMiBpdCA6IGZhY3RvcmVkKSB7IiwKCQkJICAiICAgICAgICBpZihtcFtpdF0gPj0gMSl7IiwKCQkJICAiICAgICAgICAJcmVzICo9IGl0OyIsCgkJCSAgIgkJCW1wW2l0XSArKzsiLAoJCQkgICIJCX0iLAoJCQkgICIJCWVsc2V7IiwKCQkJICAiCQkJbXBbaXRdICsrOyIsCgkJCSAgIgkJCXJlcyAqPSBpdCAtIDE7IiwKCQkJICAiCQl9IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgcmV0dXJuIHJlczsiLAoJCQkgICJ9IgoJCQldLAoJCQkiZGVzY3JpcHRpb24iOiAicHJpbWVGYWN0b3JpemF0aW9uIgoJCSAgfQoJCgkJICAiTWF0cml4IjogewoJCQkicHJlZml4IjogIk1hdHJpeCIsCgkJCSJib2R5IjogWwoJCQkgICJjbGFzcyBNYXRyaXggeyIsCgkJCSAgInByaXZhdGU6IiwKCQkJICAiICAgIGk2NCByb3csIGNvbDsiLAoJCQkgICIgICAgdmVjdG9yPHZlY3RvcjxpNjQ+PiBkYXRhOyIsCgkJCSAgIiIsCgkJCSAgInB1Ymk2NGM6IiwKCQkJICAiICAgIE1hdHJpeChjb25zdCB2ZWN0b3I8dmVjdG9yPGk2ND4+JiBiYXNlKSA6IHJvdyhiYXNlLnNpemUoKSksIGNvbChiYXNlWzBdLnNpemUoKSksIGRhdGEoYmFzZSkge30iLAoJCQkgICIiLAoJCQkgICIgICAgTWF0cml4KGk2NCByLCBpNjQgYywgaTY0IHZhbCkgOiByb3cociksIGNvbChjKSwgZGF0YSh2ZWN0b3I8dmVjdG9yPGk2ND4+KHIsIHZlY3RvcjxpNjQ+KGMsIHZhbCkpKSB7fSIsCgkJCSAgIiIsCgkJCSAgIiAgICB2b2lkIGZpbGwoY29uc3QgaTY0JiB2YWx1ZSkgeyIsCgkJCSAgIiAgICAgICAgZm9yKGF1dG8mIHJvdyA6IGRhdGEpIiwKCQkJICAiICAgICAgICAgICAgc3RkOjpmaWxsKHJvdy5iZWdpbigpLCByb3cuZW5kKCksIHZhbHVlKTsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICB2b2lkIGZpeChjb25zdCBpNjQmIGN1cnJlbnQsIGNvbnN0IGk2NCYgdmFsdWUpIHsiLAoJCQkgICIgICAgICAgIGZvcihhdXRvJiByb3cgOiBkYXRhKSIsCgkJCSAgIiAgICAgICAgICAgIGZvcihhdXRvJiBjZWxsIDogcm93KSIsCgkJCSAgIiAgICAgICAgICAgICAgICBpZihjZWxsID09IGN1cnJlbnQpIGNlbGwgPSB2YWx1ZTsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBNYXRyaXgmIG9wZXJhdG9yPShjb25zdCBNYXRyaXgmIHRoYXQpIHsiLAoJCQkgICIgICAgICAgIGlmICh0aGlzICE9ICZ0aGF0KSB7IiwKCQkJICAiICAgICAgICAgICAgcm93ID0gdGhhdC5yb3c7IiwKCQkJICAiICAgICAgICAgICAgY29sID0gdGhhdC5jb2w7IiwKCQkJICAiICAgICAgICAgICAgZGF0YSA9IHRoYXQuZGF0YTsiLAoJCQkgICIgICAgICAgIH0iLAoJCQkgICIgICAgICAgIHJldHVybiAqdGhpczsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBzdGF0aWMgaTY0IG11bHRpcGx5KGk2NCBhLCBpNjQgYikgeyIsCgkJCSAgIiAgICAgICAgaWYobW9kIDw9IDFlOSArIDcpIHJldHVybiAoYSAqIGIpICUgbW9kOyIsCgkJCSAgIiAgICAgICAgaTY0IHJlcyA9IDA7IiwKCQkJICAiICAgICAgICBhICU9IG1vZDsiLAoJCQkgICIgICAgICAgIHdoaWxlIChiID4gMCkgeyIsCgkJCSAgIiAgICAgICAgICAgIGlmIChiICYgMSkiLAoJCQkgICIgICAgICAgICAgICAgICAgcmVzID0gKHJlcyArIGEpICUgbW9kOyIsCgkJCSAgIiAgICAgICAgICAgIGEgPSAoMiAqIGEpICUgbW9kOyIsCgkJCSAgIiAgICAgICAgICAgIGIgPj49IDE7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgICAgICByZXR1cm4gcmVzOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIHN0YXRpYyBpNjQgY2FsKGk2NCBhLCBpNjQgYikgeyIsCgkJCSAgIiAgICAgICAgcmV0dXJuIChhICsgYiAlIG1vZCkgJSBtb2Q7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgTWF0cml4IG9wZXJhdG9yKihjb25zdCBNYXRyaXgmIHRoYXQpIGNvbnN0IHsiLAoJCQkgICIgICAgICAgIGlmIChjb2wgIT0gdGhhdC5yb3cpIHsiLAoJCQkgICIgICAgICAgICAgICB0aHJvdyBydW50aW1lX2Vycm9yKFwic2VnbWVudGF0aW9uIGZhdWx0XCIpOyIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgTWF0cml4IHJlcyhyb3csIHRoYXQuY29sLCAwKTsiLAoJCQkgICIgICAgICAgIGZvcihpMzIgaSA9IDA7IGkgPCByb3c7IGkrKykgeyIsCgkJCSAgIiAgICAgICAgICAgIGZvcihpMzIgaiA9IDA7IGogPCB0aGF0LmNvbDsgaisrKSB7IiwKCQkJICAiICAgICAgICAgICAgICAgIGZvcihpMzIgayA9IDA7IGsgPCBjb2w7IGsrKykgeyIsCgkJCSAgIiAgICAgICAgICAgICAgICAgICAgcmVzLmRhdGFbaV1bal0gPSBjYWwocmVzLmRhdGFbaV1bal0sIG11bHRpcGx5KGRhdGFbaV1ba10sIHRoYXQuZGF0YVtrXVtqXSkpOyIsCgkJCSAgIiAgICAgICAgICAgICAgICB9IiwKCQkJICAiICAgICAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgcmV0dXJuIHJlczsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBNYXRyaXggb3BlcmF0b3JeKGk2NCBleHApIGNvbnN0IHsiLAoJCQkgICIgICAgICAgIE1hdHJpeCByZXMocm93LCBjb2wsIDApOyIsCgkJCSAgIiAgICAgICAgTWF0cml4IGJhc2UgPSAqdGhpczsiLAoJCQkgICIgICAgICAgIGZvcihpMzIgaSA9IDA7IGkgPCByb3c7IGkrKykgcmVzLmRhdGFbaV1baV0gPSAxOyAiLAoJCQkgICIiLAoJCQkgICIgICAgICAgIHdoaWxlIChleHAgPiAwKSB7IiwKCQkJICAiICAgICAgICAgICAgaWYgKGV4cCAmIDEpIHJlcyA9IHJlcyAqIGJhc2U7IiwKCQkJICAiICAgICAgICAgICAgYmFzZSA9IGJhc2UgKiBiYXNlOyIsCgkJCSAgIiAgICAgICAgICAgIGV4cCA+Pj0gMTsiLAoJCQkgICIgICAgICAgIH0iLAoJCQkgICIgICAgICAgIHJldHVybiByZXM7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgTWF0cml4JiBvcGVyYXRvcio9KGNvbnN0IE1hdHJpeCYgdGhhdCkgeyIsCgkJCSAgIiAgICAgICAgKnRoaXMgPSAqdGhpcyAqIHRoYXQ7IiwKCQkJICAiICAgICAgICByZXR1cm4gKnRoaXM7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgTWF0cml4JiBvcGVyYXRvcl49KGk2NCBleHApIHsiLAoJCQkgICIgICAgICAgICp0aGlzID0gKnRoaXMgXiBleHA7IiwKCQkJICAiICAgICAgICByZXR1cm4gKnRoaXM7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hdHJpeCYgdGhhdCkgY29uc3QgeyIsCgkJCSAgIiAgICAgICAgcmV0dXJuIHJvdyA9PSB0aGF0LnJvdyAmJiBjb2wgPT0gdGhhdC5jb2wgJiYgZGF0YSA9PSB0aGF0LmRhdGE7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgaTY0IHJvd3MoKSBjb25zdCB7IHJldHVybiByb3c7IH0iLAoJCQkgICIgICAgaTY0IGNvbHMoKSBjb25zdCB7IHJldHVybiBjb2w7IH0iLAoJCQkgICIiLAoJCQkgICIgICAgY29uc3QgdmVjdG9yPGk2ND4mIG9wZXJhdG9yW10oaTMyIGkpIGNvbnN0IHsgcmV0dXJuIGRhdGFbaV07IH0iLAoJCQkgICIgICAgdmVjdG9yPGk2ND4mIG9wZXJhdG9yW10oaTMyIGkpIHsgcmV0dXJuIGRhdGFbaV07IH0iLAoJCQkgICIiLAoJCQkgICIgICAgdm9pZCBwcmludCgpIGNvbnN0IHsiLAoJCQkgICIgICAgICAgIGZvcihjb25zdCBhdXRvJiByb3cgOiBkYXRhKSB7IiwKCQkJICAiICAgICAgICAgICAgZm9yKGNvbnN0IGF1dG8mIGNlbGwgOiByb3cpIHsiLAoJCQkgICIgICAgICAgICAgICAgICAgY291dCA8PCBjZWxsIDw8IFwiIFwiOyIsCgkJCSAgIiAgICAgICAgICAgIH0iLAoJCQkgICIgICAgICAgICAgICBjb3V0IDw8IGVuZGw7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgIH0iLAoJCQkgICJ9OyIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIk1hdHJpeCIKCQkgIH0KCQoJCSAgIm1heF9zdWJhcnJheV9zdW0iOiB7CgkJCSJwcmVmaXgiOiAibWF4X3N1YmFycmF5X3N1bSIsCgkJCSJib2R5IjogWwoJCQkgICJ2ZWN0b3I8aTMyPiByZXM7IiwKCQkJICAidm9pZCBtYXhfc3ViYXJyYXlfc3VtKGNvbnN0IHZlY3RvcjxpMzI+JiBhcnIpIHsiLAoJCQkgICIgICAgaTMyIG1heF9zdW0gPSAtaW5mOyIsCgkJCSAgIiAgICBpMzIgY3VycmVudF9zdW0gPSAwOyIsCgkJCSAgIiAgICBpMzIgc3RhcnRfaW5kZXggPSAwOyIsCgkJCSAgIiAgICBpMzIgZW5kX2luZGV4ID0gMDsiLAoJCQkgICIgICAgaTMyIHRlbXBfc3RhcnRfaW5kZXggPSAwOyIsCgkJCSAgIiIsCgkJCSAgIiAgICBmb3IgKGkzMiBpID0gMDsgaSA8IGFyci5zaXplKCk7ICsraSkgeyIsCgkJCSAgIiAgICAgICAgY3VycmVudF9zdW0gKz0gYXJyW2ldOyIsCgkJCSAgIiIsCgkJCSAgIiAgICAgICAgaWYgKGN1cnJlbnRfc3VtID4gbWF4X3N1bSkgeyIsCgkJCSAgIiAgICAgICAgICAgIG1heF9zdW0gPSBjdXJyZW50X3N1bTsiLAoJCQkgICIgICAgICAgICAgICBzdGFydF9pbmRleCA9IHRlbXBfc3RhcnRfaW5kZXg7IiwKCQkJICAiICAgICAgICAgICAgZW5kX2luZGV4ID0gaTsiLAoJCQkgICIgICAgICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgICAgIGlmIChjdXJyZW50X3N1bSA8IDApIHsiLAoJCQkgICIgICAgICAgICAgICBjdXJyZW50X3N1bSA9IDA7IiwKCQkJICAiICAgICAgICAgICAgdGVtcF9zdGFydF9pbmRleCA9IGkgKyAxOyIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIHJlcyA9IHZlY3RvcjxpMzI+KGFyci5iZWdpbigpICsgc3RhcnRfaW5kZXgsIGFyci5iZWdpbigpICsgZW5kX2luZGV4ICsgMSk7IiwKCQkJICAifSIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIm1heF9zdWJhcnJheV9zdW0iCgkJICB9CgkKCQkgICJTZWdtZW50VHJlZSI6IHsKICAicHJlZml4IjogIlNlZ21lbnRUcmVlIiwKICAiYm9keSI6IFsKICAgICJzdHJ1Y3QgU1ROIHtpMzIgdmFsLCBsYXp5O307IiwKICAgICJzdHJ1Y3QgU2VnbWVudFRyZWUgeyIsCiAgICAiICAgIHZlY3RvcjxTVE4+IG5vZGU7IiwKICAgICIgICAgY29uc3QgU1ROIERFQUROT0RFID0gezAsIDB9OyIsCiAgICAiICAgIGkzMiB1dSwgdnYsIG47IiwKICAgICIgICAgU2VnbWVudFRyZWUoaTMyIHNpemUpIDogbihzaXplKSB7IiwKICAgICIgICAgICAgIG5vZGUucmVzaXplKDQgKiBuICsgMTAsIERFQUROT0RFKTsiLAogICAgIiAgICAgICAgdGhpcy0+dXUgPSAwOyIsCiAgICAiICAgICAgICB0aGlzLT52diA9IG47IiwKICAgICIgICAgfSIsCiAgICAiICAgIHZvaWQgcmVsZW5ndGgoaTMyIHNpemUpeyIsCiAgICAiICAgICAgICBuID0gc2l6ZTsiLAogICAgIiAgICAgICAgbm9kZS5yZXNpemUoNCAqIG4gKyAxMCwgREVBRE5PREUpOyIsCiAgICAiICAgICAgICB0aGlzLT51dSA9IDA7IiwKICAgICIgICAgICAgIHRoaXMtPnZ2ID0gbjsiLAogICAgIiAgICB9IiwKICAgICIgICAgU1ROIG1lcmdlKFNUTiBhLCBTVE4gYikgeyIsCiAgICAiICAgICAgICByZXR1cm4ge2EudmFsICsgYi52YWwsIDB9OyIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIGxhenlfdXBkYXRlKGkzMiBpZCwgaTMyIGwsIGkzMiByKXsiLAogICAgIiAgICAgICAgaWYobm9kZVtpZF0ubGF6eSAhPSAwKXsiLAogICAgIiAgICAgICAgICAgIG5vZGVbaWQgPDwgMV0ubGF6eSArPSBub2RlW2lkXS5sYXp5OyIsCiAgICAiICAgICAgICAgICAgbm9kZVtpZCA8PCAxIHwgMV0ubGF6eSArPSBub2RlW2lkXS5sYXp5OyIsCiAgICAiICAgICAgICAgICAgaTMyIG1pZCA9IChyICsgbCkgPj4gMTsiLAogICAgIiAgICAgICAgICAgIG5vZGVbaWQgPDwgMV0udmFsICs9IG5vZGVbaWRdLmxhenkgKiAobWlkIC0gbCArIDEpOyIsCiAgICAiICAgICAgICAgICAgbm9kZVtpZCA8PCAxIHwgMV0udmFsICs9IG5vZGVbaWRdLmxhenkgKiAociAtIG1pZCk7IiwKICAgICIgICAgICAgICAgICBub2RlW2lkXS5sYXp5ID0gMDsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIHVwZGF0ZVYoaTMyIHBvcywgaTMyIHZhbCkge3VwZGF0ZVYocG9zLCBwb3MsIHZhbCwgMSwgdXUsIHZ2KTt9IiwKICAgICIgICAgdm9pZCB1cGRhdGVWKGkzMiB1LCBpMzIgdiwgaTMyIHZhbCwgaTMyIGlkLCBpMzIgbCwgaTMyIHIpIHsiLAogICAgIiAgICAgICAgaWYgKGwgPiB2IHx8IHIgPCB1KSByZXR1cm47IiwKICAgICIgICAgICAgIGlmICh1IDw9IGwgJiYgciA8PSB2KSB7IiwKICAgICIgICAgICAgICAgICBub2RlW2lkXS52YWwgPSB2YWw7IiwKICAgICIgICAgICAgICAgICByZXR1cm47IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICAgICAgbGF6eV91cGRhdGUoaWQsIGwsIHIpOyIsCiAgICAiICAgICAgICBpMzIgbWlkID0gKGwgKyByKSA+PiAxOyIsCiAgICAiICAgICAgICB1cGRhdGVWKHUsIHYsIHZhbCwgaWQgPDwgMSwgbCwgbWlkKTsiLAogICAgIiAgICAgICAgdXBkYXRlVih1LCB2LCB2YWwsIGlkIDw8IDEgfCAxLCBtaWQgKyAxLCByKTsiLAogICAgIiAgICAgICAgbm9kZVtpZF0gPSBtZXJnZShub2RlW2lkIDw8IDFdLCBub2RlW2lkIDw8IDEgfCAxXSk7IiwKICAgICIgICAgfSIsCiAgICAiICAgIHZvaWQgdXBkYXRlKGkzMiB1LCBpMzIgdiwgaTMyIHZhbCkge3VwZGF0ZSh1LCB2LCB2YWwsIDEsIHV1LCB2dik7fSIsCiAgICAiICAgIHZvaWQgdXBkYXRlKGkzMiB1LCBpMzIgdiwgaTMyIHZhbCwgaTMyIGlkLCBpMzIgbCwgaTMyIHIpIHsiLAogICAgIiAgICAgICAgaWYgKGwgPiB2IHx8IHIgPCB1KSByZXR1cm47IiwKICAgICIgICAgICAgIGlmICh1IDw9IGwgJiYgciA8PSB2KSB7IiwKICAgICIgICAgICAgICAgICBub2RlW2lkXS5sYXp5ICs9IHZhbDsiLAogICAgIiAgICAgICAgICAgIG5vZGVbaWRdLnZhbCArPSB2YWwgKiAociAtIGwgKyAxKTsiLAogICAgIiAgICAgICAgICAgIHJldHVybjsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBsYXp5X3VwZGF0ZShpZCwgbCwgcik7IiwKICAgICIgICAgICAgIGkzMiBtaWQgPSAobCArIHIpID4+IDE7IiwKICAgICIgICAgICAgIHVwZGF0ZSh1LCB2LCB2YWwsIGlkIDw8IDEsIGwsIG1pZCk7IiwKICAgICIgICAgICAgIHVwZGF0ZSh1LCB2LCB2YWwsIGlkIDw8IDEgfCAxLCBtaWQgKyAxLCByKTsiLAogICAgIiAgICAgICAgbm9kZVtpZF0gPSBtZXJnZShub2RlW2lkIDw8IDFdLCBub2RlW2lkIDw8IDEgfCAxXSk7IiwKICAgICIgICAgfSIsCiAgICAiICAgIFNUTiBnZXQoaTMyIHUsIGkzMiB2KSB7cmV0dXJuIGdldCh1LCB2LCAxLCB1dSwgdnYpO30iLAogICAgIiAgICBTVE4gZ2V0KGkzMiB1LCBpMzIgdiwgaTMyIGlkLCBpMzIgbCwgaTMyIHIpIHsiLAogICAgIiAgICAgICAgaWYgKGwgPiB2IHx8IHIgPCB1KSByZXR1cm4gREVBRE5PREU7IiwKICAgICIgICAgICAgIGlmICh1IDw9IGwgJiYgciA8PSB2KSByZXR1cm4gbm9kZVtpZF07IiwKICAgICIgICAgICAgIGxhenlfdXBkYXRlKGlkLCBsLCByKTsiLAogICAgIiAgICAgICAgaTMyIG1pZCA9IChsICsgcikgPj4gMTsiLAogICAgIiAgICAgICAgcmV0dXJuIG1lcmdlKGdldCh1LCB2LCBpZCA8PCAxLCBsLCBtaWQpLCBnZXQodSwgdiwgaWQgPDwgMSB8IDEsIG1pZCArIDEsIHIpKTsiLAogICAgIiAgICB9IiwKICAgICJ9OyIsCiAgICAiIgogIF0sCiAgImRlc2NyaXB0aW9uIjogIlNlZ21lbnRUcmVlIgp9CgkKCQkgICJGZW53aWNrVHJlZSI6IHsKCQkJInByZWZpeCI6ICJGZW53aWNrVHJlZSIsCgkJCSJib2R5IjogWwoJCQkgICJzdHJ1Y3QgRmVud2lja1RyZWUgeyIsCgkJCSAgIiAgICB2ZWN0b3I8aTY0PiBiaXQxLCBiaXQyOyIsCgkJCSAgIiAgICBpNjQgbjsiLAoJCQkgICIiLAoJCQkgICIgICAgRmVud2lja1RyZWUoaTY0IHNpemUpIDogbihzaXplKSB7IiwKCQkJICAiICAgICAgICBiaXQxLnJlc2l6ZShuICsgMSwgMCk7IiwKCQkJICAiICAgICAgICBiaXQyLnJlc2l6ZShuICsgMSwgMCk7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgdm9pZCB1cGRhdGUodmVjdG9yPGk2ND4mIGIsIGk2NCB1LCBpNjQgdikgeyIsCgkJCSAgIiAgICAgICAgaTY0IGlkeCA9IHU7IiwKCQkJICAiICAgICAgICB3aGlsZSAoaWR4IDw9IG4pIHsiLAoJCQkgICIgICAgICAgICAgICBiW2lkeF0gKz0gdjsiLAoJCQkgICIgICAgICAgICAgICBpZHggKz0gKGlkeCAmICgtaWR4KSk7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgdm9pZCB1cGRhdGUoaTY0IHBvcywgaTY0IHZhbCl7IiwKCQkJICAiICAgICAgICB1cGRhdGUocG9zLCBwb3MsIHZhbCk7IiwKCQkJICAiICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgdm9pZCB1cGRhdGUoaTY0IGwsIGk2NCByLCBpNjQgdmFsKSB7IiwKCQkJICAiICAgICAgICB1cGRhdGUoYml0MSwgbCwgKG4gLSBsICsgMSkgKiB2YWwpOyIsCgkJCSAgIiAgICAgICAgdXBkYXRlKGJpdDEsIHIgKyAxLCAtKG4gLSByICsgMSkgKiB2YWwpOyIsCgkJCSAgIiAgICAgICAgdXBkYXRlKGJpdDIsIGwsIHZhbCk7IiwKCQkJICAiICAgICAgICB1cGRhdGUoYml0MiwgciArIDEsIC12YWwpOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIGk2NCBnZXROb2RlKHZlY3RvcjxpNjQ+JiBiLCBpNjQgdSkgeyIsCgkJCSAgIiAgICAgICAgaTY0IGlkeCA9IHUsIGFucyA9IDA7IiwKCQkJICAiICAgICAgICB3aGlsZSAoaWR4ID4gMCkgeyIsCgkJCSAgIiAgICAgICAgICAgIGFucyArPSBiW2lkeF07IiwKCQkJICAiICAgICAgICAgICAgaWR4IC09IChpZHggJiAoLWlkeCkpOyIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgcmV0dXJuIGFuczsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBpNjQgcHJlZlN1bShpNjQgdSkgeyIsCgkJCSAgIiAgICAgICAgcmV0dXJuIGdldE5vZGUoYml0MSwgdSkgLSBnZXROb2RlKGJpdDIsIHUpICogKG4gLSB1KTsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiIsCgkJCSAgIiAgICBpNjQgZ2V0KGk2NCB4KSB7IiwKCQkJICAiICAgICAgICByZXR1cm4gcHJlZlN1bSh4KSAtIHByZWZTdW0oeCAtIDEpOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIGk2NCBnZXQoaTY0IGwsIGk2NCByKSB7IiwKCQkJICAiICAgICAgICByZXR1cm4gcHJlZlN1bShyKSAtIHByZWZTdW0obCAtIDEpOyIsCgkJCSAgIiAgICB9IiwKCQkJICAifTsiCgkJCV0sCgkJCSJkZXNjcmlwdGlvbiI6ICJGZW53aWNrVHJlZSIKCQkgIH0KCQoJCSAgIkRpamtzdHJhIjogewogICJwcmVmaXgiOiAiRGlqa3N0cmEiLAogICJib2R5IjogWwogICAgInN0cnVjdCBFZGdlIHtpMzIgdjsgaTY0IGM7fTsiLAogICAgInN0cnVjdCBOb2RlIHtpMzIgaWR4OyBpNjQgdmFsO2Jvb2wgb3BlcmF0b3I8KGNvbnN0IE5vZGUmIG90aGVyKSBjb25zdCB7cmV0dXJuIHZhbCA+IG90aGVyLnZhbDt9fTsiLAogICAgInZvaWQgZGlqa3N0cmEoaTMyIG4sIGkzMiBzLCBjb25zdCB2ZWN0b3I8dmVjdG9yPEVkZ2U+PiYgZ3JhcGgsIHZlY3RvcjxpNjQ+JiBkcCwgdmVjdG9yPGkzMj4mIHRyYWNlKSB7IiwKICAgICIgICAgZHAucmVzaXplKG4sIGluZmxsKTsgZHBbc10gPSAwOyIsCiAgICAiICAgIHRyYWNlLnJlc2l6ZShuLCAtMSk7IiwKICAgICIgICAgcHJpb3JpdHlfcXVldWU8Tm9kZT4gcHE7IiwKICAgICIgICAgcHEucHVzaCh7cywgMH0pOyIsCiAgICAiICAgIHdoaWxlICghcHEuZW1wdHkoKSkgeyIsCiAgICAiICAgICAgICBOb2RlIGN1cnJlbnQgPSBwcS50b3AoKTsiLAogICAgIiAgICAgICAgcHEucG9wKCk7IiwKICAgICIgICAgICAgIGkzMiB1ID0gY3VycmVudC5pZHg7IiwKICAgICIgICAgICAgIGk2NCBkID0gY3VycmVudC52YWw7IiwKICAgICIgICAgICAgIGlmIChkID4gZHBbdV0pIGNvbnRpbnVlOyIsCiAgICAiICAgICAgICBmb3IgKGNvbnN0IEVkZ2UmIGVkZ2UgOiBncmFwaFt1XSkgeyIsCiAgICAiICAgICAgICAgICAgaTMyIHYgPSBlZGdlLnY7IGk2NCBjID0gZWRnZS5jOyIsCiAgICAiICAgICAgICAgICAgaWYgKGRwW3VdICsgYyA8IGRwW3ZdKSB7IiwKICAgICIgICAgICAgICAgICAgICAgZHBbdl0gPSBkcFt1XSArIGM7IiwKICAgICIgICAgICAgICAgICAgICAgdHJhY2Vbdl0gPSB1OyIsCiAgICAiICAgICAgICAgICAgICAgIHBxLnB1c2goe3YsIGRwW3ZdfSk7IiwKICAgICIgICAgICAgICAgICB9IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICB9IiwKICAgICJ9IgogIF0sCiAgImRlc2NyaXB0aW9uIjogIkRpamtzdHJhIgp9CgkKCQkgICJNaWxsZXJfcmFiaW4iOiB7CgkJCSJwcmVmaXgiOiAiTWlsbGVyX3JhYmluIiwKCQkJImJvZHkiOiBbCgkJCSAgImJvb2wgbWlsbGVyX3JhYmluKGk2NCBuLCBpNjQgaykgeyIsCgkJCSAgIiAgICBpZiAobiA8PSAxKSByZXR1cm4gZmFsc2U7IiwKCQkJICAiICAgIGlmIChuID09IDIgfHwgbiA9PSAzKSByZXR1cm4gdHJ1ZTsiLAoJCQkgICIgICAgaWYgKG4gJSAyID09IDApIHJldHVybiBmYWxzZTsiLAoJCQkgICIiLAoJCQkgICIgICAgaTY0IHIgPSAwLCBkID0gbiAtIDE7IiwKCQkJICAiICAgIHdoaWxlICghKGQgJiAxKSkgeyIsCgkJCSAgIiAgICAgICAgcisrOyIsCgkJCSAgIiAgICAgICAgZCAvPSAyOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIGZvcihpNjQgaSA9IDA7IGkgPCBrOyBpICsrKSIsCgkJCSAgIiAgICAgICAgaTY0IGEgPSByYW5kKCkgJSAobiAtIDQpICsgMjsgIiwKCQkJICAiICAgICAgICBpNjQgeCA9IHBvd2VyKGEsIGQsIG4pOyIsCgkJCSAgIiIsCgkJCSAgIiAgICAgICAgaWYgKHggPT0gMSB8fCB4ID09IG4gLSAxKSBjb250aW51ZTsiLAoJCQkgICIiLAoJCQkgICIgICAgICAgIGZvcihpNjQgaiA9IDA7IGogPCByIC0gMTsgaiArKyl7IiwKCQkJICAiICAgICAgICAgICAgeCA9IHBvd2VyKHgsIDIsIG4pOyIsCgkJCSAgIiAgICAgICAgICAgIGlmICh4ID09IG4gLSAxKSBicmVhazsiLAoJCQkgICIgICAgICAgIH0iLAoJCQkgICIiLAoJCQkgICIgICAgICAgIGlmICh4ICE9IG4gLSAxKSByZXR1cm4gZmFsc2U7ICIsCgkJCSAgIiAgICB9IiwKCQkJICAiCSIsCgkJCSAgIiAgICByZXR1cm4gdHJ1ZTsgIiwKCQkJICAifSIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIk1pbGxlcl9yYWJpbiIKCQkgIH0KCQoJCSAgIlNwYXJzZVRhYmxlIjogewoJCQkicHJlZml4IjogIlNwYXJzZVRhYmxlIiwKCQkJImJvZHkiOiBbCgkJCSAgInN0cnVjdCBTcGFyc2VUYWJsZU5vZGV7aTY0IHZhbDt9OyIsCgkJCSAgInN0cnVjdCBTcGFyc2VUYWJsZSB7IiwKCQkJICAiICAgIGk2NCBuOyIsCgkJCSAgIiAgICB2ZWN0b3I8dmVjdG9yPFNwYXJzZVRhYmxlTm9kZT4+IGRwOyIsCgkJCSAgIiAgICB2b2lkIHJlYnVpbGQoY29uc3QgdmVjdG9yPGkzMj4mIGEpIHsiLAoJCQkgICIgICAgICAgIG4gPSBhLnNpemUoKTsgZHAuY2xlYXIoKTsiLAoJCQkgICIgICAgICAgIGRwLnJlc2l6ZShuLCB2ZWN0b3I8U3BhcnNlVGFibGVOb2RlPihfX2xnKG4pICsgMSkpOyIsCgkJCSAgIiAgICAgICAgYnVpbGQoYSk7IiwKCQkJICAiICAgIH0iLAoJCQkgICIgICAgU3BhcnNlVGFibGUoY29uc3QgdmVjdG9yPGkzMj4mIGEpIDogbihhLnNpemUoKSkgeyIsCgkJCSAgIiAgICAgICAgZHAuY2xlYXIoKTsiLAoJCQkgICIgICAgICAgIGRwLnJlc2l6ZShuLCB2ZWN0b3I8U3BhcnNlVGFibGVOb2RlPihfX2xnKG4pICsgMSkpOyIsCgkJCSAgIiAgICAgICAgYnVpbGQoYSk7IiwKCQkJICAiICAgIH0iLAoJCQkgICIgICAgU3BhcnNlVGFibGVOb2RlIG1lcmdlKFNwYXJzZVRhYmxlTm9kZSBhLCBTcGFyc2VUYWJsZU5vZGUgYikgeyIsCgkJCSAgIiAgICAgICAgaWYoYS52YWwgPCBiLnZhbCkgcmV0dXJuIGE7IHJldHVybiBiOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiICAgIHZvaWQgYnVpbGQoY29uc3QgdmVjdG9yPGkzMj4mIGEpIHsiLAoJCQkgICIgICAgICAgIGZvcihpMzIgaSA9IDA7IGkgPCBuOyBpICsrKSBkcFtpXVswXSA9IHthW2ldfTsiLAoJCQkgICIgICAgICAgIGZvcihpMzIgaiA9IDE7IGogPD0gX19sZyhuKTsgaiArKykiLAoJCQkgICIgICAgICAgICAgICBmb3IoaTMyIGkgPSAwOyBpIDwgbiAtICgxIDw8IGopICsgMTsgaSArKykiLAoJCQkgICIgICAgICAgICAgICAgICAgZHBbaV1bal0gPSBtZXJnZShkcFtpXVtqIC0gMV0sIGRwW2kgKyAoMSA8PCAoaiAtIDEpKV1baiAtIDFdKTsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiAgICBTcGFyc2VUYWJsZU5vZGUgZ2V0KGk2NCBsLCBpNjQgcikgeyIsCgkJCSAgIiAgICAgICAgaTY0IG1pbmxlbiA9IF9fbGcociAtIGwgKyAxKTsiLAoJCQkgICIgICAgICAgIHJldHVybiBtZXJnZShkcFtsXVttaW5sZW5dLCBkcFtyIC0gKDEgPDwgbWlubGVuKSArIDFdW21pbmxlbl0pOyIsCgkJCSAgIiAgICB9IiwKCQkJICAifTsiCgkJCV0sCgkJCSJkZXNjcmlwdGlvbiI6ICJTcGFyc2VUYWJsZSIKCQkgIH0KCQoJCSAgIlRyaWUiOiB7CgkJCSJwcmVmaXgiOiAiVHJpZSIsCgkJCSJib2R5IjogWwoJCQkgICJjb25zdCBpNjQgbWF4XyA9IDI2OyIsCgkJCSAgInN0cnVjdCBUcmlleyIsCgkJCSAgIiAgICBzdHJ1Y3QgTm9kZXsiLAoJCQkgICIgICAgICAgIE5vZGUgKmNoaWxkW21heF9dOyIsCgkJCSAgIiAgICAgICAgaTY0IGV4aXN0LCBjbnQ7IiwKCQkJICAiICAgICAgICBOb2RlKCkge2ZvcihpMzIgaSA9IDA7IGkgPCBtYXhfOyBpICsrKSBjaGlsZFtpXSA9IE5VTEw7IGV4aXN0ID0gY250ID0gMDt9IiwKCQkJICAiICAgIH07IiwKCQkJICAiICIsCgkJCSAgIiAgICBpNjQgY3VyOyBOb2RlICpyb290OyIsCgkJCSAgIiAgICBUcmllKCkgOiBjdXIoMCkge3Jvb3QgPSBuZXcgTm9kZSgpO307IiwKCQkJICAiICAgIHZvaWQgYWRkKHN0cmluZyBzKSB7IiwKCQkJICAiICAgICAgICBOb2RlICpwID0gcm9vdDsiLAoJCQkgICIgICAgICAgIGZvciAoYXV0byBmIDogcykgeyIsCgkJCSAgIiAgICAgICAgICAgIGk2NCBjID0gZiAtICdhJzsiLAoJCQkgICIgICAgICAgICAgICBpZiAocC0+Y2hpbGRbY10gPT0gTlVMTCkgcC0+Y2hpbGRbY10gPSBuZXcgTm9kZSgpOyIsCgkJCSAgIiAgICAgICAgICAgIHAgPSBwLT5jaGlsZFtjXTsgcC0+Y250Kys7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgICAgICBwLT5leGlzdCsrOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiIiwKCQkJICAiICAgIGJvb2wgZGVsZXRlX3N0cihOb2RlICpwLCBzdHJpbmcmIHMsIGk2NCBpKSB7IiwKCQkJICAiICAgICAgICBpZiAoaSAhPSAoaTY0KXMuc2l6ZSgpKSB7IiwKCQkJICAiICAgICAgICAgICAgaTY0IGMgPSBzW2ldIC0gJ2EnOyIsCgkJCSAgIiAgICAgICAgICAgIGJvb2wgaXNfZGVsZXRlZCA9IGRlbGV0ZV9zdHIocC0+Y2hpbGRbY10sIHMsIGkgKyAxKTsiLAoJCQkgICIgICAgICAgICAgICBpZiAoaXNfZGVsZXRlZCkgcC0+Y2hpbGRbY10gPSBOVUxMOyIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgZWxzZSBwLT5leGlzdC0tOyIsCgkJCSAgIiAgICAgICAgaWYgKHAgIT0gcm9vdCkgeyIsCgkJCSAgIiAgICAgICAgICAgIHAtPmNudC0tOyIsCgkJCSAgIiAgICAgICAgICAgIGlmIChwLT5jbnQgPT0gMCkge2RlbGV0ZShwKTsgcmV0dXJuIHRydWU7fSIsCgkJCSAgIiAgICAgICAgfSIsCgkJCSAgIiAgICAgICAgcmV0dXJuIGZhbHNlOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiICAgIHZvaWQgZXJhc2Uoc3RyaW5nIHMpIHsiLAoJCQkgICIgICAgICAgIGlmIChmaW5kKHMpID09IGZhbHNlKSByZXR1cm47IiwKCQkJICAiICAgICAgICBkZWxldGVfc3RyKHJvb3QsIHMsIDApOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiICAgIGJvb2wgZmluZChzdHJpbmcgcykgeyIsCgkJCSAgIiAgICAgICAgTm9kZSAqcCA9IHJvb3Q7IiwKCQkJICAiICAgICAgICBmb3IgKGF1dG8gZiA6IHMpIHsiLAoJCQkgICIgICAgICAgICAgICBpNjQgYyA9IGYgLSAnYSc7IiwKCQkJICAiICAgICAgICAgICAgaWYgKHAtPmNoaWxkW2NdID09IE5VTEwpIHJldHVybiBmYWxzZTsiLAoJCQkgICIgICAgICAgICAgICBwID0gcC0+Y2hpbGRbY107IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgICAgICByZXR1cm4gKHAtPmV4aXN0ICE9IDApOyIsCgkJCSAgIiAgICB9IiwKCQkJICAifTsiCgkJCV0sCgkJCSJkZXNjcmlwdGlvbiI6ICJUcmllIgoJCSAgfQoJCgkJICAiTElTIjogewoJCQkicHJlZml4IjogIkxJUyIsCgkJCSJib2R5IjogWwoJCQkgICJ2b2lkIHRyYWNlaTY0Uyhjb25zdCB2ZWN0b3I8aTMyPiYgYSwgY29uc3QgdmVjdG9yPGkzMj4mIGRwLCBjb25zdCB2ZWN0b3I8aTMyPiYgYiwgdmVjdG9yPGkzMj4mIHRyYWNlKXsiLAoJCQkgICIgICAgaTMyIHJlcyA9ICptYXhfZWxlbWVudChkcC5iZWdpbigpLCBkcC5lbmQoKSkgKyAxOyIsCgkJCSAgIiAgICBmb3IoaTMyIHAgPSBiLnNpemUoKSAtIDE7IHAgPj0gMDsgcCAtLSkgaWYgKHJlcyA9PSBkcFtwXSArIDEpIHJlcy0tLCB0cmFjZS5wdXNoX2JhY2soYVtwXSk7IiwKCQkJICAiICAgIHJldmVyc2UoYWxsKHRyYWNlKSk7IiwKCQkJICAifSIsCgkJCSAgImk2NCBMSVModmVjdG9yPGkzMj4mIGEsIGJvb2wgd2l0aF90cmFjZSwgdmVjdG9yPGkzMj4mIHRyYWNlKXsiLAoJCQkgICIgICAgaTY0IG4gPSBhLnNpemUoKTsgdmVjdG9yPGkzMj4gYihuLCBpbmYpLCBkcChuLCAwKTsiLAoJCQkgICIgICAgaTY0IHJlcyA9IDE7IiwKCQkJICAiICAgIGZvcihpMzIgaSA9IDA7IGkgPCBuOyBpICsrKSB7IiwKCQkJICAiICAgICAgICBkcFtpXSA9IGxvd2VyX2JvdW5kKGIuYmVnaW4oKSwgYi5iZWdpbigpICsgcmVzLCBhW2ldKSAtIGIuYmVnaW4oKTsiLAoJCQkgICIgICAgICAgIHJlcyA9IG1heChyZXMsIGRwW2ldICsgMSk7IiwKCQkJICAiICAgICAgICBiW2RwW2ldXSA9IGFbaV07IiwKCQkJICAiICAgIH0iLAoJCQkgICIgICAgaWYod2l0aF90cmFjZSkgdHJhY2VpNjRTKGEsIGRwLCBiLCB0cmFjZSk7IiwKCQkJICAiICAgIHJldHVybiByZXM7IiwKCQkJICAifSIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIkxJUyIKCQkgIH0KCQoJCSAgIkxJU3BhaXIiOiB7CgkJCSJwcmVmaXgiOiAiTElTcGFpciIsCgkJCSJib2R5IjogWwoJCQkgICJ2b2lkIHRyYWNlaTY0Uyhjb25zdCB2aWkmIGEsIGNvbnN0IHZlY3RvcjxpMzI+JiBkcCwgY29uc3QgdmVjdG9yPGkzMj4mIGIsIHZpaSYgdHJhY2UpeyIsCgkJCSAgIiAgICBpMzIgcmVzID0gKm1heF9lbGVtZW50KGRwLmJlZ2luKCksIGRwLmVuZCgpKSArIDE7IiwKCQkJICAiICAgIGZvcihpMzIgcCA9IGIuc2l6ZSgpIC0gMTsgcCA+PSAwOyBwIC0tKSBpZiAocmVzID09IGRwW3BdICsgMSkgcmVzLS0sIHRyYWNlLnB1c2hfYmFjayhhW3BdKTsiLAoJCQkgICIgICAgcmV2ZXJzZShhbGwodHJhY2UpKTsiLAoJCQkgICJ9IiwKCQkJICAiIiwKCQkJICAiaTY0IExJUyh2aWkmIGEsIGJvb2wgd2l0aF90cmFjZSwgdmlpJiB0cmFjZSl7IiwKCQkJICAiICAgIGk2NCBuID0gYS5zaXplKCk7IiwKCQkJICAiICAgIHZlY3RvcjxpMzI+IGIobiwgaW5mKSwgZHAobiwgMCk7IiwKCQkJICAiICAgIHNvcnQoYWxsKGEpKTsiLAoJCQkgICIgICAgaTY0IHJlcyA9IDE7IiwKCQkJICAiICAgIGZvcihpMzIgaSA9IDA7IGkgPCBuOyBpICsrKSB7IiwKCQkJICAiICAgICAgICBkcFtpXSA9IGxvd2VyX2JvdW5kKGIuYmVnaW4oKSwgYi5iZWdpbigpICsgcmVzLCBhW2ldLnNlKSAtIGIuYmVnaW4oKTsiLAoJCQkgICIgICAgICAgIHJlcyA9IG1heChyZXMsIGRwW2ldICsgMSk7IiwKCQkJICAiICAgICAgICBiW2RwW2ldXSA9IGFbaV0uc2U7IiwKCQkJICAiICAgIH0iLAoJCQkgICIgICAgaWYod2l0aF90cmFjZSkgdHJhY2VpNjRTKGEsIGRwLCBiLCB0cmFjZSk7IiwKCQkJICAiICAgIHJldHVybiByZXM7IiwKCQkJICAifSIKCQkJXSwKCQkJImRlc2NyaXB0aW9uIjogIkxJU3BhaXIiCgkJICB9CgkKCQkgICJNYXRyaXgiOiB7CiAgInByZWZpeCI6ICJNYXRyaXgiLAogICJib2R5IjogWwogICAgImNsYXNzIE1hdHJpeCB7IiwKICAgICJwcml2YXRlOiIsCiAgICAiICAgIGk2NCByb3csIGNvbDsiLAogICAgIiAgICB2ZWN0b3I8dmVjdG9yPGk2ND4+IGRhdGE7IiwKICAgICIiLAogICAgInB1YmxpYzoiLAogICAgIiAgICBNYXRyaXgoY29uc3QgdmVjdG9yPHZlY3RvcjxpNjQ+PiYgYmFzZSkgeyIsCiAgICAiICAgICAgICByb3cgPSBiYXNlLnNpemUoKTsiLAogICAgIiAgICAgICAgY29sID0gYmFzZVswXS5zaXplKCk7IiwKICAgICIgICAgICAgIGRhdGEgPSBiYXNlOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBNYXRyaXgoaTY0IHIsIGk2NCBjLCBpNjQgdmFsKSA6IHJvdyhyKSwgY29sKGMpLCBkYXRhKHZlY3Rvcjx2ZWN0b3I8aTY0Pj4ociwgdmVjdG9yPGk2ND4oYywgdmFsKSkpIHt9IiwKICAgICIgICAgdm9pZCBmaWxsKGNvbnN0IGk2NCYgdGhhdCl7Zm9yKGkzMiBpID0gMDsgaSA8IGRhdGEuc2l6ZSgpOyBpICsrKSBmb3IoaTMyIGogPSAwOyBqIDwgZGF0YVtpXS5zaXplKCk7IGogKyspIGRhdGFbaV1bal0gPSB0aGF0O30iLAogICAgIiAgICB2b2lkIGZpeChjb25zdCBpNjQmIGN1ciwgY29uc3QgaTY0JiB0aGF0KXsgZm9yKGkzMiBpID0gMDsgaSA8IGRhdGEuc2l6ZSgpOyBpICsrKSBmb3IoaTMyIGogPSAwOyBqIDwgZGF0YVtpXS5zaXplKCk7IGogKyspIGlmKGRhdGFbaV1bal0gPT0gY3VyKSBkYXRhW2ldW2pdID0gdGhhdDt9IiwKICAgICIgICAgTWF0cml4JiBvcGVyYXRvcj0oY29uc3QgTWF0cml4JiB0aGF0KSB7IiwKICAgICIgICAgICAgIGlmICh0aGlzICE9ICZ0aGF0KSB7IiwKICAgICIgICAgICAgICAgICByb3cgPSB0aGF0LnJvdzsiLAogICAgIiAgICAgICAgICAgIGNvbCA9IHRoYXQuY29sOyIsCiAgICAiICAgICAgICAgICAgZGF0YSA9IHRoYXQuZGF0YTsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICByZXR1cm4gKnRoaXM7IiwKICAgICIgICAgfSIsCiAgICAiICAgIHN0YXRpYyBpNjQgbXVsdGlwbHkoaTY0IGEsIGk2NCBiKXsiLAogICAgIiAgICAgICAgaWYoTSA8PSAxZTkgKyA3KSByZXR1cm4gKGEgKiBiKSAlIE07IiwKICAgICIgICAgICAgIGk2NCByZXMgPSAwOyIsCiAgICAiICAgICAgICBhICU9IE07IiwKICAgICIgICAgICAgIHdoaWxlIChiID4gMCkgeyIsCiAgICAiICAgICAgICAgICAgaWYgKGIgJiAxKSIsCiAgICAiICAgICAgICAgICAgICAgIHJlcyA9IChyZXMgKyBhKSAlIE07IiwKICAgICIgICAgICAgICAgICBhID0gKDIgKiBhKSAlIE07IiwKICAgICIgICAgICAgICAgICBiID4+PSAxOyIsCiAgICAiICAgICAgICB9IiwKICAgICIgICAgICAgIHJldHVybiByZXM7IiwKICAgICIgICAgfSIsCiAgICAiIiwKICAgICIgICAgc3RhdGljIGk2NCBjYWwoaTY0IGEsIGk2NCBiKXtyZXR1cm4gKGEgKyBiKSAlIE07fSIsCiAgICAiICAgIE1hdHJpeCBvcGVyYXRvciooY29uc3QgTWF0cml4JiB0aGF0KSBjb25zdCB7IiwKICAgICIgICAgICAgIGlmIChjb2wgIT0gdGhhdC5yb3cpIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcihcInNlZ21lbnRhdGlvbiBmYXVsdFwiKTsiLAogICAgIiAgICAgICAgTWF0cml4IHJlcyhyb3csIHRoYXQuY29sLCAwKTsiLAogICAgIiAgICAgICAgZm9yKGkzMiBpID0gMDsgaSA8IHJvdzsgaSArKykgIiwKICAgICIgICAgICAgICAgICBmb3IoaTMyIGogPSAwOyBqIDwgdGhhdC5jb2w7IGogKyspICIsCiAgICAiICAgICAgICAgICAgICAgIGZvcihpMzIgayA9IDA7IGsgPCBjb2w7IGsgKyspICIsCiAgICAiICAgICAgICAgICAgICAgICAgICByZXMuZGF0YVtpXVtqXSA9IGNhbChyZXMuZGF0YVtpXVtqXSwgbXVsdGlwbHkoZGF0YVtpXVtrXSwgdGhhdC5kYXRhW2tdW2pdKSk7IiwKICAgICIgICAgICAgIHJldHVybiByZXM7IiwKICAgICIgICAgfSIsCiAgICAiICAgIE1hdHJpeCBvcGVyYXRvcl4oaTY0IGV4cCl7IiwKICAgICIgICAgICAgIGk2NCBpID0gcm93OyIsCiAgICAiICAgICAgICBNYXRyaXggcmVzKGksIGksIDApOyIsCiAgICAiICAgICAgICBNYXRyaXggdGVtcCA9ICp0aGlzOyIsCiAgICAiICAgICAgICBmb3IoaTMyIGogPSAwOyBqIDwgaTsgaiArKykgcmVzLmRhdGFbal1bal0gPSAxOyIsCiAgICAiICAgICAgICB3aGlsZSAoZXhwKSB7IiwKICAgICIgICAgICAgICAgICBpZiAoZXhwICYgMSkgcmVzID0gcmVzICogdGVtcDsiLAogICAgIiAgICAgICAgICAgIHRlbXAgPSB0ZW1wICogdGVtcDsiLAogICAgIiAgICAgICAgICAgIGV4cCA+Pj0gMTsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICByZXR1cm4gcmVzOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBNYXRyaXgmIG9wZXJhdG9yKj0oY29uc3QgTWF0cml4JiB0aGF0KSB7IiwKICAgICIgICAgICAgIGlmIChjb2wgIT0gdGhhdC5yb3cpIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcihcInNlZ21lbnRhdGlvbiBmYXVsdFwiKTsiLAogICAgIiAgICAgICAgTWF0cml4IHJlc3VsdCA9ICgqdGhpcykgKiB0aGF0OyIsCiAgICAiICAgICAgICAoKnRoaXMpID0gcmVzdWx0OyIsCiAgICAiICAgICAgICByZXR1cm4gKnRoaXM7IiwKICAgICIgICAgfSIsCiAgICAiICAgIE1hdHJpeCYgb3BlcmF0b3JePShpNjQgZXhwKSB7IiwKICAgICIgICAgICAgIGlmIChleHAgPT0gMCkgeyIsCiAgICAiICAgICAgICAgICAgTWF0cml4IHJlcyhyb3csIGNvbCwgMCk7IiwKICAgICIgICAgICAgICAgICBmb3IoaTMyIGkgPSAwOyBpIDwgcm93OyBpICsrKSByZXNbaV1baV0gPSAxOyIsCiAgICAiICAgICAgICAgICAgKCp0aGlzKSA9IHJlczsiLAogICAgIiAgICAgICAgICAgIHJldHVybiAqdGhpczsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBNYXRyaXggcmVzID0gKnRoaXM7IiwKICAgICIgICAgICAgIGV4cC0tOyIsCiAgICAiICAgICAgICB3aGlsZSAoZXhwID4gMCkgeyIsCiAgICAiICAgICAgICAgICAgaWYgKGV4cCAmIDEpICgqdGhpcykgKj0gcmVzOyIsCiAgICAiICAgICAgICAgICAgcmVzICo9IHJlczsiLAogICAgIiAgICAgICAgICAgIGV4cCA+Pj0gMTsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICByZXR1cm4gKnRoaXM7IiwKICAgICIgICAgfSIsCiAgICAiICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYXRyaXgmIHRoYXQpIGNvbnN0IHsiLAogICAgIiAgICAgICAgaWYgKHJvdyAhPSB0aGF0LnJvdyB8fCBjb2wgIT0gdGhhdC5jb2wpIHJldHVybiBmYWxzZTsiLAogICAgIiAgICAgICAgZm9yKGkzMiBpID0gMDsgaSA8IHJvdzsgaSArKykgIiwKICAgICIgICAgICAgICAgICBmb3IoaTMyIGogPSAwOyBqIDwgY29sOyBqICsrKSAiLAogICAgIiAgICAgICAgICAgICAgICBpZiAoZGF0YVtpXVtqXSAhPSB0aGF0LmRhdGFbaV1bal0pIHJldHVybiBmYWxzZTsiLAogICAgIiAgICAgICAgcmV0dXJuIHRydWU7IiwKICAgICIgICAgfSIsCiAgICAiICAgIGNvbnN0IHZlY3RvcjxpNjQ+JiBvcGVyYXRvcltdKGkzMiBpKSBjb25zdCB7cmV0dXJuIGRhdGFbaV07fSIsCiAgICAiICAgIHZlY3RvcjxpNjQ+JiBvcGVyYXRvcltdKGkzMiBpKSB7cmV0dXJuIGRhdGFbaV07fSIsCiAgICAiICAgIHZvaWQgcHJpbnQoKSBjb25zdCB7IiwKICAgICIgICAgICAgIGZvcihpMzIgaSA9IDA7IGkgPCByb3c7IGkgKyspeyIsCiAgICAiICAgICAgICAgICAgZm9yKGkzMiBqID0gMDsgaiA8IGNvbDsgaiArKyl7IiwKICAgICIgICAgICAgICAgICAgICAgY291dCA8PCBkYXRhW2ldW2pdIDw8IFwiIFwiOyIsCiAgICAiICAgICAgICAgICAgfSIsCiAgICAiICAgICAgICAgICAgY291dCA8PCBlbmRsOyIsCiAgICAiICAgICAgICB9IiwKICAgICIgICAgfSIsCiAgICAifTsiCiAgXSwKICAiZGVzY3JpcHRpb24iOiAiTWF0cml4Igp9CgkKCQkgICJCZXJrbGFtcE1hc3NleSI6IHsKCQkJInByZWZpeCI6ICJCZXJrbGFtcE1hc3NleSIsCgkJCSJib2R5IjogWwoJCQkgICJpNjQgcG93ZXIoaTY0IGJhc2UsIGk2NCBleHAsIGk2NCBtb2QpIHsiLAoJCQkgICIgICAgaTY0IHRlbXAgPSBiYXNlLCByZXMgPSAxOyIsCgkJCSAgIiAgICB3aGlsZSAoZXhwKSB7IiwKCQkJICAiICAgICAgICBpZiAoZXhwICUgMikgcmVzID0gKHJlcyAqIHRlbXApICUgbW9kOyIsCgkJCSAgIiAgICAgICAgdGVtcCA9ICh0ZW1wICogdGVtcCkgJSBtb2Q7IiwKCQkJICAiICAgICAgICBleHAgLz0gMjsiLAoJCQkgICIgICAgfSIsCgkJCSAgIiAgICByZXR1cm4gcmVzOyIsCgkJCSAgIn0iLAoJCQkgICIiLAoJCQkgICJ0ZW1wbGF0ZTx0eXBlbmFtZSBUPiIsCgkJCSAgInZlY3RvcjxUPiBiZXJsZWthbXBNYXNzZXkodmVjdG9yPFQ+IHMpIHsiLAoJCQkgICIgICAgaWYgKHMuZW1wdHkoKSkgcmV0dXJuIHt9OyIsCgkJCSAgIiIsCgkJCSAgIiAgICBpMzIgbiA9IHMuc2l6ZSgpLCBMID0gMCwgbSA9IDA7IC8vIG0gPSBpIC0gZiIsCgkJCSAgIiAgICB2ZWN0b3I8VD4gQyhuKSwgRChuKSwgb2xkQzsiLAoJCQkgICIgICAgQ1swXSA9IERbMF0gPSAxOyIsCgkJCSAgIiAgICBUIGRmMSA9IDE7ICAvLyBkKGYrMSkiLAoJCQkgICIgICAgZm9yIChpMzIgaSA9IDA7IGkgPCBuOyBpKyspIHsiLAoJCQkgICIgICAgICAgICsrbTsiLAoJCQkgICIgICAgICAgIC8vIGNoZWNrIGlmIEMoaSkgPT0gYShpKSIsCgkJCSAgIiAgICAgICAgLy8gZGVsdGEgPSBzX2kgLSBzdW0oIGNqICogcyhpLWopICkgPSBkKGYrMSk/IiwKCQkJICAiICAgICAgICBUIGRlbHRhID0gc1tpXTsiLAoJCQkgICIgICAgICAgIGZvciAoaTMyIGogPSAxOyBqIDw9IEw7IGorKykgeyIsCgkJCSAgIiAgICAgICAgICAgIGRlbHRhICs9IENbal0gKiBzW2ktal07ICAvLyBDKGopIGlzIGFscmVhZHkgbXVsdGlwaTY0ZWQgYnkgLTEiLAoJCQkgICIgICAgICAgICAgICBkZWx0YSAlPSBtb2Q7IiwKCQkJICAiICAgICAgICB9IiwKCQkJICAiICAgICAgICBpZiAoZGVsdGEgPT0gMCkgY29udGludWU7ICAvLyBDKGkpIGlzIGNvcnJlY3QiLAoJCQkgICIiLAoJCQkgICIgICAgICAgIC8vIFVwZGF0ZSBjID0gYyArIGQiLAoJCQkgICIgICAgICAgIG9sZEMgPSBDOyIsCgkJCSAgIiAgICAgICAgVCBjb2VmZiA9IGRlbHRhICogcG93ZXIoZGYxLCBtb2QgLSAyLCBtb2QpICUgbW9kOyIsCgkJCSAgIiAgICAgICAgZm9yIChpMzIgaiA9IG07IGogPCBuOyBqKyspIHsiLAoJCQkgICIgICAgICAgICAgICBDW2pdIC09IGNvZWZmICogRFtqIC0gbV07ICAvLyBwcmVwZW5kIEQgd2l0aCBtIHplcm9lcywgbXVsdGlwbHkgYnkgY29lZmYgYW5kIGFkZCB0byBDIiwKCQkJICAiICAgICAgICAgICAgQ1tqXSA9IChDW2pdICsgbW9kICogbW9kKSAlIG1vZDsiLAoJCQkgICIgICAgICAgIH0iLAoJCQkgICIgICAgICAgIGlmICgyKkwgPiBpKSBjb250aW51ZTsiLAoJCQkgICIgICAgICAgIEwgPSBpICsgMSAtIEwsIEQgPSBvbGRDLCBkZjEgPSBkZWx0YSwgbSA9IDA7IiwKCQkJICAiICAgIH0iLAoJCQkgICIgICAgQy5yZXNpemUoTCArIDEpOyIsCgkJCSAgIiAgICBDLmVyYXNlKEMuYmVnaW4oKSk7IiwKCQkJICAiICAgIGZvciAoYXV0byYgeCA6IEMpIHggPSAteCwgeCA9ICh4ICsgbW9kICogbW9kKSAlIG1vZDsiLAoJCQkgICIgICAgcmV0dXJuIEM7IiwKCQkJICAifSIsCgkJCSAgIiIsCgkJCSAgIi8vIEhlbHBlciBmdW5jdGlvbiIsCgkJCSAgInRlbXBsYXRlPHR5cGVuYW1lIFQ+IiwKCQkJICAidmVjdG9yPFQ+IG11bChjb25zdCB2ZWN0b3I8VD4gJmEsIGNvbnN0IHZlY3RvcjxUPiAmYiwgY29uc3QgdmVjdG9yPFQ+JiBjKSB7IiwKCQkJICAiICAgIHZlY3RvcjxUPiByZXQoYS5zaXplKCkgKyBiLnNpemUoKSAtIDEpOyIsCgkJCSAgIiAgICAvLyByZXQgPSBhICogYiIsCgkJCSAgIiAgICBmb3IgKGkzMiBpPTA7IGk8KGkzMilhLnNpemUoKTsgaSsrKSIsCgkJCSAgIiAgICAgICAgZm9yIChpMzIgaj0wOyBqPChpMzIpYi5zaXplKCk7IGorKykiLAoJCQkgICIgICAgICAgICAgICByZXRbaStqXSArPSBhW2ldICogYltqXSwgcmV0W2kgKyBqXSAlPSBtb2Q7IiwKCQkJICAiIiwKCQkJICAiICAgIGkzMiBuID0gYy5zaXplKCk7IiwKCQkJICAiICAgIC8vIHJlZHVjaW5nIHJldCBtb2QgZih4KSIsCgkJCSAgIiAgICBmb3IgKGkzMiBpPShpMzIpcmV0LnNpemUoKS0xOyBpPj1uOyBpLS0pIiwKCQkJICAiICAgICAgICBmb3IgKGkzMiBqPW4tMTsgaj49MDsgai0tKSIsCgkJCSAgIiAgICAgICAgICAgIHJldFtpLWotMV0gKz0gcmV0W2ldICogY1tqXSwgcmV0W2kgLSBqIC0gMV0gJT0gbW9kOyIsCgkJCSAgIiAgICByZXQucmVzaXplKG1pbigoaTMyKSByZXQuc2l6ZSgpLCBuKSk7IiwKCQkJICAiICAgIHJldHVybiByZXQ7IiwKCQkJICAifSIsCgkJCSAgIiIsCgkJCSAgIi8vIEZpbmQgay10aCBlbGVtZW50IGluIGk2NG5lYXIgcmVjdXJyZW5jZTogTyhkXjIgKiBsb2duKSIsCgkJCSAgIi8vIE5lZWQgZmFzdGVyIGNvZGU/IFNlZSBodHRwczovL2ouLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm8uanAvcHJvYmxlbS9rdGhfdGVybV9vZl9pNjRuZWFybHlfcmVjdXJyZW50X3NlcXVlbmNlIiwKCQkJICAiLy8gICAoYnV0IHVzdWFsbHkgbm90IG5lZWRlZCBzaW5jZSBib3R0bGVuZWNrIGlzIEJlcmxla2FtcE1hc3NleSIsCgkJCSAgIi8vIiwKCQkJICAiLy8gUGFyYW1zOiIsCgkJCSAgIi8vIC0gYzogYXMgcmV0dXJuZWQgYnkgYmVybGVrYW1wTWFzc2V5IiwKCQkJICAiLy8gLSBzOiBzMCwgczEsIC4uLiwgcyhOLTEpIiwKCQkJICAiLy8gUmV0dXJuczogcyhrKSIsCgkJCSAgInRlbXBsYXRlPHR5cGVuYW1lIFQ+IiwKCQkJICAiVCBjaGVjayhjb25zdCB2ZWN0b3I8VD4gJmMsIGNvbnN0IHZlY3RvcjxUPiAmcywgaTY0IGspIHsiLAoJCQkgICIgICAgaTMyIG4gPSAoaTMyKSBjLnNpemUoKTsiLAoJCQkgICIgICAgYXNzZXJ0KGMuc2l6ZSgpIDw9IHMuc2l6ZSgpKTsiLAoJCQkgICIiLAoJCQkgICIgICAgdmVjdG9yPFQ+IGEgPSBuID09IDEgPyB2ZWN0b3I8VD57Y1swXX0gOiB2ZWN0b3I8VD57MCwgMX0sIHh7MX07IiwKCQkJICAiICAgIGZvciAoOyBrPjA7IGsvPTIpIHsiLAoJCQkgICIgICAgICAgIGlmIChrICUgMikiLAoJCQkgICIgICAgICAgICAgICB4ID0gbXVsKHgsIGEsIGMpOyAgLy8gbXVsKGEsIGIpIGNvbXB1dGVzIGEoeCkgKiBiKHgpIG1vZCBmKHgpIiwKCQkJICAiICAgICAgICBhID0gbXVsKGEsIGEsIGMpOyIsCgkJCSAgIiAgICB9IiwKCQkJICAiICAgIHgucmVzaXplKG4pOyIsCgkJCSAgIiIsCgkJCSAgIiAgICBUIHJldCA9IDA7IiwKCQkJICAiICAgIGZvciAoaTMyIGk9MDsgaTxuOyBpKyspIiwKCQkJICAiICAgICAgICByZXQgKz0geFtpXSAqIHNbaV0sIHJldCAlPSBtb2Q7IiwKCQkJICAiICAgIHJldHVybiByZXQ7IiwKCQkJICAifSIsCgkJCSAgIiIsCgkJCSAgIi8vIFJlc3VsdCBmb3IgZltuXSIsCgkJCSAgInRlbXBsYXRlPHR5cGVuYW1lIFQ+IiwKCQkJICAiVCBtYWluX2NhbChjb25zdCB2ZWN0b3I8VD4gJmYsIGk2NCBrKSB7IiwKCQkJICAiICAgIHZlY3RvcjxpNjQ+IGMgPSBiZXJsZWthbXBNYXNzZXkoZik7IiwKCQkJICAiICAgIHJldHVybiBjaGVjayhjLCBmLCBrKTsiLAoJCQkgICJ9IgoJCQldLAoJCQkiZGVzY3JpcHRpb24iOiAiQmVya2xhbXBNYXNzZXkiCgkJICB9CgkKCQkgICJkcHRvb2xzIjogewogICJwcmVmaXgiOiAiZHB0b29scyIsCiAgImJvZHkiOiBbCiAgICAidm9pZCBhZGQoaTMyICZhLCBpMzIgYikge2EgPSAoYSArIGIpICUgTTt9IiwKICAgICJ2b2lkIGdtaW4oaTMyICZhLCBpMzIgYikge2EgPSBtaW4oYSwgYik7fSIsCiAgICAidm9pZCBnbWF4KGkzMiAmYSwgaTMyIGIpIHthID0gbWF4KGEsIGIpO30iLAogICAgImJvb2wgZ2V0KGkzMiBtYXNrLCBpMzIgaWR4KXtyZXR1cm4gKChtYXNrID4+IGlkeCkgJiAxKTt9IiwKICAgICJ2b2lkIHByaW50KGkzMiBtYXNrLCBzdHJpbmcgcykge2JpdHNldDwzPiBhKG1hc2spOyBjb3V0IDw8IGEudG9fc3RyaW5nKCkgPDwgczt9IgogIF0sCiAgImRlc2NyaXB0aW9uIjogImRwdG9vbHMiCn0KCQkgICJUcmVlIjogewogICJwcmVmaXgiOiAiVHJlZSIsCiAgImJvZHkiOiBbCiAgICAiY2xhc3MgVHJlZXsiLAogICAgIiAgICBwcml2YXRlOiIsCiAgICAiICAgICAgICB2djx2djxpMzI+PiB1cDsiLAogICAgIiAgICAgICAgdnY8aTMyPiBoOyIsCiAgICAiICAgICAgICBpMzIgbjsiLAogICAgIiAgICBwdWJsaWM6IiwKICAgICIgICAgICAgIFRyZWUoaTMyIHNpemUsIHZ2PHZ2PGkzMj4+JiBhKSA6IG4oc2l6ZSkgeyIsCiAgICAiICAgICAgICAgICAgdXAgPSB2djx2djxpMzI+PihfX2xnKG4pICsgMSwgdnY8aTMyPihuLCAwKSk7IiwKICAgICIgICAgICAgICAgICBoID0gdnY8aTMyPihuLCAwKTsiLAogICAgIiAgICAgICAgICAgIHF1ZXVlPGkzMj4gcTsgcS5wdXNoKDApOyIsCiAgICAiICAgICAgICAgICAgd2hpbGUgKCFxLmVtcHR5KCkpIHsiLAogICAgIiAgICAgICAgICAgICAgICBpMzIgbm9kZSA9IHEuZnJvbnQoKTsgcS5wb3AoKTsiLAogICAgIiAgICAgICAgICAgICAgICBmb3IgKGF1dG8geCA6IGFbbm9kZV0pIHsiLAogICAgIiAgICAgICAgICAgICAgICAgICAgaWYgKHggPT0gdXBbMF1bbm9kZV0pIGNvbnRpbnVlOyIsCiAgICAiICAgICAgICAgICAgICAgICAgICB1cFswXVt4XSA9IG5vZGU7IiwKICAgICIgICAgICAgICAgICAgICAgICAgIGhbeF0gPSBoW25vZGVdICsgMTsiLAogICAgIiAgICAgICAgICAgICAgICAgICAgcS5wdXNoKHgpOyIsCiAgICAiICAgICAgICAgICAgICAgIH0iLAogICAgIiAgICAgICAgICAgIH0iLAogICAgIiAgICAgICAgICAgIGZvciAoaTE2IGkgPSAxOyBpIDw9IF9fbGcobik7IGkrKykiLAogICAgIiAgICAgICAgICAgICAgICBmb3IgKGkzMiBqID0gMDsgaiA8IG47IGorKykiLAogICAgIiAgICAgICAgICAgICAgICAgICAgdXBbaV1bal0gPSB1cFtpIC0gMV1bdXBbaSAtIDFdW2pdXTsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBpMzIgbGNhKGkzMiB1LCBpMzIgdikgeyIsCiAgICAiICAgICAgICAgICAgaWYgKGhbdV0gPiBoW3ZdKSBzd2FwKHUsIHYpOyIsCiAgICAiICAgICAgICAgICAgaWYgKGhbdV0gIT0gaFt2XSkgeyIsCiAgICAiICAgICAgICAgICAgICAgIGkzMiBkaWYgPSBoW3ZdIC0gaFt1XTsiLAogICAgIiAgICAgICAgICAgICAgICBmb3IgKGkxNiBpID0gX19sZyhkaWYpOyBpID49IDA7IGktLSkiLAogICAgIiAgICAgICAgICAgICAgICAgICAgaWYgKGRpZiA+PSAoMSA8PCBpKSkgdiA9IHVwW2ldW3ZdLCBkaWYgLT0gKDEgPDwgaSk7IiwKICAgICIgICAgICAgICAgICB9IiwKICAgICIgICAgICAgICAgICBpZiAodSA9PSB2KSByZXR1cm4gdTsiLAogICAgIiAgICAgICAgICAgIGZvciAoaTE2IGkgPSBfX2xnKG4pOyBpID49IDA7IGktLSkiLAogICAgIiAgICAgICAgICAgICAgICBpZiAodXBbaV1bdV0gIT0gdXBbaV1bdl0pIiwKICAgICIgICAgICAgICAgICAgICAgICAgIHUgPSB1cFtpXVt1XSwgdiA9IHVwW2ldW3ZdOyIsCiAgICAiICAgICAgICAgICAgcmV0dXJuIHVwWzBdW3VdOyIsCiAgICAiICAgICAgICB9IiwKICAgICJ9OyIsCiAgICAiIgogIF0sCiAgImRlc2NyaXB0aW9uIjogIlRyZWUiCn0KCiJEaXNqb2ludFNldHMiOiB7CiAgInByZWZpeCI6ICJEaXNqb2ludFNldHMiLAogICJib2R5IjogWwogICAgInN0cnVjdCBTYXZlIHsiLAogICAgIiAgICBpMzIgdiwgcm5rdiwgdSwgcm5rdTsiLAogICAgIiAgICBTYXZlKCkge30iLAogICAgIiAgICBTYXZlKGkzMiBfdiwgaTMyIF9ybmt2LCBpMzIgX3UsIGkzMiBfcm5rdSkiLAogICAgIiAgICAgICAgOiB2KF92KSwgcm5rdihfcm5rdiksIHUoX3UpLCBybmt1KF9ybmt1KSB7fSIsCiAgICAifTsiLAogICAgInN0cnVjdCBEaXNqb2ludFNldHMgeyIsCiAgICAiICAgIHZlY3RvcjxpMzI+IHBhciwgcmFuazsiLAogICAgIiAgICBpMzIgY29tcHM7IiwKICAgICIgICAgdmVjdG9yPFNhdmU+IGhpc3Rvcnk7IiwKICAgICIiLAogICAgIiAgICBEaXNqb2ludFNldHMoKSB7fSIsCiAgICAiICAgIERpc2pvaW50U2V0cyhpMzIgbikgeyIsCiAgICAiICAgICAgICBwYXIucmVzaXplKG4pOyByYW5rLnJlc2l6ZShuLCAwKTsiLAogICAgIiAgICAgICAgZm9yIChpMzIgaSA9IDA7IGkgPCBuOyBpKyspIHBhcltpXSA9IGk7IiwKICAgICIgICAgICAgIGNvbXBzID0gbjsiLAogICAgIiAgICB9IiwKICAgICIiLAogICAgIiAgICBpMzIgcm9vdChpMzIgdikgeyIsCiAgICAiICAgICAgICByZXR1cm4gKHYgPT0gcGFyW3ZdKSA/IHYgOiByb290KHBhclt2XSk7IiwKICAgICIgICAgfSIsCiAgICAiIiwKICAgICIgICAgYm9vbCBtZXJnZShpMzIgdiwgaTMyIHUpIHsiLAogICAgIiAgICAgICAgdiA9IHJvb3Qodik7IHUgPSByb290KHUpOyIsCiAgICAiICAgICAgICBpZiAodiA9PSB1KSByZXR1cm4gZmFsc2U7IiwKICAgICIgICAgICAgIGNvbXBzLS07IiwKICAgICIgICAgICAgIGlmIChyYW5rW3ZdID4gcmFua1t1XSkgc3dhcCh2LCB1KTsiLAogICAgIiAgICAgICAgaGlzdG9yeS5wdXNoX2JhY2soU2F2ZSh2LCByYW5rW3ZdLCB1LCByYW5rW3VdKSk7IiwKICAgICIgICAgICAgIHBhclt2XSA9IHU7IiwKICAgICIgICAgICAgIGlmIChyYW5rW3VdID09IHJhbmtbdl0pIHJhbmtbdV0gKys7IiwKICAgICIgICAgICAgIHJldHVybiB0cnVlOyIsCiAgICAiICAgIH0iLAogICAgIiIsCiAgICAiICAgIHZvaWQgcm9sbGJhY2soKSB7IiwKICAgICIgICAgICAgIGlmIChoaXN0b3J5LmVtcHR5KCkpIHJldHVybjsiLAogICAgIiAgICAgICAgU2F2ZSB4ID0gaGlzdG9yeS5iYWNrKCk7IiwKICAgICIgICAgICAgIGhpc3RvcnkucG9wX2JhY2soKTsiLAogICAgIiAgICAgICAgcGFyW3gudl0gPSB4LnY7IHJhbmtbeC52XSA9IHgucm5rdjsiLAogICAgIiAgICAgICAgcGFyW3gudV0gPSB4LnU7IHJhbmtbeC51XSA9IHgucm5rdTsiLAogICAgIiAgICAgICAgY29tcHMrKzsiLAogICAgIiAgICB9IiwKICAgICJ9OyIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJEaXNqb2ludFNldHMiCn0KIlNxcnREZWNvbXBvc2l0aW9uIjogewogICJwcmVmaXgiOiAiU3FydERlY29tcG9zaXRpb24iLAogICJib2R5IjogWwogICAgInZlY3Rvcjx2ZWN0b3I8aTMyPj4gYmxvY2tzOyIsCiAgICAidmVjdG9yPHZlY3RvcjxpMzI+PiBibG9ja19mcmVxOyIsCiAgICAiaTMyIGJsb2NrX3NpemU7IGkzMiBzcV90ZW1wW05dOyIsCiAgICAidm9pZCBzcXJ0X2RlY29tcG9zaXRpb24oaTMyIG4sIGkzMiBrKSB7IiwKICAgICIgICAgYmxvY2tfc2l6ZSA9IHNxcnQobik7IiwKICAgICIgICAgYmxvY2tzLnJlc2l6ZSgobiArIGJsb2NrX3NpemUgLSAxKSAvIGJsb2NrX3NpemUpOyIsCiAgICAiICAgIGJsb2NrX2ZyZXEucmVzaXplKGJsb2Nrcy5zaXplKCksIHZlY3RvcjxpMzI+KGspKTsiLAogICAgIiAgICBmb3IoaTMyIGkgPSAwOyBpIDwgbjsgaSsrKSB7IiwKICAgICIgICAgICAgIGJsb2Nrc1tpIC8gYmxvY2tfc2l6ZV0ucHVzaF9iYWNrKHNxX3RlbXBbaV0pOyIsCiAgICAiICAgICAgICBibG9ja19mcmVxW2kgLyBibG9ja19zaXplXVtzcV90ZW1wW2ldXSsrOyIsCiAgICAiICAgIH0iLAogICAgIn0iLAogICAgImkzMiBzcXJ0X3F1ZXJ5KGkzMiBxX2wsIGkzMiBxX3IsIGkzMiBrKSB7IiwKICAgICIgICAgaTMyIGJsb2NrX2wgPSBxX2wgLyBibG9ja19zaXplOyIsCiAgICAiICAgIGkzMiBibG9ja19yID0gcV9yIC8gYmxvY2tfc2l6ZSwgY250ID0gMDsiLAogICAgIiAgICBpZiAoYmxvY2tfbCA9PSBibG9ja19yKSB7IiwKICAgICIgICAgICAgIGZvciAoaTMyIGkgPSBxX2w7IGkgPD0gcV9yOyBpKyspICIsCiAgICAiICAgICAgICAgICAgaWYoc3FfdGVtcFtpXSA8IGspIGNudCArKzsiLAogICAgIiAgICB9ICIsCiAgICAiICAgIGVsc2UgeyIsCiAgICAiICAgICAgICBmb3IgKGkzMiBpID0gcV9sOyBpIDwgKGJsb2NrX2wgKyAxKSAqIGJsb2NrX3NpemU7IGkrKykgIiwKICAgICIgICAgICAgICAgICBpZihzcV90ZW1wW2ldIDwgaykgY250Kys7IiwKICAgICIgICAgICAgIGZvciAoaTMyIGkgPSBibG9ja19sICsgMTsgaSA8IGJsb2NrX3I7IGkrKykgIiwKICAgICIgICAgICAgICAgICBmb3IgKGkzMiBqID0gMDsgaiA8IGs7IGorKykgIiwKICAgICIgICAgICAgICAgICAgICAgY250ICs9IGJsb2NrX2ZyZXFbaV1bal07IiwKICAgICIgICAgICAgIGZvciAoaTMyIGkgPSBibG9ja19yICogYmxvY2tfc2l6ZTsgaSA8PSBxX3I7IGkrKykgIiwKICAgICIgICAgICAgICAgICBpZihzcV90ZW1wW2ldIDwgaykgY250ICsrOyIsCiAgICAiICAgIH0iLAogICAgIiAgICByZXR1cm4gY250OyIsCiAgICAifSIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJTcXJ0RGVjb21wb3NpdGlvbiIKfQoKIkZlbndpY2tUcmVlIjogewogICJwcmVmaXgiOiAiRmVud2lja1RyZWUiLAogICJib2R5IjogWwogICAgInN0cnVjdCBGZW53aWNrVHJlZSB7IiwKICAgICIgICAgdmVjdG9yPGk2ND4gbm9kZTsiLAogICAgIiAgICBGZW53aWNrVHJlZShpMzIgbikgOiBub2RlKG4gKyA4LCAwKSB7fSIsCiAgICAiICAgIHZvaWQgdXBkYXRlKGkzMiBwb3MsIGk2NCB2YWwpIHsiLAogICAgIiAgICAgICAgZm9yICg7IHBvcyA8IG5vZGUuc2l6ZSgpOyBwb3MgKz0gcG9zICYgLXBvcykgIiwKICAgICIgICAgICAgICAgICBub2RlW3Bvc10gKz0gdmFsOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBpNjQgZ2V0U3VtKGkzMiBwb3MpIHsiLAogICAgIiAgICAgICAgaTY0IHJlcyA9IDA7IiwKICAgICIgICAgICAgIGZvciAoOyBwb3MgPiAwOyBwb3MgLT0gcG9zICYgLXBvcykgIiwKICAgICIgICAgICAgICAgICByZXMgKz0gbm9kZVtwb3NdOyIsCiAgICAiICAgICAgICByZXR1cm4gcmVzOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBpNjQgZ2V0KGkzMiBsLCBpMzIgcikgeyIsCiAgICAiICAgICAgICByZXR1cm4gZ2V0U3VtKHIpIC0gZ2V0U3VtKGwgLSAxKTsiLAogICAgIiAgICB9IiwKICAgICJ9OyIsCiAgICAiIgogIF0sCiAgImRlc2NyaXB0aW9uIjogIkZlbndpY2tUcmVlIgp9CgoiRmVud2lja1RyZWUyRCI6IHsKICAicHJlZml4IjogIkZlbndpY2tUcmVlMkQiLAogICJib2R5IjogWwogICAgInN0cnVjdCBGZW53aWNrVHJlZTJEIHsiLAogICAgIiAgICB2ZWN0b3I8dmVjdG9yPGk2ND4+IG5vZGU7IiwKICAgICIgICAgRmVud2lja1RyZWUyRChpMzIgbiwgaTMyIG0pIDogbm9kZShuICsgOCwgdmVjdG9yPGk2ND4obSArIDgsIDApKSB7fSIsCiAgICAiICAgIHZvaWQgdXBkYXRlKGkzMiB4LCBpMzIgeSwgaTY0IHZhbCkgeyIsCiAgICAiICAgICAgICBmb3IgKGkzMiBpID0geDsgaSA8IG5vZGUuc2l6ZSgpOyBpICs9IGkgJiAtaSkgIiwKICAgICIgICAgICAgICAgICBmb3IgKGkzMiBqID0geTsgaiA8IG5vZGVbMF0uc2l6ZSgpOyBqICs9IGogJiAtaikgIiwKICAgICIgICAgICAgICAgICAgICAgbm9kZVtpXVtqXSArPSB2YWw7IiwKICAgICIgICAgfSIsCiAgICAiICAgIGk2NCBnZXRTdW0oaTMyIHgsIGkzMiB5KSB7IiwKICAgICIgICAgICAgIGk2NCByZXMgPSAwOyIsCiAgICAiICAgICAgICBmb3IgKGkzMiBpID0geDsgaSA+IDA7IGkgLT0gaSAmIC1pKSAiLAogICAgIiAgICAgICAgICAgIGZvciAoaTMyIGogPSB5OyBqID4gMDsgaiAtPSBqICYgLWopICIsCiAgICAiICAgICAgICAgICAgICAgIHJlcyArPSBub2RlW2ldW2pdOyIsCiAgICAiICAgICAgICByZXR1cm4gcmVzOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBpNjQgZ2V0KGkzMiB4MSwgaTMyIHkxLCBpMzIgeDIsIGkzMiB5MikgeyIsCiAgICAiICAgICAgICByZXR1cm4gZ2V0U3VtKHgyLCB5MikgLSBnZXRTdW0oeDEgLSAxLCB5MikgLSBnZXRTdW0oeDIsIHkxIC0gMSkgKyBnZXRTdW0oeDEgLSAxLCB5MSAtIDEpOyIsCiAgICAiICAgIH0iLAogICAgIn07IiwKICAgICIiCiAgXSwKICAiZGVzY3JpcHRpb24iOiAiRmVud2lja1RyZWUyRCIKfQoKIkZlbndpY2tUcmVlM0QiOiB7CiAgInByZWZpeCI6ICJGZW53aWNrVHJlZTNEIiwKICAiYm9keSI6IFsKICAgICJzdHJ1Y3QgRmVud2lja1RyZWUzRCB7IiwKICAgICIgICAgdmVjdG9yPHZlY3Rvcjx2ZWN0b3I8aTY0Pj4+IG5vZGU7IiwKICAgICIgICAgRmVud2lja1RyZWUzRChpMzIgbiwgaTMyIG0sIGkzMiBwKSA6IG5vZGUobiArIDgsIHZlY3Rvcjx2ZWN0b3I8aTY0Pj4obSArIDgsIHZlY3RvcjxpNjQ+KHAgKyA4LCAwKSkpIHt9IiwKICAgICIgICAgIiwKICAgICIgICAgdm9pZCB1cGRhdGUoaTMyIHgsIGkzMiB5LCBpMzIgeiwgaTY0IHZhbCkgeyIsCiAgICAiICAgICAgICBmb3IgKGkzMiBpID0geDsgaSA8IG5vZGUuc2l6ZSgpOyBpICs9IGkgJiAtaSkgIiwKICAgICIgICAgICAgICAgICBmb3IgKGkzMiBqID0geTsgaiA8IG5vZGVbMF0uc2l6ZSgpOyBqICs9IGogJiAtaikgIiwKICAgICIgICAgICAgICAgICAgICAgZm9yIChpMzIgayA9IHo7IGsgPCBub2RlWzBdWzBdLnNpemUoKTsgayArPSBrICYgLWspICIsCiAgICAiICAgICAgICAgICAgICAgICAgICBub2RlW2ldW2pdW2tdICs9IHZhbDsiLAogICAgIiAgICB9IiwKICAgICIiLAogICAgIiAgICBpNjQgZ2V0U3VtKGkzMiB4LCBpMzIgeSwgaTMyIHopIHsiLAogICAgIiAgICAgICAgaTY0IHJlcyA9IDA7IiwKICAgICIgICAgICAgIGZvciAoaTMyIGkgPSB4OyBpID4gMDsgaSAtPSBpICYgLWkpICIsCiAgICAiICAgICAgICAgICAgZm9yIChpMzIgaiA9IHk7IGogPiAwOyBqIC09IGogJiAtaikgIiwKICAgICIgICAgICAgICAgICAgICAgZm9yIChpMzIgayA9IHo7IGsgPiAwOyBrIC09IGsgJiAtaykgIiwKICAgICIgICAgICAgICAgICAgICAgICAgIHJlcyArPSBub2RlW2ldW2pdW2tdOyIsCiAgICAiICAgICAgICByZXR1cm4gcmVzOyIsCiAgICAiICAgIH0iLAogICAgIiAgICAiLAogICAgIiAgICBpNjQgZ2V0KGkzMiB4MSwgaTMyIHkxLCBpMzIgejEsIGkzMiB4MiwgaTMyIHkyLCBpMzIgejIpIHsiLAogICAgIiAgICAgICAgcmV0dXJuIGdldFN1bSh4MiwgeTIsIHoyKSAiLAogICAgIiAgICAgICAgICAgIC0gZ2V0U3VtKHgxIC0gMSwgeTIsIHoyKSAtIGdldFN1bSh4MiwgeTEgLSAxLCB6MikgLSBnZXRTdW0oeDIsIHkyLCB6MSAtIDEpIiwKICAgICIgICAgICAgICAgICArIGdldFN1bSh4MSAtIDEsIHkxIC0gMSwgejIpICsgZ2V0U3VtKHgxIC0gMSwgeTIsIHoxIC0gMSkgKyBnZXRTdW0oeDIsIHkxIC0gMSwgejEgLSAxKSIsCiAgICAiICAgICAgICAgICAgLSBnZXRTdW0oeDEgLSAxLCB5MSAtIDEsIHoxIC0gMSk7IiwKICAgICIgICAgfSIsCiAgICAifTsiLAogICAgIiIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJGZW53aWNrVHJlZTNEIgp9CgoiRmFzdFNldCI6IHsKICAicHJlZml4IjogIkZhc3RTZXQiLAogICJib2R5IjogWwogICAgInN0cnVjdCBGYXN0U2V0IHsiLAogICAgIiAgICBzdGF0aWMgY29uc3RleHByIGkzMiBCQVNFID0gNjsiLAogICAgIiAgICBzdGF0aWMgY29uc3RleHByIGkzMiBSQU5HRSA9IDEgPDwgQkFTRTsiLAogICAgIiAgICBzdGF0aWMgY29uc3RleHByIGkzMiBGSUxURVIgPSBSQU5HRSAtIDE7IiwKICAgICIgICAgaTMyIE4sIGxvZzsiLAogICAgIiAgICB2ZWN0b3I8dmVjdG9yPGk2ND4+IHNlZzsiLAogICAgIiIsCiAgICAiICAgIEZhc3RTZXQoaTMyIF9OID0gMCwgYm9vbCB2YWwgPSAwKSB7IGJ1aWxkKF9OLCB2YWwpOyB9IiwKICAgICIgICAgIiwKICAgICIgICAgdm9pZCBidWlsZChpMzIgX04gPSAwLCBib29sIHZhbCA9IDApIHsiLAogICAgIiAgICAgICAgc2VnLmNsZWFyKCk7IE4gPSBfTiwgbG9nID0gMDsiLAogICAgIiAgICAgICAgd2hpbGUodHJ1ZSkgeyIsCiAgICAiICAgICAgICAgICAgc2VnLmVtcGxhY2VfYmFjaygoX04gKyBGSUxURVIpID4+IEJBU0UsICh2YWwgPyB+MHVsbCA6IDB1bGwpKTsgKytsb2c7IiwKICAgICIgICAgICAgICAgICBpZihzZWcuYmFjaygpLnNpemUoKSA8PSAxKSBicmVhazsiLAogICAgIiAgICAgICAgICAgIF9OID0gc2VnLmJhY2soKS5zaXplKCk7IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICB9IiwKICAgICIgICAgIiwKICAgICIgICAgdm9pZCBpbnNlcnQoaTMyIGspIHsiLAogICAgIiAgICAgICAgaTMyIGlkID0gayA+PiBCQVNFOyIsCiAgICAiICAgICAgICBmb3IoaTMyIGkgPSAwOyBpIDwgc2VnLnNpemUoKTsgKytpLCBrID4+PSBCQVNFLCBpZCA+Pj0gQkFTRSkgeyIsCiAgICAiICAgICAgICAgICAgaWYoc2VnW2ldW2lkXSA+PiAoayAmIEZJTFRFUikgJiAxKSBicmVhazsiLAogICAgIiAgICAgICAgICAgIHNlZ1tpXVtpZF0gfD0gaTY0KDEpIDw8IChrICYgRklMVEVSKTsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgIH0iLAogICAgIiIsCiAgICAiICAgIHZvaWQgZXJhc2UoaTMyIGspIHsiLAogICAgIiAgICAgICAgaWYoISgqdGhpcylba10pIHJldHVybjsiLAogICAgIiAgICAgICAgaTMyIGlkID0gayA+PiBCQVNFOyIsCiAgICAiICAgICAgICBmb3IoaTMyIGkgPSAwOyBpIDwgc2VnLnNpemUoKTsgKytpLCBrID4+PSBCQVNFLCBpZCA+Pj0gQkFTRSkgeyIsCiAgICAiICAgICAgICAgICAgc2VnW2ldW2lkXSBePSBpNjQoMSkgPDwgKGsgJiBGSUxURVIpOyIsCiAgICAiICAgICAgICAgICAgaWYoYm9vbChzZWdbaV1baWRdKSkgYnJlYWs7IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICB9IiwKICAgICIiLAogICAgIiAgICBib29sIG9wZXJhdG9yW10oaTMyIGspIHsiLAogICAgIiAgICAgICAgYXNzZXJ0KDAgPD0gayAmJiBrIDwgTik7IiwKICAgICIgICAgICAgIHJldHVybiBzZWdbMF1bayA+PiBCQVNFXSA+PiAoayAmIEZJTFRFUikgJiAxOyIsCiAgICAiICAgIH0iLAogICAgIiIsCiAgICAiICAgIGkzMiBuZXh0KGkzMiBrKSB7IiwKICAgICIgICAgICAgIGkzMiBpZCA9IGsgPj4gQkFTRTsiLAogICAgIiAgICAgICAgZm9yKGkzMiBpID0gMDsgaSA8IHNlZy5zaXplKCk7ICsraSkgeyIsCiAgICAiICAgICAgICAgICAgaWYoKGlkID0gKGsgPj4gQkFTRSkpID49IHNlZ1tpXS5zaXplKCkpIGJyZWFrOyIsCiAgICAiICAgICAgICAgICAgaTY0IHggPSBzZWdbaV1baWRdID4+IChrICYgRklMVEVSKTsiLAogICAgIiAgICAgICAgICAgIGlmKCF4KSB7IGsgPSBpZCArIDE7IGNvbnRpbnVlOyB9IiwKICAgICIgICAgICAgICAgICBrICs9IF9fYnVpbHRpbl9jdHpsbCh4KTsiLAogICAgIiAgICAgICAgICAgIGZvcihpMzIgaiA9IGkgLSAxOyBqID49IDA7IC0taikgayA9IChrIDw8IDYpIHwgX19idWlsdGluX2N0emxsKHNlZ1tqXVtrXSk7IiwKICAgICIgICAgICAgICAgICByZXR1cm4gazsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICByZXR1cm4gTjsiLAogICAgIiAgICB9IiwKICAgICIiLAogICAgIiAgICBpMzIgcHJldihpMzIgaykgeyIsCiAgICAiICAgICAgICBrID0gbWluKGssIE4gLSAxKTsiLAogICAgIiAgICAgICAgaTMyIGlkOyIsCiAgICAiICAgICAgICBmb3IoaTMyIGkgPSAwOyBpIDwgc2VnLnNpemUoKTsgKytpKSB7IiwKICAgICIgICAgICAgICAgICBpZihrIDwgMCkgYnJlYWs7IiwKICAgICIgICAgICAgICAgICBpNjQgeCA9IHNlZ1tpXVtpZCA9IChrID4+IEJBU0UpXSA8PCAoRklMVEVSIC0gKGsgJiBGSUxURVIpKTsiLAogICAgIiAgICAgICAgICAgIGlmKCF4KSB7IGsgPSBpZCAtIDE7IGNvbnRpbnVlOyB9IiwKICAgICIgICAgICAgICAgICBrIC09IF9fYnVpbHRpbl9jbHoKCWxsKHgpOyIsCiAgICAiICAgICAgICAgICAgZm9yKGkzMiBqID0gaSAtIDE7IGogPj0gMDsgLS1qKSBrID0gKGsgPDwgQkFTRSkgfCAoRklMVEVSIC0gX19idWlsdGluX2NsemxsKHNlZ1tqXVtrXSkpOyIsCiAgICAiICAgICAgICAgICAgcmV0dXJuIGs7IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICAgICAgcmV0dXJuIC0xOyIsCiAgICAiICAgIH0iLAogICAgIn07IgogIF0sCiAgImRlc2NyaXB0aW9uIjogIkZhc3RTZXQiCn0KIkNvbnZleEh1bGxUcmljayI6IHsKICAicHJlZml4IjogIkNvbnZleEh1bGxUcmljayIsCiAgImJvZHkiOiBbCiAgICAic3RydWN0IExpbmUgeyIsCiAgICAiICAgIG11dGFibGUgaTY0IGssIG0sIHA7IiwKICAgICIgICAgYm9vbCBvcGVyYXRvcjwoY29uc3QgTGluZSYgbykgY29uc3Qge3JldHVybiBrIDwgby5rO30iLAogICAgIiAgICBib29sIG9wZXJhdG9yPChpNjQgeCkgY29uc3Qge3JldHVybiBwIDwgeDt9IiwKICAgICJ9OyIsCiAgICAic3RydWN0IENvbnZleEh1bGxUcmljayA6IG11bHRpc2V0PExpbmUsIGxlc3M8Pj4geyIsCiAgICAiICAgIHN0YXRpYyBjb25zdCBpNjQgSU5GID0gTExPTkdfTUFYOyIsCiAgICAiICAgIGk2NCBkaXYoaTY0IGEsIGk2NCBiKSB7IiwKICAgICIgICAgICAgIHJldHVybiBhIC8gYiAtICgoYSBeIGIpIDwgMCAmJiBhICUgYik7ICIsCiAgICAiICAgIH0iLAogICAgIiAgICBib29sIGlzZWN0KGl0ZXJhdG9yIHgsIGl0ZXJhdG9yIHkpIHsiLAogICAgIiAgICAgICAgaWYgKHkgPT0gZW5kKCkpIHJldHVybiB4LT5wID0gSU5GLCAwOyIsCiAgICAiICAgICAgICBpZiAoeC0+ayA9PSB5LT5rKSB4LT5wID0geC0+bSA+IHktPm0gPyBJTkYgOiAtSU5GOyIsCiAgICAiICAgICAgICBlbHNlIHgtPnAgPSBkaXYoeS0+bSAtIHgtPm0sIHgtPmsgLSB5LT5rKTsiLAogICAgIiAgICAgICAgcmV0dXJuIHgtPnAgPj0geS0+cDsiLAogICAgIiAgICB9IiwKICAgICIgICAgdm9pZCBwdXNoKGk2NCBrLCBpNjQgbSkgeyIsCiAgICAiICAgICAgICBhdXRvIHogPSBpbnNlcnQoe2ssIG0sIDB9KSwgeSA9IHogKyssIHggPSB5OyIsCiAgICAiICAgICAgICB3aGlsZSAoaXNlY3QoeSwgeikpIHogPSBlcmFzZSh6KTsiLAogICAgIiAgICAgICAgaWYgKHggIT0gYmVnaW4oKSAmJiBpc2VjdCgtLSB4LCB5KSkgaXNlY3QoeCwgeSA9IGVyYXNlKHkpKTsiLAogICAgIiAgICAgICAgd2hpbGUgKCh5ID0geCkgIT0gYmVnaW4oKSAmJiAoLS0geCktPnAgPj0geS0+cCkiLAogICAgIiAgICAgICAgaXNlY3QoeCwgZXJhc2UoeSkpOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBpNjQgZ2V0KGk2NCB4KSB7IiwKICAgICIgICAgICAgIGFzc2VydCghZW1wdHkoKSk7IiwKICAgICIgICAgICAgIGF1dG8gbCA9ICpsb3dlcl9ib3VuZCh4KTsiLAogICAgIiAgICAgICAgcmV0dXJuIGwuayAqIHggKyBsLm07IiwKICAgICIgICAgfSIsCiAgICAifTsiLAogICAgIiIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJDb252ZXhIdWxsVHJpY2siCn0KIkZhc3RTZWdtZW50VHJlZSI6IHsKICAicHJlZml4IjogIkZhc3RTZWdtZW50VHJlZSIsCiAgImJvZHkiOiBbCiAgICAiI2luY2x1ZGUgPGltbWludHJpbi5oPiAiLAogICAgImNvbnN0IGludCBfU0laRSA9IDEgPDwgMjAsIElORiA9IDFlOSArIDk7IiwKICAgICJ1c2luZyBUID0gdWludDMyX3Q7IiwKICAgICJUIHN0WzIgKiBfU0laRV07ICIsCiAgICAiY29uc3QgVCBpZGVudGl0eV9lbGVtZW50ID0gSU5GOyAgIiwKICAgICJfX2F0dHJpYnV0ZV9fKCh0YXJnZXQoXCJhdngyXCIpKSkgX19tMjU2aSByZWR1Y2UoX19tMjU2aSBhLCBfX20yNTZpIGIpIHsiLAogICAgIiAgICByZXR1cm4gX21tMjU2X21pbl9lcGkzMihhLCBiKTsiLAogICAgIn0iLAogICAgIlQgcmVkdWNlKFQgYSwgVCBiKSB7IiwKICAgICIgICAgcmV0dXJuIG1pbihhLCBiKTsiLAogICAgIn0iLAogICAgInZvaWQgYnVpbGQoaW50IG4sIGNvbnN0IFQgYVtdKSB7IiwKICAgICIgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHN0W2kgKyBfU0laRV0gPSBhW2kgKyAxXTsiLAogICAgIiAgICBmb3IgKGludCBpID0gX1NJWkUgLSAxOyBpID4gMDsgaS0tKSB7IiwKICAgICIgICAgICAgIHN0W2ldID0gcmVkdWNlKHN0W2kgPDwgMV0sIHN0W2kgPDwgMSB8IDFdKTsiLAogICAgIiAgICB9IiwKICAgICJ9IiwKICAgICJfX2F0dHJpYnV0ZV9fKCh0YXJnZXQoXCJhdngyXCIpKSkgVCBxdWVyeV9wYXJhbGxlbChpbnQgbCwgaW50IHIpIHsiLAogICAgIiAgICBUIHJlcyA9IGlkZW50aXR5X2VsZW1lbnQ7IiwKICAgICIgICAgbCArPSBfU0laRSwgciArPSBfU0laRTsiLAogICAgIiAgICBfX20yNTZpIHZlY19yZXMgPSBfbW0yNTZfc2V0MV9lcGkzMihyZXMpOyAgIiwKICAgICIiLAogICAgIiAgICB3aGlsZSAobCA8PSByKSB7IiwKICAgICIgICAgICAgIGlmIChsICYgMSkgeyIsCiAgICAiICAgICAgICAgICAgX19tMjU2aSB2ZWNfbCA9IF9tbTI1Nl9zZXQxX2VwaTMyKHN0W2xdKTsiLAogICAgIiAgICAgICAgICAgIHZlY19yZXMgPSByZWR1Y2UodmVjX3JlcywgdmVjX2wpOyAiLAogICAgIiAgICAgICAgICAgICsrbDsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBpZiAoIShyICYgMSkpIHsiLAogICAgIiAgICAgICAgICAgIF9fbTI1NmkgdmVjX3IgPSBfbW0yNTZfc2V0MV9lcGkzMihzdFtyXSk7IiwKICAgICIgICAgICAgICAgICB2ZWNfcmVzID0gcmVkdWNlKHZlY19yZXMsIHZlY19yKTsgICIsCiAgICAiICAgICAgICAgICAgLS1yOyIsCiAgICAiICAgICAgICB9IiwKICAgICIgICAgICAgIGwgPj49IDEsIHIgPj49IDE7IiwKICAgICIgICAgfSIsCiAgICAiIiwKICAgICIgICAgVCByZXN1bHRbOF07IiwKICAgICIgICAgX21tMjU2X3N0b3JldV9zaTI1NigoX19tMjU2aSopcmVzdWx0LCB2ZWNfcmVzKTsiLAogICAgIiAgICBmb3IgKGludCBpID0gMDsgaSA8IDg7IGkrKykgeyIsCiAgICAiICAgICAgICByZXMgPSByZWR1Y2UocmVzLCByZXN1bHRbaV0pOyIsCiAgICAiICAgIH0iLAogICAgIiAgICByZXR1cm4gcmVzOyIsCiAgICAifSIsCiAgICAidm9pZCB1cGQoaW50IHAsIFQgdmFsKSB7IiwKICAgICIgICAgZm9yIChzdFtwICs9IF9TSVpFXSA9IHZhbDsgcCA+IDE7IHAgPj49IDEpIHsiLAogICAgIiAgICAgICAgc3RbcCA+PiAxXSA9IHJlZHVjZShzdFtwXSwgc3RbcCBeIDFdKTsiLAogICAgIiAgICB9IiwKICAgICJ9IiwKICAgICJ2b2lkIHVwZGF0ZShpbnQgcG9zLCBpbnQgdmFsKSB7dXBkKHBvcyAtIDEsIHZhbCk7fSIsCiAgICAiVCBnZXQoaW50IGwsIGludCByKSB7cmV0dXJuIHF1ZXJ5X3BhcmFsbGVsKGwgLSAxLCByIC0gMSk7fSIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJGYXN0U2VnbWVudFRyZWUiCn0sCgoiQ2hlY2tlciI6IHsKICAicHJlZml4IjogIkNoZWNrZXIiLAogICJib2R5IjogWwogICAgIiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPiIsCiAgICAidXNpbmcgbmFtZXNwYWNlIHN0ZDsiLAogICAgIiIsCiAgICAidXNpbmcgaTMyID0gaW50MzJfdDsiLAogICAgInVzaW5nIGk2NCA9IGludDY0X3Q7IiwKICAgICIiLAogICAgInRlbXBsYXRlPGNsYXNzIFQ+IiwKICAgICJ1c2luZyB2ID0gdmVjdG9yPFQ+OyIsCiAgICAiIiwKICAgICIjZGVmaW5lIGFsbChhKSAoYSkuYmVnaW4oKSwgKGEpLmVuZCgpIiwKICAgICIiLAogICAgInN0cmluZyBmaWxlID0gXCJEUkFXQVRSRUVcIjsiLAogICAgIiIsCiAgICAiaTY0IHJhbmQoaTY0IGwsIGk2NCBoKSB7IiwKICAgICIgICAgcmV0dXJuIGwgKyAocmFuZCgpICUgKGggLSBsICsgMSkpOyIsCiAgICAifSIsCiAgICAiIiwKICAgICJ2b2lkIGNoZWNrKCkgeyIsCiAgICAiICAgIG9mc3RyZWFtIG91dChmaWxlICsgXCIuaW5wXCIpOyIsCiAgICAiIiwKICAgICIgICAgaTMyIG4gPSA2MDA7IG91dCA8PCBuIDw8IGVuZGw7IiwKICAgICIgICAgZm9yIChpMzIgaSA9IDA7IGkgPCBuIC0gMTsgaSsrKSB7IiwKICAgICIgICAgICAgIGZvciAoaTMyIGogPSBpICsgMTsgaiA8IG47IGorKykgeyIsCiAgICAiICAgICAgICAgICAgb3V0IDw8IChyYW5kKDAsIDIpID09IDA/ICdOJyA6ICdZJyk7IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICAgICAgb3V0IDw8IGVuZGw7IiwKICAgICIgICAgfSIsCiAgICAiIiwKICAgICIgICAgb3V0LmNsb3NlKCk7IiwKICAgICJ9IiwKICAgICIiLAogICAgInZvaWQgc2FkKGkzMiB0ZXN0SUQpIHsiLAogICAgIiAgICBzcmFuZCh0aW1lKE5VTEwpKTsiLAogICAgIiAgICBmb3IgKGkzMiBpID0gMTsgaSA8PSAxMDA7IGkrKykgeyAiLAogICAgIiAgICAgICAgY2hlY2soKTsiLAogICAgIiAgICAgICAgc3lzdGVtKChmaWxlICsgXCIuZXhlXCIpLmNfc3RyKCkpOyAgICAgICIsCiAgICAiICAgICAgICBzeXN0ZW0oKGZpbGUgKyBcIl90cmF1LmV4ZVwiKS5jX3N0cigpKTsgICIsCiAgICAiICAgICAgICBpZiAoc3lzdGVtKChcImZjIFwiICsgKGZpbGUgKyBcIi5vdXRcIikgKyBcIiBcIiArIChmaWxlICsgXCIuYW5zXCIpKS5jX3N0cigpKSkgeyIsCiAgICAiICAgICAgICAgICAgLy8gY291dCA8PCBcIlRlc3QgXCIgPDwgaSA8PCBcIiBmYWlsZWQhXFxuXCI7IiwKICAgICIgICAgICAgICAgICByZXR1cm47IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICB9IiwKICAgICJ9IiwKICAgICIiLAogICAgImkzMiBtYWluKCkgeyIsCiAgICAiICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyIsCiAgICAiICAgIGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOyIsCiAgICAiIiwKICAgICIgICAgaTMyIHQgPSAxOyIsCiAgICAiICAgIGZvciAoaTMyIHRlc3RJRCA9IDE7IHRlc3RJRCA8PSB0OyB0ZXN0SUQrKykgeyIsCiAgICAiICAgICAgICBzYWQodGVzdElEKTsiLAogICAgIiAgICB9IiwKICAgICIgICAgcmV0dXJuIDA7IiwKICAgICJ9IiwKICAgICIiCiAgXSwKICAiZGVzY3JpcHRpb24iOiAiQ2hlY2tlciIKfSwKIm11bCI6IHsKICAicHJlZml4IjogIm11bCIsCiAgImJvZHkiOiBbCiAgICAidWk2NCBtb2RtdWwodWk2NCBhLCB1aTY0IGIsIHVpNjQgTSl7IiwKICAgICIgICAgaTY0IHJldCA9IGEgKiBiIC0gTSAqIHVpNjQoMS5MIC8gTSAqIGEgKiBiKTsiLAogICAgIiAgICByZXR1cm4gcmV0ICsgTSAqIChyZXQgPCAwKSAtIE0gKiAocmV0ID49IChpNjQpTSk7IiwKICAgICJ9IgogIF0sCiAgImRlc2NyaXB0aW9uIjogIm11bCIKfQoiUG9sbGFyZFJobyI6IHsKICAicHJlZml4IjogIlBvbGxhcmRSaG8iLAogICJib2R5IjogWwogICAgInVpNjQgUG9sbGFyZFJobyh1aTY0IG4peyIsCiAgICAiICAgIGF1dG8gZiA9IFtuXSh1aTY0IHgpe3JldHVybiBtb2RtdWwoeCwgeCwgbikgKyAxO307IiwKICAgICIgICAgdWk2NCB4PTAsIHk9MCwgdD0zMCwgcHJkPTIsIGk9MSwgcTsiLAogICAgIiAgICB3aGlsZSAodCsrICUgNDAgfHwgX19nY2QocHJkLCBuKSA9PSAxKXsiLAogICAgIiAgICAgICAgaWYgKHggPT0geSkgeCA9ICsraSwgeSA9IGYoeCk7IiwKICAgICIgICAgICAgIGlmICgocSA9IG1vZG11bChwcmQsIG1heCh4LCB5KSAtIG1pbih4LCB5KSwgbikpKSBwcmQgPSBxOyIsCiAgICAiICAgICAgICB4ID0gZih4KSwgeSA9IGYoZih5KSk7IiwKICAgICIgICAgfSIsCiAgICAiICAgIHJldHVybiBfX2djZChwcmQsIG4pOyIsCiAgICAifSIsCiAgICAidmVjdG9yPHVpNjQ+IGZhY3Rvcih1aTY0IG4peyIsCiAgICAiICAgIGlmIChuID09IDEpIHJldHVybnt9OyIsCiAgICAifSIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJQb2xsYXJkUmhvIgp9CiJCZXR0ZXJTaWV2ZSI6IHsKICAicHJlZml4IjogIkJldHRlclNpZXZlIiwKICAiYm9keSI6IFsKICAgICJ2ZWN0b3I8aTMyPiBfY2hlY2tQcmltZShOID4+IDYpLCBfcHJpbWU7IiwKICAgICJ2b2lkIFNpZXZlKCkgeyIsCiAgICAiICAgICNkZWZpbmUgc2V0KG4pIChfY2hlY2tQcmltZVtuID4+IDZdIHw9ICgxPDwoKG4gJiA2MykgPj4gMSkpKSIsCiAgICAiICAgICNkZWZpbmUgZ2V0KG4pIChfY2hlY2tQcmltZVtuID4+IDZdICYgKDEgPDwgKChuICYgNjMpID4+IDEpKSkiLAogICAgIiAgICAiLAogICAgIiAgICBfcHJpbWUucHVzaF9iYWNrKDIpOyBpMzIgdCA9IHNxcnQoTik7IiwKICAgICIgICAgZm9yIChpMzIgaSA9IDM7IGkgPCBOOyBpICs9IDIpIiwKICAgICIgICAgICAgIGlmICghZ2V0KGkpKSB7IiwKICAgICIgICAgICAgICAgICBfcHJpbWUucHVzaF9iYWNrKGkpOyIsCiAgICAiICAgICAgICAgICAgaWYgKGkgPiB0KSBjb250aW51ZTsiLAogICAgIiAgICAgICAgICAgIGZvciAoaTMyIGogPSBpICogaTsgaiA8IE47IGogKz0gKGkgPDwgMSkpIHNldChqKTsiLAogICAgIiAgICAgICAgfSIsCiAgICAifSIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJCZXR0ZXJTaWV2ZSIKfQoiZ2NkX3dpdGhFeHRlbmRlZEV1Y2xpZGVhbiI6IHsKICAicHJlZml4IjogImdjZF93aXRoRXh0ZW5kZWRFdWNsaWRlYW4iLAogICJib2R5IjogWwogICAgImk2NCBnY2Rfd2l0aEV4dGVuZGVkRXVjbGlkZWFuKGk2NCBhLCBpNjQgYiwgaTY0ICZ4LCBpNjQgJnkpIHsiLAogICAgIiAgICBpZiAoYiA9PSAwKSB7eCA9IDEsIHkgPSAwOyByZXR1cm4gYTt9IiwKICAgICIgICAgaTY0IHgxLCB5MSwgZyA9IGdjZF93aXRoRXh0ZW5kZWRFdWNsaWRlYW4oYiwgYSAlIGIsIHgxLCB5MSk7IiwKICAgICIgICAgeCA9IHkxOyB5ID0geDEgLSBhIC8gYiAqIHkxOyIsCiAgICAiICAgIHJldHVybiBnOyIsCiAgICAifSIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJnY2Rfd2l0aEV4dGVuZGVkRXVjbGlkZWFuIgp9CiJjdXN0b21faGFzaCAiOiB7CiAgInByZWZpeCI6ICJjdXN0b21faGFzaCAiLAogICJib2R5IjogWwogICAgIi8vIFNvdXJjZTogaHR0cDovL3guLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmkuaXQvc3BsaXRtaXg2NC5jIiwKICAgICJzdHJ1Y3QgY3VzdG9tX2hhc2ggeyIsCiAgICAiICAgIHN0YXRpYyB1aW50NjRfdCBzcGxpdG1peDY0KHVpbnQ2NF90IHgpIHsiLAogICAgIiAgICAgICAgeCArPSAweDllMzc3OWI5N2Y0YTdjMTU7IiwKICAgICIgICAgICAgIHggPSAoeCBeICh4ID4+IDMwKSkgKiAweGJmNTg0NzZkMWNlNGU1Yjk7IiwKICAgICIgICAgICAgIHggPSAoeCBeICh4ID4+IDI3KSkgKiAweDk0ZDA0OWJiMTMzMTExZWI7IiwKICAgICIgICAgICAgIHJldHVybiB4IF4gKHggPj4gMzEpOyIsCiAgICAiICAgIH0iLAogICAgIiAgICBzaXplX3Qgb3BlcmF0b3IoKSh1aW50NjRfdCB4KSBjb25zdCB7IiwKICAgICIgICAgICAgIHN0YXRpYyBjb25zdCB1aW50NjRfdCBGSVhFRF9SQU5ET00gPSBjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCk7IiwKICAgICIgICAgICAgIHJldHVybiBzcGxpdG1peDY0KHggKyBGSVhFRF9SQU5ET00pOyIsCiAgICAiICAgIH0iLAogICAgIn07IgogIF0sCiAgImRlc2NyaXB0aW9uIjogImN1c3RvbV9oYXNoICIKfQoiTWVyZ2VTb3J0VHJlZSAiOiB7CiAgInByZWZpeCI6ICJNZXJnZVNvcnRUcmVlICIsCiAgImJvZHkiOiBbCiAgICAic3RydWN0IE1TVE4ge3ZlY3RvcjxpMzI+IHZhbDt9OyIsCiAgICAic3RydWN0IE1lcmdlU29ydFRyZWUgeyIsCiAgICAiICAgIHZlY3RvcjxNU1ROPiBub2RlOyIsCiAgICAiICAgIGkzMiB1dSwgdnYsIG47IiwKICAgICIgICAgTWVyZ2VTb3J0VHJlZShpMzIgc2l6ZSkgOiBuKHNpemUpIHsiLAogICAgIiAgICAgICAgbm9kZS5yZXNpemUoNCAqIG4gKyAxMCk7IiwKICAgICIgICAgICAgIHRoaXMtPnV1ID0gMTsiLAogICAgIiAgICAgICAgdGhpcy0+dnYgPSBuOyIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIHJlbGVuZ3RoKGkzMiBzaXplKXsiLAogICAgIiAgICAgICAgbiA9IHNpemU7IiwKICAgICIgICAgICAgIG5vZGUucmVzaXplKDQgKiBuICsgMTApOyIsCiAgICAiICAgICAgICB0aGlzLT51dSA9IDE7IiwKICAgICIgICAgICAgIHRoaXMtPnZ2ID0gbjsiLAogICAgIiAgICB9IiwKICAgICIgICAgdm9pZCBtZXJnZShNU1ROICZhLCBNU1ROICZiLCBNU1ROICZjKSB7IiwKICAgICIgICAgICAgIGEudmFsLmNsZWFyKCk7IiwKICAgICIgICAgICAgIGkzMiBwMSA9IDAsIHAyID0gMDsiLAogICAgIiAgICAgICAgd2hpbGUodHJ1ZSkgeyIsCiAgICAiICAgICAgICAgICAgaWYocDEgPT0gYi52YWwuc2l6ZSgpKSB7IiwKICAgICIgICAgICAgICAgICAgICAgaWYocDIgPT0gYy52YWwuc2l6ZSgpKSBicmVhazsiLAogICAgIiAgICAgICAgICAgICAgICBlbHNlIGEudmFsLnB1c2hfYmFjayhjLnZhbFtwMiArK10pOyIsCiAgICAiICAgICAgICAgICAgfSIsCiAgICAiICAgICAgICAgICAgZWxzZSB7IiwKICAgICIgICAgICAgICAgICAgICAgaWYocDIgPT0gYy52YWwuc2l6ZSgpKSBhLnZhbC5wdXNoX2JhY2soYi52YWxbcDEgKytdKTsiLAogICAgIiAgICAgICAgICAgICAgICBlbHNlIGlmKGIudmFsW3AxXSA8IGMudmFsW3AyXSkgYS52YWwucHVzaF9iYWNrKGIudmFsW3AxICsrXSk7IiwKICAgICIgICAgICAgICAgICAgICAgZWxzZSBhLnZhbC5wdXNoX2JhY2soYy52YWxbcDIgKytdKTsiLAogICAgIiAgICAgICAgICAgIH0iLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIGJ1aWxkKHZlY3RvcjxpMzI+ICZhKSB7YnVpbGQoMSwgMSwgbiwgYSk7fSIsCiAgICAiICAgIHZvaWQgYnVpbGQoaTMyIGlkLCBpMzIgbCwgaTMyIHIsIHZlY3RvcjxpMzI+ICZhKSB7IiwKICAgICIgICAgICAgIGlmIChsID09IHIpIHsiLAogICAgIiAgICAgICAgICAgIG5vZGVbaWRdLnZhbC5wdXNoX2JhY2soYVtsXSk7IiwKICAgICIgICAgICAgICAgICByZXR1cm47IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICAgICAgaTMyIG1pZCA9IChsICsgcikgPj4gMTsiLAogICAgIiAgICAgICAgYnVpbGQoaWQgPDwgMSwgbCwgbWlkLCBhKTsiLAogICAgIiAgICAgICAgYnVpbGQoaWQgPDwgMSB8IDEsIG1pZCArIDEsIHIsIGEpOyIsCiAgICAiICAgICAgICBtZXJnZShub2RlW2lkXSwgbm9kZVtpZCA8PCAxXSwgbm9kZVtpZCA8PCAxIHwgMV0pOyIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIHVwZGF0ZVYoaTMyIHBvcywgaTMyIHgsIGkzMiB5KSB7dXBkYXRlVihwb3MsIHgsIHksIDEsIHV1LCB2dik7fSIsCiAgICAiICAgIHZvaWQgdXBkYXRlVihpMzIgcG9zLCBpMzIgeCwgaTMyIHksIGkzMiBpZCwgaTMyIGwsIGkzMiByKSB7IiwKICAgICIgICAgICAgIGlmIChsID4gcG9zIHx8IHIgPCBwb3MpIHJldHVybjsiLAogICAgIiAgICAgICAgaWYgKGwgPT0gcikgeyIsCiAgICAiICAgICAgICAgICAgaTMyIGxsID0gMCwgcnIgPSBub2RlW2lkXS52YWwuc2l6ZSgpIC0gMSwgcmVzID0gMDsiLAogICAgIiAgICAgICAgICAgIHdoaWxlKGxsIDw9IHJyKSB7IiwKICAgICIgICAgICAgICAgICAgICAgaTMyIG1pZCA9IChsbCArIHJyKSA+PiAxOyIsCiAgICAiICAgICAgICAgICAgICAgIGlmKG5vZGVbaWRdLnZhbFttaWRdID49IHgpIHJyID0gKHJlcyA9IG1pZCkgLSAxOyIsCiAgICAiICAgICAgICAgICAgICAgIGVsc2UgbGwgPSBtaWQgKyAxOyIsCiAgICAiICAgICAgICAgICAgfSIsCiAgICAiICAgICAgICAgICAgaWYobm9kZVtpZF0udmFsW3Jlc10gPT0geCkgbm9kZVtpZF0udmFsW3Jlc10gPSB5OyIsCiAgICAiICAgICAgICAgICAgZWxzZSB0aHJvdyBzdGQ6OnJ1bnRpbWVfZXJyb3IoXCJWYWx1ZSBub3QgZm91bmRcIik7IiwKICAgICIgICAgICAgICAgICBzb3J0KGFsbChub2RlW2lkXS52YWwpKTsiLAogICAgIiAgICAgICAgICAgIHJldHVybjsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBpMzIgbWlkID0gKGwgKyByKSA+PiAxOyIsCiAgICAiICAgICAgICB1cGRhdGVWKHBvcywgeCwgeSwgaWQgPDwgMSwgbCwgbWlkKTsiLAogICAgIiAgICAgICAgdXBkYXRlVihwb3MsIHgsIHksIGlkIDw8IDEgfCAxLCBtaWQgKyAxLCByKTsiLAogICAgIiAgICAgICAgbWVyZ2Uobm9kZVtpZF0sIG5vZGVbaWQgPDwgMV0sIG5vZGVbaWQgPDwgMSB8IDFdKTsiLAogICAgIiAgICB9IiwKICAgICIgICAgaTMyIGdldChpMzIgdSwgaTMyIHYsIGkzMiBrKSB7cmV0dXJuIGdldCh1LCB2LCBrLCAxLCB1dSwgdnYpO30iLAogICAgIiAgICBpMzIgZ2V0KGkzMiB1LCBpMzIgdiwgaTMyIGssIGkzMiBpZCwgaTMyIGwsIGkzMiByKSB7IiwKICAgICIgICAgICAgIGlmIChsID4gdiB8fCByIDwgdSkgcmV0dXJuIDA7IiwKICAgICIgICAgICAgIGlmICh1IDw9IGwgJiYgciA8PSB2KSB7IiwKICAgICIgICAgICAgICAgICBpMzIgbGwgPSAwLCByciA9IG5vZGVbaWRdLnZhbC5zaXplKCkgLSAxLCByZXMgPSBub2RlW2lkXS52YWwuc2l6ZSgpOyIsCiAgICAiICAgICAgICAgICAgd2hpbGUobGwgPD0gcnIpIHsiLAogICAgIiAgICAgICAgICAgICAgICBpMzIgbWlkID0gKGxsICsgcnIpID4+IDE7IiwKICAgICIgICAgICAgICAgICAgICAgaWYobm9kZVtpZF0udmFsW21pZF0gPiBrKSByciA9IChyZXMgPSBtaWQpIC0gMTsiLAogICAgIiAgICAgICAgICAgICAgICBlbHNlIGxsID0gbWlkICsgMTsiLAogICAgIiAgICAgICAgICAgIH0iLAogICAgIiAgICAgICAgICAgIHJldHVybiBub2RlW2lkXS52YWwuc2l6ZSgpIC0gcmVzOyIsCiAgICAiICAgICAgICB9IiwKICAgICIgICAgICAgIGkzMiBtaWQgPSAobCArIHIpID4+IDE7IiwKICAgICIgICAgICAgIHJldHVybiBnZXQodSwgdiwgaywgaWQgPDwgMSwgbCwgbWlkKSArIGdldCh1LCB2LCBrLCBpZCA8PCAxIHwgMSwgbWlkICsgMSwgcik7IiwKICAgICIgICAgfSIsCiAgICAifTsiCiAgXSwKICAiZGVzY3JpcHRpb24iOiAiTWVyZ2VTb3J0VHJlZSAiCn0KIkR5bmFtaWNDb25uZWN0aXZpdHkiOiB7CiAgInByZWZpeCI6ICJEeW5hbWljQ29ubmVjdGl2aXR5IiwKICAiYm9keSI6IFsKICAgICJzdHJ1Y3QgQ29ubmVjdCB7IiwKICAgICIgICAgaTMyIHYsIHU7IiwKICAgICIgICAgYm9vbCB1bml0ZWQ7IiwKICAgICIgICAgQ29ubmVjdChpMzIgX3YsIGkzMiBfdSkgOiB2KF92KSwgdShfdSkgeyIsCiAgICAiICAgIH0iLAogICAgIn07IiwKICAgICJzdHJ1Y3QgRHluYW1pY0Nvbm5lY3Rpdml0eSB7IiwKICAgICIgICAgdmVjdG9yPHZlY3RvcjxDb25uZWN0Pj4gdDsiLAogICAgIiAgICBEaXNqb2ludFNldHMgZHN1OyIsCiAgICAiICAgIGkzMiBUOyIsCiAgICAiIiwKICAgICIgICAgRHluYW1pY0Nvbm5lY3Rpdml0eSgpIHt9IiwKICAgICIgICAgRHluYW1pY0Nvbm5lY3Rpdml0eShpMzIgX1QsIGkzMiBuKSA6IFQoX1QpIHsiLAogICAgIiAgICAgICAgZHN1ID0gRGlzam9pbnRTZXRzKG4pOyIsCiAgICAiICAgICAgICB0LnJlc2l6ZSg0ICogVCArIDQpOyIsCiAgICAiICAgIH0iLAogICAgIiIsCiAgICAiICAgIHZvaWQgYWRkKGkzMiB2LCBpMzIgbCwgaTMyIHIsIGkzMiB1bCwgaTMyIHVyLCBDb25uZWN0JiBxKSB7IiwKICAgICIgICAgICAgIGlmICh1bCA+IHVyKSIsCiAgICAiICAgICAgICAgICAgcmV0dXJuOyIsCiAgICAiICAgICAgICBpZiAobCA9PSB1bCAmJiByID09IHVyKSB7IiwKICAgICIgICAgICAgICAgICB0W3ZdLnB1c2hfYmFjayhxKTsiLAogICAgIiAgICAgICAgICAgIHJldHVybjsiLAogICAgIiAgICAgICAgfSIsCiAgICAiICAgICAgICBpMzIgbWlkID0gKGwgKyByKSA+PiAxOyIsCiAgICAiICAgICAgICBhZGQodiA8PCAxLCBsLCBtaWQsIHVsLCBtaW4odXIsIG1pZCksIHEpOyIsCiAgICAiICAgICAgICBhZGQodiA8PCAxIHwgMSwgbWlkICsgMSwgciwgbWF4KHVsLCBtaWQgKyAxKSwgdXIsIHEpOyIsCiAgICAiICAgIH0iLAogICAgIiAgICB2b2lkIGFkZChDb25uZWN0IHEsIGkzMiBsLCBpMzIgcikgeyIsCiAgICAiICAgICAgICBhZGQoMSwgMCwgVCAtIDEsIGwsIHIsIHEpOyIsCiAgICAiICAgIH0iLAogICAgIiIsCiAgICAiICAgIHZvaWQgZGZzKGkzMiB2LCBpMzIgbCwgaTMyIHIsIHZlY3RvcjxpMzI+JiBhbnMpIHsiLAogICAgIiAgICAgICAgZm9yIChDb25uZWN0JiBxIDogdFt2XSkgeyIsCiAgICAiICAgICAgICAgICAgcS51bml0ZWQgPSBkc3UubWVyZ2UocS52LCBxLnUpOyIsCiAgICAiICAgICAgICB9IiwKICAgICIgICAgICAgIGlmIChsID09IHIpIGFuc1tsXSA9IGRzdS5jb21wczsiLAogICAgIiAgICAgICAgZWxzZSB7IiwKICAgICIgICAgICAgICAgICBpMzIgbWlkID0gKGwgKyByKSA+PiAxOyIsCiAgICAiICAgICAgICAgICAgZGZzKHYgPDwgMSwgbCwgbWlkLCBhbnMpOyIsCiAgICAiICAgICAgICAgICAgZGZzKHYgPDwgMSB8IDEsIG1pZCArIDEsIHIsIGFucyk7IiwKICAgICIgICAgICAgIH0iLAogICAgIiAgICAgICAgZm9yIChDb25uZWN0IHEgOiB0W3ZdKSBpZiAocS51bml0ZWQpIGRzdS5yb2xsYmFjaygpOyIsCiAgICAiICAgIH0iLAogICAgIiAgICB2ZWN0b3I8aTMyPiBjb21wdXRlKCkgeyIsCiAgICAiICAgICAgICB2ZWN0b3I8aTMyPiBhbnMoVCk7IiwKICAgICIgICAgICAgIGRmcygxLCAwLCBUIC0gMSwgYW5zKTsiLAogICAgIiAgICAgICAgcmV0dXJuIGFuczsiLAogICAgIiAgICB9IiwKICAgICJ9OyIKICBdLAogICJkZXNjcmlwdGlvbiI6ICJEeW5hbWljQ29ubmVjdGl2aXR5Igp9Cgl9Cgk=