#include<bits/stdc++.h>
using namespace std;
#define MD 1000000007
void *wmem;
template<class T> void malloc1d(T **arr, int x, void **mem = &wmem){
(*arr)=(T*)(*mem);
(*mem)=((*arr)+x);
}
struct mint{
static unsigned R, RR, Rinv, W, md, mdninv;
unsigned val;
mint(){
}
mint(int a){
val = mulR(a);
}
mint(unsigned a){
val = mulR(a);
}
mint(long long a){
val = mulR(a);
}
mint(unsigned long long a){
val = mulR(a);
}
int get_inv(long long a, int md){
long long e, s=md, t=a, u=1, v=0;
while(s){
e=t/s;
t-=e*s;
u-=e*v;
swap(t,s);
swap(u,v);
}
if(u<0){
u+=md;
}
return u;
}
void setmod(unsigned m){
int i;
unsigned t;
W = 32;
md = m;
R = (1ULL << W) % md;
RR = (unsigned long long)R*R % md;
switch(m){
case 104857601:
Rinv = 2560000;
mdninv = 104857599;
break;
case 998244353:
Rinv = 232013824;
mdninv = 998244351;
break;
case 1000000007:
Rinv = 518424770;
mdninv = 2226617417U;
break;
case 1000000009:
Rinv = 171601999;
mdninv = 737024967;
break;
case 1004535809:
Rinv = 234947584;
mdninv = 1004535807;
break;
case 1007681537:
Rinv = 236421376;
mdninv = 1007681535;
break;
case 1012924417:
Rinv = 238887936;
mdninv = 1012924415;
break;
case 1045430273:
Rinv = 254466304;
mdninv = 1045430271;
break;
case 1051721729:
Rinv = 257538304;
mdninv = 1051721727;
break;
default:
Rinv = get_inv(R, md);
mdninv = 0;
t = 0;
for(i=0;i<(int)W;i++){
if(t%2==0){
t+=md;
mdninv |= (1U<<i);
}
t /= 2;
}
}
}
unsigned mulR(unsigned a){
return (unsigned long long)a*R%md;
}
unsigned mulR(int a){
if(a < 0){
a = a%md+md;
}
return mulR((unsigned)a);
}
unsigned mulR(unsigned long long a){
return mulR((unsigned)(a%md));
}
unsigned mulR(long long a){
a %= md;
if(a < 0){
a += md;
}
return mulR((unsigned)a);
}
unsigned reduce(unsigned T){
unsigned m=T * mdninv, t=(unsigned)((T + (unsigned long long)m*md) >> W);
if(t >= md){
t -= md;
}
return t;
}
unsigned reduce(unsigned long long T){
unsigned m=(unsigned)T * mdninv, t=(unsigned)((T + (unsigned long long)m*md) >> W);
if(t >= md){
t -= md;
}
return t;
}
unsigned get(){
return reduce(val);
}
mint &operator+=(mint a){
val += a.val;
if(val >= md){
val -= md;
}
return *this;
}
mint &operator-=(mint a){
if(val < a.val){
val = val + md - a.val;
}
else{
val -= a.val;
}
return *this;
}
mint &operator*=(mint a){
val = reduce((unsigned long long)val*a.val);
return *this;
}
mint &operator/=(mint a){
return *this *= a.inverse();
}
mint operator+(mint a){
return mint(*this)+=a;
}
mint operator-(mint a){
return mint(*this)-=a;
}
mint operator*(mint a){
return mint(*this)*=a;
}
mint operator/(mint a){
return mint(*this)/=a;
}
mint operator+(int a){
return mint(*this)+=mint(a);
}
mint operator-(int a){
return mint(*this)-=mint(a);
}
mint operator*(int a){
return mint(*this)*=mint(a);
}
mint operator/(int a){
return mint(*this)/=mint(a);
}
mint operator+(long long a){
return mint(*this)+=mint(a);
}
mint operator-(long long a){
return mint(*this)-=mint(a);
}
mint operator*(long long a){
return mint(*this)*=mint(a);
}
mint operator/(long long a){
return mint(*this)/=mint(a);
}
mint operator-(void){
mint res;
if(val){
res.val=md-val;
}
else{
res.val=0;
}
return res;
}
operator bool(void){
return val!=0;
}
operator int(void){
return get();
}
operator long long(void){
return get();
}
mint inverse(){
int a = val, b = md, u = 1, v = 0, t;
mint res;
while(b){
t = a / b;
a -= t * b; swap(a, b);
u -= t * v; swap(u, v);
}
if(u < 0) u += md;
res.val = (unsigned long long)u*RR % md;
return res;
}
mint pw(unsigned long long b){
mint a(*this), res;
res.val = R;
while(b){
if(b&1) res *= a;
b >>= 1;
a *= a;
}
return res;
}
bool operator==(int a){return mulR(a)==val;}
bool operator!=(int a){return mulR(a)!=val;}
};
unsigned mint::md, mint::W, mint::R, mint::Rinv, mint::mdninv, mint::RR;
mint operator+(int a, mint b){return mint(a)+=b;
}
mint operator-(int a, mint b){
return mint(a)-=b;
}
mint operator*(int a, mint b){
return mint(a)*=b;
}
mint operator/(int a, mint b){
return mint(a)/=b;
}
mint operator+(long long a, mint b){
return mint(a)+=b;
}
mint operator-(long long a, mint b){
return mint(a)-=b;
}
mint operator*(long long a, mint b){
return mint(a)*=b;
}
mint operator/(long long a, mint b){
return mint(a)/=b;
}
void rd(int &x){
int k, m=0;
x=0;
for(;;){
k = getchar_unlocked();
if(k=='-'){
m=1;
break;
}
if('0'<=k&&k<='9'){
x=k-'0';
break;
}
}
for(;;){
k = getchar_unlocked();
if(k<'0'||k>'9'){
break;
}
x=x*10+k-'0';
}
if(m){
x=-x;
}
}
int rd(char c[]){
int i, sz=0;
for(;;){
i = getchar_unlocked();
if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF){
break;
}
}
c[sz++] = i;
for(;;){
i = getchar_unlocked();
if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF){
break;
}
c[sz++] = i;
}
c[sz]='\0';
return sz;
}
void wt_L(int x){
char f[10];
int m=0, s=0;
if(x<0){
m=1;
x=-x;
}
while(x){
f[s++]=x%10;
x/=10;
}
if(!s){
f[s++]=0;
}
if(m){
putchar_unlocked('-');
}
while(s--){
putchar_unlocked(f[s]+'0');
}
}
void wt_L(mint x){
int i;
i = (int)x;
wt_L(i);
}
struct combination_mint{
mint *fac, *ifac;
void init(int n, void **mem = &wmem){
int i;
malloc1d(&fac, n, mem);
malloc1d(&ifac, n, mem);
fac[0] = 1;
for(i=1;i<n;i++){
fac[i] = fac[i-1] * i;
}
ifac[n-1] = 1 / fac[n-1];
for(i=n-2;i>=0;i--){
ifac[i] = ifac[i+1] * (i+1);
}
}
mint C(int a, int b){
if(b < 0 || b > a){
return 0;
}
return fac[a]*ifac[b]*ifac[a-b];
}
mint P(int a, int b){
if(b < 0 || b > a){
return 0;
}
return fac[a]*ifac[a-b];
}
mint H(int a, int b){
if(a==0 && b==0){
return 1;
}
if(a<=0 || b<0){
return 0;
}
return C(a+b-1, b);
}
}
;
char S[500010], memarr[64000000];
int N, Q;
int main(){
combination_mint comb;
int hist[4];
mint ab, cd, res;
wmem = memarr;
{
mint x;
x.setmod(MD);
}
comb.init(500010);
rd(Q);
while(Q--){
N = rd(S);
{
int Lj4PdHRW;
for(Lj4PdHRW=0;Lj4PdHRW<(3) + 1;Lj4PdHRW++){
hist[Lj4PdHRW] = 0;
}
}
{
int KL2GvlyY;
for(KL2GvlyY=0;KL2GvlyY<(N-1) + 1;KL2GvlyY++){
hist[S[KL2GvlyY]-'a']++;
}
}
ab = cd = 0;
{
int Q5VJL1cS;
for(Q5VJL1cS=0;Q5VJL1cS<(N) + 1;Q5VJL1cS++){
ab += comb.C(hist[0],(Q5VJL1cS)) * comb.C(hist[1],(Q5VJL1cS));
}
}
{
int e98WHCEY;
for(e98WHCEY=0;e98WHCEY<(N) + 1;e98WHCEY++){
cd += comb.C(hist[2],(e98WHCEY)) * comb.C(hist[3],(e98WHCEY));
}
}
res = ab * cd - 1;
wt_L(res);
putchar_unlocked('\n');
}
return 0;
}
// cLay varsion 20170505-2
// --- original code ---
// int Q, N;
// char S[500010];
// {
// int hist[4];
// combination_mint comb;
// mint res, ab, cd;
//
// comb.init(500010);
//
// rd(Q);
// while(Q--){
// rd(S@N);
//
// hist[0..3] = 0;
// hist[S[0..N-1]-'a']++;
//
// ab = cd = 0;
// ab += comb.C(hist[0],(0..N)) * comb.C(hist[1],(0..));
// cd += comb.C(hist[2],(0..N)) * comb.C(hist[3],(0..));
//
// res = ab * cd - 1;
// wt(res);
// }
// }
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKI2RlZmluZSBNRCAxMDAwMDAwMDA3CnZvaWQgKndtZW07CnRlbXBsYXRlPGNsYXNzIFQ+IHZvaWQgbWFsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgKCphcnIpPShUKikoKm1lbSk7CiAgKCptZW0pPSgoKmFycikreCk7Cn0Kc3RydWN0IG1pbnR7CiAgc3RhdGljIHVuc2lnbmVkIFIsIFJSLCBSaW52LCBXLCBtZCwgbWRuaW52OwogIHVuc2lnbmVkIHZhbDsKICBtaW50KCl7CiAgfQogIG1pbnQoaW50IGEpewogICAgdmFsID0gbXVsUihhKTsKICB9CiAgbWludCh1bnNpZ25lZCBhKXsKICAgIHZhbCA9IG11bFIoYSk7CiAgfQogIG1pbnQobG9uZyBsb25nIGEpewogICAgdmFsID0gbXVsUihhKTsKICB9CiAgbWludCh1bnNpZ25lZCBsb25nIGxvbmcgYSl7CiAgICB2YWwgPSBtdWxSKGEpOwogIH0KICBpbnQgZ2V0X2ludihsb25nIGxvbmcgYSwgaW50IG1kKXsKICAgIGxvbmcgbG9uZyBlLCBzPW1kLCB0PWEsIHU9MSwgdj0wOwogICAgd2hpbGUocyl7CiAgICAgIGU9dC9zOwogICAgICB0LT1lKnM7CiAgICAgIHUtPWUqdjsKICAgICAgc3dhcCh0LHMpOwogICAgICBzd2FwKHUsdik7CiAgICB9CiAgICBpZih1PDApewogICAgICB1Kz1tZDsKICAgIH0KICAgIHJldHVybiB1OwogIH0KICB2b2lkIHNldG1vZCh1bnNpZ25lZCBtKXsKICAgIGludCBpOwogICAgdW5zaWduZWQgdDsKICAgIFcgPSAzMjsKICAgIG1kID0gbTsKICAgIFIgPSAoMVVMTCA8PCBXKSAlIG1kOwogICAgUlIgPSAodW5zaWduZWQgbG9uZyBsb25nKVIqUiAlIG1kOwogICAgc3dpdGNoKG0pewogICAgICBjYXNlIDEwNDg1NzYwMToKICAgICAgUmludiA9IDI1NjAwMDA7CiAgICAgIG1kbmludiA9IDEwNDg1NzU5OTsKICAgICAgYnJlYWs7CiAgICAgIGNhc2UgOTk4MjQ0MzUzOgogICAgICBSaW52ID0gMjMyMDEzODI0OwogICAgICBtZG5pbnYgPSA5OTgyNDQzNTE7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDAwMDAwMDc6CiAgICAgIFJpbnYgPSA1MTg0MjQ3NzA7CiAgICAgIG1kbmludiA9IDIyMjY2MTc0MTdVOwogICAgICBicmVhazsKICAgICAgY2FzZSAxMDAwMDAwMDA5OgogICAgICBSaW52ID0gMTcxNjAxOTk5OwogICAgICBtZG5pbnYgPSA3MzcwMjQ5Njc7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDQ1MzU4MDk6CiAgICAgIFJpbnYgPSAyMzQ5NDc1ODQ7CiAgICAgIG1kbmludiA9IDEwMDQ1MzU4MDc7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMDc2ODE1Mzc6CiAgICAgIFJpbnYgPSAyMzY0MjEzNzY7CiAgICAgIG1kbmludiA9IDEwMDc2ODE1MzU7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwMTI5MjQ0MTc6CiAgICAgIFJpbnYgPSAyMzg4ODc5MzY7CiAgICAgIG1kbmludiA9IDEwMTI5MjQ0MTU7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwNDU0MzAyNzM6CiAgICAgIFJpbnYgPSAyNTQ0NjYzMDQ7CiAgICAgIG1kbmludiA9IDEwNDU0MzAyNzE7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIDEwNTE3MjE3Mjk6CiAgICAgIFJpbnYgPSAyNTc1MzgzMDQ7CiAgICAgIG1kbmludiA9IDEwNTE3MjE3Mjc7CiAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICBSaW52ID0gZ2V0X2ludihSLCBtZCk7CiAgICAgIG1kbmludiA9IDA7CiAgICAgIHQgPSAwOwogICAgICBmb3IoaT0wO2k8KGludClXO2krKyl7CiAgICAgICAgaWYodCUyPT0wKXsKICAgICAgICAgIHQrPW1kOwogICAgICAgICAgbWRuaW52IHw9ICgxVTw8aSk7CiAgICAgICAgfQogICAgICAgIHQgLz0gMjsKICAgICAgfQogICAgfQogIH0KICB1bnNpZ25lZCBtdWxSKHVuc2lnbmVkIGEpewogICAgcmV0dXJuICh1bnNpZ25lZCBsb25nIGxvbmcpYSpSJW1kOwogIH0KICB1bnNpZ25lZCBtdWxSKGludCBhKXsKICAgIGlmKGEgPCAwKXsKICAgICAgYSA9IGElbWQrbWQ7CiAgICB9CiAgICByZXR1cm4gbXVsUigodW5zaWduZWQpYSk7CiAgfQogIHVuc2lnbmVkIG11bFIodW5zaWduZWQgbG9uZyBsb25nIGEpewogICAgcmV0dXJuIG11bFIoKHVuc2lnbmVkKShhJW1kKSk7CiAgfQogIHVuc2lnbmVkIG11bFIobG9uZyBsb25nIGEpewogICAgYSAlPSBtZDsKICAgIGlmKGEgPCAwKXsKICAgICAgYSArPSBtZDsKICAgIH0KICAgIHJldHVybiBtdWxSKCh1bnNpZ25lZClhKTsKICB9CiAgdW5zaWduZWQgcmVkdWNlKHVuc2lnbmVkIFQpewogICAgdW5zaWduZWQgbT1UICogbWRuaW52LCB0PSh1bnNpZ25lZCkoKFQgKyAodW5zaWduZWQgbG9uZyBsb25nKW0qbWQpID4+IFcpOwogICAgaWYodCA+PSBtZCl7CiAgICAgIHQgLT0gbWQ7CiAgICB9CiAgICByZXR1cm4gdDsKICB9CiAgdW5zaWduZWQgcmVkdWNlKHVuc2lnbmVkIGxvbmcgbG9uZyBUKXsKICAgIHVuc2lnbmVkIG09KHVuc2lnbmVkKVQgKiBtZG5pbnYsIHQ9KHVuc2lnbmVkKSgoVCArICh1bnNpZ25lZCBsb25nIGxvbmcpbSptZCkgPj4gVyk7CiAgICBpZih0ID49IG1kKXsKICAgICAgdCAtPSBtZDsKICAgIH0KICAgIHJldHVybiB0OwogIH0KICB1bnNpZ25lZCBnZXQoKXsKICAgIHJldHVybiByZWR1Y2UodmFsKTsKICB9CiAgbWludCAmb3BlcmF0b3IrPShtaW50IGEpewogICAgdmFsICs9IGEudmFsOwogICAgaWYodmFsID49IG1kKXsKICAgICAgdmFsIC09IG1kOwogICAgfQogICAgcmV0dXJuICp0aGlzOwogIH0KICBtaW50ICZvcGVyYXRvci09KG1pbnQgYSl7CiAgICBpZih2YWwgPCBhLnZhbCl7CiAgICAgIHZhbCA9IHZhbCArIG1kIC0gYS52YWw7CiAgICB9CiAgICBlbHNlewogICAgICB2YWwgLT0gYS52YWw7CiAgICB9CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIG1pbnQgJm9wZXJhdG9yKj0obWludCBhKXsKICAgIHZhbCA9IHJlZHVjZSgodW5zaWduZWQgbG9uZyBsb25nKXZhbCphLnZhbCk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIG1pbnQgJm9wZXJhdG9yLz0obWludCBhKXsKICAgIHJldHVybiAqdGhpcyAqPSBhLmludmVyc2UoKTsKICB9CiAgbWludCBvcGVyYXRvcisobWludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKSs9YTsKICB9CiAgbWludCBvcGVyYXRvci0obWludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKS09YTsKICB9CiAgbWludCBvcGVyYXRvcioobWludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKSo9YTsKICB9CiAgbWludCBvcGVyYXRvci8obWludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKS89YTsKICB9CiAgbWludCBvcGVyYXRvcisoaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpKz1taW50KGEpOwogIH0KICBtaW50IG9wZXJhdG9yLShpbnQgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcyktPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3IqKGludCBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKSo9bWludChhKTsKICB9CiAgbWludCBvcGVyYXRvci8oaW50IGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpLz1taW50KGEpOwogIH0KICBtaW50IG9wZXJhdG9yKyhsb25nIGxvbmcgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcykrPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3ItKGxvbmcgbG9uZyBhKXsKICAgIHJldHVybiBtaW50KCp0aGlzKS09bWludChhKTsKICB9CiAgbWludCBvcGVyYXRvcioobG9uZyBsb25nIGEpewogICAgcmV0dXJuIG1pbnQoKnRoaXMpKj1taW50KGEpOwogIH0KICBtaW50IG9wZXJhdG9yLyhsb25nIGxvbmcgYSl7CiAgICByZXR1cm4gbWludCgqdGhpcykvPW1pbnQoYSk7CiAgfQogIG1pbnQgb3BlcmF0b3ItKHZvaWQpewogICAgbWludCByZXM7CiAgICBpZih2YWwpewogICAgICByZXMudmFsPW1kLXZhbDsKICAgIH0KICAgIGVsc2V7CiAgICAgIHJlcy52YWw9MDsKICAgIH0KICAgIHJldHVybiByZXM7CiAgfQogIG9wZXJhdG9yIGJvb2wodm9pZCl7CiAgICByZXR1cm4gdmFsIT0wOwogIH0KICBvcGVyYXRvciBpbnQodm9pZCl7CiAgICByZXR1cm4gZ2V0KCk7CiAgfQogIG9wZXJhdG9yIGxvbmcgbG9uZyh2b2lkKXsKICAgIHJldHVybiBnZXQoKTsKICB9CgogIG1pbnQgaW52ZXJzZSgpewogICAgaW50IGEgPSB2YWwsIGIgPSBtZCwgdSA9IDEsIHYgPSAwLCB0OwogICAgbWludCByZXM7CiAgICB3aGlsZShiKXsKICAgICAgdCA9IGEgLyBiOwogICAgICBhIC09IHQgKiBiOyBzd2FwKGEsIGIpOwogICAgICB1IC09IHQgKiB2OyBzd2FwKHUsIHYpOwogICAgfQogICAgaWYodSA8IDApIHUgKz0gbWQ7CiAgICByZXMudmFsID0gKHVuc2lnbmVkIGxvbmcgbG9uZyl1KlJSICUgbWQ7CiAgICByZXR1cm4gcmVzOwogIH0KCiAgbWludCBwdyh1bnNpZ25lZCBsb25nIGxvbmcgYil7CiAgICBtaW50IGEoKnRoaXMpLCByZXM7CiAgICByZXMudmFsID0gUjsKICAgIHdoaWxlKGIpewogICAgICBpZihiJjEpIHJlcyAqPSBhOwogICAgICBiID4+PSAxOwogICAgICBhICo9IGE7CiAgICB9CiAgICByZXR1cm4gcmVzOwogIH0KCiAgYm9vbCBvcGVyYXRvcj09KGludCBhKXtyZXR1cm4gbXVsUihhKT09dmFsO30KICBib29sIG9wZXJhdG9yIT0oaW50IGEpe3JldHVybiBtdWxSKGEpIT12YWw7fQp9Owp1bnNpZ25lZCBtaW50OjptZCwgbWludDo6VywgbWludDo6UiwgbWludDo6UmludiwgbWludDo6bWRuaW52LCBtaW50OjpSUjsKbWludCBvcGVyYXRvcisoaW50IGEsIG1pbnQgYil7cmV0dXJuIG1pbnQoYSkrPWI7Cn0KbWludCBvcGVyYXRvci0oaW50IGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSktPWI7Cn0KbWludCBvcGVyYXRvciooaW50IGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSkqPWI7Cn0KbWludCBvcGVyYXRvci8oaW50IGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSkvPWI7Cn0KbWludCBvcGVyYXRvcisobG9uZyBsb25nIGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSkrPWI7Cn0KbWludCBvcGVyYXRvci0obG9uZyBsb25nIGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSktPWI7Cn0KbWludCBvcGVyYXRvcioobG9uZyBsb25nIGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSkqPWI7Cn0KbWludCBvcGVyYXRvci8obG9uZyBsb25nIGEsIG1pbnQgYil7CiAgcmV0dXJuIG1pbnQoYSkvPWI7Cn0Kdm9pZCByZChpbnQgJngpewogIGludCBrLCBtPTA7CiAgeD0wOwogIGZvcig7Oyl7CiAgICBrID0gZ2V0Y2hhcl91bmxvY2tlZCgpOwogICAgaWYoaz09Jy0nKXsKICAgICAgbT0xOwogICAgICBicmVhazsKICAgIH0KICAgIGlmKCcwJzw9ayYmazw9JzknKXsKICAgICAgeD1rLScwJzsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGZvcig7Oyl7CiAgICBrID0gZ2V0Y2hhcl91bmxvY2tlZCgpOwogICAgaWYoazwnMCd8fGs+JzknKXsKICAgICAgYnJlYWs7CiAgICB9CiAgICB4PXgqMTAray0nMCc7CiAgfQogIGlmKG0pewogICAgeD0teDsKICB9Cn0KaW50IHJkKGNoYXIgY1tdKXsKICBpbnQgaSwgc3o9MDsKICBmb3IoOzspewogICAgaSA9IGdldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGkhPScgJyYmaSE9J1xuJyYmaSE9J1xyJyYmaSE9J1x0JyYmaSE9RU9GKXsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGNbc3orK10gPSBpOwogIGZvcig7Oyl7CiAgICBpID0gZ2V0Y2hhcl91bmxvY2tlZCgpOwogICAgaWYoaT09JyAnfHxpPT0nXG4nfHxpPT0nXHInfHxpPT0nXHQnfHxpPT1FT0YpewogICAgICBicmVhazsKICAgIH0KICAgIGNbc3orK10gPSBpOwogIH0KICBjW3N6XT0nXDAnOwogIHJldHVybiBzejsKfQp2b2lkIHd0X0woaW50IHgpewogIGNoYXIgZlsxMF07CiAgaW50IG09MCwgcz0wOwogIGlmKHg8MCl7CiAgICBtPTE7CiAgICB4PS14OwogIH0KICB3aGlsZSh4KXsKICAgIGZbcysrXT14JTEwOwogICAgeC89MTA7CiAgfQogIGlmKCFzKXsKICAgIGZbcysrXT0wOwogIH0KICBpZihtKXsKICAgIHB1dGNoYXJfdW5sb2NrZWQoJy0nKTsKICB9CiAgd2hpbGUocy0tKXsKICAgIHB1dGNoYXJfdW5sb2NrZWQoZltzXSsnMCcpOwogIH0KfQp2b2lkIHd0X0wobWludCB4KXsKICBpbnQgaTsKICBpID0gKGludCl4OwogIHd0X0woaSk7Cn0Kc3RydWN0IGNvbWJpbmF0aW9uX21pbnR7CiAgbWludCAqZmFjLCAqaWZhYzsKICB2b2lkIGluaXQoaW50IG4sIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgICBpbnQgaTsKICAgIG1hbGxvYzFkKCZmYWMsIG4sIG1lbSk7CiAgICBtYWxsb2MxZCgmaWZhYywgbiwgbWVtKTsKICAgIGZhY1swXSA9IDE7CiAgICBmb3IoaT0xO2k8bjtpKyspewogICAgICBmYWNbaV0gPSBmYWNbaS0xXSAqIGk7CiAgICB9CiAgICBpZmFjW24tMV0gPSAxIC8gZmFjW24tMV07CiAgICBmb3IoaT1uLTI7aT49MDtpLS0pewogICAgICBpZmFjW2ldID0gaWZhY1tpKzFdICogKGkrMSk7CiAgICB9CiAgfQogIG1pbnQgQyhpbnQgYSwgaW50IGIpewogICAgaWYoYiA8IDAgfHwgYiA+IGEpewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBmYWNbYV0qaWZhY1tiXSppZmFjW2EtYl07CiAgfQogIG1pbnQgUChpbnQgYSwgaW50IGIpewogICAgaWYoYiA8IDAgfHwgYiA+IGEpewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBmYWNbYV0qaWZhY1thLWJdOwogIH0KICBtaW50IEgoaW50IGEsIGludCBiKXsKICAgIGlmKGE9PTAgJiYgYj09MCl7CiAgICAgIHJldHVybiAxOwogICAgfQogICAgaWYoYTw9MCB8fCBiPDApewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBDKGErYi0xLCBiKTsKICB9Cn0KOwpjaGFyIFNbNTAwMDEwXSwgbWVtYXJyWzY0MDAwMDAwXTsKaW50IE4sIFE7CmludCBtYWluKCl7CiAgY29tYmluYXRpb25fbWludCBjb21iOwogIGludCBoaXN0WzRdOwogIG1pbnQgYWIsIGNkLCByZXM7CiAgd21lbSA9IG1lbWFycjsKICB7CiAgICBtaW50IHg7CiAgICB4LnNldG1vZChNRCk7CiAgfQogIGNvbWIuaW5pdCg1MDAwMTApOwogIHJkKFEpOwogIHdoaWxlKFEtLSl7CiAgICBOID0gcmQoUyk7CiAgICB7CiAgICAgIGludCBMajRQZEhSVzsKICAgICAgZm9yKExqNFBkSFJXPTA7TGo0UGRIUlc8KDMpICsgMTtMajRQZEhSVysrKXsKICAgICAgICBoaXN0W0xqNFBkSFJXXSA9IDA7CiAgICAgIH0KICAgIH0KICAgIHsKICAgICAgaW50IEtMMkd2bHlZOwogICAgICBmb3IoS0wyR3ZseVk9MDtLTDJHdmx5WTwoTi0xKSArIDE7S0wyR3ZseVkrKyl7CiAgICAgICAgaGlzdFtTW0tMMkd2bHlZXS0nYSddKys7CiAgICAgIH0KICAgIH0KICAgIGFiID0gY2QgPSAwOwogICAgewogICAgICBpbnQgUTVWSkwxY1M7CiAgICAgIGZvcihRNVZKTDFjUz0wO1E1VkpMMWNTPChOKSArIDE7UTVWSkwxY1MrKyl7CiAgICAgICAgYWIgKz0gY29tYi5DKGhpc3RbMF0sKFE1VkpMMWNTKSkgKiBjb21iLkMoaGlzdFsxXSwoUTVWSkwxY1MpKTsKICAgICAgfQogICAgfQogICAgewogICAgICBpbnQgZTk4V0hDRVk7CiAgICAgIGZvcihlOThXSENFWT0wO2U5OFdIQ0VZPChOKSArIDE7ZTk4V0hDRVkrKyl7CiAgICAgICAgY2QgKz0gY29tYi5DKGhpc3RbMl0sKGU5OFdIQ0VZKSkgKiBjb21iLkMoaGlzdFszXSwoZTk4V0hDRVkpKTsKICAgICAgfQogICAgfQogICAgcmVzID0gYWIgKiBjZCAtIDE7CiAgICB3dF9MKHJlcyk7CiAgICBwdXRjaGFyX3VubG9ja2VkKCdcbicpOwogIH0KICByZXR1cm4gMDsKfQovLyBjTGF5IHZhcnNpb24gMjAxNzA1MDUtMgoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vIGludCBRLCBOOwovLyBjaGFyIFNbNTAwMDEwXTsKLy8gewovLyAgIGludCBoaXN0WzRdOwovLyAgIGNvbWJpbmF0aW9uX21pbnQgY29tYjsKLy8gICBtaW50IHJlcywgYWIsIGNkOwovLyAKLy8gICBjb21iLmluaXQoNTAwMDEwKTsKLy8gCi8vICAgcmQoUSk7Ci8vICAgd2hpbGUoUS0tKXsKLy8gICAgIHJkKFNATik7Ci8vIAovLyAgICAgaGlzdFswLi4zXSA9IDA7Ci8vICAgICBoaXN0W1NbMC4uTi0xXS0nYSddKys7Ci8vIAovLyAgICAgYWIgPSBjZCA9IDA7Ci8vICAgICBhYiArPSBjb21iLkMoaGlzdFswXSwoMC4uTikpICogY29tYi5DKGhpc3RbMV0sKDAuLikpOwovLyAgICAgY2QgKz0gY29tYi5DKGhpc3RbMl0sKDAuLk4pKSAqIGNvbWIuQyhoaXN0WzNdLCgwLi4pKTsKLy8gICAgIAovLyAgICAgcmVzID0gYWIgKiBjZCAtIDE7Ci8vICAgICB3dChyZXMpOwovLyAgIH0KLy8gfQo=