#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
#ifdef __x86_64__
#define NTT64
#endif
#define _rep(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)
using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;
namespace ntt {
#ifdef NTT64
using word_t = u64;
using dword_t = __uint128_t;
#else
using word_t = u32;
using dword_t = u64;
#endif
static const int word_bits = 8 * sizeof(word_t);
template <word_t mod, word_t prim_root>
class Mod {
private:
static constexpr word_t mul_inv(word_t n, int e=6, word_t x=1) {
return e == 0 ? x : mul_inv(n, e-1, x*(2-x*n));
}
public:
static constexpr word_t inv = mul_inv(mod);
static constexpr word_t r2 = -dword_t(mod) % mod;
static constexpr int level = __builtin_ctzll(mod - 1);
static_assert(inv * mod == 1, "invalid 1/M modulo 2^@.");
Mod() {}
Mod(word_t n) : x(init(n)) {};
static word_t modulus() { return mod; }
static word_t init(word_t w) { return reduce(dword_t(w) * r2); }
static word_t reduce(const dword_t w) { return word_t(w >> word_bits) + mod - word_t((dword_t(word_t(w) * inv) * mod) >> word_bits); }
static Mod omega() { return Mod(prim_root).pow((mod - 1) >> level); }
Mod& operator += (Mod rhs) { this->x += rhs.x; return *this; }
Mod& operator -= (Mod rhs) { this->x += 3 * mod - rhs.x; return *this; }
Mod& operator *= (Mod rhs) { this->x = reduce(dword_t(this->x) * rhs.x); return *this; }
Mod operator + (Mod rhs) const { return Mod(*this) += rhs; }
Mod operator - (Mod rhs) const { return Mod(*this) -= rhs; }
Mod operator * (Mod rhs) const { return Mod(*this) *= rhs; }
word_t get() const { return reduce(this->x) % mod; }
void set(word_t n) const { this->x = n; }
Mod pow(word_t exp) const {
Mod ret = Mod(1);
for (Mod base = *this; exp; exp >>= 1, base *= base) if (exp & 1) ret *= base;
return ret;
}
Mod inverse() const { return pow(mod - 2); }
friend ostream& operator << (ostream& os, const Mod& m) { return os << m.get(); }
static void debug() {
printf("%llu %llu %llu %llu\n", mod, inv, r2, omega().get());
}
word_t x;
};
const int size = 1 << 16;
#ifdef NTT64
using m64_1 = ntt::Mod<709143768229478401, 31>;
using m64_2 = ntt::Mod<711416664922521601, 19>; // <= 712e15 (sub.D = 3)
m64_1 f1[size], g1[size];
m64_2 f2[size], g2[size];
#else
using m32_1 = ntt::Mod<138412033, 5>;
using m32_2 = ntt::Mod<155189249, 6>;
using m32_3 = ntt::Mod<163577857, 23>; // <= 16579e4 (sub.D = 3)
m32_1 f1[size], g1[size];
m32_2 f2[size], g2[size];
m32_3 f3[size], g3[size];
#endif
template <typename mod_t>
void convolve(mod_t* A, int s1, mod_t* B, int s2, bool cyclic=false) {
int s = (cyclic ? max(s1, s2) : s1 + s2 - 1);
int size = 1;
while (size < s) size <<= 1;
mod_t roots[mod_t::level] = { mod_t::omega() };
rep(i, 1, mod_t::level) roots[i] = roots[i - 1] * roots[i - 1];
fill(A + s1, A + size, 0); ntt_dit4(A, size, 1, roots);
if (A == B && s1 == s2) {
rep(i, size) A[i] *= A[i];
} else {
fill(B + s2, B + size, 0); ntt_dit4(B, size, 1, roots);
rep(i, size) A[i] *= B[i];
}
ntt_dit4(A, size, -1, roots);
mod_t inv = mod_t(size).inverse();
rep(i, cyclic ? size : s) A[i] *= inv;
}
template <typename mod_t>
void rev_permute(mod_t* A, int n) {
int r = 0, nh = n >> 1;
rep(i, 1, n) {
for (int h = nh; !((r ^= h) & h); h >>= 1);
if (r > i) swap(A[i], A[r]);
}
}
template <typename mod_t>
void ntt_dit4(mod_t* A, int n, int sign, mod_t* roots) {
rev_permute(A, n);
int logn = __builtin_ctz(n);
assert(logn <= mod_t::level);
if (logn & 1) rep(i, 0, n, 2) {
mod_t a = A[i], b = A[i + 1];
A[i] = a + b; A[i + 1] = a - b;
}
mod_t imag = roots[mod_t::level - 2];
if (sign < 0) imag = imag.inverse();
mod_t one = mod_t(1);
rep(e, 2 + (logn & 1), logn + 1, 2) {
const int m = 1 << e;
const int m4 = m >> 2;
mod_t dw = roots[mod_t::level - e];
if (sign < 0) dw = dw.inverse();
const int block_size = min(n, max(m, (1 << 15) / int(sizeof(A[0]))));
rep(k, 0, n, block_size) {
mod_t w = one, w2 = one, w3 = one;
rep(j, m4) {
rep(i, k + j, k + block_size, m) {
mod_t a0 = A[i + m4 * 0] * one, a2 = A[i + m4 * 1] * w2;
mod_t a1 = A[i + m4 * 2] * w, a3 = A[i + m4 * 3] * w3;
mod_t t02 = a0 + a2, t13 = a1 + a3;
A[i + m4 * 0] = t02 + t13; A[i + m4 * 2] = t02 - t13;
t02 = a0 - a2, t13 = (a1 - a3) * imag;
A[i + m4 * 1] = t02 + t13; A[i + m4 * 3] = t02 - t13;
}
w *= dw; w2 = w * w; w3 = w2 * w;
}
}
}
}
} // namespace ntt
using R = int;
using R64 = i64;
class poly {
public:
#ifdef NTT64
static const int ntt_threshold = 900; // deg(f * g)
#else
static const int ntt_threshold = 1500; // deg(f * g)
#endif
static R add_mod(R a, R b) { return int(a += b - mod) < 0 ? a + mod : a; }
static R sub_mod(R a, R b) { return int(a -= b) < 0 ? a + mod : a; }
static R64 sub_mul_mod(R64 a, R b, R c) {
i64 t = i64(a) - i64(int(b)) * int(c);
return t < 0 ? t + lmod : t;
}
static R mul_mod(R a, R b) { return R64(a) * b % fast_mod; }
static R pow_mod(R a, int e) {
R ret = 1 % fast_mod;
for (; e; e >>= 1, a = mul_mod(a, a)) {
if (e & 1) ret = mul_mod(ret, a);
}
return ret;
}
static R mod_inv(R a) {
R b = mod, s = 1, t = 0;
while (b > 0) {
swap(s -= t * (a / b), t);
swap(a %= b, b);
}
if (a > 1) { fprintf(stderr, "Error: invalid modular inverse\n"); exit(1); };
return int(s) < 0 ? s + mod : s;
}
inline static void vec_add(R64* res, int s, const R* f, R c) {
rep(i, s) res[i] = sub_mul_mod(res[i], mod - c, f[i]);
}
inline static void vec_sub(R64* res, int s, const R* f, R c) {
rep(i, s) res[i] = sub_mul_mod(res[i], c, f[i]);
}
#ifdef NTT64
struct fast_div {
using u128 = __uint128_t;
fast_div() {}
fast_div(u64 n) : m(n) {
s = (n == 1) ? 0 : 127 - __builtin_clzll(n - 1);
x = ((u128(1) << s) + n - 1) / n;
}
friend u64 operator / (u64 n, fast_div d) { return u128(n) * d.x >> d.s; }
friend u64 operator % (u64 n, fast_div d) { return n - n / d * d.m; }
u64 m, s, x;
};
#else
struct fast_div {
fast_div() {}
fast_div(u32 n) : m(n) {}
friend u32 operator % (u64 n, fast_div d) { return n % d.m; }
u32 m;
};
#endif
public:
poly() {}
poly(int n) : coefs(n) {}
poly(int n, int c) : coefs(n, c % mod) {}
poly(const R* ar, int s) : coefs(ar, ar + s) {}
poly(const vector<R>& v) : coefs(v) {}
poly(const poly& f, int beg, int end=-1) {
if (end < 0) end = beg, beg = 0;
resize(end - beg);
rep(i, beg, end) if (i < f.size()) coefs[i - beg] = f[i];
}
static int ilog2(u64 n) {
return 63 - __builtin_clzll(n);
}
int size() const { return coefs.size(); }
void resize(int s) { coefs.resize(s); }
void push_back(R c) { coefs.push_back(c); }
const R* data() const { return coefs.data(); }
R* data() { return coefs.data(); }
const R& operator [] (int i) const { return coefs[i]; }
R& operator [] (int i) { return coefs[i]; }
void reverse() { std::reverse(coefs.begin(), coefs.end()); }
poly operator - () {
poly ret = *this;
rep(i, ret.size()) ret[i] = (ret[i] == 0 ? 0 : mod - ret[i]);
return ret;
}
poly& operator += (const poly& rhs) {
if (size() < rhs.size()) resize(rhs.size());
rep(i, rhs.size()) coefs[i] = add_mod(coefs[i], rhs[i]);
return *this;
}
poly& operator -= (const poly& rhs) {
if (size() < rhs.size()) resize(rhs.size());
rep(i, rhs.size()) coefs[i] = sub_mod(coefs[i], rhs[i]);
return *this;
}
poly& operator *= (const poly& rhs) { return *this = *this * rhs; }
poly& rev_add(const poly& rhs) {
if (size() < rhs.size()) {
int s = size();
resize(rhs.size());
rep(i, s) coefs[size() - 1 - i] = coefs[s - 1 - i];
rep(i, size() - s) coefs[i] = 0;
}
rep(i, rhs.size()) coefs[size() - 1 - i] = \
add_mod(coefs[size() - 1 - i], rhs.coefs[rhs.size() - 1 - i]);
return *this;
}
poly operator + (const poly& rhs) const { return poly(*this) += rhs; }
poly operator - (const poly& rhs) const { return poly(*this) -= rhs; }
poly operator * (const poly& rhs) const { return this->mul(rhs); }
static void set_mod(R m, int N=2) {
mod = m;
lmod = R64(m) << 32;
N = max(2, N);
fast_mod = fast_div(mod);
invs.assign(N + 1, 1);
facts.assign(N + 1, 1);
ifacts.assign(N + 1, 1);
invs[1] = 1;
rep(i, 2, N + 1) {
invs[i] = mul_mod(invs[mod % i], mod - mod / i);
facts[i] = mul_mod(facts[i - 1], i);
ifacts[i] = mul_mod(ifacts[i - 1], invs[i]);
}
}
private:
#ifdef NTT64
static poly mul_crt(int beg, int end) {
using namespace ntt;
auto inv = m64_2(m64_1::modulus()).inverse();
auto mod1 = m64_1::modulus() % fast_mod;
poly ret(end - beg);
rep(i, ret.size()) {
u64 r1 = f1[i + beg].get(), r2 = f2[i + beg].get();
ret[i] = (r1 + (m64_2(r2 + m64_2::modulus() - r1) * inv).get() % fast_mod * mod1) % fast_mod;
}
return ret;
}
static void mul2(const poly& f, const poly& g, bool cyclic=false) {
using namespace ntt;
if (&f == &g) {
rep(i, f.size()) f1[i] = f[i];
convolve(f1, f.size(), f1, f.size(), cyclic);
rep(i, f.size()) f2[i] = f[i];
convolve(f2, f.size(), f2, f.size(), cyclic);
} else {
rep(i, f.size()) f1[i] = f[i]; rep(i, g.size()) g1[i] = g[i];
convolve(f1, f.size(), g1, g.size(), cyclic);
rep(i, f.size()) f2[i] = f[i]; rep(i, g.size()) g2[i] = g[i];
convolve(f2, f.size(), g2, g.size(), cyclic);
}
}
#else
static poly mul_crt(int beg, int end) {
using namespace ntt;
auto m1 = m32_1::modulus();
auto m2 = m32_2::modulus();
auto m3 = m32_3::modulus();
auto m12 = u64(m1) * m2;
poly ret(end - beg);
u32 m12m = m12 % mod;
u32 inv1 = m32_2(m1).inverse().get();
u32 inv12 = m32_3(m12 % m3).inverse().get();
rep(i, ret.size()) {
u32 r1 = f1[i + beg].get(), r2 = f2[i + beg].get(), r3 = f3[i + beg].get();
u64 r = r1 + u64(r2 + m2 - r1) * inv1 % m2 * m1;
ret[i] = (r + u64(r3 + m3 - r % m3) * inv12 % m3 * m12m) % mod;
}
return ret;
}
static void mul2(const poly& f, const poly& g, bool cyclic=false) {
using namespace ntt;
if (&f == &g) {
rep(i, f.size()) f1[i] = f[i] % m32_1::modulus();
convolve(f1, f.size(), f1, f.size(), cyclic);
rep(i, f.size()) f2[i] = f[i] % m32_2::modulus();
convolve(f2, f.size(), f2, f.size(), cyclic);
rep(i, f.size()) f3[i] = f[i] % m32_3::modulus();
convolve(f3, f.size(), f3, f.size(), cyclic);
} else {
rep(i, f.size()) f1[i] = f[i] % m32_1::modulus();
rep(i, g.size()) g1[i] = g[i] % m32_1::modulus();
convolve(f1, f.size(), g1, g.size(), cyclic);
rep(i, f.size()) f2[i] = f[i] % m32_2::modulus();
rep(i, g.size()) g2[i] = g[i] % m32_2::modulus();
convolve(f2, f.size(), g2, g.size(), cyclic);
rep(i, f.size()) f3[i] = f[i] % m32_3::modulus();
rep(i, g.size()) g3[i] = g[i] % m32_3::modulus();
convolve(f3, f.size(), g3, g.size(), cyclic);
}
}
#endif
public:
static void amul(const R* f, int s1, const R* g, int s2, R* res) {
int s = s1 + s2 - 1;
tmp64.assign(s, 0);
rep(i, s2) if (g[i]) vec_add(tmp64.data() + i, s1, f, g[i]);
rep(i, s) res[i] = tmp64[i] % fast_mod;
}
poly mul_basecase(const poly& g) const {
const auto& f = *this;
int s = size() + g.size() - 1;
poly ret(s);
amul(f.data(), f.size(), g.data(), g.size(), ret.data());
return ret;
}
// 1.0 * M(n)
poly mul(const poly& g) const {
const auto& f = *this;
if (f.size() == 0 || g.size() == 0) return poly();
if (f.size() + g.size() <= ntt_threshold) {
return f.mul_basecase(g);
} else {
mul2(f, g, false);
return mul_crt(0, f.size() + g.size() - 1);
}
}
// 1.0 * M(n)
poly middle_product(const poly& g) const {
const poly& f = *this;
if (f.size() == 0 || g.size() == 0) return poly();
mul2(f, g, true);
return mul_crt(f.size(), g.size());
}
void print() const {
printf("[");
if (size()) {
printf("%u", coefs[0]);
rep(i, 1, size()) printf(", %u", coefs[i]);
}
puts("]");
}
public:
vector<R> coefs;
static vector<R> tmp32;
static vector<R64> tmp64;
static vector<R> invs, facts, ifacts;
static R mod;
static R64 lmod;
static fast_div fast_mod;
};
R poly::mod;
R64 poly::lmod;
poly::fast_div poly::fast_mod;
vector<R> poly::tmp32;
vector<R64> poly::tmp64;
vector<R> poly::invs, poly::facts, poly::ifacts;
int pow_mod(int b, int e, int mod) {
int ret = 1;
for (; e; e >>= 1, b = i64(b) * b % mod) {
if (e & 1) ret = i64(ret) * b % mod;
}
return ret;
}
int binomial_sum_mod_p(int N, int K, int mod) {
if (K == 0) return 1 % mod;
if (N <= K) return pow_mod(2, N, mod);
if (i64(K) * 2 > N) {
return (pow_mod(2, N, mod) + i64(mod) - binomial_sum_mod_p(N, N - K - 1, mod)) % mod;
}
assert(N < mod);
const int sqrt_K = sqrt(K);
poly::set_mod(mod, sqrt_K);
auto mod_invs = [&] (vector<int>& f) {
int n = f.size();
vector<int> ret(f);
if (n > 0) {
rep(i, 1, n) ret[i] = i64(ret[i - 1]) * ret[i] % mod;
int inv = poly::mod_inv(ret[n - 1]);
for (int i = n - 1; i > 0; --i) {
ret[i] = i64(ret[i - 1]) * inv % mod;
inv = i64(inv) * f[i] % mod;
}
ret[0] = inv;
}
return ret;
};
auto conv = [&] (vector<int>& f) -> poly {
int n = f.size();
const auto& ifacts = poly::ifacts;
auto g = poly(f);
rep(i, n) {
int d = i64(ifacts[i]) * ifacts[(n - 1) - i] % mod;
if ((n - 1 - i) & 1) d = mod - d;
g[i] = i64(g[i]) * d % mod;
}
return g;
};
auto shift = [&] (const poly& cf, const poly& f, i64 dx) {
if ((dx %= mod) < 0) dx += mod;
const int n = f.size();
const int a = i64(dx) * poly::mod_inv(sqrt_K) % mod;
auto g = poly(2 * n);
rep(i, g.size()) g[i] = (i64(mod) + a + i - n) % mod;
rep(i, g.size()) if (g[i] == 0) g[i] = 1;
g.coefs = mod_invs(g.coefs);
auto ret = cf.middle_product(g);
int prod = 1;
rep(i, n) prod = i64(prod) * (i64(mod) + a + n - 1 - i) % mod;
for (int i = n - 1; i >= 0; --i) {
ret[i] = i64(ret[i]) * prod % mod;
prod = i64(prod) * g[n + i] % mod * (i64(mod) + a + i - n) % mod;
}
if (dx % sqrt_K == 0) {
int k = n - dx / sqrt_K;
rep(i, k) ret[i] = f[n - k + i];
}
return ret.coefs;
};
using Pair = pair< vector<int>, vector<int> >;
function< Pair(int) > rec = [&] (int n) -> Pair {
if (n == 1) {
return Pair({N, N - sqrt_K}, {1, sqrt_K + 1});
}
int nh = n >> 1;
auto res = rec(nh);
auto& f11 = res.first, &g11 = res.second;
auto f = conv(f11), g = conv(g11);
auto g12 = shift(g, g11, nh);
auto g21 = shift(g, g11, i64(sqrt_K) * nh);
auto g22 = shift(g, g11, i64(sqrt_K) * nh + nh);
auto f12 = shift(f, f11, N - nh * i64(sqrt_K + 2));
auto f21 = shift(f, f11, i64(sqrt_K) * nh);
auto f22 = shift(f, f11, N - i64(2) * nh * (sqrt_K + 1));
rep(i, nh + 1) {
g11[i] = (i64(g11[i]) * f12[nh - i] + i64(g12[i]) * f11[i]) % mod;
}
rep(i, 1, nh + 1) {
g11.push_back( (i64(g21[i]) * f22[nh - i] + i64(g22[i]) * f21[i]) % mod );
}
f12 = shift(f, f11, nh);
f22 = shift(f, f11, i64(sqrt_K) * nh + nh);
rep(i, nh + 1) f11[i] = i64(f11[i]) * f12[i] % mod;
rep(i, 1, nh + 1) f11.push_back(i64(f21[i]) * f22[i] % mod);
if (n & 1) {
rep(i, n) {
g11[i] = (i64(g11[i]) + f11[i]) * (n + i64(i) * sqrt_K) % mod;
}
rep(i, n) {
f11[i] = i64(f11[i]) * (i64(N) + mod - sqrt_K * i - n + 1) % mod;
}
vector<int> vals(n);
rep(i, n) vals[i] = (i64(sqrt_K) * n + i + 1) % mod;
if (i64(sqrt_K + 1) * n < mod) {
int prod = 1;
rep(i, n) prod = i64(prod) * vals[i] % mod;
auto invs = mod_invs(vals);
i64 s = 0;
rep(i, n) {
s += prod;
prod = i64(prod) * invs[i] % mod * (i64(N) + mod - i64(sqrt_K) * n - i) % mod;
}
g11.push_back(s % mod);
f11.push_back(prod);
} else {
g11.push_back(0);
f11.push_back(0);
}
}
return {f11, g11};
};
auto res = rec(sqrt_K);
auto &f1 = res.first, &g1 = res.second;
auto f2 = shift(conv(f1), f1, N - i64(sqrt_K) * (sqrt_K + 1));
reverse(f2.begin(), f2.end());
f2.resize(f2.size() - 1);
f2 = mod_invs(f2);
i64 ret = 0;
rep(i, sqrt_K) {
ret = (ret * f1[sqrt_K - 1 - i] + g1[sqrt_K - 1 - i]) % mod;
ret = ret * f2[sqrt_K - 1 - i] % mod;
}
int prod = 1;
rep(i, sqrt_K) {
prod = i64(prod) * f1[i] % mod * f2[i] % mod;
}
const int rest = max(0, K - sqrt_K * sqrt_K);
ret += prod;
vector<int> invs(rest);
rep(i, rest) invs[i] = i + 1 + sqrt_K * sqrt_K;
invs = mod_invs(invs);
rep(i, rest) {
prod = i64(prod) * (N - sqrt_K * sqrt_K - i) % mod * invs[i] % mod;
ret += prod;
}
ret %= mod;
return ret;
}
void solve() {
const u32 p = u32(-1) >> 1;
printf("%d\n", binomial_sum_mod_p(2e9, 1e9, p));
}
int main() {
clock_t beg = clock();
solve();
clock_t end = clock();
fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
return 0;
}
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPMyIpCiNwcmFnbWEgR0NDIHRhcmdldCAoImF2eCIpCgojaW5jbHVkZSA8Y3N0ZGlvPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8Y3N0cmluZz4KCiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CgojaWZkZWYgX194ODZfNjRfXwojZGVmaW5lIE5UVDY0CiNlbmRpZgoKI2RlZmluZSBfcmVwKF8xLCBfMiwgXzMsIF80LCBuYW1lLCAuLi4pIG5hbWUKI2RlZmluZSByZXAyKGksIG4pIHJlcDMoaSwgMCwgbikKI2RlZmluZSByZXAzKGksIGEsIGIpIHJlcDQoaSwgYSwgYiwgMSkKI2RlZmluZSByZXA0KGksIGEsIGIsIGMpIGZvciAoaW50IGkgPSBpbnQoYSk7IGkgPCBpbnQoYik7IGkgKz0gaW50KGMpKQojZGVmaW5lIHJlcCguLi4pIF9yZXAoX19WQV9BUkdTX18sIHJlcDQsIHJlcDMsIHJlcDIsIF8pKF9fVkFfQVJHU19fKQoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnVzaW5nIGk2NCA9IGxvbmcgbG9uZzsKdXNpbmcgdTMyID0gdW5zaWduZWQ7CnVzaW5nIHU2NCA9IHVuc2lnbmVkIGxvbmcgbG9uZzsKdXNpbmcgZjgwID0gbG9uZyBkb3VibGU7CgpuYW1lc3BhY2UgbnR0IHsKCiNpZmRlZiBOVFQ2NAogIHVzaW5nIHdvcmRfdCA9IHU2NDsKICB1c2luZyBkd29yZF90ID0gX191aW50MTI4X3Q7CiNlbHNlCiAgdXNpbmcgd29yZF90ID0gdTMyOwogIHVzaW5nIGR3b3JkX3QgPSB1NjQ7CiNlbmRpZgpzdGF0aWMgY29uc3QgaW50IHdvcmRfYml0cyA9IDggKiBzaXplb2Yod29yZF90KTsKCnRlbXBsYXRlIDx3b3JkX3QgbW9kLCB3b3JkX3QgcHJpbV9yb290PgpjbGFzcyBNb2Qgewpwcml2YXRlOgogIHN0YXRpYyBjb25zdGV4cHIgd29yZF90IG11bF9pbnYod29yZF90IG4sIGludCBlPTYsIHdvcmRfdCB4PTEpIHsKICAgIHJldHVybiBlID09IDAgPyB4IDogbXVsX2ludihuLCBlLTEsIHgqKDIteCpuKSk7CiAgfQpwdWJsaWM6CiAgc3RhdGljIGNvbnN0ZXhwciB3b3JkX3QgaW52ID0gbXVsX2ludihtb2QpOwogIHN0YXRpYyBjb25zdGV4cHIgd29yZF90IHIyID0gLWR3b3JkX3QobW9kKSAlIG1vZDsKICBzdGF0aWMgY29uc3RleHByIGludCBsZXZlbCA9IF9fYnVpbHRpbl9jdHpsbChtb2QgLSAxKTsKICBzdGF0aWNfYXNzZXJ0KGludiAqIG1vZCA9PSAxLCAiaW52YWxpZCAxL00gbW9kdWxvIDJeQC4iKTsKCiAgTW9kKCkge30KICBNb2Qod29yZF90IG4pIDogeChpbml0KG4pKSB7fTsKICBzdGF0aWMgd29yZF90IG1vZHVsdXMoKSB7IHJldHVybiBtb2Q7IH0KICBzdGF0aWMgd29yZF90IGluaXQod29yZF90IHcpIHsgcmV0dXJuIHJlZHVjZShkd29yZF90KHcpICogcjIpOyB9CiAgc3RhdGljIHdvcmRfdCByZWR1Y2UoY29uc3QgZHdvcmRfdCB3KSB7IHJldHVybiB3b3JkX3QodyA+PiB3b3JkX2JpdHMpICsgbW9kIC0gd29yZF90KChkd29yZF90KHdvcmRfdCh3KSAqIGludikgKiBtb2QpID4+IHdvcmRfYml0cyk7IH0KICBzdGF0aWMgTW9kIG9tZWdhKCkgeyByZXR1cm4gTW9kKHByaW1fcm9vdCkucG93KChtb2QgLSAxKSA+PiBsZXZlbCk7IH0KICBNb2QmIG9wZXJhdG9yICs9IChNb2QgcmhzKSB7IHRoaXMtPnggKz0gcmhzLng7IHJldHVybiAqdGhpczsgfQogIE1vZCYgb3BlcmF0b3IgLT0gKE1vZCByaHMpIHsgdGhpcy0+eCArPSAzICogbW9kIC0gcmhzLng7IHJldHVybiAqdGhpczsgfQogIE1vZCYgb3BlcmF0b3IgKj0gKE1vZCByaHMpIHsgdGhpcy0+eCA9IHJlZHVjZShkd29yZF90KHRoaXMtPngpICogcmhzLngpOyByZXR1cm4gKnRoaXM7IH0KICBNb2Qgb3BlcmF0b3IgKyAoTW9kIHJocykgY29uc3QgeyByZXR1cm4gTW9kKCp0aGlzKSArPSByaHM7IH0KICBNb2Qgb3BlcmF0b3IgLSAoTW9kIHJocykgY29uc3QgeyByZXR1cm4gTW9kKCp0aGlzKSAtPSByaHM7IH0KICBNb2Qgb3BlcmF0b3IgKiAoTW9kIHJocykgY29uc3QgeyByZXR1cm4gTW9kKCp0aGlzKSAqPSByaHM7IH0KICB3b3JkX3QgZ2V0KCkgY29uc3QgeyByZXR1cm4gcmVkdWNlKHRoaXMtPngpICUgbW9kOyB9CiAgdm9pZCBzZXQod29yZF90IG4pIGNvbnN0IHsgdGhpcy0+eCA9IG47IH0KICBNb2QgcG93KHdvcmRfdCBleHApIGNvbnN0IHsKICAgIE1vZCByZXQgPSBNb2QoMSk7CiAgICBmb3IgKE1vZCBiYXNlID0gKnRoaXM7IGV4cDsgZXhwID4+PSAxLCBiYXNlICo9IGJhc2UpIGlmIChleHAgJiAxKSByZXQgKj0gYmFzZTsKICAgIHJldHVybiByZXQ7CiAgfQogIE1vZCBpbnZlcnNlKCkgY29uc3QgeyByZXR1cm4gcG93KG1vZCAtIDIpOyB9CiAgZnJpZW5kIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvcywgY29uc3QgTW9kJiBtKSB7IHJldHVybiBvcyA8PCBtLmdldCgpOyB9CiAgc3RhdGljIHZvaWQgZGVidWcoKSB7CiAgICBwcmludGYoIiVsbHUgJWxsdSAlbGx1ICVsbHVcbiIsIG1vZCwgaW52LCByMiwgb21lZ2EoKS5nZXQoKSk7CiAgfQogIHdvcmRfdCB4Owp9OwoKY29uc3QgaW50IHNpemUgPSAxIDw8IDE2OwoKI2lmZGVmIE5UVDY0CiAgdXNpbmcgbTY0XzEgPSBudHQ6Ok1vZDw3MDkxNDM3NjgyMjk0Nzg0MDEsIDMxPjsKICB1c2luZyBtNjRfMiA9IG50dDo6TW9kPDcxMTQxNjY2NDkyMjUyMTYwMSwgMTk+OyAvLyA8PSA3MTJlMTUgKHN1Yi5EID0gMykKICBtNjRfMSBmMVtzaXplXSwgZzFbc2l6ZV07CiAgbTY0XzIgZjJbc2l6ZV0sIGcyW3NpemVdOwojZWxzZQogIHVzaW5nIG0zMl8xID0gbnR0OjpNb2Q8MTM4NDEyMDMzLCA1PjsKICB1c2luZyBtMzJfMiA9IG50dDo6TW9kPDE1NTE4OTI0OSwgNj47CiAgdXNpbmcgbTMyXzMgPSBudHQ6Ok1vZDwxNjM1Nzc4NTcsIDIzPjsgLy8gPD0gIDE2NTc5ZTQgKHN1Yi5EID0gMykKICBtMzJfMSBmMVtzaXplXSwgZzFbc2l6ZV07CiAgbTMyXzIgZjJbc2l6ZV0sIGcyW3NpemVdOwogIG0zMl8zIGYzW3NpemVdLCBnM1tzaXplXTsKI2VuZGlmCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgbW9kX3Q+CnZvaWQgY29udm9sdmUobW9kX3QqIEEsIGludCBzMSwgbW9kX3QqIEIsIGludCBzMiwgYm9vbCBjeWNsaWM9ZmFsc2UpIHsKICBpbnQgcyA9IChjeWNsaWMgPyBtYXgoczEsIHMyKSA6IHMxICsgczIgLSAxKTsKICBpbnQgc2l6ZSA9IDE7CiAgd2hpbGUgKHNpemUgPCBzKSBzaXplIDw8PSAxOwogIG1vZF90IHJvb3RzW21vZF90OjpsZXZlbF0gPSB7IG1vZF90OjpvbWVnYSgpIH07CiAgcmVwKGksIDEsIG1vZF90OjpsZXZlbCkgcm9vdHNbaV0gPSByb290c1tpIC0gMV0gKiByb290c1tpIC0gMV07CiAgZmlsbChBICsgczEsIEEgKyBzaXplLCAwKTsgbnR0X2RpdDQoQSwgc2l6ZSwgMSwgcm9vdHMpOwogIGlmIChBID09IEIgJiYgczEgPT0gczIpIHsKICAgIHJlcChpLCBzaXplKSBBW2ldICo9IEFbaV07CiAgfSBlbHNlIHsKICAgIGZpbGwoQiArIHMyLCBCICsgc2l6ZSwgMCk7IG50dF9kaXQ0KEIsIHNpemUsIDEsIHJvb3RzKTsKICAgIHJlcChpLCBzaXplKSBBW2ldICo9IEJbaV07CiAgfQogIG50dF9kaXQ0KEEsIHNpemUsIC0xLCByb290cyk7CiAgbW9kX3QgaW52ID0gbW9kX3Qoc2l6ZSkuaW52ZXJzZSgpOwogIHJlcChpLCBjeWNsaWMgPyBzaXplIDogcykgQVtpXSAqPSBpbnY7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBtb2RfdD4Kdm9pZCByZXZfcGVybXV0ZShtb2RfdCogQSwgaW50IG4pIHsKICBpbnQgciA9IDAsIG5oID0gbiA+PiAxOwogIHJlcChpLCAxLCBuKSB7CiAgICBmb3IgKGludCBoID0gbmg7ICEoKHIgXj0gaCkgJiBoKTsgaCA+Pj0gMSk7CiAgICBpZiAociA+IGkpIHN3YXAoQVtpXSwgQVtyXSk7CiAgfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgbW9kX3Q+CnZvaWQgbnR0X2RpdDQobW9kX3QqIEEsIGludCBuLCBpbnQgc2lnbiwgbW9kX3QqIHJvb3RzKSB7CiAgcmV2X3Blcm11dGUoQSwgbik7CiAgaW50IGxvZ24gPSBfX2J1aWx0aW5fY3R6KG4pOwogIGFzc2VydChsb2duIDw9IG1vZF90OjpsZXZlbCk7CgogIGlmIChsb2duICYgMSkgcmVwKGksIDAsIG4sIDIpIHsKICAgIG1vZF90IGEgPSBBW2ldLCBiID0gQVtpICsgMV07CiAgICBBW2ldID0gYSArIGI7IEFbaSArIDFdID0gYSAtIGI7CiAgfQogIG1vZF90IGltYWcgPSByb290c1ttb2RfdDo6bGV2ZWwgLSAyXTsKICBpZiAoc2lnbiA8IDApIGltYWcgPSBpbWFnLmludmVyc2UoKTsKCiAgbW9kX3Qgb25lID0gbW9kX3QoMSk7CiAgcmVwKGUsIDIgKyAobG9nbiAmIDEpLCBsb2duICsgMSwgMikgewogICAgY29uc3QgaW50IG0gPSAxIDw8IGU7CiAgICBjb25zdCBpbnQgbTQgPSBtID4+IDI7CiAgICBtb2RfdCBkdyA9IHJvb3RzW21vZF90OjpsZXZlbCAtIGVdOwogICAgaWYgKHNpZ24gPCAwKSBkdyA9IGR3LmludmVyc2UoKTsKCiAgICBjb25zdCBpbnQgYmxvY2tfc2l6ZSA9IG1pbihuLCBtYXgobSwgKDEgPDwgMTUpIC8gaW50KHNpemVvZihBWzBdKSkpKTsKICAgIHJlcChrLCAwLCBuLCBibG9ja19zaXplKSB7CiAgICAgIG1vZF90IHcgPSBvbmUsIHcyID0gb25lLCB3MyA9IG9uZTsKICAgICAgcmVwKGosIG00KSB7CiAgICAgICAgcmVwKGksIGsgKyBqLCBrICsgYmxvY2tfc2l6ZSwgbSkgewogICAgICAgICAgbW9kX3QgYTAgPSBBW2kgKyBtNCAqIDBdICogb25lLCBhMiA9IEFbaSArIG00ICogMV0gKiB3MjsKICAgICAgICAgIG1vZF90IGExID0gQVtpICsgbTQgKiAyXSAqIHcsICAgYTMgPSBBW2kgKyBtNCAqIDNdICogdzM7CiAgICAgICAgICBtb2RfdCB0MDIgPSBhMCArIGEyLCB0MTMgPSBhMSArIGEzOwogICAgICAgICAgQVtpICsgbTQgKiAwXSA9IHQwMiArIHQxMzsgQVtpICsgbTQgKiAyXSA9IHQwMiAtIHQxMzsKICAgICAgICAgIHQwMiA9IGEwIC0gYTIsIHQxMyA9IChhMSAtIGEzKSAqIGltYWc7CiAgICAgICAgICBBW2kgKyBtNCAqIDFdID0gdDAyICsgdDEzOyBBW2kgKyBtNCAqIDNdID0gdDAyIC0gdDEzOwogICAgICAgIH0KICAgICAgICB3ICo9IGR3OyB3MiA9IHcgKiB3OyB3MyA9IHcyICogdzsKICAgICAgfQogICAgfQogIH0KfQoKfSAvLyBuYW1lc3BhY2UgbnR0Cgp1c2luZyBSID0gaW50Owp1c2luZyBSNjQgPSBpNjQ7CgpjbGFzcyBwb2x5IHsKcHVibGljOgojaWZkZWYgTlRUNjQKICBzdGF0aWMgY29uc3QgaW50IG50dF90aHJlc2hvbGQgPSA5MDA7IC8vIGRlZyhmICogZykKI2Vsc2UKICBzdGF0aWMgY29uc3QgaW50IG50dF90aHJlc2hvbGQgPSAxNTAwOyAvLyBkZWcoZiAqIGcpCiNlbmRpZgoKICBzdGF0aWMgUiBhZGRfbW9kKFIgYSwgUiBiKSB7IHJldHVybiBpbnQoYSArPSBiIC0gbW9kKSA8IDAgPyBhICsgbW9kIDogYTsgfQogIHN0YXRpYyBSIHN1Yl9tb2QoUiBhLCBSIGIpIHsgcmV0dXJuIGludChhIC09IGIpIDwgMCA/IGEgKyBtb2QgOiBhOyB9CiAgc3RhdGljIFI2NCBzdWJfbXVsX21vZChSNjQgYSwgUiBiLCBSIGMpIHsKICAgIGk2NCB0ID0gaTY0KGEpIC0gaTY0KGludChiKSkgKiBpbnQoYyk7CiAgICByZXR1cm4gdCA8IDAgPyB0ICsgbG1vZCA6IHQ7CiAgfQogIHN0YXRpYyBSIG11bF9tb2QoUiBhLCBSIGIpIHsgcmV0dXJuIFI2NChhKSAqIGIgJSBmYXN0X21vZDsgfQogIHN0YXRpYyBSIHBvd19tb2QoUiBhLCBpbnQgZSkgewogICAgUiByZXQgPSAxICUgZmFzdF9tb2Q7CiAgICBmb3IgKDsgZTsgZSA+Pj0gMSwgYSA9IG11bF9tb2QoYSwgYSkpIHsKICAgICAgaWYgKGUgJiAxKSByZXQgPSBtdWxfbW9kKHJldCwgYSk7CiAgICB9CiAgICByZXR1cm4gcmV0OwogIH0KICBzdGF0aWMgUiBtb2RfaW52KFIgYSkgewogICAgUiBiID0gbW9kLCBzID0gMSwgdCA9IDA7CiAgICB3aGlsZSAoYiA+IDApIHsKICAgICAgc3dhcChzIC09IHQgKiAoYSAvIGIpLCB0KTsKICAgICAgc3dhcChhICU9IGIsIGIpOwogICAgfQogICAgaWYgKGEgPiAxKSB7IGZwcmludGYoc3RkZXJyLCAiRXJyb3I6IGludmFsaWQgbW9kdWxhciBpbnZlcnNlXG4iKTsgZXhpdCgxKTsgfTsKICAgIHJldHVybiBpbnQocykgPCAwID8gcyArIG1vZCA6IHM7CiAgfQogIGlubGluZSBzdGF0aWMgdm9pZCB2ZWNfYWRkKFI2NCogcmVzLCBpbnQgcywgY29uc3QgUiogZiwgUiBjKSB7CiAgICByZXAoaSwgcykgcmVzW2ldID0gc3ViX211bF9tb2QocmVzW2ldLCBtb2QgLSBjLCBmW2ldKTsKICB9CiAgaW5saW5lIHN0YXRpYyB2b2lkIHZlY19zdWIoUjY0KiByZXMsIGludCBzLCBjb25zdCBSKiBmLCBSIGMpIHsKICAgIHJlcChpLCBzKSByZXNbaV0gPSBzdWJfbXVsX21vZChyZXNbaV0sIGMsIGZbaV0pOwogIH0KCiNpZmRlZiBOVFQ2NAogIHN0cnVjdCBmYXN0X2RpdiB7CiAgICB1c2luZyB1MTI4ID0gX191aW50MTI4X3Q7CiAgICBmYXN0X2RpdigpIHt9CiAgICBmYXN0X2Rpdih1NjQgbikgOiBtKG4pIHsKICAgICAgcyA9IChuID09IDEpID8gMCA6IDEyNyAtIF9fYnVpbHRpbl9jbHpsbChuIC0gMSk7CiAgICAgIHggPSAoKHUxMjgoMSkgPDwgcykgKyBuIC0gMSkgLyBuOwogICAgfQogICAgZnJpZW5kIHU2NCBvcGVyYXRvciAvICh1NjQgbiwgZmFzdF9kaXYgZCkgeyByZXR1cm4gdTEyOChuKSAqIGQueCA+PiBkLnM7IH0KICAgIGZyaWVuZCB1NjQgb3BlcmF0b3IgJSAodTY0IG4sIGZhc3RfZGl2IGQpIHsgcmV0dXJuIG4gLSBuIC8gZCAqIGQubTsgfQogICAgdTY0IG0sIHMsIHg7CiAgfTsKI2Vsc2UKICBzdHJ1Y3QgZmFzdF9kaXYgewogICAgZmFzdF9kaXYoKSB7fQogICAgZmFzdF9kaXYodTMyIG4pIDogbShuKSB7fQogICAgZnJpZW5kIHUzMiBvcGVyYXRvciAlICh1NjQgbiwgZmFzdF9kaXYgZCkgeyByZXR1cm4gbiAlIGQubTsgfQogICAgdTMyIG07CiAgfTsKI2VuZGlmCgpwdWJsaWM6CiAgcG9seSgpIHt9CiAgcG9seShpbnQgbikgOiBjb2VmcyhuKSB7fQogIHBvbHkoaW50IG4sIGludCBjKSA6IGNvZWZzKG4sIGMgJSBtb2QpIHt9CiAgcG9seShjb25zdCBSKiBhciwgaW50IHMpIDogY29lZnMoYXIsIGFyICsgcykge30KICBwb2x5KGNvbnN0IHZlY3RvcjxSPiYgdikgOiBjb2Vmcyh2KSB7fQogIHBvbHkoY29uc3QgcG9seSYgZiwgaW50IGJlZywgaW50IGVuZD0tMSkgewogICAgaWYgKGVuZCA8IDApIGVuZCA9IGJlZywgYmVnID0gMDsKICAgIHJlc2l6ZShlbmQgLSBiZWcpOwogICAgcmVwKGksIGJlZywgZW5kKSBpZiAoaSA8IGYuc2l6ZSgpKSBjb2Vmc1tpIC0gYmVnXSA9IGZbaV07CiAgfQoKICBzdGF0aWMgaW50IGlsb2cyKHU2NCBuKSB7CiAgICByZXR1cm4gNjMgLSBfX2J1aWx0aW5fY2x6bGwobik7CiAgfQogIGludCBzaXplKCkgY29uc3QgeyByZXR1cm4gY29lZnMuc2l6ZSgpOyB9CiAgdm9pZCByZXNpemUoaW50IHMpIHsgY29lZnMucmVzaXplKHMpOyB9CiAgdm9pZCBwdXNoX2JhY2soUiBjKSB7IGNvZWZzLnB1c2hfYmFjayhjKTsgfQoKICBjb25zdCBSKiBkYXRhKCkgY29uc3QgeyByZXR1cm4gY29lZnMuZGF0YSgpOyB9CiAgUiogZGF0YSgpIHsgcmV0dXJuIGNvZWZzLmRhdGEoKTsgfQogIGNvbnN0IFImIG9wZXJhdG9yIFtdIChpbnQgaSkgY29uc3QgeyByZXR1cm4gY29lZnNbaV07IH0KICBSJiBvcGVyYXRvciBbXSAoaW50IGkpIHsgcmV0dXJuIGNvZWZzW2ldOyB9CgogIHZvaWQgcmV2ZXJzZSgpIHsgc3RkOjpyZXZlcnNlKGNvZWZzLmJlZ2luKCksIGNvZWZzLmVuZCgpKTsgfQoKICBwb2x5IG9wZXJhdG9yIC0gKCkgewogICAgcG9seSByZXQgPSAqdGhpczsKICAgIHJlcChpLCByZXQuc2l6ZSgpKSByZXRbaV0gPSAocmV0W2ldID09IDAgPyAwIDogbW9kIC0gcmV0W2ldKTsKICAgIHJldHVybiByZXQ7CiAgfQogIHBvbHkmIG9wZXJhdG9yICs9IChjb25zdCBwb2x5JiByaHMpIHsKICAgIGlmIChzaXplKCkgPCByaHMuc2l6ZSgpKSByZXNpemUocmhzLnNpemUoKSk7CiAgICByZXAoaSwgcmhzLnNpemUoKSkgY29lZnNbaV0gPSBhZGRfbW9kKGNvZWZzW2ldLCByaHNbaV0pOwogICAgcmV0dXJuICp0aGlzOwogIH0KICBwb2x5JiBvcGVyYXRvciAtPSAoY29uc3QgcG9seSYgcmhzKSB7CiAgICBpZiAoc2l6ZSgpIDwgcmhzLnNpemUoKSkgcmVzaXplKHJocy5zaXplKCkpOwogICAgcmVwKGksIHJocy5zaXplKCkpIGNvZWZzW2ldID0gc3ViX21vZChjb2Vmc1tpXSwgcmhzW2ldKTsKICAgIHJldHVybiAqdGhpczsKICB9CiAgcG9seSYgb3BlcmF0b3IgKj0gKGNvbnN0IHBvbHkmIHJocykgeyByZXR1cm4gKnRoaXMgPSAqdGhpcyAqIHJoczsgfQoKICBwb2x5JiByZXZfYWRkKGNvbnN0IHBvbHkmIHJocykgewogICAgaWYgKHNpemUoKSA8IHJocy5zaXplKCkpIHsKICAgICAgaW50IHMgPSBzaXplKCk7CiAgICAgIHJlc2l6ZShyaHMuc2l6ZSgpKTsKICAgICAgcmVwKGksIHMpIGNvZWZzW3NpemUoKSAtIDEgLSBpXSA9IGNvZWZzW3MgLSAxIC0gaV07CiAgICAgIHJlcChpLCBzaXplKCkgLSBzKSBjb2Vmc1tpXSA9IDA7CiAgICB9CiAgICByZXAoaSwgcmhzLnNpemUoKSkgY29lZnNbc2l6ZSgpIC0gMSAtIGldID0gXAogICAgICBhZGRfbW9kKGNvZWZzW3NpemUoKSAtIDEgLSBpXSwgcmhzLmNvZWZzW3Jocy5zaXplKCkgLSAxIC0gaV0pOwogICAgcmV0dXJuICp0aGlzOwogIH0KCiAgcG9seSBvcGVyYXRvciArIChjb25zdCBwb2x5JiByaHMpIGNvbnN0IHsgcmV0dXJuIHBvbHkoKnRoaXMpICs9IHJoczsgfQogIHBvbHkgb3BlcmF0b3IgLSAoY29uc3QgcG9seSYgcmhzKSBjb25zdCB7IHJldHVybiBwb2x5KCp0aGlzKSAtPSByaHM7IH0KICBwb2x5IG9wZXJhdG9yICogKGNvbnN0IHBvbHkmIHJocykgY29uc3QgeyByZXR1cm4gdGhpcy0+bXVsKHJocyk7IH0KCiAgc3RhdGljIHZvaWQgc2V0X21vZChSIG0sIGludCBOPTIpIHsKICAgIG1vZCA9IG07CiAgICBsbW9kID0gUjY0KG0pIDw8IDMyOwogICAgTiA9IG1heCgyLCBOKTsKICAgIGZhc3RfbW9kID0gZmFzdF9kaXYobW9kKTsKICAgIGludnMuYXNzaWduKE4gKyAxLCAxKTsKICAgIGZhY3RzLmFzc2lnbihOICsgMSwgMSk7CiAgICBpZmFjdHMuYXNzaWduKE4gKyAxLCAxKTsKICAgIGludnNbMV0gPSAxOwogICAgcmVwKGksIDIsIE4gKyAxKSB7CiAgICAgIGludnNbaV0gPSBtdWxfbW9kKGludnNbbW9kICUgaV0sIG1vZCAtIG1vZCAvIGkpOwogICAgICBmYWN0c1tpXSA9IG11bF9tb2QoZmFjdHNbaSAtIDFdLCBpKTsKICAgICAgaWZhY3RzW2ldID0gbXVsX21vZChpZmFjdHNbaSAtIDFdLCBpbnZzW2ldKTsKICAgIH0KICB9Cgpwcml2YXRlOgoKI2lmZGVmIE5UVDY0CiAgc3RhdGljIHBvbHkgbXVsX2NydChpbnQgYmVnLCBpbnQgZW5kKSB7CiAgICB1c2luZyBuYW1lc3BhY2UgbnR0OwogICAgYXV0byBpbnYgPSBtNjRfMihtNjRfMTo6bW9kdWx1cygpKS5pbnZlcnNlKCk7CiAgICBhdXRvIG1vZDEgPSBtNjRfMTo6bW9kdWx1cygpICUgZmFzdF9tb2Q7CiAgICBwb2x5IHJldChlbmQgLSBiZWcpOwogICAgcmVwKGksIHJldC5zaXplKCkpIHsKICAgICAgdTY0IHIxID0gZjFbaSArIGJlZ10uZ2V0KCksIHIyID0gZjJbaSArIGJlZ10uZ2V0KCk7CiAgICAgIHJldFtpXSA9IChyMSArIChtNjRfMihyMiArIG02NF8yOjptb2R1bHVzKCkgLSByMSkgKiBpbnYpLmdldCgpICUgZmFzdF9tb2QgKiBtb2QxKSAlIGZhc3RfbW9kOwogICAgfQogICAgcmV0dXJuIHJldDsKICB9CgogIHN0YXRpYyB2b2lkIG11bDIoY29uc3QgcG9seSYgZiwgY29uc3QgcG9seSYgZywgYm9vbCBjeWNsaWM9ZmFsc2UpIHsKICAgIHVzaW5nIG5hbWVzcGFjZSBudHQ7CiAgICBpZiAoJmYgPT0gJmcpIHsKICAgICAgcmVwKGksIGYuc2l6ZSgpKSBmMVtpXSA9IGZbaV07IAogICAgICBjb252b2x2ZShmMSwgZi5zaXplKCksIGYxLCBmLnNpemUoKSwgY3ljbGljKTsKICAgICAgcmVwKGksIGYuc2l6ZSgpKSBmMltpXSA9IGZbaV07IAogICAgICBjb252b2x2ZShmMiwgZi5zaXplKCksIGYyLCBmLnNpemUoKSwgY3ljbGljKTsKICAgIH0gZWxzZSB7CiAgICAgIHJlcChpLCBmLnNpemUoKSkgZjFbaV0gPSBmW2ldOyByZXAoaSwgZy5zaXplKCkpIGcxW2ldID0gZ1tpXTsKICAgICAgY29udm9sdmUoZjEsIGYuc2l6ZSgpLCBnMSwgZy5zaXplKCksIGN5Y2xpYyk7CiAgICAgIHJlcChpLCBmLnNpemUoKSkgZjJbaV0gPSBmW2ldOyByZXAoaSwgZy5zaXplKCkpIGcyW2ldID0gZ1tpXTsKICAgICAgY29udm9sdmUoZjIsIGYuc2l6ZSgpLCBnMiwgZy5zaXplKCksIGN5Y2xpYyk7CiAgICB9CiAgfQojZWxzZQogIHN0YXRpYyBwb2x5IG11bF9jcnQoaW50IGJlZywgaW50IGVuZCkgewogICAgdXNpbmcgbmFtZXNwYWNlIG50dDsKICAgIGF1dG8gbTEgPSBtMzJfMTo6bW9kdWx1cygpOwogICAgYXV0byBtMiA9IG0zMl8yOjptb2R1bHVzKCk7CiAgICBhdXRvIG0zID0gbTMyXzM6Om1vZHVsdXMoKTsKICAgIGF1dG8gbTEyID0gdTY0KG0xKSAqIG0yOwoKICAgIHBvbHkgcmV0KGVuZCAtIGJlZyk7CiAgICB1MzIgbTEybSA9IG0xMiAlIG1vZDsKICAgIHUzMiBpbnYxID0gbTMyXzIobTEpLmludmVyc2UoKS5nZXQoKTsKICAgIHUzMiBpbnYxMiA9IG0zMl8zKG0xMiAlIG0zKS5pbnZlcnNlKCkuZ2V0KCk7CgogICAgcmVwKGksIHJldC5zaXplKCkpIHsKICAgICAgdTMyIHIxID0gZjFbaSArIGJlZ10uZ2V0KCksIHIyID0gZjJbaSArIGJlZ10uZ2V0KCksIHIzID0gZjNbaSArIGJlZ10uZ2V0KCk7CiAgICAgIHU2NCByID0gcjEgKyB1NjQocjIgKyBtMiAtIHIxKSAqIGludjEgJSBtMiAqIG0xOwogICAgICByZXRbaV0gPSAociArIHU2NChyMyArIG0zIC0gciAlIG0zKSAqIGludjEyICUgbTMgKiBtMTJtKSAlIG1vZDsKICAgIH0KICAgIHJldHVybiByZXQ7CiAgfQoKICBzdGF0aWMgdm9pZCBtdWwyKGNvbnN0IHBvbHkmIGYsIGNvbnN0IHBvbHkmIGcsIGJvb2wgY3ljbGljPWZhbHNlKSB7CiAgICB1c2luZyBuYW1lc3BhY2UgbnR0OwogICAgaWYgKCZmID09ICZnKSB7CiAgICAgIHJlcChpLCBmLnNpemUoKSkgZjFbaV0gPSBmW2ldICUgbTMyXzE6Om1vZHVsdXMoKTsKICAgICAgY29udm9sdmUoZjEsIGYuc2l6ZSgpLCBmMSwgZi5zaXplKCksIGN5Y2xpYyk7CiAgICAgIHJlcChpLCBmLnNpemUoKSkgZjJbaV0gPSBmW2ldICUgbTMyXzI6Om1vZHVsdXMoKTsKICAgICAgY29udm9sdmUoZjIsIGYuc2l6ZSgpLCBmMiwgZi5zaXplKCksIGN5Y2xpYyk7CiAgICAgIHJlcChpLCBmLnNpemUoKSkgZjNbaV0gPSBmW2ldICUgbTMyXzM6Om1vZHVsdXMoKTsKICAgICAgY29udm9sdmUoZjMsIGYuc2l6ZSgpLCBmMywgZi5zaXplKCksIGN5Y2xpYyk7CiAgICB9IGVsc2UgewogICAgICByZXAoaSwgZi5zaXplKCkpIGYxW2ldID0gZltpXSAlIG0zMl8xOjptb2R1bHVzKCk7IAogICAgICByZXAoaSwgZy5zaXplKCkpIGcxW2ldID0gZ1tpXSAlIG0zMl8xOjptb2R1bHVzKCk7CiAgICAgIGNvbnZvbHZlKGYxLCBmLnNpemUoKSwgZzEsIGcuc2l6ZSgpLCBjeWNsaWMpOwogICAgICByZXAoaSwgZi5zaXplKCkpIGYyW2ldID0gZltpXSAlIG0zMl8yOjptb2R1bHVzKCk7IAogICAgICByZXAoaSwgZy5zaXplKCkpIGcyW2ldID0gZ1tpXSAlIG0zMl8yOjptb2R1bHVzKCk7CiAgICAgIGNvbnZvbHZlKGYyLCBmLnNpemUoKSwgZzIsIGcuc2l6ZSgpLCBjeWNsaWMpOwogICAgICByZXAoaSwgZi5zaXplKCkpIGYzW2ldID0gZltpXSAlIG0zMl8zOjptb2R1bHVzKCk7IAogICAgICByZXAoaSwgZy5zaXplKCkpIGczW2ldID0gZ1tpXSAlIG0zMl8zOjptb2R1bHVzKCk7CiAgICAgIGNvbnZvbHZlKGYzLCBmLnNpemUoKSwgZzMsIGcuc2l6ZSgpLCBjeWNsaWMpOwogICAgfQogIH0KI2VuZGlmIAoKcHVibGljOgogIHN0YXRpYyB2b2lkIGFtdWwoY29uc3QgUiogZiwgaW50IHMxLCBjb25zdCBSKiBnLCBpbnQgczIsIFIqIHJlcykgewogICAgaW50IHMgPSBzMSArIHMyIC0gMTsKICAgIHRtcDY0LmFzc2lnbihzLCAwKTsKICAgIHJlcChpLCBzMikgaWYgKGdbaV0pIHZlY19hZGQodG1wNjQuZGF0YSgpICsgaSwgczEsIGYsIGdbaV0pOwogICAgcmVwKGksIHMpIHJlc1tpXSA9IHRtcDY0W2ldICUgZmFzdF9tb2Q7CiAgfQogIAogIHBvbHkgbXVsX2Jhc2VjYXNlKGNvbnN0IHBvbHkmIGcpIGNvbnN0IHsKICAgIGNvbnN0IGF1dG8mIGYgPSAqdGhpczsKICAgIGludCBzID0gc2l6ZSgpICsgZy5zaXplKCkgLSAxOwogICAgcG9seSByZXQocyk7CiAgICBhbXVsKGYuZGF0YSgpLCBmLnNpemUoKSwgZy5kYXRhKCksIGcuc2l6ZSgpLCByZXQuZGF0YSgpKTsKICAgIHJldHVybiByZXQ7CiAgfQoKICAvLyAxLjAgKiBNKG4pCiAgcG9seSBtdWwoY29uc3QgcG9seSYgZykgY29uc3QgewogICAgY29uc3QgYXV0byYgZiA9ICp0aGlzOwogICAgaWYgKGYuc2l6ZSgpID09IDAgfHwgZy5zaXplKCkgPT0gMCkgcmV0dXJuIHBvbHkoKTsKICAgIGlmIChmLnNpemUoKSArIGcuc2l6ZSgpIDw9IG50dF90aHJlc2hvbGQpIHsKICAgICAgcmV0dXJuIGYubXVsX2Jhc2VjYXNlKGcpOwogICAgfSBlbHNlIHsKICAgICAgbXVsMihmLCBnLCBmYWxzZSk7CiAgICAgIHJldHVybiBtdWxfY3J0KDAsIGYuc2l6ZSgpICsgZy5zaXplKCkgLSAxKTsKICAgIH0KICB9CgogIC8vIDEuMCAqIE0obikKICBwb2x5IG1pZGRsZV9wcm9kdWN0KGNvbnN0IHBvbHkmIGcpIGNvbnN0IHsKICAgIGNvbnN0IHBvbHkmIGYgPSAqdGhpczsKICAgIGlmIChmLnNpemUoKSA9PSAwIHx8IGcuc2l6ZSgpID09IDApIHJldHVybiBwb2x5KCk7CiAgICBtdWwyKGYsIGcsIHRydWUpOwogICAgcmV0dXJuIG11bF9jcnQoZi5zaXplKCksIGcuc2l6ZSgpKTsKICB9CgogIHZvaWQgcHJpbnQoKSBjb25zdCB7CiAgICBwcmludGYoIlsiKTsKICAgIGlmIChzaXplKCkpIHsKICAgICAgcHJpbnRmKCIldSIsIGNvZWZzWzBdKTsKICAgICAgcmVwKGksIDEsIHNpemUoKSkgcHJpbnRmKCIsICV1IiwgY29lZnNbaV0pOwogICAgfQogICAgcHV0cygiXSIpOwogIH0KCnB1YmxpYzoKICB2ZWN0b3I8Uj4gY29lZnM7CiAgc3RhdGljIHZlY3RvcjxSPiB0bXAzMjsKICBzdGF0aWMgdmVjdG9yPFI2ND4gdG1wNjQ7CiAgc3RhdGljIHZlY3RvcjxSPiBpbnZzLCBmYWN0cywgaWZhY3RzOwogIHN0YXRpYyBSIG1vZDsKICBzdGF0aWMgUjY0IGxtb2Q7CiAgc3RhdGljIGZhc3RfZGl2IGZhc3RfbW9kOwp9OwpSIHBvbHk6Om1vZDsKUjY0IHBvbHk6Omxtb2Q7CnBvbHk6OmZhc3RfZGl2IHBvbHk6OmZhc3RfbW9kOwp2ZWN0b3I8Uj4gcG9seTo6dG1wMzI7CnZlY3RvcjxSNjQ+IHBvbHk6OnRtcDY0Owp2ZWN0b3I8Uj4gcG9seTo6aW52cywgcG9seTo6ZmFjdHMsIHBvbHk6OmlmYWN0czsKCmludCBwb3dfbW9kKGludCBiLCBpbnQgZSwgaW50IG1vZCkgewogIGludCByZXQgPSAxOwogIGZvciAoOyBlOyBlID4+PSAxLCBiID0gaTY0KGIpICogYiAlIG1vZCkgewogICAgaWYgKGUgJiAxKSByZXQgPSBpNjQocmV0KSAqIGIgJSBtb2Q7CiAgfQogIHJldHVybiByZXQ7Cn0KCmludCBiaW5vbWlhbF9zdW1fbW9kX3AoaW50IE4sIGludCBLLCBpbnQgbW9kKSB7CiAgaWYgKEsgPT0gMCkgcmV0dXJuIDEgJSBtb2Q7CiAgaWYgKE4gPD0gSykgcmV0dXJuIHBvd19tb2QoMiwgTiwgbW9kKTsKICBpZiAoaTY0KEspICogMiA+IE4pIHsKICAgIHJldHVybiAocG93X21vZCgyLCBOLCBtb2QpICsgaTY0KG1vZCkgLSBiaW5vbWlhbF9zdW1fbW9kX3AoTiwgTiAtIEsgLSAxLCBtb2QpKSAlIG1vZDsKICB9CiAgYXNzZXJ0KE4gPCBtb2QpOwoKICBjb25zdCBpbnQgc3FydF9LID0gc3FydChLKTsKICBwb2x5OjpzZXRfbW9kKG1vZCwgc3FydF9LKTsKCiAgYXV0byBtb2RfaW52cyA9IFsmXSAodmVjdG9yPGludD4mIGYpIHsKICAgIGludCBuID0gZi5zaXplKCk7CiAgICB2ZWN0b3I8aW50PiByZXQoZik7CiAgICBpZiAobiA+IDApIHsKICAgICAgcmVwKGksIDEsIG4pIHJldFtpXSA9IGk2NChyZXRbaSAtIDFdKSAqIHJldFtpXSAlIG1vZDsKICAgICAgaW50IGludiA9IHBvbHk6Om1vZF9pbnYocmV0W24gLSAxXSk7CiAgICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+IDA7IC0taSkgewogICAgICAgIHJldFtpXSA9IGk2NChyZXRbaSAtIDFdKSAqIGludiAlIG1vZDsKICAgICAgICBpbnYgPSBpNjQoaW52KSAqIGZbaV0gJSBtb2Q7CiAgICAgIH0KICAgICAgcmV0WzBdID0gaW52OwogICAgfQogICAgcmV0dXJuIHJldDsKICB9OwoKICBhdXRvIGNvbnYgPSBbJl0gKHZlY3RvcjxpbnQ+JiBmKSAtPiBwb2x5IHsKICAgIGludCBuID0gZi5zaXplKCk7CiAgICBjb25zdCBhdXRvJiBpZmFjdHMgPSBwb2x5OjppZmFjdHM7CiAgICBhdXRvIGcgPSBwb2x5KGYpOwogICAgcmVwKGksIG4pIHsKICAgICAgaW50IGQgPSBpNjQoaWZhY3RzW2ldKSAqIGlmYWN0c1sobiAtIDEpIC0gaV0gJSBtb2Q7CiAgICAgIGlmICgobiAtIDEgLSBpKSAmIDEpIGQgPSBtb2QgLSBkOwogICAgICBnW2ldID0gaTY0KGdbaV0pICogZCAlIG1vZDsKICAgIH0KICAgIHJldHVybiBnOwogIH07CgogIGF1dG8gc2hpZnQgPSBbJl0gKGNvbnN0IHBvbHkmIGNmLCBjb25zdCBwb2x5JiBmLCBpNjQgZHgpIHsKICAgIGlmICgoZHggJT0gbW9kKSA8IDApIGR4ICs9IG1vZDsKICAgIGNvbnN0IGludCBuID0gZi5zaXplKCk7CiAgICBjb25zdCBpbnQgYSA9IGk2NChkeCkgKiBwb2x5Ojptb2RfaW52KHNxcnRfSykgJSBtb2Q7CgogICAgYXV0byBnID0gcG9seSgyICogbik7CiAgICByZXAoaSwgZy5zaXplKCkpIGdbaV0gPSAoaTY0KG1vZCkgKyBhICsgaSAtIG4pICUgbW9kOwogICAgcmVwKGksIGcuc2l6ZSgpKSBpZiAoZ1tpXSA9PSAwKSBnW2ldID0gMTsKCiAgICBnLmNvZWZzID0gbW9kX2ludnMoZy5jb2Vmcyk7CiAgICBhdXRvIHJldCA9IGNmLm1pZGRsZV9wcm9kdWN0KGcpOwogICAgaW50IHByb2QgPSAxOwogICAgcmVwKGksIG4pIHByb2QgPSBpNjQocHJvZCkgKiAoaTY0KG1vZCkgKyBhICsgbiAtIDEgLSBpKSAlIG1vZDsKICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgcmV0W2ldID0gaTY0KHJldFtpXSkgKiBwcm9kICUgbW9kOwogICAgICBwcm9kID0gaTY0KHByb2QpICogZ1tuICsgaV0gJSBtb2QgKiAoaTY0KG1vZCkgKyBhICsgaSAtIG4pICUgbW9kOwogICAgfQogICAgaWYgKGR4ICUgc3FydF9LID09IDApIHsKICAgICAgaW50IGsgPSBuIC0gZHggLyBzcXJ0X0s7CiAgICAgIHJlcChpLCBrKSByZXRbaV0gPSBmW24gLSBrICsgaV07CiAgICB9CiAgICByZXR1cm4gcmV0LmNvZWZzOwogIH07CgogIHVzaW5nIFBhaXIgPSBwYWlyPCB2ZWN0b3I8aW50PiwgdmVjdG9yPGludD4gPjsKICBmdW5jdGlvbjwgUGFpcihpbnQpID4gcmVjID0gWyZdIChpbnQgbikgLT4gUGFpciB7CiAgICBpZiAobiA9PSAxKSB7CiAgICAgIHJldHVybiBQYWlyKHtOLCBOIC0gc3FydF9LfSwgezEsIHNxcnRfSyArIDF9KTsKICAgIH0KICAgIGludCBuaCA9IG4gPj4gMTsKICAgIGF1dG8gcmVzID0gcmVjKG5oKTsKICAgIGF1dG8mIGYxMSA9IHJlcy5maXJzdCwgJmcxMSA9IHJlcy5zZWNvbmQ7CgogICAgYXV0byBmID0gY29udihmMTEpLCBnID0gY29udihnMTEpOwogICAgYXV0byBnMTIgPSBzaGlmdChnLCBnMTEsIG5oKTsKICAgIGF1dG8gZzIxID0gc2hpZnQoZywgZzExLCBpNjQoc3FydF9LKSAqIG5oKTsKICAgIGF1dG8gZzIyID0gc2hpZnQoZywgZzExLCBpNjQoc3FydF9LKSAqIG5oICsgbmgpOwoKICAgIGF1dG8gZjEyID0gc2hpZnQoZiwgZjExLCBOIC0gbmggKiBpNjQoc3FydF9LICsgMikpOwogICAgYXV0byBmMjEgPSBzaGlmdChmLCBmMTEsIGk2NChzcXJ0X0spICogbmgpOwogICAgYXV0byBmMjIgPSBzaGlmdChmLCBmMTEsIE4gLSBpNjQoMikgKiBuaCAqIChzcXJ0X0sgKyAxKSk7CiAgICByZXAoaSwgbmggKyAxKSB7CiAgICAgIGcxMVtpXSA9IChpNjQoZzExW2ldKSAqIGYxMltuaCAtIGldICsgaTY0KGcxMltpXSkgKiBmMTFbaV0pICUgbW9kOwogICAgfQogICAgcmVwKGksIDEsIG5oICsgMSkgewogICAgICBnMTEucHVzaF9iYWNrKCAoaTY0KGcyMVtpXSkgKiBmMjJbbmggLSBpXSArIGk2NChnMjJbaV0pICogZjIxW2ldKSAlIG1vZCApOwogICAgfQoKICAgIGYxMiA9IHNoaWZ0KGYsIGYxMSwgbmgpOwogICAgZjIyID0gc2hpZnQoZiwgZjExLCBpNjQoc3FydF9LKSAqIG5oICsgbmgpOwoKICAgIHJlcChpLCBuaCArIDEpIGYxMVtpXSA9IGk2NChmMTFbaV0pICogZjEyW2ldICUgbW9kOwogICAgcmVwKGksIDEsIG5oICsgMSkgZjExLnB1c2hfYmFjayhpNjQoZjIxW2ldKSAqIGYyMltpXSAlIG1vZCk7CgogICAgaWYgKG4gJiAxKSB7CiAgICAgIHJlcChpLCBuKSB7CiAgICAgICAgZzExW2ldID0gKGk2NChnMTFbaV0pICsgZjExW2ldKSAqIChuICsgaTY0KGkpICogc3FydF9LKSAlIG1vZDsKICAgICAgfQogICAgICByZXAoaSwgbikgewogICAgICAgIGYxMVtpXSA9IGk2NChmMTFbaV0pICogKGk2NChOKSArIG1vZCAtIHNxcnRfSyAqIGkgLSBuICsgMSkgJSBtb2Q7CiAgICAgIH0KICAgICAgdmVjdG9yPGludD4gdmFscyhuKTsKICAgICAgcmVwKGksIG4pIHZhbHNbaV0gPSAoaTY0KHNxcnRfSykgKiBuICsgaSArIDEpICUgbW9kOwogICAgICBpZiAoaTY0KHNxcnRfSyArIDEpICogbiA8IG1vZCkgewogICAgICAgIGludCBwcm9kID0gMTsKICAgICAgICByZXAoaSwgbikgcHJvZCA9IGk2NChwcm9kKSAqIHZhbHNbaV0gJSBtb2Q7CiAgICAgICAgYXV0byBpbnZzID0gbW9kX2ludnModmFscyk7CiAgICAgICAgaTY0IHMgPSAwOwogICAgICAgIHJlcChpLCBuKSB7CiAgICAgICAgICBzICs9IHByb2Q7CiAgICAgICAgICBwcm9kID0gaTY0KHByb2QpICogaW52c1tpXSAlIG1vZCAqIChpNjQoTikgKyBtb2QgLSBpNjQoc3FydF9LKSAqIG4gLSBpKSAlIG1vZDsKICAgICAgICB9CiAgICAgICAgZzExLnB1c2hfYmFjayhzICUgbW9kKTsKICAgICAgICBmMTEucHVzaF9iYWNrKHByb2QpOwogICAgICB9IGVsc2UgewogICAgICAgIGcxMS5wdXNoX2JhY2soMCk7CiAgICAgICAgZjExLnB1c2hfYmFjaygwKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHtmMTEsIGcxMX07CiAgfTsKCiAgYXV0byByZXMgPSByZWMoc3FydF9LKTsKICBhdXRvICZmMSA9IHJlcy5maXJzdCwgJmcxID0gcmVzLnNlY29uZDsKICBhdXRvIGYyID0gc2hpZnQoY29udihmMSksIGYxLCBOIC0gaTY0KHNxcnRfSykgKiAoc3FydF9LICsgMSkpOwogIHJldmVyc2UoZjIuYmVnaW4oKSwgZjIuZW5kKCkpOwogIGYyLnJlc2l6ZShmMi5zaXplKCkgLSAxKTsKICBmMiA9IG1vZF9pbnZzKGYyKTsKCiAgaTY0IHJldCA9IDA7CiAgcmVwKGksIHNxcnRfSykgewogICAgcmV0ID0gKHJldCAqIGYxW3NxcnRfSyAtIDEgLSBpXSArIGcxW3NxcnRfSyAtIDEgLSBpXSkgJSBtb2Q7CiAgICByZXQgPSByZXQgKiBmMltzcXJ0X0sgLSAxIC0gaV0gJSBtb2Q7CiAgfQoKICBpbnQgcHJvZCA9IDE7CiAgcmVwKGksIHNxcnRfSykgewogICAgcHJvZCA9IGk2NChwcm9kKSAqIGYxW2ldICUgbW9kICogZjJbaV0gJSBtb2Q7CiAgfQoKICBjb25zdCBpbnQgcmVzdCA9IG1heCgwLCBLIC0gc3FydF9LICogc3FydF9LKTsKICByZXQgKz0gcHJvZDsKICB2ZWN0b3I8aW50PiBpbnZzKHJlc3QpOwogIHJlcChpLCByZXN0KSBpbnZzW2ldID0gaSArIDEgKyBzcXJ0X0sgKiBzcXJ0X0s7CiAgaW52cyA9IG1vZF9pbnZzKGludnMpOwogIHJlcChpLCByZXN0KSB7CiAgICBwcm9kID0gaTY0KHByb2QpICogKE4gLSBzcXJ0X0sgKiBzcXJ0X0sgLSBpKSAlIG1vZCAqIGludnNbaV0gJSBtb2Q7CiAgICByZXQgKz0gcHJvZDsKICB9CiAgcmV0ICU9IG1vZDsKICByZXR1cm4gcmV0Owp9Cgp2b2lkIHNvbHZlKCkgewogIGNvbnN0IHUzMiBwID0gdTMyKC0xKSA+PiAxOwogIHByaW50ZigiJWRcbiIsIGJpbm9taWFsX3N1bV9tb2RfcCgyZTksIDFlOSwgcCkpOwp9CgppbnQgbWFpbigpIHsKICBjbG9ja190IGJlZyA9IGNsb2NrKCk7CiAgc29sdmUoKTsKICBjbG9ja190IGVuZCA9IGNsb2NrKCk7CiAgZnByaW50ZihzdGRlcnIsICIlLjNmIHNlY1xuIiwgZG91YmxlKGVuZCAtIGJlZykgLyBDTE9DS1NfUEVSX1NFQyk7CiAgcmV0dXJuIDA7Cn0K