#include <bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<ll,null_type,less_equal<ll>,rb_tree_tag,tree_order_statistics_node_update> order_set;
//mt19937 mt_rand(chrono::high_resolution_clock::now().time_since_epoch().count());
//uniform_int_distribution<int> gen(-1e9, 1e8); ///(min, max)
//int random() {return gen(mt_rand);}
const int mxN = 3001;
const int mod = 1e9+7;
const int mxlogN = 20;
const int mxK = 26;
const ll inf = 1e9;

///hvala bogu ako ovo prodje ps. resenja sam se setio u lapo 2 ujutru ko i svaki put
/// :)

short dp[mxN][mxN]; ///najbolji answer tako da sam cuttovao na [i, j]
short dp2[mxN][mxN]; /// max(dp[i][>j])
short dp3[mxN][mxN]; ///best2, dp[j][sz]
short match[mxN][mxN]; ///how many elements match at [j i],[i k]
///CARE YOU CANT CUT SEGMENT SIZE 1
short n;
short solve(short l, short r);
short solve2(short l, short r)
{
    if(r+2>=n) return 0;
    if(dp2[l][r] != -1) return dp2[l][r];
    return dp2[l][r] = max(solve(l, r), solve2(l, r+1));
}
short solve3(short l, short sz)
{
    sz = min(n-l, (int)sz);
    if(sz < 2) return 0;
    if(dp3[l][sz] != -1) return dp3[l][sz];
    return dp3[l][sz] = max((int)solve3(l, sz-1), solve2(l, l+sz-1)+match[l][l+sz-1]);
}
short solve(short l, short r) ///last cut[l, r];
{
    if(l==r || r+2>=n) return 0; ///nemoze len 1
    if(dp[l][r] != -1) return dp[l][r];
    return dp[l][r] = solve3(r+1, r-l+1);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    for(short j = 0; j < mxN; j++)
    {
        for(short i = 0; i < mxN; i++)
        {
            dp[j][i]=dp2[j][i]=dp3[j][i]= -1;
        }
    }
    string s; cin >> s;
    n = s.size();
    for(short i = 0; i < n; i++)
    {
        for(short j = 1; true; j++)
        {
            if(i+j-1 >= n) break;
            if(j>1) match[i][i+j-1] = match[i][i+j-2];
            //int k = i-j;
            //cout << "i " << i << " " << i+j-1 << "\n";
            if(i-j >= 0 && s[i+j-1]==s[i-j]) match[i][i+j-1]++;
        }
    }
    short ans = 0;
    for(short i = 1; i+1 < n; i++) ///nemogu prefix len 1 ni suffix
    {
        ans = max(ans, solve(0, i));
    }
    cout << ans << "\n";
}
/**
aaabbabbaa
2 4
2 5
3 5
5 7
6 9
-1 -1
*/