// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // codeforces
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native") // yandex
#include "bits/stdc++.h"
using namespace std;
#ifndef LOCAL
#define endl '\n'
#endif
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define rf(i, a, b) for(int i = a; i >= b; i--)
#define pf push_front
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
typedef long long ll;
typedef long double f80;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int pct(int x) { return __builtin_popcount(x); }
int pct(ll x) { return __builtin_popcountll(x); }
int bt(int x) { return 31 - __builtin_clz(x); } // floor(log2(x))
int bt(ll x) { return 63 - __builtin_clzll(x); } // floor(log2(x))
int cdiv(int a, int b) { return a / b + !(a < 0 || a % b == 0); }
ll cdiv(ll a, ll b) { return a / b + !(a < 0 || a % b == 0); }
int nxt_C(int x) { int c = x & -x, r = x + c; return (((r ^ x) >> 2) / c) | r; }
ll nxt_C(ll x) { ll c = x & -x, r = x + c; return (((r ^ x) >> 2) / c) | r; }
vector<int> get_bits(int mask) {
vector<int> bb;
while(mask) { int b = bt(mask); bb.pb(b); mask ^= (1 << b); }
reverse(all(bb));
return bb;
}
int get_mask(vector<int> v) {
int mask = 0;
for(int x : v) { mask ^= (1 << x); }
return mask;
}
template<typename T>
void uniq(vector<T> &v) { sort(all(v)); v.resize(unique(all(v)) - v.begin()); }
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll rand(ll l, ll r){
uniform_int_distribution<ll> uid(l, r);
return uid(rng);
}
void sc() {}
template <typename Head, typename... Tail>
void sc(Head &H, Tail &... T) { cin >> H; sc(T...); }
#ifdef LOCAL
#define debug(...) cerr << "[L:" << __LINE__ << "][" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
// #ifndef LOCAL
// string to_string(__int128 x) {
// string s = "";
// bool neg = 0;
// if(x < 0) { s += "-"; neg = 1; x = -x; }
// if(!x) s += '0';
// while(x) {
// int rem = x % 10;
// s += to_string(rem);
// x /= 10;
// }
// reverse(s.begin() + neg, s.end());
// return s;
// }
// #endif
const int mod = 1e9 + 7; // 998244353;
int pwr(int a,ll b) {
int ans = 1;
while(b) {
if(b & 1) ans = (ans * 1LL * a) % mod;
a = (a * 1LL * a) % mod;
b >>= 1;
}
return ans;
}
/*
Lookout for overflows!!
Check array sizes!!
Clear before test cases!!
Use the correct modulo!!
Check for corner cases!!
Are you forgetting something?!
Read problem statement carefully!!!
*/
template <typename T>
T inverse(T a, T m) {
T u = 0, v = 1;
while (a != 0) {
T t = m / a;
m -= t * a; swap(a, m);
u -= t * v; swap(u, v);
}
assert(m == 1);
return u;
}
template <typename T>
class Modular {
public:
using Type = typename decay<decltype(T::value)>::type;
constexpr Modular() : value() {}
template <typename U>
Modular(const U& x) {
value = normalize(x);
}
template <typename U>
static Type normalize(const U& x) {
Type v;
if (-mod() <= x && x < mod()) v = static_cast<Type>(x);
else v = static_cast<Type>(x % mod());
if (v < 0) v += mod();
return v;
}
const Type& operator()() const { return value; }
template <typename U>
explicit operator U() const { return static_cast<U>(value); }
constexpr static Type mod() { return T::value; }
Modular& operator+=(const Modular& other) { if ((value += other.value) >= mod()) value -= mod(); return *this; }
Modular& operator-=(const Modular& other) { if ((value -= other.value) < 0) value += mod(); return *this; }
template <typename U> Modular& operator+=(const U& other) { return *this += Modular(other); }
template <typename U> Modular& operator-=(const U& other) { return *this -= Modular(other); }
Modular& operator++() { return *this += 1; }
Modular& operator--() { return *this -= 1; }
Modular operator++(int) { Modular result(*this); *this += 1; return result; }
Modular operator--(int) { Modular result(*this); *this -= 1; return result; }
Modular operator-() const { return Modular(-value); }
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, int>::value, Modular>::type& operator*=(const Modular& rhs) {
#ifdef _WIN32
uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
asm(
"divl %4; \n\t"
: "=a" (d), "=d" (m)
: "d" (xh), "a" (xl), "r" (mod())
);
value = m;
#else
value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
#endif
return *this;
}
template <typename U = T>
typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs) {
int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());
value = normalize(value * rhs.value - q * mod());
return *this;
}
template <typename U = T>
typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs) {
value = normalize(value * rhs.value);
return *this;
}
Modular& operator/=(const Modular& other) { return *this *= Modular(inverse(other.value, mod())); }
template <typename U>
friend const Modular<U>& abs(const Modular<U>& v) { return v; }
template <typename U>
friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename U>
friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);
template <typename U>
friend std::istream& operator>>(std::istream& stream, Modular<U>& number);
private:
Type value;
};
template <typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value == rhs.value; }
template <typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs) { return lhs == Modular<T>(rhs); }
template <typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) == rhs; }
template <typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs) { return !(lhs == rhs); }
template <typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs) { return !(lhs == rhs); }
template <typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs) { return lhs.value < rhs.value; }
template <typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) += rhs; }
template <typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) += rhs; }
template <typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) -= rhs; }
template <typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) *= rhs; }
template <typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs) { return Modular<T>(lhs) /= rhs; }
template <typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs) { return Modular<T>(lhs) /= rhs; }
template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b) {
assert(b >= 0);
Modular<T> x = a, res = 1;
U p = b;
while (p > 0) {
if (p & 1) res *= x;
x *= x;
p >>= 1;
}
return res;
}
template <typename T>
bool IsZero(const Modular<T>& number) {
return number() == 0;
}
template <typename T>
string to_string(const Modular<T>& number) {
return to_string(number());
}
template <typename T>
std::ostream& operator<<(std::ostream& stream, const Modular<T>& number) {
return stream << number();
}
template <typename T>
std::istream& operator>>(std::istream& stream, Modular<T>& number) {
typename common_type<typename Modular<T>::Type, int64_t>::type x;
stream >> x;
number.value = Modular<T>::normalize(x);
return stream;
}
/*
using ModType = int;
struct VarMod { static ModType value; };
ModType VarMod::value;
ModType& md = VarMod::value;
using Mint = Modular<VarMod>;
*/
constexpr int md = 1e9 + 7;
using Mint = Modular<std::integral_constant<decay<decltype(md)>::type, md>>;
Mint pwr(Mint a, ll k) {
Mint ans = 1;
while(k) {
if(k & 1) ans = ans * a;
a = a * a;
k >>= 1;
}
return ans;
}
const int N = 55;
Mint dp[N][N][N][N];
Mint ans[N][N];
void solve() {
fr(i, 1, N - 1) {
fr(j, 1, i) {
fr(k, 1, i) {
fr(l, k, i) {
dp[i][j][k][l] = 0;
}
}
}
}
dp[1][1][1][1] = 1;
fr(i, 1, N - 2) {
fr(j, 1, i) {
fr(k, 1, i) {
fr(l, k, i) {
Mint val = dp[i][j][k][l];
ans[i][l] += val;
fr(m, j + 1, i + 1) {
dp[i + 1][m][k + 1][max(k + 1, l)] += val;
}
fr(m, 1, j) {
dp[i + 1][m][1][l] += val;
}
}
}
}
}
int t;
sc(t);
while(t--) {
int n, k;
sc(n, k);
cout << ans[n][k] << endl;
}
}
int main() {
ios :: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
for(int tt = 1; tt <= t; tt++) {
solve();
}
return 0;
}
Ly8gI3ByYWdtYSBjb21tZW50KGxpbmtlciwgIi9zdGFjazoyMDAwMDAwMDAiKQovLyAjcHJhZ21hIEdDQyBvcHRpbWl6ZSgiT2Zhc3QiKQovLyAjcHJhZ21hIEdDQyBvcHRpbWl6ZSAoInVucm9sbC1sb29wcyIpCi8vICNwcmFnbWEgR0NDIHRhcmdldCgic3NlLHNzZTIsc3NlMyxzc3NlMyxzc2U0LHBvcGNudCxhYm0sbW14LGF2eCx0dW5lPW5hdGl2ZSIpIC8vIGNvZGVmb3JjZXMKLy8jcHJhZ21hIEdDQyB0YXJnZXQoImF2eCxhdngyLGZtYSIpCi8vI3ByYWdtYSBHQ0MgdGFyZ2V0KCJzc2Usc3NlMixzc2UzLHNzc2UzLHNzZTQscG9wY250LGFibSxtbXgsdHVuZT1uYXRpdmUiKSAvLyB5YW5kZXgKCiNpbmNsdWRlICJiaXRzL3N0ZGMrKy5oIgp1c2luZyBuYW1lc3BhY2Ugc3RkOwojaWZuZGVmIExPQ0FMCiNkZWZpbmUgZW5kbCAnXG4nCiNlbmRpZgoKI2RlZmluZSBmcihpLCBhLCBiKSBmb3IoaW50IGkgPSBhOyBpIDw9IGI7IGkrKykKI2RlZmluZSByZihpLCBhLCBiKSBmb3IoaW50IGkgPSBhOyBpID49IGI7IGktLSkKI2RlZmluZSBwZiBwdXNoX2Zyb250CiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgZWIgZW1wbGFjZV9iYWNrCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBhbGwoeCkgeC5iZWdpbigpLCB4LmVuZCgpCiNkZWZpbmUgcmFsbCh4KSB4LnJiZWdpbigpLCB4LnJlbmQoKQojZGVmaW5lIHN6KHgpIChpbnQpeC5zaXplKCkKI2RlZmluZSBsYiBsb3dlcl9ib3VuZAojZGVmaW5lIHViIHVwcGVyX2JvdW5kCgp0eXBlZGVmIGxvbmcgbG9uZyBsbDsKdHlwZWRlZiBsb25nIGRvdWJsZSBmODA7CnR5cGVkZWYgcGFpcjxpbnQsaW50PiBwaWk7CnR5cGVkZWYgcGFpcjxsbCxsbD4gcGxsOwoKaW50IHBjdChpbnQgeCkgeyByZXR1cm4gX19idWlsdGluX3BvcGNvdW50KHgpOyB9CmludCBwY3QobGwgeCkgeyByZXR1cm4gX19idWlsdGluX3BvcGNvdW50bGwoeCk7IH0KaW50IGJ0KGludCB4KSB7IHJldHVybiAzMSAtIF9fYnVpbHRpbl9jbHooeCk7IH0gLy8gZmxvb3IobG9nMih4KSkKaW50IGJ0KGxsIHgpIHsgcmV0dXJuIDYzIC0gX19idWlsdGluX2NsemxsKHgpOyB9IC8vIGZsb29yKGxvZzIoeCkpCmludCBjZGl2KGludCBhLCBpbnQgYikgeyByZXR1cm4gYSAvIGIgKyAhKGEgPCAwIHx8IGEgJSBiID09IDApOyB9CmxsIGNkaXYobGwgYSwgbGwgYikgeyByZXR1cm4gYSAvIGIgKyAhKGEgPCAwIHx8IGEgJSBiID09IDApOyB9CmludCBueHRfQyhpbnQgeCkgeyBpbnQgYyA9IHggJiAteCwgciA9IHggKyBjOyByZXR1cm4gKCgociBeIHgpID4+IDIpIC8gYykgfCByOyB9CmxsIG54dF9DKGxsIHgpIHsgbGwgYyA9IHggJiAteCwgciA9IHggKyBjOyByZXR1cm4gKCgociBeIHgpID4+IDIpIC8gYykgfCByOyB9Cgp2ZWN0b3I8aW50PiBnZXRfYml0cyhpbnQgbWFzaykgewoJdmVjdG9yPGludD4gYmI7Cgl3aGlsZShtYXNrKSB7IGludCBiID0gYnQobWFzayk7IGJiLnBiKGIpOyBtYXNrIF49ICgxIDw8IGIpOyB9CglyZXZlcnNlKGFsbChiYikpOwoJcmV0dXJuIGJiOwp9CgppbnQgZ2V0X21hc2sodmVjdG9yPGludD4gdikgewoJaW50IG1hc2sgPSAwOwoJZm9yKGludCB4IDogdikgeyBtYXNrIF49ICgxIDw8IHgpOyB9CglyZXR1cm4gbWFzazsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZCB1bmlxKHZlY3RvcjxUPiAmdikgeyBzb3J0KGFsbCh2KSk7IHYucmVzaXplKHVuaXF1ZShhbGwodikpIC0gdi5iZWdpbigpKTsgfQoKbXQxOTkzN182NCBybmcoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsKCmxsIHJhbmQobGwgbCwgbGwgcil7Cgl1bmlmb3JtX2ludF9kaXN0cmlidXRpb248bGw+IHVpZChsLCByKTsKCXJldHVybiB1aWQocm5nKTsKfQoKdm9pZCBzYygpIHt9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSGVhZCwgdHlwZW5hbWUuLi4gVGFpbD4Kdm9pZCBzYyhIZWFkICZILCBUYWlsICYuLi4gVCkgeyBjaW4gPj4gSDsgc2MoVC4uLik7IH0KCiNpZmRlZiBMT0NBTAojZGVmaW5lIGRlYnVnKC4uLikgY2VyciA8PCAiW0w6IiA8PCBfX0xJTkVfXyA8PCAiXVsiIDw8ICNfX1ZBX0FSR1NfXyA8PCAiXToiLCBkZWJ1Z19vdXQoX19WQV9BUkdTX18pCiNlbHNlCiNkZWZpbmUgZGVidWcoLi4uKSA0MgojZW5kaWYKCi8vICNpZm5kZWYgTE9DQUwKLy8gc3RyaW5nIHRvX3N0cmluZyhfX2ludDEyOCB4KSB7Ci8vIAlzdHJpbmcgcyA9ICIiOwovLyAJYm9vbCBuZWcgPSAwOwovLyAJaWYoeCA8IDApIHsgcyArPSAiLSI7IG5lZyA9IDE7IHggPSAteDsgfQovLyAJaWYoIXgpIHMgKz0gJzAnOwovLyAJd2hpbGUoeCkgewovLyAJCWludCByZW0gPSB4ICUgMTA7Ci8vIAkJcyArPSB0b19zdHJpbmcocmVtKTsKLy8gCQl4IC89IDEwOwovLyAJfQovLyAJcmV2ZXJzZShzLmJlZ2luKCkgKyBuZWcsIHMuZW5kKCkpOwovLyAJcmV0dXJuIHM7Ci8vIH0KLy8gI2VuZGlmCgpjb25zdCBpbnQgbW9kID0gMWU5ICsgNzsgLy8gOTk4MjQ0MzUzOwoKaW50IHB3cihpbnQgYSxsbCBiKSB7CglpbnQgYW5zID0gMTsKCXdoaWxlKGIpIHsKCQlpZihiICYgMSkgYW5zID0gKGFucyAqIDFMTCAqIGEpICUgbW9kOwoJCWEgPSAoYSAqIDFMTCAqIGEpICUgbW9kOwoJCWIgPj49IDE7Cgl9CglyZXR1cm4gYW5zOwp9CgovKgoJTG9va291dCBmb3Igb3ZlcmZsb3dzISEKCUNoZWNrIGFycmF5IHNpemVzISEKCUNsZWFyIGJlZm9yZSB0ZXN0IGNhc2VzISEKCVVzZSB0aGUgY29ycmVjdCBtb2R1bG8hIQoJQ2hlY2sgZm9yIGNvcm5lciBjYXNlcyEhCglBcmUgeW91IGZvcmdldHRpbmcgc29tZXRoaW5nPyEKCVJlYWQgcHJvYmxlbSBzdGF0ZW1lbnQgY2FyZWZ1bGx5ISEhCiovCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KVCBpbnZlcnNlKFQgYSwgVCBtKSB7CiAgVCB1ID0gMCwgdiA9IDE7CiAgd2hpbGUgKGEgIT0gMCkgewogICAgVCB0ID0gbSAvIGE7CiAgICBtIC09IHQgKiBhOyBzd2FwKGEsIG0pOwogICAgdSAtPSB0ICogdjsgc3dhcCh1LCB2KTsKICB9CiAgYXNzZXJ0KG0gPT0gMSk7CiAgcmV0dXJuIHU7Cn0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KY2xhc3MgTW9kdWxhciB7CiBwdWJsaWM6CiAgdXNpbmcgVHlwZSA9IHR5cGVuYW1lIGRlY2F5PGRlY2x0eXBlKFQ6OnZhbHVlKT46OnR5cGU7CiAKICBjb25zdGV4cHIgTW9kdWxhcigpIDogdmFsdWUoKSB7fQogIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogIE1vZHVsYXIoY29uc3QgVSYgeCkgewogICAgdmFsdWUgPSBub3JtYWxpemUoeCk7CiAgfQogCiAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CiAgc3RhdGljIFR5cGUgbm9ybWFsaXplKGNvbnN0IFUmIHgpIHsKICAgIFR5cGUgdjsKICAgIGlmICgtbW9kKCkgPD0geCAmJiB4IDwgbW9kKCkpIHYgPSBzdGF0aWNfY2FzdDxUeXBlPih4KTsKICAgIGVsc2UgdiA9IHN0YXRpY19jYXN0PFR5cGU+KHggJSBtb2QoKSk7CiAgICBpZiAodiA8IDApIHYgKz0gbW9kKCk7CiAgICByZXR1cm4gdjsKICB9CiAKICBjb25zdCBUeXBlJiBvcGVyYXRvcigpKCkgY29uc3QgeyByZXR1cm4gdmFsdWU7IH0KICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KICBleHBsaWNpdCBvcGVyYXRvciBVKCkgY29uc3QgeyByZXR1cm4gc3RhdGljX2Nhc3Q8VT4odmFsdWUpOyB9CiAgY29uc3RleHByIHN0YXRpYyBUeXBlIG1vZCgpIHsgcmV0dXJuIFQ6OnZhbHVlOyB9CiAKICBNb2R1bGFyJiBvcGVyYXRvcis9KGNvbnN0IE1vZHVsYXImIG90aGVyKSB7IGlmICgodmFsdWUgKz0gb3RoZXIudmFsdWUpID49IG1vZCgpKSB2YWx1ZSAtPSBtb2QoKTsgcmV0dXJuICp0aGlzOyB9CiAgTW9kdWxhciYgb3BlcmF0b3ItPShjb25zdCBNb2R1bGFyJiBvdGhlcikgeyBpZiAoKHZhbHVlIC09IG90aGVyLnZhbHVlKSA8IDApIHZhbHVlICs9IG1vZCgpOyByZXR1cm4gKnRoaXM7IH0KICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gTW9kdWxhciYgb3BlcmF0b3IrPShjb25zdCBVJiBvdGhlcikgeyByZXR1cm4gKnRoaXMgKz0gTW9kdWxhcihvdGhlcik7IH0KICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gTW9kdWxhciYgb3BlcmF0b3ItPShjb25zdCBVJiBvdGhlcikgeyByZXR1cm4gKnRoaXMgLT0gTW9kdWxhcihvdGhlcik7IH0KICBNb2R1bGFyJiBvcGVyYXRvcisrKCkgeyByZXR1cm4gKnRoaXMgKz0gMTsgfQogIE1vZHVsYXImIG9wZXJhdG9yLS0oKSB7IHJldHVybiAqdGhpcyAtPSAxOyB9CiAgTW9kdWxhciBvcGVyYXRvcisrKGludCkgeyBNb2R1bGFyIHJlc3VsdCgqdGhpcyk7ICp0aGlzICs9IDE7IHJldHVybiByZXN1bHQ7IH0KICBNb2R1bGFyIG9wZXJhdG9yLS0oaW50KSB7IE1vZHVsYXIgcmVzdWx0KCp0aGlzKTsgKnRoaXMgLT0gMTsgcmV0dXJuIHJlc3VsdDsgfQogIE1vZHVsYXIgb3BlcmF0b3ItKCkgY29uc3QgeyByZXR1cm4gTW9kdWxhcigtdmFsdWUpOyB9CiAKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVSA9IFQ+CiAgdHlwZW5hbWUgZW5hYmxlX2lmPGlzX3NhbWU8dHlwZW5hbWUgTW9kdWxhcjxVPjo6VHlwZSwgaW50Pjo6dmFsdWUsIE1vZHVsYXI+Ojp0eXBlJiBvcGVyYXRvcio9KGNvbnN0IE1vZHVsYXImIHJocykgewojaWZkZWYgX1dJTjMyCiAgICB1aW50NjRfdCB4ID0gc3RhdGljX2Nhc3Q8aW50NjRfdD4odmFsdWUpICogc3RhdGljX2Nhc3Q8aW50NjRfdD4ocmhzLnZhbHVlKTsKICAgIHVpbnQzMl90IHhoID0gc3RhdGljX2Nhc3Q8dWludDMyX3Q+KHggPj4gMzIpLCB4bCA9IHN0YXRpY19jYXN0PHVpbnQzMl90Pih4KSwgZCwgbTsKICAgIGFzbSgKICAgICAgImRpdmwgJTQ7IFxuXHQiCiAgICAgIDogIj1hIiAoZCksICI9ZCIgKG0pCiAgICAgIDogImQiICh4aCksICJhIiAoeGwpLCAiciIgKG1vZCgpKQogICAgKTsKICAgIHZhbHVlID0gbTsKI2Vsc2UKICAgIHZhbHVlID0gbm9ybWFsaXplKHN0YXRpY19jYXN0PGludDY0X3Q+KHZhbHVlKSAqIHN0YXRpY19jYXN0PGludDY0X3Q+KHJocy52YWx1ZSkpOwojZW5kaWYKICAgIHJldHVybiAqdGhpczsKICB9CiAgdGVtcGxhdGUgPHR5cGVuYW1lIFUgPSBUPgogIHR5cGVuYW1lIGVuYWJsZV9pZjxpc19zYW1lPHR5cGVuYW1lIE1vZHVsYXI8VT46OlR5cGUsIGludDY0X3Q+Ojp2YWx1ZSwgTW9kdWxhcj46OnR5cGUmIG9wZXJhdG9yKj0oY29uc3QgTW9kdWxhciYgcmhzKSB7CiAgICBpbnQ2NF90IHEgPSBzdGF0aWNfY2FzdDxpbnQ2NF90PihzdGF0aWNfY2FzdDxsb25nIGRvdWJsZT4odmFsdWUpICogcmhzLnZhbHVlIC8gbW9kKCkpOwogICAgdmFsdWUgPSBub3JtYWxpemUodmFsdWUgKiByaHMudmFsdWUgLSBxICogbW9kKCkpOwogICAgcmV0dXJuICp0aGlzOwogIH0KICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVSA9IFQ+CiAgdHlwZW5hbWUgZW5hYmxlX2lmPCFpc19pbnRlZ3JhbDx0eXBlbmFtZSBNb2R1bGFyPFU+OjpUeXBlPjo6dmFsdWUsIE1vZHVsYXI+Ojp0eXBlJiBvcGVyYXRvcio9KGNvbnN0IE1vZHVsYXImIHJocykgewogICAgdmFsdWUgPSBub3JtYWxpemUodmFsdWUgKiByaHMudmFsdWUpOwogICAgcmV0dXJuICp0aGlzOwogIH0KIAogIE1vZHVsYXImIG9wZXJhdG9yLz0oY29uc3QgTW9kdWxhciYgb3RoZXIpIHsgcmV0dXJuICp0aGlzICo9IE1vZHVsYXIoaW52ZXJzZShvdGhlci52YWx1ZSwgbW9kKCkpKTsgfQogCiAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CiAgZnJpZW5kIGNvbnN0IE1vZHVsYXI8VT4mIGFicyhjb25zdCBNb2R1bGFyPFU+JiB2KSB7IHJldHVybiB2OyB9CiAKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1vZHVsYXI8VT4mIGxocywgY29uc3QgTW9kdWxhcjxVPiYgcmhzKTsKIAogIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogIGZyaWVuZCBib29sIG9wZXJhdG9yPChjb25zdCBNb2R1bGFyPFU+JiBsaHMsIGNvbnN0IE1vZHVsYXI8VT4mIHJocyk7CiAKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KICBmcmllbmQgc3RkOjppc3RyZWFtJiBvcGVyYXRvcj4+KHN0ZDo6aXN0cmVhbSYgc3RyZWFtLCBNb2R1bGFyPFU+JiBudW1iZXIpOwogCiBwcml2YXRlOgogIFR5cGUgdmFsdWU7Cn07CiAKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGJvb2wgb3BlcmF0b3I9PShjb25zdCBNb2R1bGFyPFQ+JiBsaHMsIGNvbnN0IE1vZHVsYXI8VD4mIHJocykgeyByZXR1cm4gbGhzLnZhbHVlID09IHJocy52YWx1ZTsgfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4gYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuIGxocyA9PSBNb2R1bGFyPFQ+KHJocyk7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IGJvb2wgb3BlcmF0b3I9PShVIGxocywgY29uc3QgTW9kdWxhcjxUPiYgcmhzKSB7IHJldHVybiBNb2R1bGFyPFQ+KGxocykgPT0gcmhzOyB9CiAKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGJvb2wgb3BlcmF0b3IhPShjb25zdCBNb2R1bGFyPFQ+JiBsaHMsIGNvbnN0IE1vZHVsYXI8VD4mIHJocykgeyByZXR1cm4gIShsaHMgPT0gcmhzKTsgfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4gYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuICEobGhzID09IHJocyk7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IGJvb2wgb3BlcmF0b3IhPShVIGxocywgY29uc3QgTW9kdWxhcjxUPiYgcmhzKSB7IHJldHVybiAhKGxocyA9PSByaHMpOyB9CiAKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGJvb2wgb3BlcmF0b3I8KGNvbnN0IE1vZHVsYXI8VD4mIGxocywgY29uc3QgTW9kdWxhcjxUPiYgcmhzKSB7IHJldHVybiBsaHMudmFsdWUgPCByaHMudmFsdWU7IH0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gTW9kdWxhcjxUPiBvcGVyYXRvcisoY29uc3QgTW9kdWxhcjxUPiYgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSArPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IrKGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSArPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IrKFUgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSArPSByaHM7IH0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gTW9kdWxhcjxUPiBvcGVyYXRvci0oY29uc3QgTW9kdWxhcjxUPiYgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAtPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3ItKGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAtPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3ItKFUgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAtPSByaHM7IH0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gTW9kdWxhcjxUPiBvcGVyYXRvciooY29uc3QgTW9kdWxhcjxUPiYgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAqPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IqKGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAqPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IqKFUgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAqPSByaHM7IH0KIAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gTW9kdWxhcjxUPiBvcGVyYXRvci8oY29uc3QgTW9kdWxhcjxUPiYgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAvPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IvKGNvbnN0IE1vZHVsYXI8VD4mIGxocywgVSByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAvPSByaHM7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+IE1vZHVsYXI8VD4gb3BlcmF0b3IvKFUgbGhzLCBjb25zdCBNb2R1bGFyPFQ+JiByaHMpIHsgcmV0dXJuIE1vZHVsYXI8VD4obGhzKSAvPSByaHM7IH0KIAp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPgpNb2R1bGFyPFQ+IHBvd2VyKGNvbnN0IE1vZHVsYXI8VD4mIGEsIGNvbnN0IFUmIGIpIHsKICBhc3NlcnQoYiA+PSAwKTsKICBNb2R1bGFyPFQ+IHggPSBhLCByZXMgPSAxOwogIFUgcCA9IGI7CiAgd2hpbGUgKHAgPiAwKSB7CiAgICBpZiAocCAmIDEpIHJlcyAqPSB4OwogICAgeCAqPSB4OwogICAgcCA+Pj0gMTsKICB9CiAgcmV0dXJuIHJlczsKfQogCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpib29sIElzWmVybyhjb25zdCBNb2R1bGFyPFQ+JiBudW1iZXIpIHsKICByZXR1cm4gbnVtYmVyKCkgPT0gMDsKfQogCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJpbmcgdG9fc3RyaW5nKGNvbnN0IE1vZHVsYXI8VD4mIG51bWJlcikgewogIHJldHVybiB0b19zdHJpbmcobnVtYmVyKCkpOwp9CiAKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIHN0cmVhbSwgY29uc3QgTW9kdWxhcjxUPiYgbnVtYmVyKSB7CiAgcmV0dXJuIHN0cmVhbSA8PCBudW1iZXIoKTsKfQogCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdGQ6OmlzdHJlYW0mIG9wZXJhdG9yPj4oc3RkOjppc3RyZWFtJiBzdHJlYW0sIE1vZHVsYXI8VD4mIG51bWJlcikgewogIHR5cGVuYW1lIGNvbW1vbl90eXBlPHR5cGVuYW1lIE1vZHVsYXI8VD46OlR5cGUsIGludDY0X3Q+Ojp0eXBlIHg7CiAgc3RyZWFtID4+IHg7CiAgbnVtYmVyLnZhbHVlID0gTW9kdWxhcjxUPjo6bm9ybWFsaXplKHgpOwogIHJldHVybiBzdHJlYW07Cn0KIAovKgp1c2luZyBNb2RUeXBlID0gaW50OwogCnN0cnVjdCBWYXJNb2QgeyBzdGF0aWMgTW9kVHlwZSB2YWx1ZTsgfTsKTW9kVHlwZSBWYXJNb2Q6OnZhbHVlOwpNb2RUeXBlJiBtZCA9IFZhck1vZDo6dmFsdWU7CnVzaW5nIE1pbnQgPSBNb2R1bGFyPFZhck1vZD47CgoqLwoKY29uc3RleHByIGludCBtZCA9IDFlOSArIDc7CnVzaW5nIE1pbnQgPSBNb2R1bGFyPHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8ZGVjYXk8ZGVjbHR5cGUobWQpPjo6dHlwZSwgbWQ+PjsKCk1pbnQgcHdyKE1pbnQgYSwgbGwgaykgewoJTWludCBhbnMgPSAxOwoJd2hpbGUoaykgewoJCWlmKGsgJiAxKSBhbnMgPSBhbnMgKiBhOwoJCWEgPSBhICogYTsKCQlrID4+PSAxOwoJfQoJcmV0dXJuIGFuczsKfQoKY29uc3QgaW50IE4gPSA1NTsKTWludCBkcFtOXVtOXVtOXVtOXTsKTWludCBhbnNbTl1bTl07Cgp2b2lkIHNvbHZlKCkgewogICAgZnIoaSwgMSwgTiAtIDEpIHsKICAgICAgICBmcihqLCAxLCBpKSB7CiAgICAgICAgICAgIGZyKGssIDEsIGkpIHsKICAgICAgICAgICAgICAgIGZyKGwsIGssIGkpIHsKICAgICAgICAgICAgICAgICAgICBkcFtpXVtqXVtrXVtsXSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBkcFsxXVsxXVsxXVsxXSA9IDE7CiAgICBmcihpLCAxLCBOIC0gMikgewogICAgICAgIGZyKGosIDEsIGkpIHsKICAgICAgICAgICAgZnIoaywgMSwgaSkgewogICAgICAgICAgICAgICAgZnIobCwgaywgaSkgewogICAgICAgICAgICAgICAgICAgIE1pbnQgdmFsID0gZHBbaV1bal1ba11bbF07CiAgICAgICAgICAgICAgICAgICAgYW5zW2ldW2xdICs9IHZhbDsKICAgICAgICAgICAgICAgICAgICBmcihtLCBqICsgMSwgaSArIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZHBbaSArIDFdW21dW2sgKyAxXVttYXgoayArIDEsIGwpXSArPSB2YWw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZyKG0sIDEsIGopIHsKICAgICAgICAgICAgICAgICAgICAgICAgZHBbaSArIDFdW21dWzFdW2xdICs9IHZhbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpbnQgdDsKICAgIHNjKHQpOwogICAgd2hpbGUodC0tKSB7CiAgICAgICAgaW50IG4sIGs7CiAgICAgICAgc2Mobiwgayk7CiAgICAgICAgY291dCA8PCBhbnNbbl1ba10gPDwgZW5kbDsKICAgIH0KfQoKaW50IG1haW4oKSB7Cglpb3MgOjogc3luY193aXRoX3N0ZGlvKDApOwoJY2luLnRpZSgwKTsKCWNvdXQudGllKDApOwoJaW50IHQgPSAxOwoJLy8gY2luID4+IHQ7Cglmb3IoaW50IHR0ID0gMTsgdHQgPD0gdDsgdHQrKykgewoJCXNvbHZlKCk7Cgl9CglyZXR1cm4gMDsKfQ==