#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
template<class T> struct cLtraits_identity{
using type = T;
}
;
template<class T> using cLtraits_try_make_signed =
typename conditional<
is_integral<T>::value,
make_signed<T>,
cLtraits_identity<T>
>::type;
template <class S, class T> struct cLtraits_common_type{
using tS = typename cLtraits_try_make_signed<S>::type;
using tT = typename cLtraits_try_make_signed<T>::type;
using type = typename common_type<tS,tT>::type;
}
;
void*wmem;
char memarr[96000000];
template<class S, class T> inline auto min_L(S a, T b)
-> typename cLtraits_common_type<S,T>::type{
return (typename cLtraits_common_type<S,T>::type) a <= (typename cLtraits_common_type<S,T>::type) b ? a : b;
}
template<class S, class T> inline auto max_L(S a, T b)
-> typename cLtraits_common_type<S,T>::type{
return (typename cLtraits_common_type<S,T>::type) a >= (typename cLtraits_common_type<S,T>::type) b ? a : b;
}
template<class T> inline void walloc1d(T **arr, int x, void **mem = &wmem){
static int skip[16] = {0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
(*mem) = (void*)( ((char*)(*mem)) + skip[((unsigned long long)(*mem)) & 15] );
(*arr)=(T*)(*mem);
(*mem)=((*arr)+x);
}
template<class T> inline void walloc1d(T **arr, int x1, int x2, void **mem = &wmem){
walloc1d(arr, x2-x1, mem);
(*arr) -= x1;
}
inline int my_getchar_unlocked(){
static char buf[1048576];
static int s = 1048576;
static int e = 1048576;
if(s == e && e == 1048576){
e = fread_unlocked(buf, 1, 1048576, stdin);
s = 0;
}
if(s == e){
return EOF;
}
return buf[s++];
}
inline void rd(int &x){
int k;
int m=0;
x=0;
for(;;){
k = my_getchar_unlocked();
if(k=='-'){
m=1;
break;
}
if('0'<=k&&k<='9'){
x=k-'0';
break;
}
}
for(;;){
k = my_getchar_unlocked();
if(k<'0'||k>'9'){
break;
}
x=x*10+k-'0';
}
if(m){
x=-x;
}
}
inline void rd(long long &x){
int k;
int m=0;
x=0;
for(;;){
k = my_getchar_unlocked();
if(k=='-'){
m=1;
break;
}
if('0'<=k&&k<='9'){
x=k-'0';
break;
}
}
for(;;){
k = my_getchar_unlocked();
if(k<'0'||k>'9'){
break;
}
x=x*10+k-'0';
}
if(m){
x=-x;
}
}
inline void rd(char &c){
int i;
for(;;){
i = my_getchar_unlocked();
if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF){
break;
}
}
c = i;
}
inline int rd(char c[]){
int i;
int sz = 0;
for(;;){
i = my_getchar_unlocked();
if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF){
break;
}
}
c[sz++] = i;
for(;;){
i = my_getchar_unlocked();
if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF){
break;
}
c[sz++] = i;
}
c[sz]='\0';
return sz;
}
inline int rd_int(void){
int x;
rd(x);
return x;
}
struct MY_WRITER{
char buf[1048576];
int s;
int e;
MY_WRITER(){
s = 0;
e = 1048576;
}
~MY_WRITER(){
if(s){
fwrite_unlocked(buf, 1, s, stdout);
}
}
}
;
MY_WRITER MY_WRITER_VAR;
void my_putchar_unlocked(int a){
if(MY_WRITER_VAR.s == MY_WRITER_VAR.e){
fwrite_unlocked(MY_WRITER_VAR.buf, 1, MY_WRITER_VAR.s, stdout);
MY_WRITER_VAR.s = 0;
}
MY_WRITER_VAR.buf[MY_WRITER_VAR.s++] = a;
}
inline void wt_L(char a){
my_putchar_unlocked(a);
}
inline void wt_L(int x){
int s=0;
int m=0;
char f[10];
if(x<0){
m=1;
x=-x;
}
while(x){
f[s++]=x%10;
x/=10;
}
if(!s){
f[s++]=0;
}
if(m){
my_putchar_unlocked('-');
}
while(s--){
my_putchar_unlocked(f[s]+'0');
}
}
inline void wt_L(long long x){
int s=0;
int m=0;
char f[20];
if(x<0){
m=1;
x=-x;
}
while(x){
f[s++]=x%10;
x/=10;
}
if(!s){
f[s++]=0;
}
if(m){
my_putchar_unlocked('-');
}
while(s--){
my_putchar_unlocked(f[s]+'0');
}
}
inline void wt_L(const char c[]){
int i=0;
for(i=0;c[i]!='\0';i++){
my_putchar_unlocked(c[i]);
}
}
template<class S, class T> inline S chmin(S &a, T b){
if(a>b){
a=b;
}
return a;
}
template <class T> struct LHeap{
int*hp;
int*place;
int size;
T*val;
void malloc(int N){
hp = (int*)std::malloc(N*sizeof(int));
place=(int*)std::malloc(N*sizeof(int));
val=(T*)std::malloc(N*sizeof(T));
}
void malloc(int N, int ini){
hp = (int*)std::malloc(N*sizeof(int));
place=(int*)std::malloc(N*sizeof(int));
val=(T*)std::malloc(N*sizeof(T));
if(ini){
init(N);
}
}
void walloc(int N, void **mem=&wmem){
walloc1d(&hp, N, mem);
walloc1d(&place, N, mem);
walloc1d(&val, N, mem);
}
void walloc(int N, int ini, void **mem=&wmem){
walloc1d(&hp, N, mem);
walloc1d(&place, N, mem);
walloc1d(&val, N, mem);
if(ini){
init(N);
}
}
void free(){
std::free(hp);
std::free(place);
std::free(val);
}
void init(int N){
int i;
size=0;
for(i=(0);i<(N);i++){
place[i]=-1;
}
}
void up(int n){
int m;
while(n){
m=(n-1)/2;
if(val[hp[m]]<=val[hp[n]]){
break;
}
swap(hp[m],hp[n]);
swap(place[hp[m]],place[hp[n]]);
n=m;
}
}
void down(int n){
int m;
for(;;){
m=2*n+1;
if(m>=size){
break;
}
if(m+1<size&&val[hp[m]]>val[hp[m+1]]){
m++;
}
if(val[hp[m]]>=val[hp[n]]){
break;
}
swap(hp[m],hp[n]);
swap(place[hp[m]],place[hp[n]]);
n=m;
}
}
void change(int n, T v){
T f = val[n];
val[n] = v;
if(place[n]==-1){
place[n] = size;
hp[size++] = n;
up(place[n]);
}
else{
if(f < v){
down(place[n]);
}
else if(f > v){
up(place[n]);
}
}
}
int pop(void){
int res = hp[0];
place[res] = -1;
size--;
if(size){
hp[0]=hp[size];
place[hp[0]]=0;
down(0);
}
return res;
}
}
;
template<class FT, class CT> struct minCostFlow{
int node;
int*es;
int*emem;
int**edge;
int**rev;
FT**flow;
FT f_eps;
CT**cost;
CT*potential;
CT c_eps;
LHeap<CT> hp;
char*reached;
FT*cur_flow;
CT*cur_cost;
int*back_edge;
void malloc(int N){
int i;
es = (int*)std::malloc(N*sizeof(int));
emem = (int*)std::malloc(N*sizeof(int));
edge = (int**)std::malloc(N*sizeof(int*));
rev = (int**)std::malloc(N*sizeof(int*));
flow = (FT**)std::malloc(N*sizeof(FT*));
cost = (CT**)std::malloc(N*sizeof(CT*));
for(i=(0);i<(N);i++){
emem[i] = 0;
edge[i] = rev[i] = NULL;
flow[i] = NULL;
cost[i] = NULL;
}
hp.malloc(N);
reached = (char*)std::malloc(N*sizeof(char));
cur_flow = (FT*)std::malloc(N*sizeof(FT));
cur_cost = (CT*)std::malloc(N*sizeof(CT));
potential = (CT*)std::malloc(N*sizeof(CT));
back_edge = (int*)std::malloc(N*sizeof(int));
node = N;
for(i=(0);i<(N);i++){
es[i] = 0;
}
f_eps = (FT)1e-9;
c_eps = (CT)1e-9;
}
void init(int N){
int i;
node = N;
for(i=(0);i<(N);i++){
es[i] = 0;
}
f_eps = (FT)1e-9;
c_eps = (CT)1e-9;
}
void memoryExpand(int i, int sz){
if(sz <= emem[i]){
return;
}
sz =max_L(max_L(sz, 3), 2*emem[i]);
emem[i] = sz;
edge[i] = (int*)realloc(edge[i], sz*sizeof(int));
rev[i] = (int*)realloc(rev[i], sz*sizeof(int));
flow[i] = (FT*)realloc(flow[i], sz*sizeof(FT));
cost[i] = (CT*)realloc(cost[i], sz*sizeof(CT));
}
void addEdge(int n1, int n2, FT f, CT c){
int s1 = es[n1]++;
int s2 = es[n2]++;
if(s1 >= emem[n1]){
memoryExpand(n1, es[n1]);
}
if(s2 >= emem[n2]){
memoryExpand(n2, es[n2]);
}
edge[n1][s1] = n2;
edge[n2][s2] = n1;
rev[n1][s1] = s2;
rev[n2][s2] = s1;
flow[n1][s1] = f;
flow[n2][s2] = 0;
cost[n1][s1] = c;
cost[n2][s2] = -c;
}
template<class FTS, class CTS> void solve(int st, int ed, FTS &fres, CTS &cres, FT flim = -1, CT clim = 0){
int i;
int j;
int k;
int l;
FT f;
CT nc;
fres = 0;
cres = 0;
for(i=(0);i<(node);i++){
potential[i] = 0;
}
for(;;){
if(flim >= -f_eps && flim <= f_eps){
break;
}
hp.init(node);
for(i=(0);i<(node);i++){
reached[i] = 0;
}
reached[st] = 1;
cur_cost[st] = 0;
l = 0;
hp.change(st, cur_cost[st]);
while(hp.size){
i = hp.pop();
for(j=(0);j<(es[i]);j++){
if(flow[i][j] <= f_eps){
continue;
}
k = edge[i][j];
nc = cur_cost[i] + cost[i][j] + potential[i] - potential[k];
if(reached[k]==0 || cur_cost[k] > nc+c_eps){
reached[k] = 1;
cur_cost[k] = nc;
cur_flow[k] = flow[i][j];
if(i != st){
chmin(cur_flow[k], cur_flow[i]);
}
back_edge[k] = rev[i][j];
hp.change(k, cur_cost[k]);
}
}
}
if(reached[ed]==0){
break;
}
if(flim==-2 && cur_cost[ed] + potential[ed] >= clim){
break;
}
f = cur_flow[ed];
if(flim >= -f_eps){
chmin(f, flim);
flim -= f;
}
if(f <= f_eps){
break;
}
for(i=(0);i<(node);i++){
if(reached[i]){
potential[i] += cur_cost[i];
}
}
fres += f;
cres += f * potential[ed];
i = ed;
while(i != st){
j = back_edge[i];
k = edge[i][j];
flow[i][j] += f;
flow[k][rev[i][j]] -= f;
i = k;
}
}
}
}
;
struct dimcomp2{
int B;
dimcomp2(){
}
dimcomp2(int b){
B = b;
}
dimcomp2(int a, int b){
B = b;
}
inline void set(int b){
B = b;
}
inline void set(int a, int b){
B = b;
}
inline int mask(int a, int b){
return a * B + b;
}
inline int operator()(int a, int b){
return a * B + b;
}
inline void para(int mask, int &a, int &b){
a = mask / B;
b = mask % B;
}
inline void operator()(int mask, int &a, int &b){
a = mask / B;
b = mask % B;
}
}
;
int TEST;
int X;
int Y;
long long F;
long long S;
char A[10][12];
char B[10][12];
int main(){
wmem = memarr;
int node;
int st;
int ed;
dimcomp2 dm;
minCostFlow<long long,long long> flow;
flow.malloc(100000);
int Lj4PdHRW = rd_int();
for(TEST=(0);TEST<(Lj4PdHRW);TEST++){
int i, i1;
long long res = 0;
long long f;
long long c;
wt_L("Case #");
wt_L(TEST+1);
wt_L(": ");
rd(X);
rd(Y);
rd(F);
rd(S);
{
int e98WHCEY;
for(e98WHCEY=(0);e98WHCEY<(X);e98WHCEY++){
rd(A[e98WHCEY]);
}
}
{
int FmcKpFmN;
for(FmcKpFmN=(0);FmcKpFmN<(X);FmcKpFmN++){
rd(B[FmcKpFmN]);
}
}
node = X*Y;
st = node++;
ed = node++;
dm.set(X,Y);
flow.init(node);
for(i=(0);i<(X);i++){
int j;
for(j=(0);j<(Y);j++){
if(A[i][j]=='M' && B[i][j]=='G'){
flow.addEdge(st, dm(i,j), 1, 0);
}
}
}
for(i=(0);i<(X);i++){
int j;
for(j=(0);j<(Y);j++){
if(A[i][j]=='G' && B[i][j]=='M'){
flow.addEdge(dm(i,j), ed, 1, 0);
}
}
}
for(i1=(0);i1<(X);i1++){
int j1;
for(j1=(0);j1<(Y);j1++){
if(A[i1][j1]=='M' && B[i1][j1]=='G'){
int i2;
for(i2=(0);i2<(X);i2++){
int j2;
for(j2=(0);j2<(Y);j2++){
if(A[i2][j2]=='G' && B[i2][j2]=='M'){
flow.addEdge(dm(i1,j1), dm(i2,j2), 1, (abs(i1-i2) + abs(j1-j2)) * S - 2*F);
}
}
}
}
}
}
for(i=(0);i<(X);i++){
int j;
for(j=(0);j<(Y);j++){
if(A[i][j] != B[i][j]){
res += F;
}
}
}
flow.solve(st, ed, f, c, -2, 0);
wt_L(res + c);
wt_L('\n');
}
return 0;
}
// cLay version 20210405-1
// --- original code ---
// int TEST;
// int X, Y; ll F, S;
// char A[10][12], B[10][12];
// {
// int node, st, ed;
// dimcomp2 dm;
// minCostFlow<ll,ll> flow;
// flow.malloc(1d5);
// REP(TEST,rd_int()){
// ll res = 0, f, c;
// wtF("Case #{TEST+1}: ");
// rd(X,Y,F,S,A(X),B(X));
// node = X*Y;
// st = node++;
// ed = node++;
// dm.set(X,Y);
// flow.init(node);
//
// rep(i,X) rep(j,Y) if(A[i][j]=='M' && B[i][j]=='G') flow.addEdge(st, dm(i,j), 1, 0);
// rep(i,X) rep(j,Y) if(A[i][j]=='G' && B[i][j]=='M') flow.addEdge(dm(i,j), ed, 1, 0);
// rep(i1,X) rep(j1,Y) if(A[i1][j1]=='M' && B[i1][j1]=='G'){
// rep(i2,X) rep(j2,Y) if(A[i2][j2]=='G' && B[i2][j2]=='M'){
// flow.addEdge(dm(i1,j1), dm(i2,j2), 1, (abs(i1-i2) + abs(j1-j2)) * S - 2*F);
// }
// }
//
// rep(i,X) rep(j,Y) if(A[i][j] != B[i][j]) res += F;
// flow.solve(st, ed, f, c, -2, 0);
// wt(res + c);
// }
// }
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnRlbXBsYXRlPGNsYXNzIFQ+IHN0cnVjdCBjTHRyYWl0c19pZGVudGl0eXsKICB1c2luZyB0eXBlID0gVDsKfQo7CnRlbXBsYXRlPGNsYXNzIFQ+IHVzaW5nIGNMdHJhaXRzX3RyeV9tYWtlX3NpZ25lZCA9CiAgdHlwZW5hbWUgY29uZGl0aW9uYWw8CiAgICBpc19pbnRlZ3JhbDxUPjo6dmFsdWUsCiAgICBtYWtlX3NpZ25lZDxUPiwKICAgIGNMdHJhaXRzX2lkZW50aXR5PFQ+CiAgICA+Ojp0eXBlOwp0ZW1wbGF0ZSA8Y2xhc3MgUywgY2xhc3MgVD4gc3RydWN0IGNMdHJhaXRzX2NvbW1vbl90eXBlewogIHVzaW5nIHRTID0gdHlwZW5hbWUgY0x0cmFpdHNfdHJ5X21ha2Vfc2lnbmVkPFM+Ojp0eXBlOwogIHVzaW5nIHRUID0gdHlwZW5hbWUgY0x0cmFpdHNfdHJ5X21ha2Vfc2lnbmVkPFQ+Ojp0eXBlOwogIHVzaW5nIHR5cGUgPSB0eXBlbmFtZSBjb21tb25fdHlwZTx0Uyx0VD46OnR5cGU7Cn0KOwp2b2lkKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgUywgY2xhc3MgVD4gaW5saW5lIGF1dG8gbWluX0woUyBhLCBUIGIpCi0+IHR5cGVuYW1lIGNMdHJhaXRzX2NvbW1vbl90eXBlPFMsVD46OnR5cGV7CiAgcmV0dXJuICh0eXBlbmFtZSBjTHRyYWl0c19jb21tb25fdHlwZTxTLFQ+Ojp0eXBlKSBhIDw9ICh0eXBlbmFtZSBjTHRyYWl0c19jb21tb25fdHlwZTxTLFQ+Ojp0eXBlKSBiID8gYSA6IGI7Cn0KdGVtcGxhdGU8Y2xhc3MgUywgY2xhc3MgVD4gaW5saW5lIGF1dG8gbWF4X0woUyBhLCBUIGIpCi0+IHR5cGVuYW1lIGNMdHJhaXRzX2NvbW1vbl90eXBlPFMsVD46OnR5cGV7CiAgcmV0dXJuICh0eXBlbmFtZSBjTHRyYWl0c19jb21tb25fdHlwZTxTLFQ+Ojp0eXBlKSBhID49ICh0eXBlbmFtZSBjTHRyYWl0c19jb21tb25fdHlwZTxTLFQ+Ojp0eXBlKSBiID8gYSA6IGI7Cn0KdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgdm9pZCB3YWxsb2MxZChUICoqYXJyLCBpbnQgeDEsIGludCB4Miwgdm9pZCAqKm1lbSA9ICZ3bWVtKXsKICB3YWxsb2MxZChhcnIsIHgyLXgxLCBtZW0pOwogICgqYXJyKSAtPSB4MTsKfQppbmxpbmUgaW50IG15X2dldGNoYXJfdW5sb2NrZWQoKXsKICBzdGF0aWMgY2hhciBidWZbMTA0ODU3Nl07CiAgc3RhdGljIGludCBzID0gMTA0ODU3NjsKICBzdGF0aWMgaW50IGUgPSAxMDQ4NTc2OwogIGlmKHMgPT0gZSAmJiBlID09IDEwNDg1NzYpewogICAgZSA9IGZyZWFkX3VubG9ja2VkKGJ1ZiwgMSwgMTA0ODU3Niwgc3RkaW4pOwogICAgcyA9IDA7CiAgfQogIGlmKHMgPT0gZSl7CiAgICByZXR1cm4gRU9GOwogIH0KICByZXR1cm4gYnVmW3MrK107Cn0KaW5saW5lIHZvaWQgcmQoaW50ICZ4KXsKICBpbnQgazsKICBpbnQgbT0wOwogIHg9MDsKICBmb3IoOzspewogICAgayA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGs9PSctJyl7CiAgICAgIG09MTsKICAgICAgYnJlYWs7CiAgICB9CiAgICBpZignMCc8PWsmJms8PSc5Jyl7CiAgICAgIHg9ay0nMCc7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBmb3IoOzspewogICAgayA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGs8JzAnfHxrPic5Jyl7CiAgICAgIGJyZWFrOwogICAgfQogICAgeD14KjEwK2stJzAnOwogIH0KICBpZihtKXsKICAgIHg9LXg7CiAgfQp9CmlubGluZSB2b2lkIHJkKGxvbmcgbG9uZyAmeCl7CiAgaW50IGs7CiAgaW50IG09MDsKICB4PTA7CiAgZm9yKDs7KXsKICAgIGsgPSBteV9nZXRjaGFyX3VubG9ja2VkKCk7CiAgICBpZihrPT0nLScpewogICAgICBtPTE7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYoJzAnPD1rJiZrPD0nOScpewogICAgICB4PWstJzAnOwogICAgICBicmVhazsKICAgIH0KICB9CiAgZm9yKDs7KXsKICAgIGsgPSBteV9nZXRjaGFyX3VubG9ja2VkKCk7CiAgICBpZihrPCcwJ3x8az4nOScpewogICAgICBicmVhazsKICAgIH0KICAgIHg9eCoxMCtrLScwJzsKICB9CiAgaWYobSl7CiAgICB4PS14OwogIH0KfQppbmxpbmUgdm9pZCByZChjaGFyICZjKXsKICBpbnQgaTsKICBmb3IoOzspewogICAgaSA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGkhPScgJyYmaSE9J1xuJyYmaSE9J1xyJyYmaSE9J1x0JyYmaSE9RU9GKXsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGMgPSBpOwp9CmlubGluZSBpbnQgcmQoY2hhciBjW10pewogIGludCBpOwogIGludCBzeiA9IDA7CiAgZm9yKDs7KXsKICAgIGkgPSBteV9nZXRjaGFyX3VubG9ja2VkKCk7CiAgICBpZihpIT0nICcmJmkhPSdcbicmJmkhPSdccicmJmkhPSdcdCcmJmkhPUVPRil7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBjW3N6KytdID0gaTsKICBmb3IoOzspewogICAgaSA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGk9PScgJ3x8aT09J1xuJ3x8aT09J1xyJ3x8aT09J1x0J3x8aT09RU9GKXsKICAgICAgYnJlYWs7CiAgICB9CiAgICBjW3N6KytdID0gaTsKICB9CiAgY1tzel09J1wwJzsKICByZXR1cm4gc3o7Cn0KaW5saW5lIGludCByZF9pbnQodm9pZCl7CiAgaW50IHg7CiAgcmQoeCk7CiAgcmV0dXJuIHg7Cn0Kc3RydWN0IE1ZX1dSSVRFUnsKICBjaGFyIGJ1ZlsxMDQ4NTc2XTsKICBpbnQgczsKICBpbnQgZTsKICBNWV9XUklURVIoKXsKICAgIHMgPSAwOwogICAgZSA9IDEwNDg1NzY7CiAgfQogIH5NWV9XUklURVIoKXsKICAgIGlmKHMpewogICAgICBmd3JpdGVfdW5sb2NrZWQoYnVmLCAxLCBzLCBzdGRvdXQpOwogICAgfQogIH0KfQo7Ck1ZX1dSSVRFUiBNWV9XUklURVJfVkFSOwp2b2lkIG15X3B1dGNoYXJfdW5sb2NrZWQoaW50IGEpewogIGlmKE1ZX1dSSVRFUl9WQVIucyA9PSBNWV9XUklURVJfVkFSLmUpewogICAgZndyaXRlX3VubG9ja2VkKE1ZX1dSSVRFUl9WQVIuYnVmLCAxLCBNWV9XUklURVJfVkFSLnMsIHN0ZG91dCk7CiAgICBNWV9XUklURVJfVkFSLnMgPSAwOwogIH0KICBNWV9XUklURVJfVkFSLmJ1ZltNWV9XUklURVJfVkFSLnMrK10gPSBhOwp9CmlubGluZSB2b2lkIHd0X0woY2hhciBhKXsKICBteV9wdXRjaGFyX3VubG9ja2VkKGEpOwp9CmlubGluZSB2b2lkIHd0X0woaW50IHgpewogIGludCBzPTA7CiAgaW50IG09MDsKICBjaGFyIGZbMTBdOwogIGlmKHg8MCl7CiAgICBtPTE7CiAgICB4PS14OwogIH0KICB3aGlsZSh4KXsKICAgIGZbcysrXT14JTEwOwogICAgeC89MTA7CiAgfQogIGlmKCFzKXsKICAgIGZbcysrXT0wOwogIH0KICBpZihtKXsKICAgIG15X3B1dGNoYXJfdW5sb2NrZWQoJy0nKTsKICB9CiAgd2hpbGUocy0tKXsKICAgIG15X3B1dGNoYXJfdW5sb2NrZWQoZltzXSsnMCcpOwogIH0KfQppbmxpbmUgdm9pZCB3dF9MKGxvbmcgbG9uZyB4KXsKICBpbnQgcz0wOwogIGludCBtPTA7CiAgY2hhciBmWzIwXTsKICBpZih4PDApewogICAgbT0xOwogICAgeD0teDsKICB9CiAgd2hpbGUoeCl7CiAgICBmW3MrK109eCUxMDsKICAgIHgvPTEwOwogIH0KICBpZighcyl7CiAgICBmW3MrK109MDsKICB9CiAgaWYobSl7CiAgICBteV9wdXRjaGFyX3VubG9ja2VkKCctJyk7CiAgfQogIHdoaWxlKHMtLSl7CiAgICBteV9wdXRjaGFyX3VubG9ja2VkKGZbc10rJzAnKTsKICB9Cn0KaW5saW5lIHZvaWQgd3RfTChjb25zdCBjaGFyIGNbXSl7CiAgaW50IGk9MDsKICBmb3IoaT0wO2NbaV0hPSdcMCc7aSsrKXsKICAgIG15X3B1dGNoYXJfdW5sb2NrZWQoY1tpXSk7CiAgfQp9CnRlbXBsYXRlPGNsYXNzIFMsIGNsYXNzIFQ+IGlubGluZSBTIGNobWluKFMgJmEsIFQgYil7CiAgaWYoYT5iKXsKICAgIGE9YjsKICB9CiAgcmV0dXJuIGE7Cn0KdGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBMSGVhcHsKICBpbnQqaHA7CiAgaW50KnBsYWNlOwogIGludCBzaXplOwogIFQqdmFsOwogIHZvaWQgbWFsbG9jKGludCBOKXsKICAgIGhwID0gKGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICBwbGFjZT0oaW50KilzdGQ6Om1hbGxvYyhOKnNpemVvZihpbnQpKTsKICAgIHZhbD0oVCopc3RkOjptYWxsb2MoTipzaXplb2YoVCkpOwogIH0KICB2b2lkIG1hbGxvYyhpbnQgTiwgaW50IGluaSl7CiAgICBocCA9IChpbnQqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKGludCkpOwogICAgcGxhY2U9KGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICB2YWw9KFQqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKFQpKTsKICAgIGlmKGluaSl7CiAgICAgIGluaXQoTik7CiAgICB9CiAgfQogIHZvaWQgd2FsbG9jKGludCBOLCB2b2lkICoqbWVtPSZ3bWVtKXsKICAgIHdhbGxvYzFkKCZocCwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZwbGFjZSwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZ2YWwsIE4sIG1lbSk7CiAgfQogIHZvaWQgd2FsbG9jKGludCBOLCBpbnQgaW5pLCB2b2lkICoqbWVtPSZ3bWVtKXsKICAgIHdhbGxvYzFkKCZocCwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZwbGFjZSwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZ2YWwsIE4sIG1lbSk7CiAgICBpZihpbmkpewogICAgICBpbml0KE4pOwogICAgfQogIH0KICB2b2lkIGZyZWUoKXsKICAgIHN0ZDo6ZnJlZShocCk7CiAgICBzdGQ6OmZyZWUocGxhY2UpOwogICAgc3RkOjpmcmVlKHZhbCk7CiAgfQogIHZvaWQgaW5pdChpbnQgTil7CiAgICBpbnQgaTsKICAgIHNpemU9MDsKICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICBwbGFjZVtpXT0tMTsKICAgIH0KICB9CiAgdm9pZCB1cChpbnQgbil7CiAgICBpbnQgbTsKICAgIHdoaWxlKG4pewogICAgICBtPShuLTEpLzI7CiAgICAgIGlmKHZhbFtocFttXV08PXZhbFtocFtuXV0pewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHN3YXAoaHBbbV0saHBbbl0pOwogICAgICBzd2FwKHBsYWNlW2hwW21dXSxwbGFjZVtocFtuXV0pOwogICAgICBuPW07CiAgICB9CiAgfQogIHZvaWQgZG93bihpbnQgbil7CiAgICBpbnQgbTsKICAgIGZvcig7Oyl7CiAgICAgIG09MipuKzE7CiAgICAgIGlmKG0+PXNpemUpewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGlmKG0rMTxzaXplJiZ2YWxbaHBbbV1dPnZhbFtocFttKzFdXSl7CiAgICAgICAgbSsrOwogICAgICB9CiAgICAgIGlmKHZhbFtocFttXV0+PXZhbFtocFtuXV0pewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHN3YXAoaHBbbV0saHBbbl0pOwogICAgICBzd2FwKHBsYWNlW2hwW21dXSxwbGFjZVtocFtuXV0pOwogICAgICBuPW07CiAgICB9CiAgfQogIHZvaWQgY2hhbmdlKGludCBuLCBUIHYpewogICAgVCBmID0gdmFsW25dOwogICAgdmFsW25dID0gdjsKICAgIGlmKHBsYWNlW25dPT0tMSl7CiAgICAgIHBsYWNlW25dID0gc2l6ZTsKICAgICAgaHBbc2l6ZSsrXSA9IG47CiAgICAgIHVwKHBsYWNlW25dKTsKICAgIH0KICAgIGVsc2V7CiAgICAgIGlmKGYgPCB2KXsKICAgICAgICBkb3duKHBsYWNlW25dKTsKICAgICAgfQogICAgICBlbHNlIGlmKGYgPiB2KXsKICAgICAgICB1cChwbGFjZVtuXSk7CiAgICAgIH0KICAgIH0KICB9CiAgaW50IHBvcCh2b2lkKXsKICAgIGludCByZXMgPSBocFswXTsKICAgIHBsYWNlW3Jlc10gPSAtMTsKICAgIHNpemUtLTsKICAgIGlmKHNpemUpewogICAgICBocFswXT1ocFtzaXplXTsKICAgICAgcGxhY2VbaHBbMF1dPTA7CiAgICAgIGRvd24oMCk7CiAgICB9CiAgICByZXR1cm4gcmVzOwogIH0KfQo7CnRlbXBsYXRlPGNsYXNzIEZULCBjbGFzcyBDVD4gc3RydWN0IG1pbkNvc3RGbG93ewogIGludCBub2RlOwogIGludCplczsKICBpbnQqZW1lbTsKICBpbnQqKmVkZ2U7CiAgaW50KipyZXY7CiAgRlQqKmZsb3c7CiAgRlQgZl9lcHM7CiAgQ1QqKmNvc3Q7CiAgQ1QqcG90ZW50aWFsOwogIENUIGNfZXBzOwogIExIZWFwPENUPiBocDsKICBjaGFyKnJlYWNoZWQ7CiAgRlQqY3VyX2Zsb3c7CiAgQ1QqY3VyX2Nvc3Q7CiAgaW50KmJhY2tfZWRnZTsKICB2b2lkIG1hbGxvYyhpbnQgTil7CiAgICBpbnQgaTsKICAgIGVzID0gKGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICBlbWVtID0gKGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICBlZGdlID0gKGludCoqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKGludCopKTsKICAgIHJldiA9IChpbnQqKilzdGQ6Om1hbGxvYyhOKnNpemVvZihpbnQqKSk7CiAgICBmbG93ID0gKEZUKiopc3RkOjptYWxsb2MoTipzaXplb2YoRlQqKSk7CiAgICBjb3N0ID0gKENUKiopc3RkOjptYWxsb2MoTipzaXplb2YoQ1QqKSk7CiAgICBmb3IoaT0oMCk7aTwoTik7aSsrKXsKICAgICAgZW1lbVtpXSA9IDA7CiAgICAgIGVkZ2VbaV0gPSByZXZbaV0gPSBOVUxMOwogICAgICBmbG93W2ldID0gTlVMTDsKICAgICAgY29zdFtpXSA9IE5VTEw7CiAgICB9CiAgICBocC5tYWxsb2MoTik7CiAgICByZWFjaGVkID0gKGNoYXIqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKGNoYXIpKTsKICAgIGN1cl9mbG93ID0gKEZUKilzdGQ6Om1hbGxvYyhOKnNpemVvZihGVCkpOwogICAgY3VyX2Nvc3QgPSAoQ1QqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKENUKSk7CiAgICBwb3RlbnRpYWwgPSAoQ1QqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKENUKSk7CiAgICBiYWNrX2VkZ2UgPSAoaW50KilzdGQ6Om1hbGxvYyhOKnNpemVvZihpbnQpKTsKICAgIG5vZGUgPSBOOwogICAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICAgIGVzW2ldID0gMDsKICAgIH0KICAgIGZfZXBzID0gKEZUKTFlLTk7CiAgICBjX2VwcyA9IChDVCkxZS05OwogIH0KICB2b2lkIGluaXQoaW50IE4pewogICAgaW50IGk7CiAgICBub2RlID0gTjsKICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICBlc1tpXSA9IDA7CiAgICB9CiAgICBmX2VwcyA9IChGVCkxZS05OwogICAgY19lcHMgPSAoQ1QpMWUtOTsKICB9CiAgdm9pZCBtZW1vcnlFeHBhbmQoaW50IGksIGludCBzeil7CiAgICBpZihzeiA8PSBlbWVtW2ldKXsKICAgICAgcmV0dXJuOwogICAgfQogICAgc3ogPW1heF9MKG1heF9MKHN6LCAzKSwgMiplbWVtW2ldKTsKICAgIGVtZW1baV0gPSBzejsKICAgIGVkZ2VbaV0gPSAoaW50KilyZWFsbG9jKGVkZ2VbaV0sIHN6KnNpemVvZihpbnQpKTsKICAgIHJldltpXSA9IChpbnQqKXJlYWxsb2MocmV2W2ldLCBzeipzaXplb2YoaW50KSk7CiAgICBmbG93W2ldID0gKEZUKilyZWFsbG9jKGZsb3dbaV0sIHN6KnNpemVvZihGVCkpOwogICAgY29zdFtpXSA9IChDVCopcmVhbGxvYyhjb3N0W2ldLCBzeipzaXplb2YoQ1QpKTsKICB9CiAgdm9pZCBhZGRFZGdlKGludCBuMSwgaW50IG4yLCBGVCBmLCBDVCBjKXsKICAgIGludCBzMSA9IGVzW24xXSsrOwogICAgaW50IHMyID0gZXNbbjJdKys7CiAgICBpZihzMSA+PSBlbWVtW24xXSl7CiAgICAgIG1lbW9yeUV4cGFuZChuMSwgZXNbbjFdKTsKICAgIH0KICAgIGlmKHMyID49IGVtZW1bbjJdKXsKICAgICAgbWVtb3J5RXhwYW5kKG4yLCBlc1tuMl0pOwogICAgfQogICAgZWRnZVtuMV1bczFdID0gbjI7CiAgICBlZGdlW24yXVtzMl0gPSBuMTsKICAgIHJldltuMV1bczFdICA9IHMyOwogICAgcmV2W24yXVtzMl0gID0gczE7CiAgICBmbG93W24xXVtzMV0gPSBmOwogICAgZmxvd1tuMl1bczJdID0gMDsKICAgIGNvc3RbbjFdW3MxXSA9IGM7CiAgICBjb3N0W24yXVtzMl0gPSAtYzsKICB9CiAgdGVtcGxhdGU8Y2xhc3MgRlRTLCBjbGFzcyBDVFM+IHZvaWQgc29sdmUoaW50IHN0LCBpbnQgZWQsIEZUUyAmZnJlcywgQ1RTICZjcmVzLCBGVCBmbGltID0gLTEsIENUIGNsaW0gPSAwKXsKICAgIGludCBpOwogICAgaW50IGo7CiAgICBpbnQgazsKICAgIGludCBsOwogICAgRlQgZjsKICAgIENUIG5jOwogICAgZnJlcyA9IDA7CiAgICBjcmVzID0gMDsKICAgIGZvcihpPSgwKTtpPChub2RlKTtpKyspewogICAgICBwb3RlbnRpYWxbaV0gPSAwOwogICAgfQogICAgZm9yKDs7KXsKICAgICAgaWYoZmxpbSA+PSAtZl9lcHMgJiYgZmxpbSA8PSBmX2Vwcyl7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgaHAuaW5pdChub2RlKTsKICAgICAgZm9yKGk9KDApO2k8KG5vZGUpO2krKyl7CiAgICAgICAgcmVhY2hlZFtpXSA9IDA7CiAgICAgIH0KICAgICAgcmVhY2hlZFtzdF0gPSAxOwogICAgICBjdXJfY29zdFtzdF0gPSAwOwogICAgICBsID0gMDsKICAgICAgaHAuY2hhbmdlKHN0LCBjdXJfY29zdFtzdF0pOwogICAgICB3aGlsZShocC5zaXplKXsKICAgICAgICBpID0gaHAucG9wKCk7CiAgICAgICAgZm9yKGo9KDApO2o8KGVzW2ldKTtqKyspewogICAgICAgICAgaWYoZmxvd1tpXVtqXSA8PSBmX2Vwcyl7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgayA9IGVkZ2VbaV1bal07CiAgICAgICAgICBuYyA9IGN1cl9jb3N0W2ldICsgY29zdFtpXVtqXSArIHBvdGVudGlhbFtpXSAtIHBvdGVudGlhbFtrXTsKICAgICAgICAgIGlmKHJlYWNoZWRba109PTAgfHwgY3VyX2Nvc3Rba10gPiBuYytjX2Vwcyl7CiAgICAgICAgICAgIHJlYWNoZWRba10gPSAxOwogICAgICAgICAgICBjdXJfY29zdFtrXSA9IG5jOwogICAgICAgICAgICBjdXJfZmxvd1trXSA9IGZsb3dbaV1bal07CiAgICAgICAgICAgIGlmKGkgIT0gc3QpewogICAgICAgICAgICAgIGNobWluKGN1cl9mbG93W2tdLCBjdXJfZmxvd1tpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYmFja19lZGdlW2tdID0gcmV2W2ldW2pdOwogICAgICAgICAgICBocC5jaGFuZ2UoaywgY3VyX2Nvc3Rba10pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZihyZWFjaGVkW2VkXT09MCl7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgaWYoZmxpbT09LTIgJiYgY3VyX2Nvc3RbZWRdICsgcG90ZW50aWFsW2VkXSA+PSBjbGltKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBmID0gY3VyX2Zsb3dbZWRdOwogICAgICBpZihmbGltID49IC1mX2Vwcyl7CiAgICAgICAgY2htaW4oZiwgZmxpbSk7CiAgICAgICAgZmxpbSAtPSBmOwogICAgICB9CiAgICAgIGlmKGYgPD0gZl9lcHMpewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGZvcihpPSgwKTtpPChub2RlKTtpKyspewogICAgICAgIGlmKHJlYWNoZWRbaV0pewogICAgICAgICAgcG90ZW50aWFsW2ldICs9IGN1cl9jb3N0W2ldOwogICAgICAgIH0KICAgICAgfQogICAgICBmcmVzICs9IGY7CiAgICAgIGNyZXMgKz0gZiAqIHBvdGVudGlhbFtlZF07CiAgICAgIGkgPSBlZDsKICAgICAgd2hpbGUoaSAhPSBzdCl7CiAgICAgICAgaiA9IGJhY2tfZWRnZVtpXTsKICAgICAgICBrID0gZWRnZVtpXVtqXTsKICAgICAgICBmbG93W2ldW2pdICs9IGY7CiAgICAgICAgZmxvd1trXVtyZXZbaV1bal1dIC09IGY7CiAgICAgICAgaSA9IGs7CiAgICAgIH0KICAgIH0KICB9Cn0KOwpzdHJ1Y3QgZGltY29tcDJ7CiAgaW50IEI7CiAgZGltY29tcDIoKXsKICB9CiAgZGltY29tcDIoaW50IGIpewogICAgQiA9IGI7CiAgfQogIGRpbWNvbXAyKGludCBhLCBpbnQgYil7CiAgICBCID0gYjsKICB9CiAgaW5saW5lIHZvaWQgc2V0KGludCBiKXsKICAgIEIgPSBiOwogIH0KICBpbmxpbmUgdm9pZCBzZXQoaW50IGEsIGludCBiKXsKICAgIEIgPSBiOwogIH0KICBpbmxpbmUgaW50IG1hc2soaW50IGEsIGludCBiKXsKICAgIHJldHVybiBhICogQiArIGI7CiAgfQogIGlubGluZSBpbnQgb3BlcmF0b3IoKShpbnQgYSwgaW50IGIpewogICAgcmV0dXJuIGEgKiBCICsgYjsKICB9CiAgaW5saW5lIHZvaWQgcGFyYShpbnQgbWFzaywgaW50ICZhLCBpbnQgJmIpewogICAgYSA9IG1hc2sgLyBCOwogICAgYiA9IG1hc2sgJSBCOwogIH0KICBpbmxpbmUgdm9pZCBvcGVyYXRvcigpKGludCBtYXNrLCBpbnQgJmEsIGludCAmYil7CiAgICBhID0gbWFzayAvIEI7CiAgICBiID0gbWFzayAlIEI7CiAgfQp9CjsKaW50IFRFU1Q7CmludCBYOwppbnQgWTsKbG9uZyBsb25nIEY7CmxvbmcgbG9uZyBTOwpjaGFyIEFbMTBdWzEyXTsKY2hhciBCWzEwXVsxMl07CmludCBtYWluKCl7CiAgd21lbSA9IG1lbWFycjsKICBpbnQgbm9kZTsKICBpbnQgc3Q7CiAgaW50IGVkOwogIGRpbWNvbXAyIGRtOwogIG1pbkNvc3RGbG93PGxvbmcgbG9uZyxsb25nIGxvbmc+IGZsb3c7CiAgZmxvdy5tYWxsb2MoMTAwMDAwKTsKICBpbnQgTGo0UGRIUlcgPSByZF9pbnQoKTsKICBmb3IoVEVTVD0oMCk7VEVTVDwoTGo0UGRIUlcpO1RFU1QrKyl7CiAgICBpbnQgaSwgaTE7CiAgICBsb25nIGxvbmcgcmVzID0gMDsKICAgIGxvbmcgbG9uZyBmOwogICAgbG9uZyBsb25nIGM7CiAgICB3dF9MKCJDYXNlICMiKTsKICAgIHd0X0woVEVTVCsxKTsKICAgIHd0X0woIjogIik7CiAgICByZChYKTsKICAgIHJkKFkpOwogICAgcmQoRik7CiAgICByZChTKTsKICAgIHsKICAgICAgaW50IGU5OFdIQ0VZOwogICAgICBmb3IoZTk4V0hDRVk9KDApO2U5OFdIQ0VZPChYKTtlOThXSENFWSsrKXsKICAgICAgICByZChBW2U5OFdIQ0VZXSk7CiAgICAgIH0KICAgIH0KICAgIHsKICAgICAgaW50IEZtY0twRm1OOwogICAgICBmb3IoRm1jS3BGbU49KDApO0ZtY0twRm1OPChYKTtGbWNLcEZtTisrKXsKICAgICAgICByZChCW0ZtY0twRm1OXSk7CiAgICAgIH0KICAgIH0KICAgIG5vZGUgPSBYKlk7CiAgICBzdCA9IG5vZGUrKzsKICAgIGVkID0gbm9kZSsrOwogICAgZG0uc2V0KFgsWSk7CiAgICBmbG93LmluaXQobm9kZSk7CiAgICBmb3IoaT0oMCk7aTwoWCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihqPSgwKTtqPChZKTtqKyspewogICAgICAgIGlmKEFbaV1bal09PSdNJyAmJiBCW2ldW2pdPT0nRycpewogICAgICAgICAgZmxvdy5hZGRFZGdlKHN0LCBkbShpLGopLCAxLCAwKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvcihpPSgwKTtpPChYKTtpKyspewogICAgICBpbnQgajsKICAgICAgZm9yKGo9KDApO2o8KFkpO2orKyl7CiAgICAgICAgaWYoQVtpXVtqXT09J0cnICYmIEJbaV1bal09PSdNJyl7CiAgICAgICAgICBmbG93LmFkZEVkZ2UoZG0oaSxqKSwgZWQsIDEsIDApOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yKGkxPSgwKTtpMTwoWCk7aTErKyl7CiAgICAgIGludCBqMTsKICAgICAgZm9yKGoxPSgwKTtqMTwoWSk7ajErKyl7CiAgICAgICAgaWYoQVtpMV1bajFdPT0nTScgJiYgQltpMV1bajFdPT0nRycpewogICAgICAgICAgaW50IGkyOwogICAgICAgICAgZm9yKGkyPSgwKTtpMjwoWCk7aTIrKyl7CiAgICAgICAgICAgIGludCBqMjsKICAgICAgICAgICAgZm9yKGoyPSgwKTtqMjwoWSk7ajIrKyl7CiAgICAgICAgICAgICAgaWYoQVtpMl1bajJdPT0nRycgJiYgQltpMl1bajJdPT0nTScpewogICAgICAgICAgICAgICAgZmxvdy5hZGRFZGdlKGRtKGkxLGoxKSwgZG0oaTIsajIpLCAxLCAoYWJzKGkxLWkyKSArIGFicyhqMS1qMikpICogUyAtIDIqRik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoWCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihqPSgwKTtqPChZKTtqKyspewogICAgICAgIGlmKEFbaV1bal0gIT0gQltpXVtqXSl7CiAgICAgICAgICByZXMgKz0gRjsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZsb3cuc29sdmUoc3QsIGVkLCBmLCBjLCAtMiwgMCk7CiAgICB3dF9MKHJlcyArIGMpOwogICAgd3RfTCgnXG4nKTsKICB9CiAgcmV0dXJuIDA7Cn0KLy8gY0xheSB2ZXJzaW9uIDIwMjEwNDA1LTEKCi8vIC0tLSBvcmlnaW5hbCBjb2RlIC0tLQovLyBpbnQgVEVTVDsKLy8gaW50IFgsIFk7IGxsIEYsIFM7Ci8vIGNoYXIgQVsxMF1bMTJdLCBCWzEwXVsxMl07Ci8vIHsKLy8gICBpbnQgbm9kZSwgc3QsIGVkOwovLyAgIGRpbWNvbXAyIGRtOwovLyAgIG1pbkNvc3RGbG93PGxsLGxsPiBmbG93OwovLyAgIGZsb3cubWFsbG9jKDFkNSk7Ci8vICAgUkVQKFRFU1QscmRfaW50KCkpewovLyAgICAgbGwgcmVzID0gMCwgZiwgYzsKLy8gICAgIHd0RigiQ2FzZSAje1RFU1QrMX06ICIpOwovLyAgICAgcmQoWCxZLEYsUyxBKFgpLEIoWCkpOwovLyAgICAgbm9kZSA9IFgqWTsKLy8gICAgIHN0ID0gbm9kZSsrOwovLyAgICAgZWQgPSBub2RlKys7Ci8vICAgICBkbS5zZXQoWCxZKTsKLy8gICAgIGZsb3cuaW5pdChub2RlKTsKLy8gCi8vICAgICByZXAoaSxYKSByZXAoaixZKSBpZihBW2ldW2pdPT0nTScgJiYgQltpXVtqXT09J0cnKSBmbG93LmFkZEVkZ2Uoc3QsIGRtKGksaiksIDEsIDApOwovLyAgICAgcmVwKGksWCkgcmVwKGosWSkgaWYoQVtpXVtqXT09J0cnICYmIEJbaV1bal09PSdNJykgZmxvdy5hZGRFZGdlKGRtKGksaiksIGVkLCAxLCAwKTsKLy8gICAgIHJlcChpMSxYKSByZXAoajEsWSkgaWYoQVtpMV1bajFdPT0nTScgJiYgQltpMV1bajFdPT0nRycpewovLyAgICAgICByZXAoaTIsWCkgcmVwKGoyLFkpIGlmKEFbaTJdW2oyXT09J0cnICYmIEJbaTJdW2oyXT09J00nKXsKLy8gICAgICAgICBmbG93LmFkZEVkZ2UoZG0oaTEsajEpLCBkbShpMixqMiksIDEsIChhYnMoaTEtaTIpICsgYWJzKGoxLWoyKSkgKiBTIC0gMipGKTsKLy8gICAgICAgfQovLyAgICAgfQovLyAKLy8gICAgIHJlcChpLFgpIHJlcChqLFkpIGlmKEFbaV1bal0gIT0gQltpXVtqXSkgcmVzICs9IEY7Ci8vICAgICBmbG93LnNvbHZlKHN0LCBlZCwgZiwgYywgLTIsIDApOwovLyAgICAgd3QocmVzICsgYyk7Ci8vICAgfQovLyB9Cg==