#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>

using namespace std;

#define MAXN 200050

int N;
char S[MAXN];
int Zaux[MAXN];
int Z[MAXN];
int RZ[MAXN];
bool flag;
long long ans;

// index idx in [a..b]
inline char getCh(int a, int b, int idx) {
	return S[a + idx * (a <= b ? 1 : -1)];
}

// Z for [a..b] in [c..d]
void calcZ(int a, int b, int c, int d, int Z[MAXN]) {
	int sz1 = abs(b - a) + 1;
	int sz2 = abs(d - c) + 1;
	
	int L = -1;
	int R = -1;
	
	Zaux[0] = sz2;
	for (int i = 1; i < sz1; i++) {
		if (i > R) {
			L = R = i;
			while (R < sz2 && R - L < sz2 && getCh(c, d, R) == getCh(c, d, R - L)) {
				R++;
			}
			R--;
			Zaux[i] = R - L + 1;
		}
		else {
			int k = i - L;
			Zaux[i] = min(Zaux[k], R - i + 1);
			if (Zaux[i] == R - i + 1) {
				L = i;
				while (R < sz2 && R - L < sz2 && getCh(c, d, R) == getCh(c, d, R - L)) {
					R++;
				}
				R--;
				Zaux[i] = R - L + 1;
			}
		}
	}
	
	if (a <= b) {	
		L = R = -1;
		for (int i = 0; i < sz1; i++) {
			if (i > R) {
				L = i;
				R = i;
				while (R < sz1 && R - L < sz2 && getCh(a, b, R) == getCh(c, d, R - L)) {
					R++;
				}
				R--;
				Z[i] = R - L + 1;
			}
			else {
				int k = i - L;
				Z[i] = min(Zaux[k], R - i + 1);
				if (Z[i] == R - i + 1) {
					L = i;
					while (R < sz1 && R - L < sz2 && getCh(a, b, R) == getCh(c, d, R - L)) {
						R++;
					}
					R--;
					Z[i] = R - L + 1;
				}
			}
		}
	}
	else { // a > b
		for (int i = 0; i < sz1; i++) {
			Z[i] = Zaux[sz1 - 1 - i];
		}
	}
}

void go(int st, int m, int dr) {
	calcZ(st, m, m + 1, dr, Z);
	calcZ(m, st, m, st, RZ);
	
	int len = m - st + 1;
	
//	printf("(%d, %d, %d) ->\n", st, m, dr);
//	for (int i = 0; i < len; i++) { printf("%d ", Z[i]); } printf("\n");
//	for (int i = 0; i < len; i++) { printf("%d ", RZ[i]); } printf("\n");
	
	if (flag) {
		for (int i = 0; i < len; i++) {
			if (i + Z[i] == len) {
				ans++;
			}
		}
	}
	
	for (int i = 1; i < len - 1; i++) {
		int upper = min(i + Z[i], len - 1);
		int lower = max(i + 1, len - RZ[i - 1]);
		ans += max(0, upper - lower + 1);
	}
}

void solve(int st, int dr) {
	if (st == dr) {
		return;
	}
	int m = (st + dr) / 2;
	if (!flag) {
		m = (st + dr - 1) / 2;
	}
	
	go(st, m, dr);
	
	solve(st, m);
	solve(m + 1, dr);
}

int brute() {
	string ss(S);
	int ret = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 1; i + 2 * j - 1 < N; j++) {
			if (ss.substr(i, j) == ss.substr(i + j, j)) {
				ret++;
			}
		}
	}
	return ret;
}

int main() {
//	freopen("date.in", "r", stdin);
//	freopen("date.out","w", stdout);
	
	fgets(S, sizeof(S), stdin);
	N = strlen(S);
	while (!isalpha(S[N - 1])) {
		S[N - 1] = '\0';
		N--;
	}
	
//	cout << brute() << endl;
	
	ans = 0;
	flag = true;
	solve(0, N - 1);
	
	reverse(S, S + N);
	flag = false;
	solve(0, N - 1);
	
	cout << ans << endl;
	
//	srand(time(0));
//	for (int i = 0; i < 500; i++) {
//		printf("%c", 'a' + rand() % 8);
//	}
	
	return 0;
}
