#include <cstdio>
#include <cstring>
#define NMax 505
using namespace std;
char String[NMax];
int N, DP[NMax][NMax], MaxS;
int AI[4*NMax][255];
inline int Max (int a, int b)
{
if (a>b)
{
return a;
}
return b;
}
void Read ()
{
freopen ("palm.in", "r", stdin);
scanf ("%s", String);
N=strlen (String);
}
void Update (int K, int L, int R, int P, int C, int V)
{
int Mid=(L+R)/2;
if (L==R)
{
for (int c=C; c>=(int)'a'; --c)
{
AI[K][c]=Max (AI[K][c], V);
}
return;
}
if (P<=Mid)
{
Update (2*K, L, Mid, P, C, V);
}
else
{
Update (2*K+1, Mid+1, R, P, C, V);
}
for (int c=(int)'a'; c<='z'; ++c)
{
AI[K][c]=Max (AI[2*K][c], AI[2*K+1][c]);
}
}
int Query (int K, int L, int R, int Q, int V)
{
int Mid=(L+R)/2;
if (R<=Q)
{
return AI[K][V];
}
if (Q<=Mid)
{
return Query (2*K, L, Mid, Q, V);
}
return Max (Query (2*K, L, Mid, Q, V), Query (2*K+1, Mid+1, R, Q, V));
}
void Solve ()
{
for (int i=N-1; i>=0; --i)
{
DP[i][i]=1;
for (int j=i+1; j<N; ++j)
{
if (String[i]!=String[j])
{
continue;
}
/*DP[i][j]=2;
for (int ii=i+1; ii<j; ++ii)
{
for (int jj=ii; jj<j; ++jj)
{
if (String[ii]!=String[jj])
{
continue;
}
if (String[i]<=String[ii] and String[jj]>=String[j])
{
DP[i][j]=Max (DP[i][j], DP[ii][jj]+2);
}
}
}*/
DP[i][j]=2+Query (1, 0, N-1, j-1, (int)String[i]);
MaxS=Max (MaxS, DP[i][j]);
}
for (int j=i; j<N; ++j)
{
if (String[i]!=String[j])
{
continue;
}
Update (1, 0, N-1, j, (int)String[j], DP[i][j]);
}
}
}
void Print ()
{
freopen ("palm.out", "w", stdout);
printf ("%d\n", MaxS);
}
void Test ()
{
freopen ("palm.in", "w", stdout);
for (char c='a'; c<='z'; ++c)
{
for (int i=1; i<=9; ++i)
{
printf ("%c", c);
}
}
for (char c='z'; c>='a'; --c)
{
for (int i=1; i<=9; ++i)
{
printf ("%c", c);
}
}
}
int main()
{
Read ();
Solve ();
Print ();
//Test ();
return 0;
}