#include <bits/stdc++.h>
#include <time.h>
using namespace std;

#define sz(x) ((int)(x).size())
#define pb push_back
#define vec vector
#define fi first
#define se second
#define ends "\n"
#define sp ' '
#define fun function
#define ar(x) array<int, x>
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const long long MOD=1e9+7; 

void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) { cerr << to_string(h); if(sizeof...(t)) cerr << ", "; DBG(t...); }
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)

//abc_
//1234
//0123

int main(void){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr); cerr.tie(nullptr);
 	
    string s;
    cin >> s;
    s = s + "_";

    int n = sz(s);

 	vec<vec<int>> dpScore(n + 1, vec<int>(n + 1));

    for(int i = 1; i <= n; ++i){
        for(int k = 1; k < n; ++k){
            if((i - k) < 1 && (i + k) > n)
                break;
            dpScore[i][k] = dpScore[i][k - 1];
            if((i - k) >= 1 && (i + k) <= n){
                dpScore[i][k] += (s[i - k - 1] == s[i - 2 + k]);
            }
        }
    }

    int ans = 0;

    vec<vec<int>> dp(n + 1, vec<int>(n + 1));
    vec<vec<int>> maxDp(n + 1, vec<int>(n + 1));
    vec<int> dpMaxStart(n + 1);

    for(int breakPoint = 1; breakPoint <= n; ++breakPoint){
        for(int startPoint = 1; startPoint < breakPoint; ++startPoint){
            int len = breakPoint - startPoint;
            dp[startPoint][breakPoint] = dpScore[startPoint][len] + maxDp[startPoint - 1][startPoint];

            dpMaxStart[startPoint] = max(dpMaxStart[startPoint], dp[startPoint][breakPoint]);

            dp[startPoint][breakPoint] = max(dp[startPoint][breakPoint], dpMaxStart[startPoint]);


            maxDp[startPoint][breakPoint] = max(dp[startPoint][breakPoint], maxDp[startPoint - 1][breakPoint]);
            ans = max(ans, dp[startPoint][breakPoint]);
        }
    }

    cout << ans << ends;
}