import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
// 定义辅助变量
// 开始和结束下标用于最后输出结果
private static int start = 0;
private static int end = -1;
// 记录回文串最右和中间的位置
private static int right = -1;
private static int center = -1;
// 主函数
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 获取输入字符串
String s = br.readLine();
// 对字符串进行预处理转换
StringBuffer buffer = new StringBuffer("#");
for (int i = 0; i < s.length(); i++) {
buffer.append(s.charAt(i));
buffer.append("#");
}
buffer.append("#");
s = buffer.toString(); // 预处理完毕
// 定义列表存储臂长
List<Integer> armLens = new ArrayList<>();
// 遍历字符串的每个位置,求出其所对应的最大臂长
for (int i = 0; i < s.length(); i++) {
int curArmLen = 0;
if (i <= right) { // 落点在某个回文串之内
int mirror = 2 * center - i; // 找到当前i关于center的镜像位置
// 在镜像臂长和边界臂长中选较小者,确保长度不越界
int minArmLen = Math.min(armLens.get(mirror), right - i);
// 跳过此最小长度的字符数后,继续对比两端字符,以扩张当前位置的臂长
curArmLen = expand(s, i - minArmLen, i + minArmLen);
} else {
// 落点在回文串之外,直接从落点位置中心扩散,暴力求解
curArmLen = expand(s, i, i);
}
// 记录当前臂长
armLens.add(curArmLen);
// 更新最右位置和中心位置
if (i + curArmLen > right) {
center = i;
right = i + curArmLen;
}
// 更新最长回文子串的开始和结束下标
if (curArmLen * 2 + 1 > end - start + 1) { // 长度大于原先的长度
start = i - curArmLen;
end = i + curArmLen;
}
} // 遍历结束
// 拼接结果后输出其长度
StringBuffer ans = new StringBuffer();
for (int i = start; i <= end; i++) {
if (s.charAt(i) != '#') {
ans.append(s.charAt(i));
}
}
System.out.println(ans.toString().length());
}
// 辅助函数,用于扩展回文字符串的长度,以当前位置的臂长所体现
private static int expand(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
// 减2是因为最后两指针都多移了一次
// 右指针减左指针的值为长度减1,刚好等于臂长的两倍(臂长 * 2 + 1中点 = 长度)
return (right - left - 2) / 2; // 返回的结果即为臂长
}
}