#include #include #include #define int long long using namespace std; class PalindromicTree { private: vector st; vector length; vector parent; vector count; vector> link; int lastNodeIdx; public: PalindromicTree() { st.push_back(0); length.push_back(-1); length.push_back(0); parent.push_back(0); parent.push_back(0); count.push_back(0); count.push_back(0); link.push_back({}); link.push_back({}); lastNodeIdx = 0; } void add(char v) { st.push_back(v); int prevNodeIdx = lastNodeIdx; int nextNodeIdx = lastNodeIdx; while (true) { int head = length[nextNodeIdx] + 2; if (head <= st.size() && st[st.size() - head] == st.back()) { break; } nextNodeIdx = parent[nextNodeIdx]; } int nextLen = length[nextNodeIdx] + 2; if (link[nextNodeIdx].count(v)) { lastNodeIdx = link[nextNodeIdx][v]; count[lastNodeIdx]++; return; } lastNodeIdx = length.size(); length.push_back(nextLen); if (nextLen == 1) { parent.push_back(1); } else { int prevNodeIdx = parent[nextNodeIdx]; while (true) { int head = length[prevNodeIdx] + 2; if (head <= st.size() && st[st.size() - head] == st.back()) { break; } prevNodeIdx = parent[prevNodeIdx]; } parent.push_back(link[prevNodeIdx][v]); } count.push_back(1); link[nextNodeIdx][v] = lastNodeIdx; link.push_back({}); } int maxScore() { int nodeCount = length.size(); vector score(nodeCount, 0); vector tempCount = count; for (int i = nodeCount - 1; i >= 2; i--) { tempCount[parent[i]] += tempCount[i]; } for (int i = 2; i < nodeCount; i++) { score[i] = score[parent[i]] + length[i] * tempCount[i]; } int maxScore = 0; for (int s : score) { maxScore = max(maxScore, s); } return maxScore; } }; signed main() { string s; cin >> s; PalindromicTree pt; for (int i = s.length() - 1; i >= 0; i--) { pt.add(s[i]); } cout << pt.maxScore() << endl; return 0; }