#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define PI 3.14159265358979323846
void*wmem;
char memarr[96000000];
template<class S, class T> inline S min_L(S a,T b){
return a<=b?a:b;
}
template<class S, class T> inline S max_L(S a,T b){
return a>=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(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;
}
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(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');
}
}
struct fft_pnt{
double x;
double y;
fft_pnt(void){
}
fft_pnt(double a, double b){
x = a;
y = b;
}
void set(double a, double b){
x = a;
y = b;
}
fft_pnt& operator+=(fft_pnt a){
x+=a.x;
y+=a.y;
return *this;
}
fft_pnt& operator-=(fft_pnt a){
x-=a.x;
y-=a.y;
return *this;
}
fft_pnt& operator*=(fft_pnt a){
fft_pnt p = *this;
x = p.x*a.x-p.y*a.y;
y = p.x*a.y+p.y*a.x;
return *this;
}
fft_pnt operator+(fft_pnt a){
return fft_pnt(*this) += a;
}
fft_pnt operator-(fft_pnt a){
return fft_pnt(*this) -= a;
}
fft_pnt operator*(fft_pnt a){
return fft_pnt(*this) *= a;
}
}
;
void fft_L(int n, fft_pnt x[], void *mem){
int i;
int j;
int n1;
int n2;
int n3;
int step = 1;
double theta = 2*PI / n;
double tmp;
fft_pnt w1;
fft_pnt w2;
fft_pnt w3;
fft_pnt a;
fft_pnt b;
fft_pnt c;
fft_pnt d;
fft_pnt aa;
fft_pnt bb;
fft_pnt cc;
fft_pnt dd;
fft_pnt*y = (fft_pnt*)mem;
while(n > 2){
n1 = n / 4;
n2 = n1 + n1;
n3 = n1 + n2;
for(i=(0);i<(n1);i++){
w1 = fft_pnt(cos(i*theta),-sin(i*theta));
w2 = w1*w1;
w3 = w1*w2;
for(j=(0);j<(step);j++){
a = x[j+step*i];
b = x[j+step*(i+n1)];
c = x[j+step*(i+n2)];
d = x[j+step*(i+n3)];
aa = a + c;
bb = a - c;
cc = b + d;
dd = b - d;
tmp = dd.y;
dd.y = dd.x;
dd.x = -tmp;
y[j+step*(4*i )] = aa + cc;
y[j+step*(4*i+1)] = w1*(bb - dd);
y[j+step*(4*i+2)] = w2*(aa - cc);
y[j+step*(4*i+3)] = w3*(bb + dd);
}
}
n /= 4;
step *= 4;
theta *= 4;
swap(x,y);
}
if(n==2){
for(i=(0);i<(step);i++){
y[i] = x[i] + x[i+step];
y[i+step] = x[i] - x[i+step];
}
n /= 2;
step *= 2;
theta *= 2;
swap(x,y);
}
for(i=(0);i<(step);i++){
y[i] = x[i];
}
}
void fftinv_L(int n, fft_pnt x[], void *mem){
int i;
int j;
int n1;
int n2;
int n3;
int step = 1;
double theta = 2*PI / n;
double tmp;
fft_pnt w1;
fft_pnt w2;
fft_pnt w3;
fft_pnt a;
fft_pnt b;
fft_pnt c;
fft_pnt d;
fft_pnt aa;
fft_pnt bb;
fft_pnt cc;
fft_pnt dd;
fft_pnt*y = (fft_pnt*)mem;
while(n > 2){
n1 = n / 4;
n2 = n1 + n1;
n3 = n1 + n2;
for(i=(0);i<(n1);i++){
w1 = fft_pnt(cos(i*theta),sin(i*theta));
w2 = w1*w1;
w3 = w1*w2;
for(j=(0);j<(step);j++){
a = x[j+step*i];
b = x[j+step*(i+n1)];
c = x[j+step*(i+n2)];
d = x[j+step*(i+n3)];
aa = a + c;
bb = a - c;
cc = b + d;
dd = b - d;
tmp = dd.y;
dd.y = dd.x;
dd.x = -tmp;
y[j+step*(4*i )] = aa + cc;
y[j+step*(4*i+1)] = w1*(bb + dd);
y[j+step*(4*i+2)] = w2*(aa - cc);
y[j+step*(4*i+3)] = w3*(bb - dd);
}
}
n /= 4;
step *= 4;
theta *= 4;
swap(x,y);
}
if(n==2){
for(i=(0);i<(step);i++){
y[i] = x[i] + x[i+step];
y[i+step] = x[i] - x[i+step];
}
n /= 2;
step *= 2;
theta *= 2;
swap(x,y);
}
for(i=(0);i<(step);i++){
y[i] = x[i];
}
}
void convolution_L(double A[], int As, double B[], int Bs, double res[], int Rs, void *mem = wmem){
int i;
int n;
int n2;
double mul;
fft_pnt*a;
fft_pnt*b;
n =max_L(As+Bs, Rs);
for(n2=1;n2<n;n2*=2){
;
}
walloc1d(&a, n2, &mem);
walloc1d(&b, n2, &mem);
for(i=(0);i<(As);i++){
a[i].set(A[i], 0);
}
int jO2HaRTX = n2;
for(i=(As);i<(jO2HaRTX);i++){
a[i].set(0,0);
}
for(i=(0);i<(Bs);i++){
b[i].set(B[i], 0);
}
int n23oAcQn = n2;
for(i=(Bs);i<(n23oAcQn);i++){
b[i].set(0,0);
}
fft_L(n2, a, mem);
fft_L(n2, b, mem);
for(i=(0);i<(n2);i++){
a[i] *= b[i];
}
fftinv_L(n2, a, mem);
mul = 1.0 / n2;
for(i=(0);i<(Rs);i++){
res[i] = a[i].x * mul;
}
}
void convolution_L(double A[], int As, double res[], int Rs, void *mem = wmem){
int i;
int n;
int n2;
double mul;
fft_pnt*a;
n =max_L(As+As, Rs);
for(n2=1;n2<n;n2*=2){
;
}
walloc1d(&a, n2, &mem);
for(i=(0);i<(As);i++){
a[i].set(A[i], 0);
}
int W9o_dQUM = n2;
for(i=(As);i<(W9o_dQUM);i++){
a[i].set(0,0);
}
fft_L(n2, a, mem);
for(i=(0);i<(n2);i++){
a[i] *= a[i];
}
fftinv_L(n2, a, mem);
mul = 1.0 / n2;
for(i=(0);i<(Rs);i++){
res[i] = a[i].x * mul;
}
}
int N;
char S[500000+2];
double a[500000+2];
double c[500000+2];
double t[1000000+2];
int main(){
wmem = memarr;
int block = 5000;
int st;
int ed;
int i;
int j;
int len;
long long res = 0;
long long m;
N = rd(S);
for(st=(0);st<(N);st+=(block)){
ed =min_L(st+block, N);
len =min_L(st, N-ed)+ block;
for(i=(0);i<(len);i++){
a[i] = c[i] = 0;
}
for(i=(0);i<(len);i++){
if(st-len+i >= 0 && S[st-len+i]=='a'){
a[i]++;
}
}
for(i=(0);i<(len);i++){
if(st-len+i >= 0 && S[st-len+i]=='A'){
a[i]+=2;
}
}
for(i=(0);i<(len);i++){
if(ed+i < N && S[ed+i]=='c'){
c[i]++;
}
}
for(i=(0);i<(len);i++){
if(ed+i < N && S[ed+i]=='C'){
c[i]+=2;
}
}
convolution_L(a, len, c, len, t, 2*len);
for(i=(st);i<(ed);i++){
if(S[i]=='b' && 0 <= 2*i+len-st-ed && 2*i+len-st-ed < 2*len){
res += round(t[2*i+len-st-ed]);
}
}
for(i=(st);i<(ed);i++){
if(S[i]=='B' && 0 <= 2*i+len-st-ed && 2*i+len-st-ed < 2*len){
res += 2*round(t[2*i+len-st-ed]);
}
}
for(i=(st);i<(ed);i++){
if(S[i]=='b' || S[i]=='B'){
for(j=1;;j++){
if(i-j < 0 || i+j >= N){
break;
}
if(i-j < st && i+j >= ed){
break;
}
if(S[i-j]!='a' && S[i-j]!='A'){
continue;
}
if(S[i+j]!='c' && S[i+j]!='C'){
continue;
}
m = 1;
if(S[i]=='B'){
m*=2;
}
if(S[i-j]=='A'){
m*=2;
}
if(S[i+j]=='C'){
m*=2;
}
res += m;
}
}
}
}
wt_L(res);
wt_L('\n');
return 0;
}
// cLay varsion 20201102-1
// --- original code ---
// int N;
// char S[5d5+2];
// double a[5d5+2], c[5d5+2], t[1d6+2];
// {
// int block = 5000, st, ed, i, j, len;
// ll res = 0, m;
// rd(S@N);
//
// rep(st,0,N,block){
// ed = min(st+block, N);
// len = min(st, N-ed) + block;
// rep(i,len) a[i] = c[i] = 0;
// rep(i,len) if(st-len+i >= 0 && S[st-len+i]=='a') a[i]++;
// rep(i,len) if(st-len+i >= 0 && S[st-len+i]=='A') a[i]+=2;
// rep(i,len) if(ed+i < N && S[ed+i]=='c') c[i]++;
// rep(i,len) if(ed+i < N && S[ed+i]=='C') c[i]+=2;
// convolution(a, len, c, len, t, 2*len);
// rep(i,st,ed) if(S[i]=='b' && 0 <= 2*i+len-st-ed < 2*len) res += round(t[2*i+len-st-ed]);
// rep(i,st,ed) if(S[i]=='B' && 0 <= 2*i+len-st-ed < 2*len) res += 2*round(t[2*i+len-st-ed]);
//
// rep(i,st,ed) if(S[i]=='b' || S[i]=='B'){
// for(j=1;;j++){
// if(i-j < 0 || i+j >= N) break;
// if(i-j < st && i+j >= ed) break;
// if(S[i-j]!='a' && S[i-j]!='A') continue;
// if(S[i+j]!='c' && S[i+j]!='C') continue;
// m = 1;
// if(S[i]=='B') m*=2;
// if(S[i-j]=='A') m*=2;
// if(S[i+j]=='C') m*=2;
// res += m;
// }
// }
// }
// wt(res);
// }
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgUEkgMy4xNDE1OTI2NTM1ODk3OTMyMzg0Ngp2b2lkKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgUywgY2xhc3MgVD4gaW5saW5lIFMgbWluX0woUyBhLFQgYil7CiAgcmV0dXJuIGE8PWI/YTpiOwp9CnRlbXBsYXRlPGNsYXNzIFMsIGNsYXNzIFQ+IGlubGluZSBTIG1heF9MKFMgYSxUIGIpewogIHJldHVybiBhPj1iP2E6YjsKfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgdm9pZCB3YWxsb2MxZChUICoqYXJyLCBpbnQgeCwgdm9pZCAqKm1lbSA9ICZ3bWVtKXsKICBzdGF0aWMgaW50IHNraXBbMTZdID0gezAsIDE1LCAxNCwgMTMsIDEyLCAxMSwgMTAsIDksIDgsIDcsIDYsIDUsIDQsIDMsIDIsIDF9OwogICgqbWVtKSA9ICh2b2lkKikoICgoY2hhciopKCptZW0pKSArIHNraXBbKCh1bnNpZ25lZCBsb25nIGxvbmcpKCptZW0pKSAmIDE1XSApOwogICgqYXJyKT0oVCopKCptZW0pOwogICgqbWVtKT0oKCphcnIpK3gpOwp9CnRlbXBsYXRlPGNsYXNzIFQ+IGlubGluZSB2b2lkIHdhbGxvYzFkKFQgKiphcnIsIGludCB4MSwgaW50IHgyLCB2b2lkICoqbWVtID0gJndtZW0pewogIHdhbGxvYzFkKGFyciwgeDIteDEsIG1lbSk7CiAgKCphcnIpIC09IHgxOwp9CmlubGluZSBpbnQgbXlfZ2V0Y2hhcl91bmxvY2tlZCgpewogIHN0YXRpYyBjaGFyIGJ1ZlsxMDQ4NTc2XTsKICBzdGF0aWMgaW50IHMgPSAxMDQ4NTc2OwogIHN0YXRpYyBpbnQgZSA9IDEwNDg1NzY7CiAgaWYocyA9PSBlICYmIGUgPT0gMTA0ODU3Nil7CiAgICBlID0gZnJlYWRfdW5sb2NrZWQoYnVmLCAxLCAxMDQ4NTc2LCBzdGRpbik7CiAgICBzID0gMDsKICB9CiAgaWYocyA9PSBlKXsKICAgIHJldHVybiBFT0Y7CiAgfQogIHJldHVybiBidWZbcysrXTsKfQppbmxpbmUgdm9pZCByZChjaGFyICZjKXsKICBpbnQgaTsKICBmb3IoOzspewogICAgaSA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGkhPScgJyYmaSE9J1xuJyYmaSE9J1xyJyYmaSE9J1x0JyYmaSE9RU9GKXsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIGMgPSBpOwp9CmlubGluZSBpbnQgcmQoY2hhciBjW10pewogIGludCBpOwogIGludCBzeiA9IDA7CiAgZm9yKDs7KXsKICAgIGkgPSBteV9nZXRjaGFyX3VubG9ja2VkKCk7CiAgICBpZihpIT0nICcmJmkhPSdcbicmJmkhPSdccicmJmkhPSdcdCcmJmkhPUVPRil7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBjW3N6KytdID0gaTsKICBmb3IoOzspewogICAgaSA9IG15X2dldGNoYXJfdW5sb2NrZWQoKTsKICAgIGlmKGk9PScgJ3x8aT09J1xuJ3x8aT09J1xyJ3x8aT09J1x0J3x8aT09RU9GKXsKICAgICAgYnJlYWs7CiAgICB9CiAgICBjW3N6KytdID0gaTsKICB9CiAgY1tzel09J1wwJzsKICByZXR1cm4gc3o7Cn0Kc3RydWN0IE1ZX1dSSVRFUnsKICBjaGFyIGJ1ZlsxMDQ4NTc2XTsKICBpbnQgczsKICBpbnQgZTsKICBNWV9XUklURVIoKXsKICAgIHMgPSAwOwogICAgZSA9IDEwNDg1NzY7CiAgfQogIH5NWV9XUklURVIoKXsKICAgIGlmKHMpewogICAgICBmd3JpdGVfdW5sb2NrZWQoYnVmLCAxLCBzLCBzdGRvdXQpOwogICAgfQogIH0KfQo7Ck1ZX1dSSVRFUiBNWV9XUklURVJfVkFSOwp2b2lkIG15X3B1dGNoYXJfdW5sb2NrZWQoaW50IGEpewogIGlmKE1ZX1dSSVRFUl9WQVIucyA9PSBNWV9XUklURVJfVkFSLmUpewogICAgZndyaXRlX3VubG9ja2VkKE1ZX1dSSVRFUl9WQVIuYnVmLCAxLCBNWV9XUklURVJfVkFSLnMsIHN0ZG91dCk7CiAgICBNWV9XUklURVJfVkFSLnMgPSAwOwogIH0KICBNWV9XUklURVJfVkFSLmJ1ZltNWV9XUklURVJfVkFSLnMrK10gPSBhOwp9CmlubGluZSB2b2lkIHd0X0woY2hhciBhKXsKICBteV9wdXRjaGFyX3VubG9ja2VkKGEpOwp9CmlubGluZSB2b2lkIHd0X0wobG9uZyBsb25nIHgpewogIGludCBzPTA7CiAgaW50IG09MDsKICBjaGFyIGZbMjBdOwogIGlmKHg8MCl7CiAgICBtPTE7CiAgICB4PS14OwogIH0KICB3aGlsZSh4KXsKICAgIGZbcysrXT14JTEwOwogICAgeC89MTA7CiAgfQogIGlmKCFzKXsKICAgIGZbcysrXT0wOwogIH0KICBpZihtKXsKICAgIG15X3B1dGNoYXJfdW5sb2NrZWQoJy0nKTsKICB9CiAgd2hpbGUocy0tKXsKICAgIG15X3B1dGNoYXJfdW5sb2NrZWQoZltzXSsnMCcpOwogIH0KfQpzdHJ1Y3QgZmZ0X3BudHsKICBkb3VibGUgeDsKICBkb3VibGUgeTsKICBmZnRfcG50KHZvaWQpewogIH0KICBmZnRfcG50KGRvdWJsZSBhLCBkb3VibGUgYil7CiAgICB4ID0gYTsKICAgIHkgPSBiOwogIH0KICB2b2lkIHNldChkb3VibGUgYSwgZG91YmxlIGIpewogICAgeCA9IGE7CiAgICB5ID0gYjsKICB9CiAgZmZ0X3BudCYgb3BlcmF0b3IrPShmZnRfcG50IGEpewogICAgeCs9YS54OwogICAgeSs9YS55OwogICAgcmV0dXJuICp0aGlzOwogIH0KICBmZnRfcG50JiBvcGVyYXRvci09KGZmdF9wbnQgYSl7CiAgICB4LT1hLng7CiAgICB5LT1hLnk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIGZmdF9wbnQmIG9wZXJhdG9yKj0oZmZ0X3BudCBhKXsKICAgIGZmdF9wbnQgcCA9ICp0aGlzOwogICAgeCA9IHAueCphLngtcC55KmEueTsKICAgIHkgPSBwLngqYS55K3AueSphLng7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIGZmdF9wbnQgb3BlcmF0b3IrKGZmdF9wbnQgYSl7CiAgICByZXR1cm4gZmZ0X3BudCgqdGhpcykgKz0gYTsKICB9CiAgZmZ0X3BudCBvcGVyYXRvci0oZmZ0X3BudCBhKXsKICAgIHJldHVybiBmZnRfcG50KCp0aGlzKSAtPSBhOwogIH0KICBmZnRfcG50IG9wZXJhdG9yKihmZnRfcG50IGEpewogICAgcmV0dXJuIGZmdF9wbnQoKnRoaXMpICo9IGE7CiAgfQp9CjsKdm9pZCBmZnRfTChpbnQgbiwgZmZ0X3BudCB4W10sIHZvaWQgKm1lbSl7CiAgaW50IGk7CiAgaW50IGo7CiAgaW50IG4xOwogIGludCBuMjsKICBpbnQgbjM7CiAgaW50IHN0ZXAgPSAxOwogIGRvdWJsZSB0aGV0YSA9IDIqUEkgLyBuOwogIGRvdWJsZSB0bXA7CiAgZmZ0X3BudCB3MTsKICBmZnRfcG50IHcyOwogIGZmdF9wbnQgdzM7CiAgZmZ0X3BudCBhOwogIGZmdF9wbnQgYjsKICBmZnRfcG50IGM7CiAgZmZ0X3BudCBkOwogIGZmdF9wbnQgYWE7CiAgZmZ0X3BudCBiYjsKICBmZnRfcG50IGNjOwogIGZmdF9wbnQgZGQ7CiAgZmZ0X3BudCp5ID0gKGZmdF9wbnQqKW1lbTsKICB3aGlsZShuID4gMil7CiAgICBuMSA9IG4gLyA0OwogICAgbjIgPSBuMSArIG4xOwogICAgbjMgPSBuMSArIG4yOwogICAgZm9yKGk9KDApO2k8KG4xKTtpKyspewogICAgICB3MSA9IGZmdF9wbnQoY29zKGkqdGhldGEpLC1zaW4oaSp0aGV0YSkpOwogICAgICB3MiA9IHcxKncxOwogICAgICB3MyA9IHcxKncyOwogICAgICBmb3Ioaj0oMCk7ajwoc3RlcCk7aisrKXsKICAgICAgICBhID0geFtqK3N0ZXAqaV07CiAgICAgICAgYiA9IHhbaitzdGVwKihpK24xKV07CiAgICAgICAgYyA9IHhbaitzdGVwKihpK24yKV07CiAgICAgICAgZCA9IHhbaitzdGVwKihpK24zKV07CiAgICAgICAgYWEgPSBhICsgYzsKICAgICAgICBiYiA9IGEgLSBjOwogICAgICAgIGNjID0gYiArIGQ7CiAgICAgICAgZGQgPSBiIC0gZDsKICAgICAgICB0bXAgPSBkZC55OwogICAgICAgIGRkLnkgPSBkZC54OwogICAgICAgIGRkLnggPSAtdG1wOwogICAgICAgIHlbaitzdGVwKig0KmkgICldID0gYWEgKyBjYzsKICAgICAgICB5W2orc3RlcCooNCppKzEpXSA9IHcxKihiYiAtIGRkKTsKICAgICAgICB5W2orc3RlcCooNCppKzIpXSA9IHcyKihhYSAtIGNjKTsKICAgICAgICB5W2orc3RlcCooNCppKzMpXSA9IHczKihiYiArIGRkKTsKICAgICAgfQogICAgfQogICAgbiAvPSA0OwogICAgc3RlcCAqPSA0OwogICAgdGhldGEgKj0gNDsKICAgIHN3YXAoeCx5KTsKICB9CiAgaWYobj09Mil7CiAgICBmb3IoaT0oMCk7aTwoc3RlcCk7aSsrKXsKICAgICAgeVtpXSA9IHhbaV0gKyB4W2krc3RlcF07CiAgICAgIHlbaStzdGVwXSA9IHhbaV0gLSB4W2krc3RlcF07CiAgICB9CiAgICBuIC89IDI7CiAgICBzdGVwICo9IDI7CiAgICB0aGV0YSAqPSAyOwogICAgc3dhcCh4LHkpOwogIH0KICBmb3IoaT0oMCk7aTwoc3RlcCk7aSsrKXsKICAgIHlbaV0gPSB4W2ldOwogIH0KfQp2b2lkIGZmdGludl9MKGludCBuLCBmZnRfcG50IHhbXSwgdm9pZCAqbWVtKXsKICBpbnQgaTsKICBpbnQgajsKICBpbnQgbjE7CiAgaW50IG4yOwogIGludCBuMzsKICBpbnQgc3RlcCA9IDE7CiAgZG91YmxlIHRoZXRhID0gMipQSSAvIG47CiAgZG91YmxlIHRtcDsKICBmZnRfcG50IHcxOwogIGZmdF9wbnQgdzI7CiAgZmZ0X3BudCB3MzsKICBmZnRfcG50IGE7CiAgZmZ0X3BudCBiOwogIGZmdF9wbnQgYzsKICBmZnRfcG50IGQ7CiAgZmZ0X3BudCBhYTsKICBmZnRfcG50IGJiOwogIGZmdF9wbnQgY2M7CiAgZmZ0X3BudCBkZDsKICBmZnRfcG50KnkgPSAoZmZ0X3BudCopbWVtOwogIHdoaWxlKG4gPiAyKXsKICAgIG4xID0gbiAvIDQ7CiAgICBuMiA9IG4xICsgbjE7CiAgICBuMyA9IG4xICsgbjI7CiAgICBmb3IoaT0oMCk7aTwobjEpO2krKyl7CiAgICAgIHcxID0gZmZ0X3BudChjb3MoaSp0aGV0YSksc2luKGkqdGhldGEpKTsKICAgICAgdzIgPSB3MSp3MTsKICAgICAgdzMgPSB3MSp3MjsKICAgICAgZm9yKGo9KDApO2o8KHN0ZXApO2orKyl7CiAgICAgICAgYSA9IHhbaitzdGVwKmldOwogICAgICAgIGIgPSB4W2orc3RlcCooaStuMSldOwogICAgICAgIGMgPSB4W2orc3RlcCooaStuMildOwogICAgICAgIGQgPSB4W2orc3RlcCooaStuMyldOwogICAgICAgIGFhID0gYSArIGM7CiAgICAgICAgYmIgPSBhIC0gYzsKICAgICAgICBjYyA9IGIgKyBkOwogICAgICAgIGRkID0gYiAtIGQ7CiAgICAgICAgdG1wID0gZGQueTsKICAgICAgICBkZC55ID0gZGQueDsKICAgICAgICBkZC54ID0gLXRtcDsKICAgICAgICB5W2orc3RlcCooNCppICApXSA9IGFhICsgY2M7CiAgICAgICAgeVtqK3N0ZXAqKDQqaSsxKV0gPSB3MSooYmIgKyBkZCk7CiAgICAgICAgeVtqK3N0ZXAqKDQqaSsyKV0gPSB3MiooYWEgLSBjYyk7CiAgICAgICAgeVtqK3N0ZXAqKDQqaSszKV0gPSB3MyooYmIgLSBkZCk7CiAgICAgIH0KICAgIH0KICAgIG4gLz0gNDsKICAgIHN0ZXAgKj0gNDsKICAgIHRoZXRhICo9IDQ7CiAgICBzd2FwKHgseSk7CiAgfQogIGlmKG49PTIpewogICAgZm9yKGk9KDApO2k8KHN0ZXApO2krKyl7CiAgICAgIHlbaV0gPSB4W2ldICsgeFtpK3N0ZXBdOwogICAgICB5W2krc3RlcF0gPSB4W2ldIC0geFtpK3N0ZXBdOwogICAgfQogICAgbiAvPSAyOwogICAgc3RlcCAqPSAyOwogICAgdGhldGEgKj0gMjsKICAgIHN3YXAoeCx5KTsKICB9CiAgZm9yKGk9KDApO2k8KHN0ZXApO2krKyl7CiAgICB5W2ldID0geFtpXTsKICB9Cn0Kdm9pZCBjb252b2x1dGlvbl9MKGRvdWJsZSBBW10sIGludCBBcywgZG91YmxlIEJbXSwgaW50IEJzLCBkb3VibGUgcmVzW10sIGludCBScywgdm9pZCAqbWVtID0gd21lbSl7CiAgaW50IGk7CiAgaW50IG47CiAgaW50IG4yOwogIGRvdWJsZSBtdWw7CiAgZmZ0X3BudCphOwogIGZmdF9wbnQqYjsKICBuID1tYXhfTChBcytCcywgUnMpOwogIGZvcihuMj0xO24yPG47bjIqPTIpewogICAgOwogIH0KICB3YWxsb2MxZCgmYSwgbjIsICZtZW0pOwogIHdhbGxvYzFkKCZiLCBuMiwgJm1lbSk7CiAgZm9yKGk9KDApO2k8KEFzKTtpKyspewogICAgYVtpXS5zZXQoQVtpXSwgMCk7CiAgfQogIGludCBqTzJIYVJUWCA9IG4yOwogIGZvcihpPShBcyk7aTwoak8ySGFSVFgpO2krKyl7CiAgICBhW2ldLnNldCgwLDApOwogIH0KICBmb3IoaT0oMCk7aTwoQnMpO2krKyl7CiAgICBiW2ldLnNldChCW2ldLCAwKTsKICB9CiAgaW50IG4yM29BY1FuID0gbjI7CiAgZm9yKGk9KEJzKTtpPChuMjNvQWNRbik7aSsrKXsKICAgIGJbaV0uc2V0KDAsMCk7CiAgfQogIGZmdF9MKG4yLCBhLCBtZW0pOwogIGZmdF9MKG4yLCBiLCBtZW0pOwogIGZvcihpPSgwKTtpPChuMik7aSsrKXsKICAgIGFbaV0gKj0gYltpXTsKICB9CiAgZmZ0aW52X0wobjIsIGEsIG1lbSk7CiAgbXVsID0gMS4wIC8gbjI7CiAgZm9yKGk9KDApO2k8KFJzKTtpKyspewogICAgcmVzW2ldID0gYVtpXS54ICogbXVsOwogIH0KfQp2b2lkIGNvbnZvbHV0aW9uX0woZG91YmxlIEFbXSwgaW50IEFzLCBkb3VibGUgcmVzW10sIGludCBScywgdm9pZCAqbWVtID0gd21lbSl7CiAgaW50IGk7CiAgaW50IG47CiAgaW50IG4yOwogIGRvdWJsZSBtdWw7CiAgZmZ0X3BudCphOwogIG4gPW1heF9MKEFzK0FzLCBScyk7CiAgZm9yKG4yPTE7bjI8bjtuMio9Mil7CiAgICA7CiAgfQogIHdhbGxvYzFkKCZhLCBuMiwgJm1lbSk7CiAgZm9yKGk9KDApO2k8KEFzKTtpKyspewogICAgYVtpXS5zZXQoQVtpXSwgMCk7CiAgfQogIGludCBXOW9fZFFVTSA9IG4yOwogIGZvcihpPShBcyk7aTwoVzlvX2RRVU0pO2krKyl7CiAgICBhW2ldLnNldCgwLDApOwogIH0KICBmZnRfTChuMiwgYSwgbWVtKTsKICBmb3IoaT0oMCk7aTwobjIpO2krKyl7CiAgICBhW2ldICo9IGFbaV07CiAgfQogIGZmdGludl9MKG4yLCBhLCBtZW0pOwogIG11bCA9IDEuMCAvIG4yOwogIGZvcihpPSgwKTtpPChScyk7aSsrKXsKICAgIHJlc1tpXSA9IGFbaV0ueCAqIG11bDsKICB9Cn0KaW50IE47CmNoYXIgU1s1MDAwMDArMl07CmRvdWJsZSBhWzUwMDAwMCsyXTsKZG91YmxlIGNbNTAwMDAwKzJdOwpkb3VibGUgdFsxMDAwMDAwKzJdOwppbnQgbWFpbigpewogIHdtZW0gPSBtZW1hcnI7CiAgaW50IGJsb2NrID0gNTAwMDsKICBpbnQgc3Q7CiAgaW50IGVkOwogIGludCBpOwogIGludCBqOwogIGludCBsZW47CiAgbG9uZyBsb25nIHJlcyA9IDA7CiAgbG9uZyBsb25nIG07CiAgTiA9IHJkKFMpOwogIGZvcihzdD0oMCk7c3Q8KE4pO3N0Kz0oYmxvY2spKXsKICAgIGVkID1taW5fTChzdCtibG9jaywgTik7CiAgICBsZW4gPW1pbl9MKHN0LCBOLWVkKSsgYmxvY2s7CiAgICBmb3IoaT0oMCk7aTwobGVuKTtpKyspewogICAgICBhW2ldID0gY1tpXSA9IDA7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwobGVuKTtpKyspewogICAgICBpZihzdC1sZW4raSA+PSAwICYmIFNbc3QtbGVuK2ldPT0nYScpewogICAgICAgIGFbaV0rKzsKICAgICAgfQogICAgfQogICAgZm9yKGk9KDApO2k8KGxlbik7aSsrKXsKICAgICAgaWYoc3QtbGVuK2kgPj0gMCAmJiBTW3N0LWxlbitpXT09J0EnKXsKICAgICAgICBhW2ldKz0yOwogICAgICB9CiAgICB9CiAgICBmb3IoaT0oMCk7aTwobGVuKTtpKyspewogICAgICBpZihlZCtpIDwgTiAmJiBTW2VkK2ldPT0nYycpewogICAgICAgIGNbaV0rKzsKICAgICAgfQogICAgfQogICAgZm9yKGk9KDApO2k8KGxlbik7aSsrKXsKICAgICAgaWYoZWQraSA8IE4gJiYgU1tlZCtpXT09J0MnKXsKICAgICAgICBjW2ldKz0yOwogICAgICB9CiAgICB9CiAgICBjb252b2x1dGlvbl9MKGEsIGxlbiwgYywgbGVuLCB0LCAyKmxlbik7CiAgICBmb3IoaT0oc3QpO2k8KGVkKTtpKyspewogICAgICBpZihTW2ldPT0nYicgJiYgMCA8PSAyKmkrbGVuLXN0LWVkICAmJiAgMippK2xlbi1zdC1lZCA8IDIqbGVuKXsKICAgICAgICByZXMgKz0gcm91bmQodFsyKmkrbGVuLXN0LWVkXSk7CiAgICAgIH0KICAgIH0KICAgIGZvcihpPShzdCk7aTwoZWQpO2krKyl7CiAgICAgIGlmKFNbaV09PSdCJyAmJiAwIDw9IDIqaStsZW4tc3QtZWQgICYmICAyKmkrbGVuLXN0LWVkIDwgMipsZW4pewogICAgICAgIHJlcyArPSAyKnJvdW5kKHRbMippK2xlbi1zdC1lZF0pOwogICAgICB9CiAgICB9CiAgICBmb3IoaT0oc3QpO2k8KGVkKTtpKyspewogICAgICBpZihTW2ldPT0nYicgfHwgU1tpXT09J0InKXsKICAgICAgICBmb3Ioaj0xOztqKyspewogICAgICAgICAgaWYoaS1qIDwgMCB8fCBpK2ogPj0gTil7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYoaS1qIDwgc3QgJiYgaStqID49IGVkKXsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBpZihTW2ktal0hPSdhJyAmJiBTW2ktal0hPSdBJyl7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaWYoU1tpK2pdIT0nYycgJiYgU1tpK2pdIT0nQycpewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIG0gPSAxOwogICAgICAgICAgaWYoU1tpXT09J0InKXsKICAgICAgICAgICAgbSo9MjsKICAgICAgICAgIH0KICAgICAgICAgIGlmKFNbaS1qXT09J0EnKXsKICAgICAgICAgICAgbSo9MjsKICAgICAgICAgIH0KICAgICAgICAgIGlmKFNbaStqXT09J0MnKXsKICAgICAgICAgICAgbSo9MjsKICAgICAgICAgIH0KICAgICAgICAgIHJlcyArPSBtOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICB3dF9MKHJlcyk7CiAgd3RfTCgnXG4nKTsKICByZXR1cm4gMDsKfQovLyBjTGF5IHZhcnNpb24gMjAyMDExMDItMQoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vIGludCBOOwovLyBjaGFyIFNbNWQ1KzJdOwovLyBkb3VibGUgYVs1ZDUrMl0sIGNbNWQ1KzJdLCB0WzFkNisyXTsKLy8gewovLyAgIGludCBibG9jayA9IDUwMDAsIHN0LCBlZCwgaSwgaiwgbGVuOwovLyAgIGxsIHJlcyA9IDAsIG07Ci8vICAgcmQoU0BOKTsKLy8gCi8vICAgcmVwKHN0LDAsTixibG9jayl7Ci8vICAgICBlZCA9IG1pbihzdCtibG9jaywgTik7Ci8vICAgICBsZW4gPSBtaW4oc3QsIE4tZWQpICsgYmxvY2s7Ci8vICAgICByZXAoaSxsZW4pIGFbaV0gPSBjW2ldID0gMDsKLy8gICAgIHJlcChpLGxlbikgaWYoc3QtbGVuK2kgPj0gMCAmJiBTW3N0LWxlbitpXT09J2EnKSBhW2ldKys7Ci8vICAgICByZXAoaSxsZW4pIGlmKHN0LWxlbitpID49IDAgJiYgU1tzdC1sZW4raV09PSdBJykgYVtpXSs9MjsKLy8gICAgIHJlcChpLGxlbikgaWYoZWQraSA8IE4gJiYgU1tlZCtpXT09J2MnKSBjW2ldKys7Ci8vICAgICByZXAoaSxsZW4pIGlmKGVkK2kgPCBOICYmIFNbZWQraV09PSdDJykgY1tpXSs9MjsKLy8gICAgIGNvbnZvbHV0aW9uKGEsIGxlbiwgYywgbGVuLCB0LCAyKmxlbik7Ci8vICAgICByZXAoaSxzdCxlZCkgaWYoU1tpXT09J2InICYmIDAgPD0gMippK2xlbi1zdC1lZCA8IDIqbGVuKSByZXMgKz0gcm91bmQodFsyKmkrbGVuLXN0LWVkXSk7Ci8vICAgICByZXAoaSxzdCxlZCkgaWYoU1tpXT09J0InICYmIDAgPD0gMippK2xlbi1zdC1lZCA8IDIqbGVuKSByZXMgKz0gMipyb3VuZCh0WzIqaStsZW4tc3QtZWRdKTsKLy8gCi8vICAgICByZXAoaSxzdCxlZCkgaWYoU1tpXT09J2InIHx8IFNbaV09PSdCJyl7Ci8vICAgICAgIGZvcihqPTE7O2orKyl7Ci8vICAgICAgICAgaWYoaS1qIDwgMCB8fCBpK2ogPj0gTikgYnJlYWs7Ci8vICAgICAgICAgaWYoaS1qIDwgc3QgJiYgaStqID49IGVkKSBicmVhazsKLy8gICAgICAgICBpZihTW2ktal0hPSdhJyAmJiBTW2ktal0hPSdBJykgY29udGludWU7Ci8vICAgICAgICAgaWYoU1tpK2pdIT0nYycgJiYgU1tpK2pdIT0nQycpIGNvbnRpbnVlOwovLyAgICAgICAgIG0gPSAxOwovLyAgICAgICAgIGlmKFNbaV09PSdCJykgbSo9MjsKLy8gICAgICAgICBpZihTW2ktal09PSdBJykgbSo9MjsKLy8gICAgICAgICBpZihTW2kral09PSdDJykgbSo9MjsKLy8gICAgICAgICByZXMgKz0gbTsKLy8gICAgICAgfQovLyAgICAgfQovLyAgIH0KLy8gICB3dChyZXMpOwovLyB9Cg==