struct PAM { int next[maxn][ALP] , fail[maxn] , cnt[maxn] , num[maxn] , len[maxn] , s[maxn]; int last, n, p; struct edge { int v, nxt; } e[maxn]; int ecnt, head[maxn]; bool vis[maxn];
void adde(int u, int v) { e[++ecnt].v = v; e[ecnt].nxt = head[u]; head[u] = ecnt; }
int newnode(int l) { for (int i = 0; i < ALP; i++) next[p][i] = 0; cnt[p] = num[p] = 0; len[p] = l; return p++; }
void init() { vis[0] = vis[1] = 0; ecnt = 0; for (int i = 0; i <= p; ++i) head[i] = 0; p = 0; newnode(0); newnode(-1); last = 0; n = 0; s[n] = -1; fail[0] = 1; }
int get_fail(int x) { while (s[n - len[x] - 1] != s[n]) x = fail[x]; return x; }
void add(int c) { c = c - 'a'; s[++n] = c; int cur = get_fail(last); if (!next[cur][c]) { int now = newnode(len[cur] + 2); fail[now] = next[get_fail(fail[cur])][c]; next[cur][c] = now; num[now] = num[fail[now]] + 1; } last = next[cur][c]; cnt[last]++; }
void count() { for (int i = p - 1; i >= 0; i--) cnt[fail[i]] += cnt[i]; }
void build() { for (int i = 0; i <= p - 1; ++i) adde(fail[i], i); }