// C++ program for building LCP array for given text
#include <bits/stdc++.h>
#include <vector>
#include <string>
#include <time.h>
using namespace std;
#define mod 1000000007
bool isSuffix (string &str, int iStart, int iEnd, int jStart)
{
for (int i = iStart, j = jStart; i <= iEnd; i++, j++)
if (str[i] != str[j])
return false;
return true;
}
void isPalin(string &str, int i, int j, int &count)
{
static int id = 0;
//cout << "PA " << "id = " << id << " " << endl;
id++;
int start = i;
int end = j;
while (i < end)
{
if (str[i] == str[j])
{
if (isSuffix(str, start, i, j))
{
count++;
count %= mod;
// cout << i << " " << j << " " << count << endl;
}
i++, j--;
}
else
{
break;
}
}
}
int main()
{
int t;
//cin >> t;
t = 1;
while (t > 0) {
string str;
cin >> str;
int start_s = clock();
int n = str.length();
//buildSuffixArray(str, str.length());
//int n = suffixArr.size();
int count = 0;
int indx = 1;
for (int c = 0; c < n; c++)
{
for (int i = 1; i <= n - c; i++)
{
//string sub_str = str.substr(c, i);
//cout << indx << " " << c << " " << i << " " << sub_str << endl;
indx++;
int left = c;
int right = c + i - 1;
isPalin(str, left, right, count);
}
}
cout << count << endl;
int stop_s = clock();
float run_time = (stop_s - start_s) / double(CLOCKS_PER_SEC);
cout << endl << "palindromic borders \t\tExecution time = " << run_time << " seconds" << endl;
t--;
}
return 0;
}
Ly8gQysrIHByb2dyYW0gZm9yIGJ1aWxkaW5nIExDUCBhcnJheSBmb3IgZ2l2ZW4gdGV4dAojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHRpbWUuaD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIG1vZCAxMDAwMDAwMDA3Cgpib29sIGlzU3VmZml4IChzdHJpbmcgJnN0ciwgaW50IGlTdGFydCwgaW50IGlFbmQsIGludCBqU3RhcnQpCnsKCWZvciAoaW50IGkgPSBpU3RhcnQsIGogPSBqU3RhcnQ7IGkgPD0gaUVuZDsgaSsrLCBqKyspCgkJCWlmIChzdHJbaV0gIT0gc3RyW2pdKQoJCQkJcmV0dXJuIGZhbHNlOwoJcmV0dXJuIHRydWU7Cn0KCnZvaWQgaXNQYWxpbihzdHJpbmcgJnN0ciwgaW50IGksIGludCBqLCBpbnQgJmNvdW50KQp7CglzdGF0aWMgaW50IGlkID0gMDsKCS8vY291dCA8PCAiUEEgIiA8PCAiaWQgPSAiIDw8IGlkICA8PCAgIiAgIiAgPDwgZW5kbDsKCWlkKys7CgoKCglpbnQgc3RhcnQgPSBpOwoJaW50IGVuZCA9IGo7CgoJd2hpbGUgKGkgPCBlbmQpCgl7CgkJaWYgKHN0cltpXSA9PSBzdHJbal0pIAoJCXsKCQkJaWYgKGlzU3VmZml4KHN0ciwgc3RhcnQsIGksICBqKSkKCQkJewoJCQkJY291bnQrKzsKCQkJCWNvdW50ICU9IG1vZDsKCQkJLy8JY291dCA8PCBpIDw8ICIgICIgIDw8IGogIDw8ICIgICIgIDw8ICBjb3VudCAgPDwgIGVuZGw7CgoJCQl9CgkJCWkrKywgai0tOwoJCQkKCQl9CgkJZWxzZQoJCXsKCQkJYnJlYWs7CgkJfQoJfQoJCn0KCmludCBtYWluKCkKewoJaW50IHQ7CgkvL2NpbiA+PiB0OwoJdCA9IDE7CgoJd2hpbGUgKHQgPiAwKSAgewoKCQlzdHJpbmcgc3RyOwoKCQljaW4gPj4gc3RyOwoKCQlpbnQgc3RhcnRfcyA9IGNsb2NrKCk7CgoKCQlpbnQgbiA9IHN0ci5sZW5ndGgoKTsKCgkJLy9idWlsZFN1ZmZpeEFycmF5KHN0ciwgc3RyLmxlbmd0aCgpKTsKCQkvL2ludCBuID0gc3VmZml4QXJyLnNpemUoKTsKCgkJaW50IGNvdW50ID0gMDsKCQlpbnQgaW5keCA9IDE7CgkJZm9yIChpbnQgYyA9IDA7IGMgPCBuOyBjKyspCgkJewoJCQlmb3IgKGludCBpID0gMTsgaSA8PSBuIC0gYzsgaSsrKQoJCQl7CgkJCQkvL3N0cmluZyBzdWJfc3RyID0gc3RyLnN1YnN0cihjLCBpKTsKCQkJCS8vY291dCA8PCBpbmR4IDw8ICIgICIgIDw8ICBjICA8PCAgIiAgIiAgPDwgIGkgIDw8ICAiICAiICA8PCBzdWJfc3RyIDw8IGVuZGw7CgkJCQlpbmR4Kys7CgoJCQkJaW50IGxlZnQgPSBjOwoJCQkJaW50IHJpZ2h0ID0gYyArIGkgLSAxOwoKCQkJCWlzUGFsaW4oc3RyLCBsZWZ0LCByaWdodCwgY291bnQpOwoJCQl9CgoJCX0KCgkJY291dCA8PCBjb3VudCAgPDwgIGVuZGw7CgoJCWludCBzdG9wX3MgPSBjbG9jaygpOwoJCWZsb2F0IHJ1bl90aW1lID0gKHN0b3BfcyAtIHN0YXJ0X3MpIC8gZG91YmxlKENMT0NLU19QRVJfU0VDKTsKCQljb3V0IDw8IGVuZGwgPDwgInBhbGluZHJvbWljIGJvcmRlcnMgIFx0XHRFeGVjdXRpb24gdGltZSA9ICIgPDwgcnVuX3RpbWUgPDwgIiBzZWNvbmRzIiA8PCBlbmRsOwoKCQl0LS07Cgl9CgoJcmV0dXJuIDA7Cn0K