#include <bits/stdc++.h>
using namespace std;
#define mset(x,val) memset(x,val,sizeof(x))
#define allof(x) x.begin(), x.end()
#define fi first
#define se second
using ll = long long;
using vi = vector<int>;
using vii = vector<vector<int>>;
using vl = vector<long long>;
using vll = vector<vector<long long>>;
using vb = vector<bool>;
using vbb = vector<vector<bool>>;
using mii = map<int,int>;
using umii = unordered_map<int,int>;
using pii = pair<int,int>;
using pll = pair<long long,long long>;
using pli = pair<long long, int>;
using pil = pair<int, long long>;
#define __builtin_popcount __builtin_popcountll
#define BIT(x, i) (((x) >> (i)) & 1)
#define MASK(x) ((1ll << (x)))
#define debug(a, l, r) for (int _i = (l); _i <= (r); ++_i) cout << (a)[_i] << ' '; cout << '\n';
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 5;
int a, b, m, n, k, q;
struct Eertree
{
struct Node
{
int len;
int link;
int next[26];
int cnt;
int s_cnt;
int first_pos;
Node (int _n)
{
len = _n;
link = 0;
cnt = 0;
s_cnt = 0;
mset(next, 0);
}
};
int n;
vector <Node> tree;
string s;
int last;
Eertree(int _n)
{
n = _n;
tree.reserve(n+3);
tree.push_back(Node(-1));
tree.push_back(Node(0));
tree[0].link = 0;
tree[1].link = 0;
last = 1;
s="";
}
int get_link(int v, int pos)
{
while (1)
{
int curlen = tree[v].len;
if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) break;
v = tree[v].link;
}
return v;
}
void add_char(char c)
{
int pos = s.size();
s+=c;
int cur = get_link(last, pos);
int cidx = c-'a';
if (tree[cur].next[cidx])
{
last = tree[cur].next[cidx];
tree[last].cnt++;
tree[last].s_cnt++;
return;
}
int new_node = tree.size();
tree.push_back(Node(tree[cur].len + 2));
tree[new_node].first_pos = pos;
tree[cur].next[cidx] = new_node;
if (tree[new_node].len == 1) tree[new_node].link = 1;
else
{
int num = get_link(tree[cur].link, pos);
tree[new_node].link = tree[num].next[cidx];
}
tree[new_node].cnt = 1;
tree[new_node].s_cnt = 1;
last = new_node;
}
void build(string str)
{
for (char c : str) add_char(c);
}
void propagate()
{
for (int i=tree.size()-1; i>=2; --i)
{
tree[tree[i].link].s_cnt += tree[i].s_cnt;
}
}
int distinct_palin_cnt()
{
return tree.size() - 2;
}
int palin_cnt()
{
int res=0;
for (int i=2; i<tree.size(); ++i) res+=tree[i].s_cnt;
return res;
}
};
string s;
void Input()
{
cin>>s;
Eertree Eet = Eertree(s.size());
Eet.build(s);
Eet.propagate();
cout<<Eet.palin_cnt();
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
Input();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBtc2V0KHgsdmFsKSBtZW1zZXQoeCx2YWwsc2l6ZW9mKHgpKQojZGVmaW5lIGFsbG9mKHgpIHguYmVnaW4oKSwgeC5lbmQoKQojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCgp1c2luZyBsbCA9IGxvbmcgbG9uZzsKdXNpbmcgdmkgPSB2ZWN0b3I8aW50PjsKdXNpbmcgdmlpID0gdmVjdG9yPHZlY3RvcjxpbnQ+PjsKdXNpbmcgdmwgPSB2ZWN0b3I8bG9uZyBsb25nPjsKdXNpbmcgdmxsID0gdmVjdG9yPHZlY3Rvcjxsb25nIGxvbmc+PjsKdXNpbmcgdmIgPSB2ZWN0b3I8Ym9vbD47CnVzaW5nIHZiYiA9IHZlY3Rvcjx2ZWN0b3I8Ym9vbD4+Owp1c2luZyBtaWkgPSBtYXA8aW50LGludD47CnVzaW5nIHVtaWkgPSB1bm9yZGVyZWRfbWFwPGludCxpbnQ+Owp1c2luZyBwaWkgPSBwYWlyPGludCxpbnQ+Owp1c2luZyBwbGwgPSBwYWlyPGxvbmcgbG9uZyxsb25nIGxvbmc+Owp1c2luZyBwbGkgPSBwYWlyPGxvbmcgbG9uZywgaW50PjsKdXNpbmcgcGlsID0gcGFpcjxpbnQsIGxvbmcgbG9uZz47CiNkZWZpbmUgX19idWlsdGluX3BvcGNvdW50IF9fYnVpbHRpbl9wb3Bjb3VudGxsCiNkZWZpbmUgQklUKHgsIGkpICgoKHgpID4+IChpKSkgJiAxKQojZGVmaW5lIE1BU0soeCkgKCgxbGwgPDwgKHgpKSkKI2RlZmluZSBkZWJ1ZyhhLCBsLCByKSBmb3IgKGludCBfaSA9IChsKTsgX2kgPD0gKHIpOyArK19pKSBjb3V0IDw8IChhKVtfaV0gPDwgJyAnOyBjb3V0IDw8ICdcbic7IAoKY29uc3QgaW50IE1PRCA9IDFlOSArIDc7CmNvbnN0IGludCBtYXhuID0gMWU1ICsgNTsKCmludCBhLCBiLCBtLCBuLCBrLCBxOwoKc3RydWN0IEVlcnRyZWUKewogICAgc3RydWN0IE5vZGUKICAgIHsKICAgICAgICBpbnQgbGVuOwogICAgICAgIGludCBsaW5rOwogICAgICAgIGludCBuZXh0WzI2XTsKICAgICAgICBpbnQgY250OwogICAgICAgIGludCBzX2NudDsKICAgICAgICBpbnQgZmlyc3RfcG9zOwoKICAgICAgICBOb2RlIChpbnQgX24pCiAgICAgICAgewogICAgICAgICAgICBsZW4gPSBfbjsKICAgICAgICAgICAgbGluayA9IDA7CiAgICAgICAgICAgIGNudCA9IDA7CiAgICAgICAgICAgIHNfY250ID0gMDsKICAgICAgICAgICAgbXNldChuZXh0LCAwKTsKICAgICAgICB9CiAgICB9OwoKICAgIGludCBuOwogICAgdmVjdG9yIDxOb2RlPiB0cmVlOwogICAgc3RyaW5nIHM7CiAgICBpbnQgbGFzdDsKCiAgICBFZXJ0cmVlKGludCBfbikKICAgIHsKICAgICAgICBuID0gX247CiAgICAgICAgdHJlZS5yZXNlcnZlKG4rMyk7CiAgICAgICAgdHJlZS5wdXNoX2JhY2soTm9kZSgtMSkpOwogICAgICAgIHRyZWUucHVzaF9iYWNrKE5vZGUoMCkpOwoKICAgICAgICB0cmVlWzBdLmxpbmsgPSAwOwogICAgICAgIHRyZWVbMV0ubGluayA9IDA7CgogICAgICAgIGxhc3QgPSAxOwogICAgICAgIHM9IiI7CiAgICB9CgogICAgaW50IGdldF9saW5rKGludCB2LCBpbnQgcG9zKQogICAgewogICAgICAgIHdoaWxlICgxKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGN1cmxlbiA9IHRyZWVbdl0ubGVuOwogICAgICAgICAgICBpZiAocG9zIC0gMSAtIGN1cmxlbiA+PSAwICYmIHNbcG9zIC0gMSAtIGN1cmxlbl0gPT0gc1twb3NdKSBicmVhazsKICAgICAgICAgICAgdiA9IHRyZWVbdl0ubGluazsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHY7ICAgIAogICAgfQoKICAgIHZvaWQgYWRkX2NoYXIoY2hhciBjKQogICAgewogICAgICAgIGludCBwb3MgPSBzLnNpemUoKTsKICAgICAgICBzKz1jOwogICAgICAgIGludCBjdXIgPSBnZXRfbGluayhsYXN0LCBwb3MpOwoKICAgICAgICBpbnQgY2lkeCA9IGMtJ2EnOwoKICAgICAgICBpZiAodHJlZVtjdXJdLm5leHRbY2lkeF0pCiAgICAgICAgewogICAgICAgICAgICBsYXN0ID0gdHJlZVtjdXJdLm5leHRbY2lkeF07CiAgICAgICAgICAgIHRyZWVbbGFzdF0uY250Kys7CiAgICAgICAgICAgIHRyZWVbbGFzdF0uc19jbnQrKzsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaW50IG5ld19ub2RlID0gdHJlZS5zaXplKCk7CiAgICAgICAgdHJlZS5wdXNoX2JhY2soTm9kZSh0cmVlW2N1cl0ubGVuICsgMikpOwogICAgICAgIHRyZWVbbmV3X25vZGVdLmZpcnN0X3BvcyA9IHBvczsKICAgICAgICAKICAgICAgICB0cmVlW2N1cl0ubmV4dFtjaWR4XSA9IG5ld19ub2RlOwoKICAgICAgICBpZiAodHJlZVtuZXdfbm9kZV0ubGVuID09IDEpIHRyZWVbbmV3X25vZGVdLmxpbmsgPSAxOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGludCBudW0gPSBnZXRfbGluayh0cmVlW2N1cl0ubGluaywgcG9zKTsKICAgICAgICAgICAgdHJlZVtuZXdfbm9kZV0ubGluayA9IHRyZWVbbnVtXS5uZXh0W2NpZHhdOwogICAgICAgIH0KCiAgICAgICAgdHJlZVtuZXdfbm9kZV0uY250ID0gMTsKICAgICAgICB0cmVlW25ld19ub2RlXS5zX2NudCA9IDE7CiAgICAgICAgbGFzdCA9IG5ld19ub2RlOwogICAgfQoKICAgIHZvaWQgYnVpbGQoc3RyaW5nIHN0cikKICAgIHsKICAgICAgICBmb3IgKGNoYXIgYyA6IHN0cikgYWRkX2NoYXIoYyk7CiAgICB9CgogICAgdm9pZCBwcm9wYWdhdGUoKQogICAgewogICAgICAgIGZvciAoaW50IGk9dHJlZS5zaXplKCktMTsgaT49MjsgLS1pKQogICAgICAgIHsKICAgICAgICAgICAgdHJlZVt0cmVlW2ldLmxpbmtdLnNfY250ICs9IHRyZWVbaV0uc19jbnQ7CiAgICAgICAgfQogICAgfQoKICAgIGludCBkaXN0aW5jdF9wYWxpbl9jbnQoKQogICAgewogICAgICAgIHJldHVybiB0cmVlLnNpemUoKSAtIDI7IAogICAgfQoKICAgIGludCBwYWxpbl9jbnQoKQogICAgewogICAgICAgIGludCByZXM9MDsKICAgICAgICAKICAgICAgICBmb3IgKGludCBpPTI7IGk8dHJlZS5zaXplKCk7ICsraSkgcmVzKz10cmVlW2ldLnNfY250OwogICAgICAgIAogICAgICAgIHJldHVybiByZXM7CiAgICB9CgoKfTsKCnN0cmluZyBzOwoKdm9pZCBJbnB1dCgpCnsKICAgIGNpbj4+czsKICAgIEVlcnRyZWUgRWV0ID0gRWVydHJlZShzLnNpemUoKSk7CiAgICBFZXQuYnVpbGQocyk7CiAgICBFZXQucHJvcGFnYXRlKCk7CiAgICBjb3V0PDxFZXQucGFsaW5fY250KCk7Cgp9CgppbnQgbWFpbigpCnsKICAgIAogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oMCk7CiAgICBjaW4udGllKDApOwogICAgY291dC50aWUoMCk7CgogICAgSW5wdXQoKTsKICAgIHJldHVybiAwOwp9