#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define dec(x, y) fixed << setprecision((y)) << (x)
#define xx first
#define yy second
#define srt(v) sort((v).begin(), (v).end())
#define srtr(v) sort((v).rbegin(), (v).rend())
#define pb push_back
#define popb pop_back
#define sz(a) (int)(a).size()
#define len(a) (int)(a).length()
#define mp make_pair

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

int n;
string s;
struct ralf {
    int vr, lazy;
} st[3002][12002];
void prop(int koji, int node, int tl, int tr) {
    st[koji][node].vr=max(st[koji][node].vr, st[koji][node].lazy);
    if(tl!=tr) {
        st[koji][2*node].lazy=max(st[koji][2*node].lazy, st[koji][node].lazy);
        st[koji][2*node+1].lazy=max(st[koji][2*node+1].lazy, st[koji][node].lazy);
    }
    st[koji][node].lazy=0;
}
void upd(int koji, int node, int tl, int tr, int gl, int gr, int val) {
    prop(koji, node, tl, tr);
    if(tl>=gl && tr<=gr) {
        st[koji][node].lazy=max(st[koji][node].lazy, val);
        return;
    }
    int mid=(tl+tr)/2;
    if(mid>=gl) upd(koji, 2*node, tl, mid, gl, gr, val);
    if(mid+1<=gr) upd(koji, 2*node+1, mid+1, tr, gl, gr, val);
    prop(koji, 2*node, tl, mid);
    prop(koji, 2*node+1, mid+1, tr);
    st[koji][node].vr=max(st[koji][2*node].vr, st[koji][2*node+1].vr);
}
int query(int koji, int node, int tl, int tr, int poz) {
    prop(koji, node, tl, tr);
    if(tl==tr) return st[koji][node].vr;
    int mid=(tl+tr)/2;
    if(mid>=poz) return query(koji, 2*node, tl, mid, poz);
    return query(koji, 2*node+1, mid+1, tr, poz);
}
vector<int> pal[3002];
int main() {
    ios;
    cin >> s;
    n=len(s);
    for(int k=0; k<n-1; k++) {
        for(int i=k, j=k+1; i>=0 && j<n; i--, j++) {
            if(s[i]==s[j]) pal[k+1].pb(j+1);
        }
    }
    /*for(int i=1; i<=n-1; i++) {
        cout << i << ' ';
        for(auto x:pal[i]) cout << x << ' ';
        cout << endl;
    }*/
    for(int j=0; j<=n; j++) {
        if(j==1) continue;
        for(int i=1; i<=n; i++) {
            if(i-j<2) continue;
            int uzmi=query(j, 1, 1, n, i);
            for(int k=0; k<sz(pal[i]); k++) {
                if(pal[i][k]-i>i-j) break;
                upd(i, 1, 1, n, pal[i][k], (k==sz(pal[i])-1 || pal[i][k+1]-i>i-j?n:pal[i][k+1]-1), uzmi+k+1);
            }
        }
    }
    int maxi=0;
    for(int j=0; j<=n-2; j++) {
        maxi=max(maxi, query(j, 1, 1, n, n));
    }
    cout << maxi;
    return 0;
}