#ifndef LOCAL
#pragma GCC optimize ("-Ofast")
#pragma GCC optimize ("-unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
//fast IO by yosupo
struct Scanner {
FILE* fp = nullptr;
char line[(1 << 15) + 1];
size_t st = 0, ed = 0;
void reread() {
memmove(line, line + st, ed - st);
ed -= st;
st = 0;
ed += fread(line + ed, 1, (1 << 15) - ed, fp);
line[ed] = '\0';
}
bool succ() {
while (true) {
if (st == ed) {
reread();
if (st == ed) return false;
}
while (st != ed && isspace(line[st])) st++;
if (st != ed) break;
}
if (ed - st <= 50) reread();
return true;
}
template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
while (true) {
size_t sz = 0;
while (st + sz < ed && !isspace(line[st + sz])) sz++;
ref.append(line + st, sz);
st += sz;
if (!sz || st != ed) break;
reread();
}
return true;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
bool neg = false;
if (line[st] == '-') {
neg = true;
st++;
}
ref = T(0);
while (isdigit(line[st])) {
ref = 10 * ref + (line[st++] - '0');
}
if (neg) ref = -ref;
return true;
}
template <class T> bool read_single(vector<T>& ref) {
for (auto& d : ref) {
if (!read_single(d)) return false;
}
return true;
}
void read() {}
template <class H, class... T> void read(H& h, T&... t) {
bool f = read_single(h);
assert(f);
read(t...);
}
Scanner(FILE* _fp) : fp(_fp) {}
};
struct Printer {
public:
template <bool F = false> void write() {}
template <bool F = false, class H, class... T>
void write(const H& h, const T&... t) {
if (F) write_single(' ');
write_single(h);
write<true>(t...);
}
template <class... T> void writeln(const T&... t) {
write(t...);
write_single('\n');
}
Printer(FILE* _fp) : fp(_fp) {}
~Printer() { flush(); }
private:
static constexpr size_t SIZE = 1 << 15;
FILE* fp;
char line[SIZE], small[50];
size_t pos = 0;
void flush() {
fwrite(line, 1, pos, fp);
pos = 0;
}
void write_single(const char& val) {
if (pos == SIZE) flush();
line[pos++] = val;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
void write_single(T val) {
if (pos > (1 << 15) - 50) flush();
if (val == 0) {
write_single('0');
return;
}
if (val < 0) {
write_single('-');
val = -val; // todo min
}
size_t len = 0;
while (val) {
small[len++] = char('0' + (val % 10));
val /= 10;
}
for (size_t i = 0; i < len; i++) {
line[pos + i] = small[len - 1 - i];
}
pos += len;
}
void write_single(const string& s) {
for (char c : s) write_single(c);
}
void write_single(const char* s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) write_single(s[i]);
}
template <class T> void write_single(const vector<T>& val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write_single(' ');
write_single(val[i]);
}
}
};
Scanner sc(stdin);
Printer pr(stdout);
using ll=long long;
//#define int ll
#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
using pi=pair<int,int>;
using vi=vc<int>;
template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
return os<<"{"<<p.a<<","<<p.b<<"}";
}
template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
os<<"{";
for(auto e:v)os<<e<<",";
return os<<"}";
}
#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
os<<t<<" ";
dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif
using uint=unsigned;
using ull=unsigned long long;
template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
return os<<vc<t>(all(a));
}
template<int i,class T>
void print_tuple(ostream&,const T&){
}
template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
if(i)os<<",";
os<<get<i>(t);
print_tuple<i+1,T,Args...>(os,t);
}
template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
os<<"{";
print_tuple<0,tuple<Args...>,Args...>(os,t);
return os<<"}";
}
template<class t>
void print(t x,int suc=1){
cout<<x;
if(suc==1)
cout<<"\n";
if(suc==2)
cout<<" ";
}
ll read(){
ll i;
cin>>i;
return i;
}
vi readvi(int n,int off=0){
vi v(n);
rep(i,n)v[i]=read()+off;
return v;
}
pi readpi(int off=0){
int a,b;cin>>a>>b;
return pi(a+off,b+off);
}
template<class t,class u>
void print(const pair<t,u>&p,int suc=1){
print(p.a,2);
print(p.b,suc);
}
template<class T>
void print(const vector<T>&v,int suc=1){
rep(i,v.size())
print(v[i],i==int(v.size())-1?suc:2);
}
string readString(){
string s;
cin>>s;
return s;
}
template<class T>
T sq(const T& t){
return t*t;
}
void yes(){
pr.writeln("YES");
}
void no(){
pr.writeln("NO");
}
void possible(bool ex=true){
#ifdef CAPITAL
cout<<"POSSIBLE"<<"\n";
#else
cout<<"Possible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void impossible(bool ex=true){
#ifdef CAPITAL
cout<<"IMPOSSIBLE"<<"\n";
#else
cout<<"Impossible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
constexpr ll ten(int n){
return n==0?1:ten(n-1)*10;
}
const ll infLL=LLONG_MAX/3;
#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif
int topbit(signed t){
return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
return __builtin_popcount(t);
}
int popcount(ll t){
return __builtin_popcountll(t);
}
bool ispow2(int i){
return i&&(i&-i)==i;
}
ll mask(int i){
return (ll(1)<<i)-1;
}
bool inc(int a,int b,int c){
return a<=b&&b<=c;
}
template<class t> void mkuni(vc<t>&v){
sort(all(v));
v.erase(unique(all(v)),v.ed);
}
ll rand_int(ll l, ll r) { //[l, r]
#ifdef LOCAL
static mt19937_64 gen;
#else
static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
#endif
return uniform_int_distribution<ll>(l, r)(gen);
}
template<class t>
void myshuffle(vc<t>&a){
rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}
template<class t>
int lwb(const vc<t>&v,const t&a){
return lower_bound(all(v),a)-v.bg;
}
vvc<int> readGraph(int n,int m){
vvc<int> g(n);
rep(i,m){
int a,b;
cin>>a>>b;
//sc.read(a,b);
a--;b--;
g[a].pb(b);
g[b].pb(a);
}
return g;
}
vvc<int> readTree(int n){
return readGraph(n,n-1);
}
/*
* Time Complexity: Suffix Array: O(N + Character_Set_Size) time and space // 128 --- ASCII
* LCP: O(N) time and space
* Usage:
* 1. Suffix Array (returns s.size() elements, NOT considering 0-length/empty suffix)
* auto sa = suffix_array(s); // s is the input string with ASCII characters
* auto sa_wide_char = suffix_array(s, LIM); // LIM = max(s[i]) + 2, s is the string with arbitary big characters.
* 2. LCP:
* auto lcp = LCP(s, suffix_array(s)); // returns s.size() elements, where lcp[i]=LCP(sa[i], sa[i+1])
* Status: Tested (DMOJ: ccc03s4, SPOJ: SARRAY (100pts), Yosupo's: Suffix Array & Number of Substrings, CodeForces EDU
*/
// Based on: Rickypon, https://j...content-available-to-author-only...o.jp/submission/10105
void induced_sort(const vector<int> &vec, int val_range, vector<int> &SA, const vector<bool> &sl, const vector<int> &lms_idx) {
vector<int> l(val_range, 0), r(val_range, 0);
for (int c : vec) {
if (c + 1 < val_range) ++l[c + 1];
++r[c];
}
partial_sum(l.begin(), l.end(), l.begin());
partial_sum(r.begin(), r.end(), r.begin());
fill(SA.begin(), SA.end(), -1);
for (int i = lms_idx.size() - 1; i >= 0; --i)
SA[--r[vec[lms_idx[i]]]] = lms_idx[i];
for (int i : SA)
if (i >= 1 && sl[i - 1]) {
SA[l[vec[i - 1]]++] = i - 1;
}
fill(r.begin(), r.end(), 0);
for (int c : vec)
++r[c];
partial_sum(r.begin(), r.end(), r.begin());
for (int k = SA.size() - 1, i = SA[k]; k >= 1; --k, i = SA[k])
if (i >= 1 && !sl[i - 1]) {
SA[--r[vec[i - 1]]] = i - 1;
}
}
vector<int> SA_IS(const vector<int> &vec, int val_range) {
const int n = vec.size();
vector<int> SA(n), lms_idx;
vector<bool> sl(n);
sl[n - 1] = false;
for (int i = n - 2; i >= 0; --i) {
sl[i] = (vec[i] > vec[i + 1] || (vec[i] == vec[i + 1] && sl[i + 1]));
if (sl[i] && !sl[i + 1]) lms_idx.push_back(i + 1);
}
reverse(lms_idx.begin(), lms_idx.end());
induced_sort(vec, val_range, SA, sl, lms_idx);
vector<int> new_lms_idx(lms_idx.size()), lms_vec(lms_idx.size());
for (int i = 0, k = 0; i < n; ++i)
if (!sl[SA[i]] && SA[i] >= 1 && sl[SA[i] - 1]) {
new_lms_idx[k++] = SA[i];
}
int cur = 0;
SA[n - 1] = cur;
for (size_t k = 1; k < new_lms_idx.size(); ++k) {
int i = new_lms_idx[k - 1], j = new_lms_idx[k];
if (vec[i] != vec[j]) {
SA[j] = ++cur;
continue;
}
bool flag = false;
for (int a = i + 1, b = j + 1;; ++a, ++b) {
if (vec[a] != vec[b]) {
flag = true;
break;
}
if ((!sl[a] && sl[a - 1]) || (!sl[b] && sl[b - 1])) {
flag = !((!sl[a] && sl[a - 1]) && (!sl[b] && sl[b - 1]));
break;
}
}
SA[j] = (flag ? ++cur : cur);
}
for (size_t i = 0; i < lms_idx.size(); ++i)
lms_vec[i] = SA[lms_idx[i]];
if (cur + 1 < (int)lms_idx.size()) {
auto lms_SA = SA_IS(lms_vec, cur + 1);
for (size_t i = 0; i < lms_idx.size(); ++i) {
new_lms_idx[i] = lms_idx[lms_SA[i]];
}
}
induced_sort(vec, val_range, SA, sl, new_lms_idx);
return SA;
}
vector<int> suffix_array(const string &s, const int LIM = 128) {
vector<int> vec(s.size() + 1);
copy(begin(s), end(s), begin(vec));
vec.back() = '$';
auto ret = SA_IS(vec, LIM);
ret.erase(ret.begin());
return ret;
}
// Author: https://c...content-available-to-author-only...s.com/blog/entry/12796?#comment-175287
// Uses kasai's algorithm linear in time and space
vector<int> LCP(const string &s, const vector<int> &sa, const vector<int>& as) {
int n = s.size(), k = 0;
vector<int> lcp(n);
for (int i = 0; i < n; i++, k ? k-- : 0) {
if (as[i] == n - 1) {
k = 0;
continue;
}
int j = sa[as[i] + 1];
while (i + k < n && j + k < n && s[i + k] == s[j + k])
k++;
lcp[as[i]] = k;
}
lcp[n - 1] = 0;
return lcp;
}
const int L=21;
const int S=1<<L;
int buf[L][S];
void spinit(const vi&d){
int n=d.size(),h=topbit(n);
rep(i,n)buf[0][i]=d[i];
rng(j,1,h+1){
rep(i,n-(1<<j)+1)
buf[j][i]=min(buf[j-1][i],buf[j-1][i+(1<<(j-1))]);
}
}
int spget(int b,int e){
assert(b<=e);
if(b==e)return inf;
int d=topbit(e-b);
return min(buf[d][b],buf[d][e-(1<<d)]);
}
const int kmax=1050;
int dp[kmax][kmax],pre[kmax][kmax];
void slv(){
int n,m,k;sc.read(n,m,k);
string src;sc.read(src);
string dst;sc.read(dst);
int dif=abs(n-m),aff=k-dif;
if(aff<0)return no();
int lw=min(0,m-n)-aff/2,up=max(0,m-n)+aff/2;
int s=up-lw+1;
rep(i,k+1)rep(j,s){
dp[i][j]=-inf;
pre[i][j]=-inf;
}
string rw=src+'W'+dst;
vi sa=suffix_array(rw);
vi as(n+m+1);rep(i,n+m+1)as[sa[i]]=i;
vi lcp=LCP(rw,sa,as);
//sparsetable<int,decltype(imin)> st(lcp,imin,inf);
spinit(lcp);
const auto common=[&](int i,int j){
if(i==n||j==m)return 0;
i=as[i];
j=as[n+1+j];
if(i>j)swap(i,j);
return spget(i,j);
};
dp[0][0-lw]=common(0,0)*2;
rep(ans,k+1){
if(dp[ans][m-n-lw]==n+m){
yes();
pr.writeln(ans);
int idx=m-n;
while(ans){
int p=pre[ans][idx-lw];
int i=(dp[ans-1][p-lw]-p)/2;
int j=(dp[ans-1][p-lw]+p)/2;
if(p==idx){
pr.writeln("REPLACE",i+1,dst[j]);
}else if(p+1==idx){
pr.writeln("INSERT",i+1,dst[j]);
}else if(p-1==idx){
pr.writeln("DELETE",i+1);
}else{
assert(false);
}
ans--;
idx=p;
}
return;
}
if(ans==k)return no();
rng(idx,lw,up+1){
if(dp[ans][idx-lw]>-inf){
int i=(dp[ans][idx-lw]-idx)/2;
int j=(dp[ans][idx-lw]+idx)/2;
if(i<n&&j<m){
int len=common(i+1,j+1);
int y=i+1+len,x=j+1+len;
int z=x+y;
if(dp[ans+1][idx-lw]<z){
dp[ans+1][idx-lw]=z;
pre[ans+1][idx-lw]=idx;
}
}
if(idx<up&&j<m){
int len=common(i,j+1);
int y=i+len,x=j+1+len;
int z=x+y;
if(dp[ans+1][idx+1-lw]<z){
dp[ans+1][idx+1-lw]=z;
pre[ans+1][idx+1-lw]=idx;
}
}
if(lw<idx&&i<n){
int len=common(i+1,j);
int y=i+1+len,x=j+len;
int z=x+y;
if(dp[ans+1][idx-1-lw]<z){
dp[ans+1][idx-1-lw]=z;
pre[ans+1][idx-1-lw]=idx;
}
}
}
}
}
assert(false);
}
signed main(){
int t;sc.read(t);rep(_,t)
slv();
}
I2lmbmRlZiBMT0NBTAojcHJhZ21hIEdDQyBvcHRpbWl6ZSAoIi1PZmFzdCIpCiNwcmFnbWEgR0NDIG9wdGltaXplICgiLXVucm9sbC1sb29wcyIpCiNlbmRpZgoKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovL2Zhc3QgSU8gYnkgeW9zdXBvCnN0cnVjdCBTY2FubmVyIHsKICAgIEZJTEUqIGZwID0gbnVsbHB0cjsKICAgIGNoYXIgbGluZVsoMSA8PCAxNSkgKyAxXTsKICAgIHNpemVfdCBzdCA9IDAsIGVkID0gMDsKICAgIHZvaWQgcmVyZWFkKCkgewogICAgICAgIG1lbW1vdmUobGluZSwgbGluZSArIHN0LCBlZCAtIHN0KTsKICAgICAgICBlZCAtPSBzdDsKICAgICAgICBzdCA9IDA7CiAgICAgICAgZWQgKz0gZnJlYWQobGluZSArIGVkLCAxLCAoMSA8PCAxNSkgLSBlZCwgZnApOwogICAgICAgIGxpbmVbZWRdID0gJ1wwJzsKICAgIH0KICAgIGJvb2wgc3VjYygpIHsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAoc3QgPT0gZWQpIHsKICAgICAgICAgICAgICAgIHJlcmVhZCgpOwogICAgICAgICAgICAgICAgaWYgKHN0ID09IGVkKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgKHN0ICE9IGVkICYmIGlzc3BhY2UobGluZVtzdF0pKSBzdCsrOwogICAgICAgICAgICBpZiAoc3QgIT0gZWQpIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoZWQgLSBzdCA8PSA1MCkgcmVyZWFkKCk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgZW5hYmxlX2lmX3Q8aXNfc2FtZTxULCBzdHJpbmc+Ojp2YWx1ZSwgaW50PiA9IDA+CiAgICBib29sIHJlYWRfc2luZ2xlKFQmIHJlZikgewogICAgICAgIGlmICghc3VjYygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgc2l6ZV90IHN6ID0gMDsKICAgICAgICAgICAgd2hpbGUgKHN0ICsgc3ogPCBlZCAmJiAhaXNzcGFjZShsaW5lW3N0ICsgc3pdKSkgc3orKzsKICAgICAgICAgICAgcmVmLmFwcGVuZChsaW5lICsgc3QsIHN6KTsKICAgICAgICAgICAgc3QgKz0gc3o7CiAgICAgICAgICAgIGlmICghc3ogfHwgc3QgIT0gZWQpIGJyZWFrOwogICAgICAgICAgICByZXJlYWQoKTsgICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgZW5hYmxlX2lmX3Q8aXNfaW50ZWdyYWw8VD46OnZhbHVlLCBpbnQ+ID0gMD4KICAgIGJvb2wgcmVhZF9zaW5nbGUoVCYgcmVmKSB7CiAgICAgICAgaWYgKCFzdWNjKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBib29sIG5lZyA9IGZhbHNlOwogICAgICAgIGlmIChsaW5lW3N0XSA9PSAnLScpIHsKICAgICAgICAgICAgbmVnID0gdHJ1ZTsKICAgICAgICAgICAgc3QrKzsKICAgICAgICB9CiAgICAgICAgcmVmID0gVCgwKTsKICAgICAgICB3aGlsZSAoaXNkaWdpdChsaW5lW3N0XSkpIHsKICAgICAgICAgICAgcmVmID0gMTAgKiByZWYgKyAobGluZVtzdCsrXSAtICcwJyk7CiAgICAgICAgfQogICAgICAgIGlmIChuZWcpIHJlZiA9IC1yZWY7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVD4gYm9vbCByZWFkX3NpbmdsZSh2ZWN0b3I8VD4mIHJlZikgewogICAgICAgIGZvciAoYXV0byYgZCA6IHJlZikgewogICAgICAgICAgICBpZiAoIXJlYWRfc2luZ2xlKGQpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgdm9pZCByZWFkKCkge30KICAgIHRlbXBsYXRlIDxjbGFzcyBILCBjbGFzcy4uLiBUPiB2b2lkIHJlYWQoSCYgaCwgVCYuLi4gdCkgewogICAgICAgIGJvb2wgZiA9IHJlYWRfc2luZ2xlKGgpOwogICAgICAgIGFzc2VydChmKTsKICAgICAgICByZWFkKHQuLi4pOwogICAgfQogICAgU2Nhbm5lcihGSUxFKiBfZnApIDogZnAoX2ZwKSB7fQp9OwoKc3RydWN0IFByaW50ZXIgewogIHB1YmxpYzoKICAgIHRlbXBsYXRlIDxib29sIEYgPSBmYWxzZT4gdm9pZCB3cml0ZSgpIHt9CiAgICB0ZW1wbGF0ZSA8Ym9vbCBGID0gZmFsc2UsIGNsYXNzIEgsIGNsYXNzLi4uIFQ+CiAgICB2b2lkIHdyaXRlKGNvbnN0IEgmIGgsIGNvbnN0IFQmLi4uIHQpIHsKICAgICAgICBpZiAoRikgd3JpdGVfc2luZ2xlKCcgJyk7CiAgICAgICAgd3JpdGVfc2luZ2xlKGgpOwogICAgICAgIHdyaXRlPHRydWU+KHQuLi4pOwogICAgfQogICAgdGVtcGxhdGUgPGNsYXNzLi4uIFQ+IHZvaWQgd3JpdGVsbihjb25zdCBUJi4uLiB0KSB7CiAgICAgICAgd3JpdGUodC4uLik7CiAgICAgICAgd3JpdGVfc2luZ2xlKCdcbicpOwogICAgfQoKICAgIFByaW50ZXIoRklMRSogX2ZwKSA6IGZwKF9mcCkge30KICAgIH5QcmludGVyKCkgeyBmbHVzaCgpOyB9CgogIHByaXZhdGU6CiAgICBzdGF0aWMgY29uc3RleHByIHNpemVfdCBTSVpFID0gMSA8PCAxNTsKICAgIEZJTEUqIGZwOwogICAgY2hhciBsaW5lW1NJWkVdLCBzbWFsbFs1MF07CiAgICBzaXplX3QgcG9zID0gMDsKICAgIHZvaWQgZmx1c2goKSB7CiAgICAgICAgZndyaXRlKGxpbmUsIDEsIHBvcywgZnApOwogICAgICAgIHBvcyA9IDA7CiAgICB9CiAgICB2b2lkIHdyaXRlX3NpbmdsZShjb25zdCBjaGFyJiB2YWwpIHsKICAgICAgICBpZiAocG9zID09IFNJWkUpIGZsdXNoKCk7CiAgICAgICAgbGluZVtwb3MrK10gPSB2YWw7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgZW5hYmxlX2lmX3Q8aXNfaW50ZWdyYWw8VD46OnZhbHVlLCBpbnQ+ID0gMD4KICAgIHZvaWQgd3JpdGVfc2luZ2xlKFQgdmFsKSB7CiAgICAgICAgaWYgKHBvcyA+ICgxIDw8IDE1KSAtIDUwKSBmbHVzaCgpOwogICAgICAgIGlmICh2YWwgPT0gMCkgewogICAgICAgICAgICB3cml0ZV9zaW5nbGUoJzAnKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAodmFsIDwgMCkgewogICAgICAgICAgICB3cml0ZV9zaW5nbGUoJy0nKTsKICAgICAgICAgICAgdmFsID0gLXZhbDsgIC8vIHRvZG8gbWluCiAgICAgICAgfQogICAgICAgIHNpemVfdCBsZW4gPSAwOwogICAgICAgIHdoaWxlICh2YWwpIHsKICAgICAgICAgICAgc21hbGxbbGVuKytdID0gY2hhcignMCcgKyAodmFsICUgMTApKTsKICAgICAgICAgICAgdmFsIC89IDEwOwogICAgICAgIH0KICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgIGxpbmVbcG9zICsgaV0gPSBzbWFsbFtsZW4gLSAxIC0gaV07CiAgICAgICAgfQogICAgICAgIHBvcyArPSBsZW47CiAgICB9CiAgICB2b2lkIHdyaXRlX3NpbmdsZShjb25zdCBzdHJpbmcmIHMpIHsKICAgICAgICBmb3IgKGNoYXIgYyA6IHMpIHdyaXRlX3NpbmdsZShjKTsKICAgIH0KICAgIHZvaWQgd3JpdGVfc2luZ2xlKGNvbnN0IGNoYXIqIHMpIHsKICAgICAgICBzaXplX3QgbGVuID0gc3RybGVuKHMpOwogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHdyaXRlX3NpbmdsZShzW2ldKTsKICAgIH0KICAgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIHdyaXRlX3NpbmdsZShjb25zdCB2ZWN0b3I8VD4mIHZhbCkgewogICAgICAgIGF1dG8gbiA9IHZhbC5zaXplKCk7CiAgICAgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgaWYgKGkpIHdyaXRlX3NpbmdsZSgnICcpOwogICAgICAgICAgICB3cml0ZV9zaW5nbGUodmFsW2ldKTsKICAgICAgICB9CiAgICB9Cn07CgpTY2FubmVyIHNjKHN0ZGluKTsKUHJpbnRlciBwcihzdGRvdXQpOwoKdXNpbmcgbGw9bG9uZyBsb25nOwovLyNkZWZpbmUgaW50IGxsCgojZGVmaW5lIHJuZyhpLGEsYikgZm9yKGludCBpPWludChhKTtpPGludChiKTtpKyspCiNkZWZpbmUgcmVwKGksYikgcm5nKGksMCxiKQojZGVmaW5lIGducihpLGEsYikgZm9yKGludCBpPWludChiKS0xO2k+PWludChhKTtpLS0pCiNkZWZpbmUgcGVyKGksYikgZ25yKGksMCxiKQojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIGViIGVtcGxhY2VfYmFjawojZGVmaW5lIGEgZmlyc3QKI2RlZmluZSBiIHNlY29uZAojZGVmaW5lIGJnIGJlZ2luKCkKI2RlZmluZSBlZCBlbmQoKQojZGVmaW5lIGFsbCh4KSB4LmJnLHguZWQKI2RlZmluZSBzaSh4KSBpbnQoeC5zaXplKCkpCiNpZmRlZiBMT0NBTAojZGVmaW5lIGRtcCh4KSBjZXJyPDxfX0xJTkVfXzw8IiAiPDwjeDw8IiAiPDx4PDxlbmRsCiNlbHNlCiNkZWZpbmUgZG1wKHgpIHZvaWQoMCkKI2VuZGlmCgp0ZW1wbGF0ZTxjbGFzcyB0LGNsYXNzIHU+IGJvb2wgY2htYXgodCZhLHUgYil7aWYoYTxiKXthPWI7cmV0dXJuIHRydWU7fWVsc2UgcmV0dXJuIGZhbHNlO30KdGVtcGxhdGU8Y2xhc3MgdCxjbGFzcyB1PiBib29sIGNobWluKHQmYSx1IGIpe2lmKGI8YSl7YT1iO3JldHVybiB0cnVlO31lbHNlIHJldHVybiBmYWxzZTt9Cgp0ZW1wbGF0ZTxjbGFzcyB0PiB1c2luZyB2Yz12ZWN0b3I8dD47CnRlbXBsYXRlPGNsYXNzIHQ+IHVzaW5nIHZ2Yz12Yzx2Yzx0Pj47Cgp1c2luZyBwaT1wYWlyPGludCxpbnQ+Owp1c2luZyB2aT12YzxpbnQ+OwoKdGVtcGxhdGU8Y2xhc3MgdCxjbGFzcyB1Pgpvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG9zLGNvbnN0IHBhaXI8dCx1PiYgcCl7CglyZXR1cm4gb3M8PCJ7Ijw8cC5hPDwiLCI8PHAuYjw8In0iOwp9Cgp0ZW1wbGF0ZTxjbGFzcyB0PiBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG9zLGNvbnN0IHZjPHQ+JiB2KXsKCW9zPDwieyI7Cglmb3IoYXV0byBlOnYpb3M8PGU8PCIsIjsKCXJldHVybiBvczw8In0iOwp9CgojZGVmaW5lIG1wIG1ha2VfcGFpcgojZGVmaW5lIG10IG1ha2VfdHVwbGUKI2RlZmluZSBvbmUoeCkgbWVtc2V0KHgsLTEsc2l6ZW9mKHgpKQojZGVmaW5lIHplcm8oeCkgbWVtc2V0KHgsMCxzaXplb2YoeCkpCiNpZmRlZiBMT0NBTAp2b2lkIGRtcHIob3N0cmVhbSZvcyl7b3M8PGVuZGw7fQp0ZW1wbGF0ZTxjbGFzcyBULGNsYXNzLi4uIEFyZ3M+CnZvaWQgZG1wcihvc3RyZWFtJm9zLGNvbnN0IFQmdCxjb25zdCBBcmdzJi4uLiBhcmdzKXsKCW9zPDx0PDwiICI7CglkbXByKG9zLGFyZ3MuLi4pOwp9CiNkZWZpbmUgZG1wMiguLi4pIGRtcHIoY2VycixfX0xJTkVfXywjI19fVkFfQVJHU19fKQojZWxzZQojZGVmaW5lIGRtcDIoLi4uKSB2b2lkKDApCiNlbmRpZgoKdXNpbmcgdWludD11bnNpZ25lZDsKdXNpbmcgdWxsPXVuc2lnbmVkIGxvbmcgbG9uZzsKCnRlbXBsYXRlPGNsYXNzIHQsc2l6ZV90IG4+Cm9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSZvcyxjb25zdCBhcnJheTx0LG4+JmEpewoJcmV0dXJuIG9zPDx2Yzx0PihhbGwoYSkpOwp9Cgp0ZW1wbGF0ZTxpbnQgaSxjbGFzcyBUPgp2b2lkIHByaW50X3R1cGxlKG9zdHJlYW0mLGNvbnN0IFQmKXsKfQoKdGVtcGxhdGU8aW50IGksY2xhc3MgVCxjbGFzcyBILGNsYXNzIC4uLkFyZ3M+CnZvaWQgcHJpbnRfdHVwbGUob3N0cmVhbSZvcyxjb25zdCBUJnQpewoJaWYoaSlvczw8IiwiOwoJb3M8PGdldDxpPih0KTsKCXByaW50X3R1cGxlPGkrMSxULEFyZ3MuLi4+KG9zLHQpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyAuLi5BcmdzPgpvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mb3MsY29uc3QgdHVwbGU8QXJncy4uLj4mdCl7Cglvczw8InsiOwoJcHJpbnRfdHVwbGU8MCx0dXBsZTxBcmdzLi4uPixBcmdzLi4uPihvcyx0KTsKCXJldHVybiBvczw8In0iOwp9Cgp0ZW1wbGF0ZTxjbGFzcyB0Pgp2b2lkIHByaW50KHQgeCxpbnQgc3VjPTEpewoJY291dDw8eDsKCWlmKHN1Yz09MSkKCQljb3V0PDwiXG4iOwoJaWYoc3VjPT0yKQoJCWNvdXQ8PCIgIjsKfQoKbGwgcmVhZCgpewoJbGwgaTsKCWNpbj4+aTsKCXJldHVybiBpOwp9Cgp2aSByZWFkdmkoaW50IG4saW50IG9mZj0wKXsKCXZpIHYobik7CglyZXAoaSxuKXZbaV09cmVhZCgpK29mZjsKCXJldHVybiB2Owp9CgpwaSByZWFkcGkoaW50IG9mZj0wKXsKCWludCBhLGI7Y2luPj5hPj5iOwoJcmV0dXJuIHBpKGErb2ZmLGIrb2ZmKTsKfQoKdGVtcGxhdGU8Y2xhc3MgdCxjbGFzcyB1Pgp2b2lkIHByaW50KGNvbnN0IHBhaXI8dCx1PiZwLGludCBzdWM9MSl7CglwcmludChwLmEsMik7CglwcmludChwLmIsc3VjKTsKfQoKdGVtcGxhdGU8Y2xhc3MgVD4Kdm9pZCBwcmludChjb25zdCB2ZWN0b3I8VD4mdixpbnQgc3VjPTEpewoJcmVwKGksdi5zaXplKCkpCgkJcHJpbnQodltpXSxpPT1pbnQodi5zaXplKCkpLTE/c3VjOjIpOwp9CgpzdHJpbmcgcmVhZFN0cmluZygpewoJc3RyaW5nIHM7CgljaW4+PnM7CglyZXR1cm4gczsKfQoKdGVtcGxhdGU8Y2xhc3MgVD4KVCBzcShjb25zdCBUJiB0KXsKCXJldHVybiB0KnQ7Cn0KCnZvaWQgeWVzKCl7Cglwci53cml0ZWxuKCJZRVMiKTsKfQp2b2lkIG5vKCl7Cglwci53cml0ZWxuKCJOTyIpOwp9CnZvaWQgcG9zc2libGUoYm9vbCBleD10cnVlKXsKCSNpZmRlZiBDQVBJVEFMCgljb3V0PDwiUE9TU0lCTEUiPDwiXG4iOwoJI2Vsc2UKCWNvdXQ8PCJQb3NzaWJsZSI8PCJcbiI7CgkjZW5kaWYKCWlmKGV4KWV4aXQoMCk7CgkjaWZkZWYgTE9DQUwKCWNvdXQuZmx1c2goKTsKCSNlbmRpZgp9CnZvaWQgaW1wb3NzaWJsZShib29sIGV4PXRydWUpewoJI2lmZGVmIENBUElUQUwKCWNvdXQ8PCJJTVBPU1NJQkxFIjw8IlxuIjsKCSNlbHNlCgljb3V0PDwiSW1wb3NzaWJsZSI8PCJcbiI7CgkjZW5kaWYKCWlmKGV4KWV4aXQoMCk7CgkjaWZkZWYgTE9DQUwKCWNvdXQuZmx1c2goKTsKCSNlbmRpZgp9Cgpjb25zdGV4cHIgbGwgdGVuKGludCBuKXsKCXJldHVybiBuPT0wPzE6dGVuKG4tMSkqMTA7Cn0KCmNvbnN0IGxsIGluZkxMPUxMT05HX01BWC8zOwoKI2lmZGVmIGludApjb25zdCBpbnQgaW5mPWluZkxMOwojZWxzZQpjb25zdCBpbnQgaW5mPUlOVF9NQVgvMi0xMDA7CiNlbmRpZgoKaW50IHRvcGJpdChzaWduZWQgdCl7CglyZXR1cm4gdD09MD8tMTozMS1fX2J1aWx0aW5fY2x6KHQpOwp9CmludCB0b3BiaXQobGwgdCl7CglyZXR1cm4gdD09MD8tMTo2My1fX2J1aWx0aW5fY2x6bGwodCk7Cn0KaW50IGJvdGJpdChzaWduZWQgYSl7CglyZXR1cm4gYT09MD8zMjpfX2J1aWx0aW5fY3R6KGEpOwp9CmludCBib3RiaXQobGwgYSl7CglyZXR1cm4gYT09MD82NDpfX2J1aWx0aW5fY3R6bGwoYSk7Cn0KaW50IHBvcGNvdW50KHNpZ25lZCB0KXsKCXJldHVybiBfX2J1aWx0aW5fcG9wY291bnQodCk7Cn0KaW50IHBvcGNvdW50KGxsIHQpewoJcmV0dXJuIF9fYnVpbHRpbl9wb3Bjb3VudGxsKHQpOwp9CmJvb2wgaXNwb3cyKGludCBpKXsKCXJldHVybiBpJiYoaSYtaSk9PWk7Cn0KbGwgbWFzayhpbnQgaSl7CglyZXR1cm4gKGxsKDEpPDxpKS0xOwp9Cgpib29sIGluYyhpbnQgYSxpbnQgYixpbnQgYyl7CglyZXR1cm4gYTw9YiYmYjw9YzsKfQoKdGVtcGxhdGU8Y2xhc3MgdD4gdm9pZCBta3VuaSh2Yzx0PiZ2KXsKCXNvcnQoYWxsKHYpKTsKCXYuZXJhc2UodW5pcXVlKGFsbCh2KSksdi5lZCk7Cn0KCmxsIHJhbmRfaW50KGxsIGwsIGxsIHIpIHsgLy9bbCwgcl0KCSNpZmRlZiBMT0NBTAoJc3RhdGljIG10MTk5MzdfNjQgZ2VuOwoJI2Vsc2UKCXN0YXRpYyBtdDE5OTM3XzY0IGdlbihjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwoJI2VuZGlmCglyZXR1cm4gdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGxsPihsLCByKShnZW4pOwp9Cgp0ZW1wbGF0ZTxjbGFzcyB0Pgp2b2lkIG15c2h1ZmZsZSh2Yzx0PiZhKXsKCXJlcChpLHNpKGEpKXN3YXAoYVtpXSxhW3JhbmRfaW50KDAsaSldKTsKfQoKdGVtcGxhdGU8Y2xhc3MgdD4KaW50IGx3Yihjb25zdCB2Yzx0PiZ2LGNvbnN0IHQmYSl7CglyZXR1cm4gbG93ZXJfYm91bmQoYWxsKHYpLGEpLXYuYmc7Cn0KCnZ2YzxpbnQ+IHJlYWRHcmFwaChpbnQgbixpbnQgbSl7Cgl2dmM8aW50PiBnKG4pOwoJcmVwKGksbSl7CgkJaW50IGEsYjsKCQljaW4+PmE+PmI7CgkJLy9zYy5yZWFkKGEsYik7CgkJYS0tO2ItLTsKCQlnW2FdLnBiKGIpOwoJCWdbYl0ucGIoYSk7Cgl9CglyZXR1cm4gZzsKfQoKdnZjPGludD4gcmVhZFRyZWUoaW50IG4pewoJcmV0dXJuIHJlYWRHcmFwaChuLG4tMSk7Cn0KCi8qCiAqIFRpbWUgQ29tcGxleGl0eTogU3VmZml4IEFycmF5OiBPKE4gKyBDaGFyYWN0ZXJfU2V0X1NpemUpIHRpbWUgYW5kIHNwYWNlIC8vIDEyOCAtLS0gQVNDSUkKICogICAgICAgICAgICAgICAgICBMQ1A6IE8oTikgdGltZSBhbmQgc3BhY2UKICogVXNhZ2U6CiAqICAgICAgIDEuIFN1ZmZpeCBBcnJheSAocmV0dXJucyBzLnNpemUoKSBlbGVtZW50cywgTk9UIGNvbnNpZGVyaW5nIDAtbGVuZ3RoL2VtcHR5IHN1ZmZpeCkKICogICAgICAgICAgICAgYXV0byBzYSA9IHN1ZmZpeF9hcnJheShzKTsgLy8gcyBpcyB0aGUgaW5wdXQgc3RyaW5nIHdpdGggQVNDSUkgY2hhcmFjdGVycwogKiAgICAgICAgICAgICBhdXRvIHNhX3dpZGVfY2hhciA9IHN1ZmZpeF9hcnJheShzLCBMSU0pOyAvLyBMSU0gPSBtYXgoc1tpXSkgKyAyLCBzIGlzIHRoZSBzdHJpbmcgd2l0aCBhcmJpdGFyeSBiaWcgY2hhcmFjdGVycy4KICogICAgICAgMi4gTENQOgogKiAgICAgICAgICAgIGF1dG8gbGNwID0gTENQKHMsIHN1ZmZpeF9hcnJheShzKSk7IC8vIHJldHVybnMgcy5zaXplKCkgZWxlbWVudHMsIHdoZXJlIGxjcFtpXT1MQ1Aoc2FbaV0sIHNhW2krMV0pCiAqIFN0YXR1czogVGVzdGVkIChETU9KOiBjY2MwM3M0LCBTUE9KOiBTQVJSQVkgKDEwMHB0cyksIFlvc3VwbydzOiBTdWZmaXggQXJyYXkgJiBOdW1iZXIgb2YgU3Vic3RyaW5ncywgQ29kZUZvcmNlcyBFRFUKICovCgovLyBCYXNlZCBvbjogUmlja3lwb24sIGh0dHBzOi8vai4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uby5qcC9zdWJtaXNzaW9uLzEwMTA1CnZvaWQgaW5kdWNlZF9zb3J0KGNvbnN0IHZlY3RvcjxpbnQ+ICZ2ZWMsIGludCB2YWxfcmFuZ2UsIHZlY3RvcjxpbnQ+ICZTQSwgY29uc3QgdmVjdG9yPGJvb2w+ICZzbCwgY29uc3QgdmVjdG9yPGludD4gJmxtc19pZHgpIHsKICAgIHZlY3RvcjxpbnQ+IGwodmFsX3JhbmdlLCAwKSwgcih2YWxfcmFuZ2UsIDApOwogICAgZm9yIChpbnQgYyA6IHZlYykgewogICAgICAgIGlmIChjICsgMSA8IHZhbF9yYW5nZSkgKytsW2MgKyAxXTsKICAgICAgICArK3JbY107CiAgICB9CiAgICBwYXJ0aWFsX3N1bShsLmJlZ2luKCksIGwuZW5kKCksIGwuYmVnaW4oKSk7CiAgICBwYXJ0aWFsX3N1bShyLmJlZ2luKCksIHIuZW5kKCksIHIuYmVnaW4oKSk7CiAgICBmaWxsKFNBLmJlZ2luKCksIFNBLmVuZCgpLCAtMSk7CiAgICBmb3IgKGludCBpID0gbG1zX2lkeC5zaXplKCkgLSAxOyBpID49IDA7IC0taSkKICAgICAgICBTQVstLXJbdmVjW2xtc19pZHhbaV1dXV0gPSBsbXNfaWR4W2ldOwogICAgZm9yIChpbnQgaSA6IFNBKQogICAgICAgIGlmIChpID49IDEgJiYgc2xbaSAtIDFdKSB7CiAgICAgICAgICAgIFNBW2xbdmVjW2kgLSAxXV0rK10gPSBpIC0gMTsKICAgICAgICB9CiAgICBmaWxsKHIuYmVnaW4oKSwgci5lbmQoKSwgMCk7CiAgICBmb3IgKGludCBjIDogdmVjKQogICAgICAgICsrcltjXTsKICAgIHBhcnRpYWxfc3VtKHIuYmVnaW4oKSwgci5lbmQoKSwgci5iZWdpbigpKTsKICAgIGZvciAoaW50IGsgPSBTQS5zaXplKCkgLSAxLCBpID0gU0Fba107IGsgPj0gMTsgLS1rLCBpID0gU0Fba10pCiAgICAgICAgaWYgKGkgPj0gMSAmJiAhc2xbaSAtIDFdKSB7CiAgICAgICAgICAgIFNBWy0tclt2ZWNbaSAtIDFdXV0gPSBpIC0gMTsKICAgICAgICB9Cn0KCnZlY3RvcjxpbnQ+IFNBX0lTKGNvbnN0IHZlY3RvcjxpbnQ+ICZ2ZWMsIGludCB2YWxfcmFuZ2UpIHsKICAgIGNvbnN0IGludCBuID0gdmVjLnNpemUoKTsKICAgIHZlY3RvcjxpbnQ+IFNBKG4pLCBsbXNfaWR4OwogICAgdmVjdG9yPGJvb2w+IHNsKG4pOwogICAgc2xbbiAtIDFdID0gZmFsc2U7CiAgICBmb3IgKGludCBpID0gbiAtIDI7IGkgPj0gMDsgLS1pKSB7CiAgICAgICAgc2xbaV0gPSAodmVjW2ldID4gdmVjW2kgKyAxXSB8fCAodmVjW2ldID09IHZlY1tpICsgMV0gJiYgc2xbaSArIDFdKSk7CiAgICAgICAgaWYgKHNsW2ldICYmICFzbFtpICsgMV0pIGxtc19pZHgucHVzaF9iYWNrKGkgKyAxKTsKICAgIH0KICAgIHJldmVyc2UobG1zX2lkeC5iZWdpbigpLCBsbXNfaWR4LmVuZCgpKTsKICAgIGluZHVjZWRfc29ydCh2ZWMsIHZhbF9yYW5nZSwgU0EsIHNsLCBsbXNfaWR4KTsKICAgIHZlY3RvcjxpbnQ+IG5ld19sbXNfaWR4KGxtc19pZHguc2l6ZSgpKSwgbG1zX3ZlYyhsbXNfaWR4LnNpemUoKSk7CiAgICBmb3IgKGludCBpID0gMCwgayA9IDA7IGkgPCBuOyArK2kpCiAgICAgICAgaWYgKCFzbFtTQVtpXV0gJiYgU0FbaV0gPj0gMSAmJiBzbFtTQVtpXSAtIDFdKSB7CiAgICAgICAgICAgIG5ld19sbXNfaWR4W2srK10gPSBTQVtpXTsKICAgICAgICB9CiAgICBpbnQgY3VyID0gMDsKICAgIFNBW24gLSAxXSA9IGN1cjsKICAgIGZvciAoc2l6ZV90IGsgPSAxOyBrIDwgbmV3X2xtc19pZHguc2l6ZSgpOyArK2spIHsKICAgICAgICBpbnQgaSA9IG5ld19sbXNfaWR4W2sgLSAxXSwgaiA9IG5ld19sbXNfaWR4W2tdOwogICAgICAgIGlmICh2ZWNbaV0gIT0gdmVjW2pdKSB7CiAgICAgICAgICAgIFNBW2pdID0gKytjdXI7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBib29sIGZsYWcgPSBmYWxzZTsKICAgICAgICBmb3IgKGludCBhID0gaSArIDEsIGIgPSBqICsgMTs7ICsrYSwgKytiKSB7CiAgICAgICAgICAgIGlmICh2ZWNbYV0gIT0gdmVjW2JdKSB7CiAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgoIXNsW2FdICYmIHNsW2EgLSAxXSkgfHwgKCFzbFtiXSAmJiBzbFtiIC0gMV0pKSB7CiAgICAgICAgICAgICAgICBmbGFnID0gISgoIXNsW2FdICYmIHNsW2EgLSAxXSkgJiYgKCFzbFtiXSAmJiBzbFtiIC0gMV0pKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFNBW2pdID0gKGZsYWcgPyArK2N1ciA6IGN1cik7CiAgICB9CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxtc19pZHguc2l6ZSgpOyArK2kpCiAgICAgICAgbG1zX3ZlY1tpXSA9IFNBW2xtc19pZHhbaV1dOwogICAgaWYgKGN1ciArIDEgPCAoaW50KWxtc19pZHguc2l6ZSgpKSB7CiAgICAgICAgYXV0byBsbXNfU0EgPSBTQV9JUyhsbXNfdmVjLCBjdXIgKyAxKTsKICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGxtc19pZHguc2l6ZSgpOyArK2kpIHsKICAgICAgICAgICAgbmV3X2xtc19pZHhbaV0gPSBsbXNfaWR4W2xtc19TQVtpXV07CiAgICAgICAgfQogICAgfQogICAgaW5kdWNlZF9zb3J0KHZlYywgdmFsX3JhbmdlLCBTQSwgc2wsIG5ld19sbXNfaWR4KTsKICAgIHJldHVybiBTQTsKfQp2ZWN0b3I8aW50PiBzdWZmaXhfYXJyYXkoY29uc3Qgc3RyaW5nICZzLCBjb25zdCBpbnQgTElNID0gMTI4KSB7CiAgICB2ZWN0b3I8aW50PiB2ZWMocy5zaXplKCkgKyAxKTsKICAgIGNvcHkoYmVnaW4ocyksIGVuZChzKSwgYmVnaW4odmVjKSk7CiAgICB2ZWMuYmFjaygpID0gJyQnOwogICAgYXV0byByZXQgPSBTQV9JUyh2ZWMsIExJTSk7CiAgICByZXQuZXJhc2UocmV0LmJlZ2luKCkpOwogICAgcmV0dXJuIHJldDsKfQoKLy8gQXV0aG9yOiBodHRwczovL2MuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL2Jsb2cvZW50cnkvMTI3OTY/I2NvbW1lbnQtMTc1Mjg3Ci8vIFVzZXMga2FzYWkncyBhbGdvcml0aG0gbGluZWFyIGluIHRpbWUgYW5kIHNwYWNlCnZlY3RvcjxpbnQ+IExDUChjb25zdCBzdHJpbmcgJnMsIGNvbnN0IHZlY3RvcjxpbnQ+ICZzYSwgY29uc3QgdmVjdG9yPGludD4mIGFzKSB7CiAgICBpbnQgbiA9IHMuc2l6ZSgpLCBrID0gMDsKICAgIHZlY3RvcjxpbnQ+IGxjcChuKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrLCBrID8gay0tIDogMCkgewogICAgICAgIGlmIChhc1tpXSA9PSBuIC0gMSkgewogICAgICAgICAgICBrID0gMDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGludCBqID0gc2FbYXNbaV0gKyAxXTsKICAgICAgICB3aGlsZSAoaSArIGsgPCBuICYmIGogKyBrIDwgbiAmJiBzW2kgKyBrXSA9PSBzW2ogKyBrXSkKICAgICAgICAgICAgaysrOwogICAgICAgIGxjcFthc1tpXV0gPSBrOwogICAgfQogICAgbGNwW24gLSAxXSA9IDA7CiAgICByZXR1cm4gbGNwOwp9Cgpjb25zdCBpbnQgTD0yMTsKY29uc3QgaW50IFM9MTw8TDsKaW50IGJ1ZltMXVtTXTsKdm9pZCBzcGluaXQoY29uc3QgdmkmZCl7CglpbnQgbj1kLnNpemUoKSxoPXRvcGJpdChuKTsKCXJlcChpLG4pYnVmWzBdW2ldPWRbaV07CglybmcoaiwxLGgrMSl7CgkJcmVwKGksbi0oMTw8aikrMSkKCQkJYnVmW2pdW2ldPW1pbihidWZbai0xXVtpXSxidWZbai0xXVtpKygxPDwoai0xKSldKTsKCX0KfQppbnQgc3BnZXQoaW50IGIsaW50IGUpewoJYXNzZXJ0KGI8PWUpOwoJaWYoYj09ZSlyZXR1cm4gaW5mOwoJaW50IGQ9dG9wYml0KGUtYik7CglyZXR1cm4gbWluKGJ1ZltkXVtiXSxidWZbZF1bZS0oMTw8ZCldKTsKfQoKY29uc3QgaW50IGttYXg9MTA1MDsKaW50IGRwW2ttYXhdW2ttYXhdLHByZVtrbWF4XVtrbWF4XTsKCnZvaWQgc2x2KCl7CglpbnQgbixtLGs7c2MucmVhZChuLG0sayk7CglzdHJpbmcgc3JjO3NjLnJlYWQoc3JjKTsKCXN0cmluZyBkc3Q7c2MucmVhZChkc3QpOwoJaW50IGRpZj1hYnMobi1tKSxhZmY9ay1kaWY7CglpZihhZmY8MClyZXR1cm4gbm8oKTsKCWludCBsdz1taW4oMCxtLW4pLWFmZi8yLHVwPW1heCgwLG0tbikrYWZmLzI7CglpbnQgcz11cC1sdysxOwoJcmVwKGksaysxKXJlcChqLHMpewoJCWRwW2ldW2pdPS1pbmY7CgkJcHJlW2ldW2pdPS1pbmY7Cgl9CgkKCXN0cmluZyBydz1zcmMrJ1cnK2RzdDsKCXZpIHNhPXN1ZmZpeF9hcnJheShydyk7Cgl2aSBhcyhuK20rMSk7cmVwKGksbittKzEpYXNbc2FbaV1dPWk7Cgl2aSBsY3A9TENQKHJ3LHNhLGFzKTsKCS8vc3BhcnNldGFibGU8aW50LGRlY2x0eXBlKGltaW4pPiBzdChsY3AsaW1pbixpbmYpOwoJc3Bpbml0KGxjcCk7Cgljb25zdCBhdXRvIGNvbW1vbj1bJl0oaW50IGksaW50IGopewoJCWlmKGk9PW58fGo9PW0pcmV0dXJuIDA7CgkJaT1hc1tpXTsKCQlqPWFzW24rMStqXTsKCQlpZihpPmopc3dhcChpLGopOwoJCXJldHVybiBzcGdldChpLGopOwoJfTsKCQoJZHBbMF1bMC1sd109Y29tbW9uKDAsMCkqMjsKCXJlcChhbnMsaysxKXsKCQlpZihkcFthbnNdW20tbi1sd109PW4rbSl7CgkJCXllcygpOwoJCQlwci53cml0ZWxuKGFucyk7CgkJCWludCBpZHg9bS1uOwoJCQl3aGlsZShhbnMpewoJCQkJaW50IHA9cHJlW2Fuc11baWR4LWx3XTsKCQkJCWludCBpPShkcFthbnMtMV1bcC1sd10tcCkvMjsKCQkJCWludCBqPShkcFthbnMtMV1bcC1sd10rcCkvMjsKCQkJCWlmKHA9PWlkeCl7CgkJCQkJcHIud3JpdGVsbigiUkVQTEFDRSIsaSsxLGRzdFtqXSk7CgkJCQl9ZWxzZSBpZihwKzE9PWlkeCl7CgkJCQkJcHIud3JpdGVsbigiSU5TRVJUIixpKzEsZHN0W2pdKTsKCQkJCX1lbHNlIGlmKHAtMT09aWR4KXsKCQkJCQlwci53cml0ZWxuKCJERUxFVEUiLGkrMSk7CgkJCQl9ZWxzZXsKCQkJCQlhc3NlcnQoZmFsc2UpOwoJCQkJfQoJCQkJYW5zLS07CgkJCQlpZHg9cDsKCQkJfQoJCQlyZXR1cm47CgkJfQoJCWlmKGFucz09aylyZXR1cm4gbm8oKTsKCQlybmcoaWR4LGx3LHVwKzEpewoJCQlpZihkcFthbnNdW2lkeC1sd10+LWluZil7CgkJCQlpbnQgaT0oZHBbYW5zXVtpZHgtbHddLWlkeCkvMjsKCQkJCWludCBqPShkcFthbnNdW2lkeC1sd10raWR4KS8yOwoJCQkJaWYoaTxuJiZqPG0pewoJCQkJCWludCBsZW49Y29tbW9uKGkrMSxqKzEpOwoJCQkJCWludCB5PWkrMStsZW4seD1qKzErbGVuOwoJCQkJCWludCB6PXgreTsKCQkJCQlpZihkcFthbnMrMV1baWR4LWx3XTx6KXsKCQkJCQkJZHBbYW5zKzFdW2lkeC1sd109ejsKCQkJCQkJcHJlW2FucysxXVtpZHgtbHddPWlkeDsKCQkJCQl9CgkJCQl9CgkJCQlpZihpZHg8dXAmJmo8bSl7CgkJCQkJaW50IGxlbj1jb21tb24oaSxqKzEpOwoJCQkJCWludCB5PWkrbGVuLHg9aisxK2xlbjsKCQkJCQlpbnQgej14K3k7CgkJCQkJaWYoZHBbYW5zKzFdW2lkeCsxLWx3XTx6KXsKCQkJCQkJZHBbYW5zKzFdW2lkeCsxLWx3XT16OwoJCQkJCQlwcmVbYW5zKzFdW2lkeCsxLWx3XT1pZHg7CgkJCQkJfQoJCQkJfQoJCQkJaWYobHc8aWR4JiZpPG4pewoJCQkJCWludCBsZW49Y29tbW9uKGkrMSxqKTsKCQkJCQlpbnQgeT1pKzErbGVuLHg9aitsZW47CgkJCQkJaW50IHo9eCt5OwoJCQkJCWlmKGRwW2FucysxXVtpZHgtMS1sd108eil7CgkJCQkJCWRwW2FucysxXVtpZHgtMS1sd109ejsKCQkJCQkJcHJlW2FucysxXVtpZHgtMS1sd109aWR4OwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KCWFzc2VydChmYWxzZSk7Cn0KCnNpZ25lZCBtYWluKCl7CglpbnQgdDtzYy5yZWFkKHQpO3JlcChfLHQpCglzbHYoKTsKfQo=