// in the name of Allah ;
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 1e3 + 10 ;
int arr[100] , dp[maxn][maxn] , n ;
pair < int , int > par[maxn][maxn] ;
string s , ans = ""  ;
void cal_dp()
{
	for ( int i = 0 ; i < n ; i++ )
		dp[i][i+1] = 1 ;
	for ( int i = n-1 ; i >= 0 ; i-- )
		for ( int j = i+2 ; j <= n ; j++ )
		{
			if ( s[i] == s[j-1] && dp[i][j] < dp[i+1][j-1]+2 )
				dp[i][j] = dp[i+1][j-1] + 2 , par[i][j] = { 1 , 1 } ;
			if ( dp[i][j] < dp[i+1][j] )
				dp[i][j] = dp[i+1][j] , par[i][j] = { 1 , 0 } ;
			if ( dp[i][j] < dp[i][j-1] )
				dp[i][j] = dp[i][j-1] , par[i][j] = { 0 , 1 } ;
		}
}
int main()
{
	cin >> s ;
	n = s.size() ;
	for ( int i = 0 ; i < n ; i++ )
		arr[s[i]-'a']++ ;
	for ( int i = 0 ; i < 26; i++ )
		if ( arr[i] >= 100 )
		{
			for ( int j = 0 ; j < 100 ; j++ )
				cout << (char)(i+'a') ;
			cout << endl;
			return 0;
		}
	cal_dp() ;
	int len = 0 , l = 0 , r = n ;
	while ( l+1 < r )
	{
		if ( len == 100 )
			break ;
		auto tmp = par[l][r] ;
		if ( par[l][r] == make_pair ( 1 , 1 ) )
			ans += s[l] , len += 2 ;
		l += tmp.first , r -= tmp.second ;
	}
	cout << ans ;
	if ( len != 100 &&  l+1 == r )
		cout << s[l] ;
	reverse ( ans.begin() , ans.end() ) ;
	cout << ans << endl;
}


// in the name of Allah ;
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 4e3 + 10 ;
int arr[100] , dp[maxn][maxn] , n ;
pair < int , int > par[maxn][maxn] ;
string s , ans = ""  ;
void cal_dp()
{
	for ( int i = 0 ; i < n ; i++ )
		dp[i][i+1] = 1 ;
	for ( int i = n-1 ; i >= 0 ; i-- )
		for ( int j = i+2 ; j <= n ; j++ )
		{
			if ( s[i] == s[j-1] && dp[i][j] < dp[i+1][j-1]+2 )
				dp[i][j] = dp[i+1][j-1] + 2 , par[i][j] = { 1 , 1 } ;
			if ( dp[i][j] < dp[i+1][j] )
				dp[i][j] = dp[i+1][j] , par[i][j] = { 1 , 0 } ;
			if ( dp[i][j] < dp[i][j-1] )
				dp[i][j] = dp[i][j-1] , par[i][j] = { 0 , 1 } ;
		}
}
int main()
{
	cin >> s ;
	n = s.size() ;
	for ( int i = 0 ; i < n ; i++ )
		arr[s[i]-'a']++ ;
	for ( int i = 0 ; i < 26; i++ )
		if ( arr[i] >= 100 )
		{
			for ( int j = 0 ; j < 100 ; j++ )
				cout << (char)(i+'a') ;
			cout << endl;
			return 0;
		}
	cal_dp() ;
	int len = 0 , l = 0 , r = n ;
	while ( l+1 < r )
	{
		if ( len == 100 )
			break ;
		auto tmp = par[l][r] ;
		if ( par[l][r] == make_pair ( 1 , 1 ) )
			ans += s[l] , len += 2 ;
		l += tmp.first , r -= tmp.second ;
	}
	cout << ans ;
	if ( len != 100 &&  l+1 == r )
		cout << s[l] ;
	reverse ( ans.begin() , ans.end() ) ;
	cout << ans << endl;
}


#include<bits/stdc++.h>
using namespace std;
#define FS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long int
#define ld long double
#define pb push_back
#define bp __builtin_popcount
#define sz size()
#define ff first
#define ss second
#define vll vector<ll>
#define vbool vector<bool>
#define vpll vector<pair<ll,ll>>
#define pll pair<ll,ll>
#define vllv vector<vector<ll>>
#define setpri(x) cout<<setprecision(x)<<fixed;
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
#define yesr {cout<<"YES"<<endl;return;}
#define nor {cout<<"NO"<<endl;return;}
// getline (std::cin,name);
ll MOD=1e9+7;
ll ceil1(ll n,ll x){if(n%x==0)return n/x; else return (n/x)+1;}
ll gcd(ll a,ll b){return __gcd(a,b);}
ll lcm(ll a,ll b){return (max(a,b)/gcd(a,b))*min(a,b);}
ll pow1(ll n,ll k,ll mm){
    if(k==0)return 1;
    if(k%2==0)return (pow1((n%mm)*(n%mm),k/2,mm))%mm;
    return ((n%mm)*(pow1((n%mm)*(n%mm),k/2,mm)%mm))%mm;
}
ll pow2(ll n,ll k){ll ans=1;
    while(k>0){
        if(k%2==1)ans=ans*n;n=n*n;k/=2;
    }return ans;
}
ll modinv(ll A,ll M){return pow1(A,M-2,M);}
ll fact(ll n){ll s=1; for(ll i=1;i<=n;i++)s*=i; return s;}
ll factmod(ll n,ll mod){ll s=1; for(ll i=1;i<=n;i++){s*=i;s%=mod;} return s;}
vll fact1tonmod(ll n,ll mod){vll  ans(n+1);ans[0]=ans[1]=1;
    for(ll i=2;i<=n;i++)ans[i]=(ans[i-1]*i)%mod;
    return ans;
}
ll ncrmod(ll n,ll r,ll mod){
    ll ans=((((factmod(n,mod)%mod)*(modinv(factmod(r,mod),mod)%mod))%mod)*(modinv(factmod(n-r,mod),mod)))%mod;
    return ans;
}
ll ncr(ll n,ll r){if(n==1 || r==0)return 1;if(r>n/2)r=n-r;
    ll ans=1;for(ll i=1;i<=r;i++){ans=((ans * n )/i);n--;}return ans;
}
bool isprime(ll n){if(n==1 || (n!=2 && n%2==0))return false; if(n==2)return true;
        for(ll i=3;i<=sqrt(n);i+=2)if(n%i==0)return false; return true; }
bool func(pair<ll,ll> &a,pair<ll,ll> &b ){
    if(a.ff != b.ff)return a.ff < b.ff;
    return a.ss > b.ss;
}
string s;
ll dp[3000][3000];
ll dpo(ll i,ll j){
    if(j<i)return 0;
    ll &ans=dp[i][j];
    if(ans!=-1)return ans;
    if(i==j){
        dp[i][j]=1;
        return 1;
    }
    if(s[i]==s[j]){
        dp[i][j]=2+dpo(i+1,j-1);
        return dp[i][j];
    }

    dp[i][j]=max(dpo(i+1,j),dpo(i,j-1));
    return dp[i][j];
}
string a="",b="";
void sts(ll i,ll j){
    if(j<i)return;
    if(a.sz+b.sz==100)return;
    if(i==j){
        a+=s[i];
        return;
    }
    if(s[i]==s[j]){
        a+=s[i];
        b+=s[j];
        return sts(i+1,j-1);
    }
    if(dp[i][j-1]>dp[i+1][j]){
        return sts(i,j-1);
    }else return sts(i+1,j);
}
void solve(){
    ll i,j,k,n,l,m,x,y,z,d,r;

   cin>>s;
   n=s.sz;
   // vll aa(26);
   // for(i=0;i<n;i++){
   //     aa[s[i]-'a']++;
   //     if(aa[s[i]-'a']>=100){
   //         for(j=0;j<100;j++){
   //             cout<<s[i];
   //         }
   //         return;
   //     }
   // }
   memset(dp,-1,sizeof(dp));
   ll ans=dpo(0,n-1);
    sts(0,n-1);
    cout<<a;
    reverse(all(b));
    cout<<b<<endl;

}
int main(){
    FS;
    ll i,j,k,n,m,x,y,z,q;
    q=1;
    // cin>>q;
    while(q--){
        solve();
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define FS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long int
#define ld long double
#define pb push_back
#define bp __builtin_popcount
#define sz size()
#define ff first
#define ss second
#define vll vector<ll>
#define vbool vector<bool>
#define vpll vector<pair<ll,ll>>
#define pll pair<ll,ll>
#define vllv vector<vector<ll>>
#define setpri(x) cout<<setprecision(x)<<fixed;
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
#define yesr {cout<<"YES"<<endl;return;}
#define nor {cout<<"NO"<<endl;return;}
// getline (std::cin,name);
ll MOD=1e9+7;
ll ceil1(ll n,ll x){if(n%x==0)return n/x; else return (n/x)+1;}
ll gcd(ll a,ll b){return __gcd(a,b);}
ll lcm(ll a,ll b){return (max(a,b)/gcd(a,b))*min(a,b);}
ll pow1(ll n,ll k,ll mm){
    if(k==0)return 1;
    if(k%2==0)return (pow1((n%mm)*(n%mm),k/2,mm))%mm;
    return ((n%mm)*(pow1((n%mm)*(n%mm),k/2,mm)%mm))%mm;
}
ll pow2(ll n,ll k){ll ans=1;
    while(k>0){
        if(k%2==1)ans=ans*n;n=n*n;k/=2;
    }return ans;
}
ll modinv(ll A,ll M){return pow1(A,M-2,M);}
ll fact(ll n){ll s=1; for(ll i=1;i<=n;i++)s*=i; return s;}
ll factmod(ll n,ll mod){ll s=1; for(ll i=1;i<=n;i++){s*=i;s%=mod;} return s;}
vll fact1tonmod(ll n,ll mod){vll  ans(n+1);ans[0]=ans[1]=1;
    for(ll i=2;i<=n;i++)ans[i]=(ans[i-1]*i)%mod;
    return ans;
}
ll ncrmod(ll n,ll r,ll mod){
    ll ans=((((factmod(n,mod)%mod)*(modinv(factmod(r,mod),mod)%mod))%mod)*(modinv(factmod(n-r,mod),mod)))%mod;
    return ans;
}
ll ncr(ll n,ll r){if(n==1 || r==0)return 1;if(r>n/2)r=n-r;
    ll ans=1;for(ll i=1;i<=r;i++){ans=((ans * n )/i);n--;}return ans;
}
bool isprime(ll n){if(n==1 || (n!=2 && n%2==0))return false; if(n==2)return true;
        for(ll i=3;i<=sqrt(n);i+=2)if(n%i==0)return false; return true; }
bool func(pair<ll,ll> &a,pair<ll,ll> &b ){
    if(a.ff != b.ff)return a.ff < b.ff;
    return a.ss > b.ss;
}
string s;
ll dp[55555][55555];
ll dpo(ll i,ll j){
    if(j<i)return 0;
    ll &ans=dp[i][j];
    if(ans!=-1)return ans;
    if(i==j){
        dp[i][j]=1;
        return 1;
    }
    if(s[i]==s[j]){
        dp[i][j]=2+dpo(i+1,j-1);
        return dp[i][j];
    }

    dp[i][j]=max(dpo(i+1,j),dpo(i,j-1));
    return dp[i][j];
}
string a="",b="";
void sts(ll i,ll j){
    if(j<i)return;
    if(a.sz+b.sz==100)return;
    if(i==j){
        a+=s[i];
        return;
    }
    if(s[i]==s[j]){
        a+=s[i];
        b+=s[j];
        return sts(i+1,j-1);
    }
    if(dp[i][j-1]>dp[i+1][j]){
        return sts(i,j-1);
    }else return sts(i+1,j);
}
void solve(){
    ll i,j,k,n,l,m,x,y,z,d,r;

   cin>>s;
   n=s.sz;
   // vll aa(26);
   // for(i=0;i<n;i++){
   //     aa[s[i]-'a']++;
   //     if(aa[s[i]-'a']>=100){
   //         for(j=0;j<100;j++){
   //             cout<<s[i];
   //         }
   //         return;
   //     }
   // }
   memset(dp,-1,sizeof(dp));
   ll ans=dpo(0,n-1);
    sts(0,n-1);
    cout<<a;
    reverse(all(b));
    cout<<b<<endl;

}
int main(){
    FS;
    ll i,j,k,n,m,x,y,z,q;
    q=1;
    // cin>>q;
    while(q--){
        solve();
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define FS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long int
#define ld long double
#define pb push_back
#define bp __builtin_popcount
#define sz size()
#define ff first
#define ss second
#define vll vector<ll>
#define vbool vector<bool>
#define vpll vector<pair<ll,ll>>
#define pll pair<ll,ll>
#define vllv vector<vector<ll>>
#define setpri(x) cout<<setprecision(x)<<fixed;
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
#define yesr {cout<<"YES"<<endl;return;}
#define nor {cout<<"NO"<<endl;return;}
// getline (std::cin,name);
ll MOD=1e9+7;
ll ceil1(ll n,ll x){if(n%x==0)return n/x; else return (n/x)+1;}
ll gcd(ll a,ll b){return __gcd(a,b);}
ll lcm(ll a,ll b){return (max(a,b)/gcd(a,b))*min(a,b);}
ll pow1(ll n,ll k,ll mm){
    if(k==0)return 1;
    if(k%2==0)return (pow1((n%mm)*(n%mm),k/2,mm))%mm;
    return ((n%mm)*(pow1((n%mm)*(n%mm),k/2,mm)%mm))%mm;
}
ll pow2(ll n,ll k){ll ans=1;
    while(k>0){
        if(k%2==1)ans=ans*n;n=n*n;k/=2;
    }return ans;
}
ll modinv(ll A,ll M){return pow1(A,M-2,M);}
ll fact(ll n){ll s=1; for(ll i=1;i<=n;i++)s*=i; return s;}
ll factmod(ll n,ll mod){ll s=1; for(ll i=1;i<=n;i++){s*=i;s%=mod;} return s;}
vll fact1tonmod(ll n,ll mod){vll  ans(n+1);ans[0]=ans[1]=1;
    for(ll i=2;i<=n;i++)ans[i]=(ans[i-1]*i)%mod;
    return ans;
}
ll ncrmod(ll n,ll r,ll mod){
    ll ans=((((factmod(n,mod)%mod)*(modinv(factmod(r,mod),mod)%mod))%mod)*(modinv(factmod(n-r,mod),mod)))%mod;
    return ans;
}
ll ncr(ll n,ll r){if(n==1 || r==0)return 1;if(r>n/2)r=n-r;
    ll ans=1;for(ll i=1;i<=r;i++){ans=((ans * n )/i);n--;}return ans;
}
bool isprime(ll n){if(n==1 || (n!=2 && n%2==0))return false; if(n==2)return true;
        for(ll i=3;i<=sqrt(n);i+=2)if(n%i==0)return false; return true; }
bool func(pair<ll,ll> &a,pair<ll,ll> &b ){
    if(a.ff != b.ff)return a.ff < b.ff;
    return a.ss > b.ss;
}
bool ispal(string &t){
    for(ll i=0;i<t.sz;i++){
        if(t[i]!=t[t.sz-1-i])return false;
    }
    return true;
}
void solve(){
    ll i,j,k,n,l,m,x,y,z,d,r;

   string s;
   cin>>s;

   n=s.sz;

   vll a(26);
   for(i=0;i<n;i++){
       a[s[i]-'a']++;
       if(a[s[i]-'a']>=100){
           for(j=0;j<100;j++){
               cout<<s[i];
           }
           return;
       }
   }
   string t=s;
   reverse(all(t));
   vector<string> an;
   vector<vector<string>> dpo(n+1,vector<string> (n+1,""));
    ll dp[n+1][n+1];
   memset(dp,0,sizeof(dp));
    for(i=0;i<n;i++){
        string sts="";
        for(j=0;j<n;j++){
            if(s[i]==t[j]){
                dp[i+1][j+1]=dp[i][j]+1;
                   dpo[i+1][j+1]=dpo[i][j]+s[i];
            }else {
                dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
                if((ll)dpo[i][j+1].sz > (ll)dpo[i+1][j].sz){
                    dpo[i+1][j+1]=dpo[i][j+1];
                }else{
                    dpo[i+1][j+1]=dpo[i+1][j];
                }
            }
        }
    }
    ll mxsz=0;
    string ans="";
    for(i=n;i>0;i--){
        for(j=n;j>0;j--){
            if(ispal(dpo[i][j]) && (ll)dpo[i][j].sz<=100 && (ll)dpo[i][j].sz>mxsz){
                mxsz=(ll)dpo[i][j].sz;
                ans=dpo[i][j];
            }
        }
    }
   cout<<ans<<endl;
}
int main(){
    FS;
    ll i,j,k,n,m,x,y,z,q;
    q=1;
    // cin>>q;
    while(q--){
        solve();
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define FS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long int
#define ld long double
#define pb push_back
#define bp __builtin_popcount
#define sz size()
#define ff first
#define ss second
#define vll vector<ll>
#define vbool vector<bool>
#define vpll vector<pair<ll,ll>>
#define pll pair<ll,ll>
#define vllv vector<vector<ll>>
#define setpri(x) cout<<setprecision(x)<<fixed;
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
#define yesr {cout<<"YES"<<endl;return;}
#define nor {cout<<"NO"<<endl;return;}
// getline (std::cin,name);
ll MOD=1e9+7;
ll ceil1(ll n,ll x){if(n%x==0)return n/x; else return (n/x)+1;}
ll gcd(ll a,ll b){return __gcd(a,b);}
ll lcm(ll a,ll b){return (max(a,b)/gcd(a,b))*min(a,b);}
ll pow1(ll n,ll k,ll mm){
    if(k==0)return 1;
    if(k%2==0)return (pow1((n%mm)*(n%mm),k/2,mm))%mm;
    return ((n%mm)*(pow1((n%mm)*(n%mm),k/2,mm)%mm))%mm;
}
ll pow2(ll n,ll k){ll ans=1;
    while(k>0){
        if(k%2==1)ans=ans*n;n=n*n;k/=2;
    }return ans;
}
ll modinv(ll A,ll M){return pow1(A,M-2,M);}
ll fact(ll n){ll s=1; for(ll i=1;i<=n;i++)s*=i; return s;}
ll factmod(ll n,ll mod){ll s=1; for(ll i=1;i<=n;i++){s*=i;s%=mod;} return s;}
vll fact1tonmod(ll n,ll mod){vll  ans(n+1);ans[0]=ans[1]=1;
    for(ll i=2;i<=n;i++)ans[i]=(ans[i-1]*i)%mod;
    return ans;
}
ll ncrmod(ll n,ll r,ll mod){
    ll ans=((((factmod(n,mod)%mod)*(modinv(factmod(r,mod),mod)%mod))%mod)*(modinv(factmod(n-r,mod),mod)))%mod;
    return ans;
}
ll ncr(ll n,ll r){if(n==1 || r==0)return 1;if(r>n/2)r=n-r;
    ll ans=1;for(ll i=1;i<=r;i++){ans=((ans * n )/i);n--;}return ans;
}
bool isprime(ll n){if(n==1 || (n!=2 && n%2==0))return false; if(n==2)return true;
        for(ll i=3;i<=sqrt(n);i+=2)if(n%i==0)return false; return true; }
bool func(pair<ll,ll> &a,pair<ll,ll> &b ){
    if(a.ff != b.ff)return a.ff < b.ff;
    return a.ss > b.ss;
}
string s;
ll dp[3000][3000];
ll dpo(ll i,ll j){
    if(j<i)return 0;
    ll &ans=dp[i][j];
    if(ans!=-1)return ans;
    if(i==j){
        dp[i][j]=1;
        return 1;
    }
    if(s[i]==s[j]){
        dp[i][j]=2+dpo(i+1,j-1);
        return dp[i][j];
    }

    dp[i][j]=max(dpo(i+1,j),dpo(i,j-1));
    return dp[i][j];
}
string a="",b="";
void sts(ll i,ll j){
    if(j<i)return;
    if(a.sz+b.sz==100)return;
    if(i==j){
        a+=s[i];
        return;
    }
    if(s[i]==s[j]){
        a+=s[i];
        b+=s[j];
        return sts(i+1,j-1);
    }
    if(dp[i][j-1]>dp[i+1][j]){
        return sts(i,j-1);
    }else return sts(i+1,j);
}
void solve(){
    ll i,j,k,n,l,m,x,y,z,d,r;

   cin>>s;
   n=s.sz;
   vll aa(26);
   for(i=0;i<n;i++){
       aa[s[i]-'a']++;
       if(aa[s[i]-'a']>=100){
           for(j=0;j<100;j++){
               cout<<s[i];
           }
           return;
       }
   }
   memset(dp,-1,sizeof(dp));
   ll ans=dpo(0,n-1);
    sts(0,n-1);
    cout<<a;
    reverse(all(b));
    cout<<b<<endl;

}
int main(){
    FS;
    ll i,j,k,n,m,x,y,z,q;
    q=1;
    // cin>>q;
    while(q--){
        solve();
    }
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef vector<long long> vl;
typedef pair<long long , long long > pl;
#define po pop_back
#define pb push_back
#define mk make_pair
#define lw lower_bound
#define up upper_bound
#define ff first
#define ss second
#define boost ios_base::sync_with_stdio(); cin.tie(0); cout.tie(0);
#define MOD 1000000007
#define MAX 1e18
#define MIN -1e18
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define per(i,a,b) for(ll i=a;i>=b;i--)
#define con continue
#define freopen freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define PI 3.14159265358979323846264338327950288419716939937510582097494459230781640628
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
//template< typename T>
//using indexed_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
const int N=1e6+1;
ll ans,mid,mn,mx,cnt,m,T,sum,h1,h2,a,b,c[1234567],d[1234567],c1[1234][1234],n,k,i,j,l,x,y,r;
bool used[10000005];
ll dp[2700][2700];
string s;
char res[2700];
map<ll,ll> mp;
ll len;
ll rec(ll x, ll y){
    if (x > y) return 0;
    if (dp[x][y]) return dp[x][y];
    if (x == y) return dp[x][y] = 1;
    if (s[x] == s[y]) return dp[x][y] = rec(x + 1, y - 1) + 2;
    return dp[x][y] = max(rec(x + 1, y), rec(x, y - 1));
}
void trace(ll x, ll y){
    if (x > y) return;
    if (x == y) res[len] = s[x],len++;
    else if (s[x] == s[y]){
        res[len] = s[x],len++;
        trace(x + 1, y - 1);
        res[len] = s[y],len++;
    }
    else{
        if (dp[x+1][y] < dp[x][y-1]) trace(x, y - 1);
        else trace(x + 1, y);
    }
}
int main(){
    cin>>s;
    n=s.size();
    if(n>=2600){
        for(auto x:s){
            mp[x]++;
        }
        rep(i,'a','z'){
            if(mp[i]>=100){
                rep(j,1,100)cout<<char(i);
                exit(0);
            }
        }
    }
    else{
        rec(0, n - 1);
        len = 0;
        trace(0, n - 1);
        if(len <= 100) cout<<res;
        else{
            rep(i,0,49)cout<<res[i];
            rep(i,len-50,len-1)cout<<res[i];
        }
    }
}


/*!enjoy karo yaar!*/

//CF,CC,AtC,SPOJ: hp1999
//HE: hemant269
//HR: hemant2132

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

#define     ll             long long int
#define     int            ll
#define     ld             long double
#define     fast()         ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define     all(x)         x.begin(),x.end()
#define     rz(x)          resize(x)
#define     mem(a,b)       memset(a,b,sizeof(a))
#define     gcd(a,b)       (__gcd((a),(b)))
#define     lcm(a,b)       (((a)*(b))/gcd((a),(b)))
#define     pb             push_back
#define     ins            insert
#define     pii            pair<int,int>
#define     F              first
#define     S              second
#define     makep          make_pair
#define     maket          make_tuple
#define     show(x)        for(auto c:x)cout<<c<<" ";cout<<"\n";
#define     nshow(x,n)     for(int i=0;i<n;++i)cout<<x[i]<<" ";cout<<"\n";
#define     show2(x)       for(auto c:x)cout<<c.F<<" "<<c.S<<"\n";

const ld pi=acos(-1);
const int inf=1e18,M=1e9+7;
const int N=2600;

int dp[N][N];

void solve()
{
    string s;
    cin>>s;

    int n=s.length();

    int a[30]={0};
    for(auto& c:s)
        ++a[c-'a'];

    auto mx=max_element(a,a+30);
    if(*mx>=100)
    {
        int pos=mx-a;
        for(int i=0;i<100;++i)
            cout<<(char)(pos+'a');
        return;
    }

    mem(dp,0);

    for(int i=0;i<n;++i)
        dp[i][i]=1;

    for(int i=0;i+1<n;++i)
    {
        if(s[i]==s[i+1])
            dp[i][i+1]=2;
        else
            dp[i][i+1]=1;
    }

    for(int len=3;len<=n;++len)
    {
        for(int i=0;i+len-1<n;++i)
        {
            int j=i+len-1;

            if(s[i]==s[j])
            {
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
                dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);
            }
            else
            {
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
            }
        }
    }

//    for(int i=0;i<n;++i)
//    {
//        for(int j=0;j<n;++j)
//            cout<<dp[i][j]<<" ";
//        cout<<"\n";
//    }

    int len=dp[0][n-1];
    //cout<<len<<"\n";
    string ans;
    ans.rz(len);

    int x=0,y=n-1,pos=0;
    while(x<=y)
    {
        if(y-x+1>=3)
        {
            if(dp[x][y]==dp[x+1][y-1]+2 && dp[x+1][y-1]+2>max(dp[x+1][y],dp[x][y-1]))
            {
                ans[pos]=s[x];
                ans[len-pos-1]=s[y];
                ++pos;

                ++x,--y;
            }
            else
            {
                if(dp[x+1][y]>dp[x][y-1])
                    ++x;
                else
                    --y;
            }
        }
        else if(y-x+1==2)
        {
            if(s[x]==s[y])
            {
                ans[pos]=s[x];
                ans[len-pos-1]=s[y];

                break;
            }
            else
                ++x;
        }
        else
        {
            ans[pos]=s[x];
            break;
        }
    }

    cout<<ans;
}

int32_t main()
{
    fast();

    int t=1;
    //cin>>t;
    while(t--)
    {
        solve();
        //cout<<"\n";
    }

    return 0;
}


/*!enjoy karo yaar!*/

//CF,CC,AtC,SPOJ: hp1999
//HE: hemant269
//HR: hemant2132

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

#define     ll             long long int
#define     int            ll
#define     ld             long double
#define     fast()         ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define     all(x)         x.begin(),x.end()
#define     rz(x)          resize(x)
#define     mem(a,b)       memset(a,b,sizeof(a))
#define     gcd(a,b)       (__gcd((a),(b)))
#define     lcm(a,b)       (((a)*(b))/gcd((a),(b)))
#define     pb             push_back
#define     ins            insert
#define     pii            pair<int,int>
#define     F              first
#define     S              second
#define     makep          make_pair
#define     maket          make_tuple
#define     show(x)        for(auto c:x)cout<<c<<" ";cout<<"\n";
#define     nshow(x,n)     for(int i=0;i<n;++i)cout<<x[i]<<" ";cout<<"\n";
#define     show2(x)       for(auto c:x)cout<<c.F<<" "<<c.S<<"\n";

const ld pi=acos(-1);
const int inf=1e18,M=1e9+7;
const int N=2600;

int dp[N][N];

void solve()
{
    string s;
    cin>>s;

    int n=s.length();

    int a[30]={0};
    for(auto& c:s)
        ++a[c-'a'];

    auto mx=max_element(a,a+30);
    if(*mx>=100)
    {
        int pos=mx-a;
        for(int i=0;i<100;++i)
            cout<<(char)(pos+'a');
        return;
    }

    mem(dp,0);

    for(int i=0;i<n;++i)
        dp[i][i]=1;

    for(int i=0;i+1<n;++i)
    {
        if(s[i]==s[i+1])
            dp[i][i+1]=2;
        else
            dp[i][i+1]=1;
    }

    for(int len=3;len<=n;++len)
    {
        for(int i=0;i+len-1<n;++i)
        {
            int j=i+len-1;

            if(s[i]==s[j])
            {
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
                dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);
            }
            else
            {
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
            }
        }
    }

//    for(int i=0;i<n;++i)
//    {
//        for(int j=0;j<n;++j)
//            cout<<dp[i][j]<<" ";
//        cout<<"\n";
//    }

    int len=dp[0][n-1];
    //cout<<len<<"\n";
    string ans;
    ans.rz(len);

    int x=0,y=n-1,pos=0;
    while(x<=y)
    {
        if(y-x+1>=3)
        {
            if(dp[x][y]==dp[x+1][y-1]+2 && dp[x+1][y-1]+2>max(dp[x+1][y],dp[x][y-1]))
            {
                ans[pos]=s[x];
                ans[len-pos-1]=s[y];
                ++pos;

                ++x,--y;
            }
            else
            {
                if(dp[x+1][y]>dp[x][y-1])
                    ++x;
                else
                    --y;
            }
        }
        else if(y-x+1==2)
        {
            if(s[x]==s[y])
            {
                ans[pos]=s[x];
                ans[len-pos-1]=s[y];

                break;
            }
            else
                ++x;
        }
        else
        {
            ans[pos]=s[x];
            break;
        }
    }

    if(len<=100)
        cout<<ans;
    else
    {
        for(int i=0;i<len;++i)
        {
            if(i<50 || len-50<=i)
                cout<<ans[i];
        }
    }
}

int32_t main()
{
    fast();

    int t=1;
    //cin>>t;
    while(t--)
    {
        solve();
        //cout<<"\n";
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int table[100][100],k;
int main()
{

    string s1,s2;
cin>>s1;
    s2=s1;
    reverse(s1.begin(),s1.end());
    for(int i=1;i<=s1.size();i++)
    {
        for(int j=1;j<=s2.size();j++)
        {
            if(s1[i-1]==s2[j-1])
            {
                table[i][j]=1+table[i-1][j-1];
            }
            else
            {
                table[i][j]=max(table[i-1][j],table[i][j-1]);
            }
        }
    }

    string s3="";
    int i,j;
    i=s1.size();
j=s2.size();
    while(i!=0&&j!=0)
    {
        if(s1[i-1]==s2[j-1])
        {
            s3=s1[i-1]+s3;
            i--;
            j--;

        }
        else if(table[i-1][j]>table[i][j-1])
            i--;
        else j--;

    }
    cout<<s3;
}


#include <bits/stdc++.h>
using namespace std;
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
map<char, int> mp;
int dp[2601][2601];
int main(){
	IOS
	string s;
	cin>>s;
	int n=s.size();
	for(int i=0;i<s.size();i++){
		mp[s[i]]++;
		if(mp[s[i]]==100){
			while(mp[s[i]]--){
				cout<<s[i];
			}
			return 0;
		}
	}
	for(int i=0;i<=n;i++){
		dp[i][i]=1;
	}
	for(int len=2;len<=n;len++){
		for(int l=0;l+len-1<n;l++){
			int r=l+len-1;
			if(s[l]==s[r]){
				dp[l][r]=2+dp[l+1][r-1];
			}
			else{
				dp[l][r]=max(dp[l][r-1],dp[l+1][r]);
			}
		}
	}
	int l=0,r=n-1;
	string ans="";
	char c='1';
	while(l<r&&ans.size()<50){
		if(s[l]==s[r]){
			ans+=s[l];
			l++;
			r--;
		}
		else if(dp[l+1][r]>dp[l][r-1]){
			l++;
		}
		else{
			r--;
		}
	}
	if(l==r&&s[l]==s[r]&&ans.size()<50){
		c=s[l];
	}
	cout<<ans;
	reverse(ans.begin(),ans.end());
	if(c!='1'){
		cout<<c;
	}
	cout<<ans;
	return 0;
}
/*

*/


#include <bits/stdc++.h>
using namespace std;
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
map<char, int> mp;
int dp[2601][2601];
int main(){
	IOS
	string s;
	cin>>s;
	int n=s.size();
	for(int i=0;i<s.size();i++){
		mp[s[i]]++;
		if(mp[s[i]]==100){
			while(mp[s[i]]--){
				cout<<s[i];
			}
			return 0;
		}
	}
	for(int i=0;i<=n;i++){
		dp[i][i]=1;
	}
	for(int len=2;len<=n;len++){
		for(int l=0;l+len-1<n;l++){
			int r=l+len-1;
			if(s[l]==s[r]){
				dp[l][r]=2+dp[l+1][r-1];
			}
			else{
				dp[l][r]=max(dp[l][r-1],dp[l+1][r]);
			}
		}
	}
	int l=0,r=n-1;
	string ans="";
	char c='1';
	while(l<r&&ans.size()<50){
		if(s[l]==s[r]){
			ans+=s[l];
			l++;
			r--;
		}
		else if(dp[l+1][r]>dp[l][r-1]){
			l++;
		}
		else{
			r--;
		}
	}
	if(l==r&&s[l]==s[r]){
		c=s[l];
	}
	cout<<ans;
	reverse(ans.begin(),ans.end());
	if(c!='1'){
		cout<<c;
	}
	cout<<ans;
	return 0;
}
/*

*/


#include <bits/stdc++.h>
using namespace std;
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
map<char, int> mp;
int dp[2601][2601];
int main(){
	IOS
	string s;
	cin>>s;
	int n=s.size();
	for(int i=0;i<s.size();i++){
		mp[s[i]]++;
		if(mp[s[i]]==100){
			while(mp[s[i]]--){
				cout<<s[i];
			}
			return 0;
		}
	}
	for(int i=0;i<=n;i++){
		dp[i][i]=1;
	}
	for(int len=2;len<=n;len++){
		for(int l=0;l+len-1<n;l++){
			int r=l+len-1;
			if(s[l]==s[r]){
				dp[l][r]=2+dp[l+1][r-1];
			}
			else{
				dp[l][r]=max(dp[l][r-1],dp[l+1][r]);
			}
		}
	}
	int l=0,r=n-1;
	string ans="";
	char c='1';
	while(l<r&&ans.size()<50){
		if(s[l]==s[r]){
			ans+=s[l];
			l++;
			r--;
		}
		else if(dp[l+1][r]>dp[l][r-1]){
			l++;
		}
		else{
			r--;
		}
		if(l==r&&s[l]==s[r]){
			c=s[l];
		}
	}
	cout<<ans;
	reverse(ans.begin(),ans.end());
	if(c!='1'){
		cout<<c;
	}
	cout<<ans;
	return 0;
}
/*

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   if (n < 2600)
   {
      l = 1, r = n;
      s = "%" + s;
      for (int i = 1;i <= n;++i)
         g[s[i]].push_back(i);
      for (char c = 'a';c <= 'z';++c)
      {
         p[c].L = 0;
         p[c].R = g[c].size() - 1;
      }
      /**
         p[c].L is left iterator of positions of c
         p[c].R is right iterator of positions of c
         size(c) is count of non-seen c elements
         dist(c) is distance between s[p[c].R] and s[p[c].L] elements
         g[s[i]].size() is number of non-seen s[i] elements
         g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
         g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
         size(c) = g[s[i]].size()
      */
      while (l <= r)
      {
         if (s[l] != s[r])
         {
            if (size(s[l]) == 1 && size(s[r]) > 1)
            {
               p[s[l]].L++;
               l++;
            }
            else if (size(s[l]) >= 1 && size(s[r]) == 1)
            {
               p[s[r]].R--;
               r--;
            }
            else if (size(s[l]) & 1)
            {
               p[s[l]].L++;
               l++;
            }
            else if (size(s[r]) & 1)
            {
               p[s[r]].R--;
               r--;
            }
            else
            {
               ll Ldist = dist(s[l]);
               ll Rdist = dist(s[r]);
               if (Ldist < Rdist)
               {
                  p[s[l]].L++;
                  l++;
               }
               else if (Ldist > Rdist)
               {
                  p[s[r]].R--;
                  r--;
               }
            }
         }
         else
         {
            if (l == r)
            {
               ans += s[l];
               p[s[l]].L++;
            }
            else
            {
               ans += s[l];
               rans += s[r];
               p[s[l]].R--;
               p[s[l]].L++;
            }
            l++;
            r--;
         }
      }
      reverse(rans.begin(), rans.end());
      string out = ans + rans;
      cout << out;
   }
   else
   {
      cout << string(100, 'a');
   }
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (int i = 1;i <= n;++i)
   {
      p[s[i]].L = 0;
      p[s[i]].R = g[s[i]].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   if (out.length() < 100)
      cout << out;
   else
      cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

int dp[3333][3333];
int len = 0;
string ans(3333, ' ');
string s;

int Len(int l, int r){
   if (l > r)
      return 0;
   if (dp[l][r])
      return dp[l][r];
   if (l == r)
      return dp[l][r] = 1;
   if (s[l] == s[r])
      return dp[l][r] = Len(l + 1, r - 1) + 2;
   return dp[l][r] = max(Len(l + 1, r), Len(l, r - 1));
}

void rec(int l, int r){
   if (l > r)
      return;
   if (l == r)
      ans[len++] = s[l];
   else if (s[l] == s[r])
   {
      ans[len++] = s[l];
      rec(l + 1, r - 1);
      ans[len++] = s[r];
   }
   else
   {
      if (dp[l + 1][r] < dp[l][r - 1])
         rec(l, r - 1);
      else
         rec(l + 1, r);
   }
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   int n = s.size();
   if (n < 2600)
   {
      Len(0, n - 1);
      rec(0, n - 1);
      if (len <= 100)
      {
         cout << ans.substr(0, len);
      }
      else
      {
         cout << ans.substr(0, 50) << ans.substr(len - 50, 50);
      }
   }
   else
   {
      vector<int> c(28, 0);
      for(auto it : s)
      {
         c[it - 'a']++;
      }
      for (int i = 0;i <= 26;++i)
      {
         if (c[i] >= 100)
         {
            cout << string(100, i + 'a');
            return 0;
         }
      }
   }
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   string s;
   cin >> s;
   int n = s.length();
   s = "#" + s;
   vector<int> g[222];
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   int l = 1, r = n;
   string ans = "", rans = "";
   while (l <= r)
   {
//      cout << "INF\n";
//      cout << l << " " << r << " \n";
      if (s[l] != s[r])
      {
         if (g[s[l]].size() == 1 && g[s[r]].size() > 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[l]].size() >= 1 && g[s[r]].size() == 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else if (g[s[l]].size() & 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[r]].size() & 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else
         {
            ll Ldist = 1ll * abs(*g[s[l]].begin() - *--g[s[l]].end());
            ll Rdist = 1ll * abs(*g[s[r]].begin() - *--g[s[r]].end());
            if (Ldist <= Rdist)
            {
               g[s[l]].erase(g[s[l]].begin());
               l++;
            }
            else if (Ldist > Rdist)
            {
               g[s[r]].erase(--g[s[r]].end());
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            g[s[l]].erase(g[s[l]].begin());
         }
         else
         {
            ans += s[l];
            rans += s[r];
            g[s[l]].erase(--g[s[l]].end());
            g[s[l]].erase(g[s[l]].begin());
         }
         l++;
         r--;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   if (out.length() < 100)
      cout << out;
   else
      cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (char c = 'a';c <= 'z';++c)
   {
      p[c].L = 0;
      p[c].R = g[c].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
      if (ans.size() + rans.size() > 100)
      {
         reverse(rans.begin(), rans.end());
         string out = ans + rans;
         cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
         return 0;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   cout << out;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (char c = 'a';c <= 'z';++c)
   {
      p[c].L = 0;
      p[c].R = g[c].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
      if (ans.size() + rans.size() == 100)
      {
         reverse(rans.begin(), rans.end());
         string out = ans + rans;
         cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
         return 0;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   cout << out;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (char c = 'a';c <= 'z';++c)
   {
      p[c].L = 0;
      p[c].R = g[c].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
      if (ans.size() + rans.size() >= 100)
      {
         reverse(rans.begin(), rans.end());
         string out = ans + rans;
         cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
         return 0;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   cout << out;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   string s;
   cin >> s;
   int n = s.length();
   s = "#" + s;
   vector<int> g[222];
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   int l = 1, r = n;
   string ans = "", rans = "";
   while (l <= r)
   {
//      cout << "INF\n";
//      cout << l << " " << r << " \n";
      if (s[l] != s[r])
      {
         if (g[s[l]].size() == 1 && g[s[r]].size() > 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[l]].size() >= 1 && g[s[r]].size() == 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else if (g[s[l]].size() & 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[r]].size() & 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else
         {
            ll Ldist = 1ll * abs(*g[s[l]].begin() - *--g[s[l]].end());
            ll Rdist = 1ll * abs(*g[s[r]].begin() - *--g[s[r]].end());
            if (Ldist < Rdist)
            {
               g[s[l]].erase(g[s[l]].begin());
               l++;
            }
            else if (Ldist > Rdist)
            {
               g[s[r]].erase(--g[s[r]].end());
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            g[s[l]].erase(g[s[l]].begin());
         }
         else
         {
            ans += s[l];
            rans += s[r];
            g[s[l]].erase(--g[s[l]].end());
            g[s[l]].erase(g[s[l]].begin());
         }
         l++;
         r--;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   if (out.length() < 100)
      cout << out;
   else
      cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (char c = 'a';c <= 'z';++c)
   {
      p[c].L = 0;
      p[c].R = g[c].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   if (out.length() < 100)
      cout << out;
   else
      cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   string s;
   cin >> s;
   int n = s.length();
   s = "#" + s;
   vector<int> g[222];
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   int l = 1, r = n;
   string ans = "", rans = "";
   while (l <= r)
   {
//      cout << "INF\n";
//      cout << l << " " << r << " \n";
      if (s[l] != s[r])
      {
         if (g[s[l]].size() == 1 && g[s[r]].size() > 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[l]].size() >= 1 && g[s[r]].size() == 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else if (g[s[l]].size() & 1)
         {
            g[s[l]].erase(g[s[l]].begin());
            l++;
         }
         else if (g[s[r]].size() & 1)
         {
            g[s[r]].erase(--g[s[r]].end());
            r--;
         }
         else
         {
            ll Ldist = 1ll * abs(*g[s[l]].begin() - *--g[s[l]].end());
            ll Rdist = 1ll * abs(*g[s[r]].begin() - *--g[s[r]].end());
            if (Ldist < Rdist)
            {
               g[s[l]].erase(g[s[l]].begin());
               l++;
            }
            else if (Ldist >= Rdist)
            {
               g[s[r]].erase(--g[s[r]].end());
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            g[s[l]].erase(g[s[l]].begin());
         }
         else
         {
            ans += s[l];
            rans += s[r];
            g[s[l]].erase(--g[s[l]].end());
            g[s[l]].erase(g[s[l]].begin());
         }
         l++;
         r--;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   if (out.length() < 100)
      cout << out;
   else
      cout << out.substr(0, 50) + out.substr(s.length() - 51, 50);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   if (n < 2600)
   {
      l = 1, r = n;
      s = "%" + s;
      for (int i = 1;i <= n;++i)
         g[s[i]].push_back(i);
      for (char c = 'a';c <= 'z';++c)
      {
         p[c].L = 0;
         p[c].R = g[c].size() - 1;
      }
      /**
         p[c].L is left iterator of positions of c
         p[c].R is right iterator of positions of c
         size(c) is count of non-seen c elements
         dist(c) is distance between s[p[c].R] and s[p[c].L] elements
         g[s[i]].size() is number of non-seen s[i] elements
         g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
         g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
         size(c) = g[s[i]].size()
      */
      while (l <= r)
      {
         if (s[l] != s[r])
         {
            if (size(s[l]) == 1 && size(s[r]) > 1)
            {
               p[s[l]].L++;
               l++;
            }
            else if (size(s[l]) >= 1 && size(s[r]) == 1)
            {
               p[s[r]].R--;
               r--;
            }
            else if (size(s[l]) & 1)
            {
               p[s[l]].L++;
               l++;
            }
            else if (size(s[r]) & 1)
            {
               p[s[r]].R--;
               r--;
            }
            else
            {
               ll Ldist = dist(s[l]);
               ll Rdist = dist(s[r]);
               if (Ldist < Rdist)
               {
                  p[s[l]].L++;
                  l++;
               }
               else if (Ldist > Rdist)
               {
                  p[s[r]].R--;
                  r--;
               }
            }
         }
         else
         {
            if (l == r)
            {
               ans += s[l];
               p[s[l]].L++;
            }
            else
            {
               ans += s[l];
               rans += s[r];
               p[s[l]].R--;
               p[s[l]].L++;
            }
            l++;
            r--;
         }
         if (ans.size() + rans.size() == 100)
         {
            reverse(rans.begin(), rans.end());
            string out = ans + rans;
            cout << out << "\n";
            return 0;
         }
      }
      reverse(rans.begin(), rans.end());
      string out = ans + rans;
      cout << out;
   }
   else
   {
      cout << string(100, 'j');
   }
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
using ll = long long;

const int maxin = 2e5 + 10;
const int inf = INT_MAX - 10;
const ll llinf = LLONG_MAX - 10;

struct pos
{
   int L, R;
};

vector<int> g[222];
vector<pos> p(222);
string s, ans, rans;
int n, l, r;

int dist(char c)
{
   return g[c][p[c].R] - g[c][p[c].L];
}

int size(char c)
{
   return p[c].R - p[c].L + 1;
}

main ()
{
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   if (fopen("in.in", "r"))
   {
      freopen("in.in", "r", stdin);
      freopen("out.out", "w", stdout);
   }
   cin >> s;
   n = s.length();
   l = 1, r = n;
   s = "%" + s;
   for (int i = 1;i <= n;++i)
      g[s[i]].push_back(i);
   for (char c = 'a';c <= 'z';++c)
   {
      p[c].L = 0;
      p[c].R = g[c].size() - 1;
   }
   /**
      p[c].L is left iterator of positions of c
      p[c].R is right iterator of positions of c
      size(c) is count of non-seen c elements
      dist(c) is distance between s[p[c].R] and s[p[c].L] elements
      g[s[i]].size() is number of non-seen s[i] elements
      g[s[i]].erase(g[s[i]].begin()) is equals to move l pointer
      g[s[i]].erase(--g[s[i]].end()) is equals to move r pointer
      size(c) = g[s[i]].size()
   */
   while (l <= r)
   {
      if (s[l] != s[r])
      {
         if (size(s[l]) == 1 && size(s[r]) > 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[l]) >= 1 && size(s[r]) == 1)
         {
            p[s[r]].R--;
            r--;
         }
         else if (size(s[l]) & 1)
         {
            p[s[l]].L++;
            l++;
         }
         else if (size(s[r]) & 1)
         {
            p[s[r]].R--;
            r--;
         }
         else
         {
            ll Ldist = dist(s[l]);
            ll Rdist = dist(s[r]);
            if (Ldist < Rdist)
            {
               p[s[l]].L++;
               l++;
            }
            else if (Ldist > Rdist)
            {
               p[s[r]].R--;
               r--;
            }
         }
      }
      else
      {
         if (l == r)
         {
            ans += s[l];
            p[s[l]].L++;
         }
         else
         {
            ans += s[l];
            rans += s[r];
            p[s[l]].R--;
            p[s[l]].L++;
         }
         l++;
         r--;
      }
      if (ans.size() + rans.size() == 100)
      {
         reverse(rans.begin(), rans.end());
         string out = ans + rans;
         cout << out << "\n";
         return 0;
      }
   }
   reverse(rans.begin(), rans.end());
   string out = ans + rans;
   cout << out;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < n; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  string lmao = res;
  if(res.size() % 2 == 0){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  if(f(0, n - 1) == 1){
    cout << s[0];
    return 0;
  }
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  cout << res << endl;
  string lmao = res;
  if(res.size() % 2 == 0){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  if(res.size() > 100){
    string a = res.substr(0, 50);
    string b = a;
    reverse(all(b));
    a += b;
    res = a;
  }
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  if(f(0, n - 1) == 1){
    cout << s[0];
    return 0;
  }
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  string lmao = res;
  if(res.size() % 2 == 0){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  if(res.size() > 100){
    string a = res.substr(0, 50);
    string b = a;
    reverse(all(b));
    a += b;
    res = a;
  }
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  string s;
  int n;
  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  vector <vi> dp(n, vi(n));
  vector <vector<ii>> choice(n, vector<ii>(n));
  for(int i = 0; i < n; i++){
    dp[i][i] = 1;
    choice[i][i] = {i - 1, i + 1};
  }
  for(int i = 0; i < n; i++){
    for(int j = i - 1; j >= 0; j--){ // [j, i]
      if(s[i] == s[j]){
        dp[i][j] = 2 + (i - 1 < j + 1 ? 0 : dp[i - 1][j + 1]);
        choice[i][j] = {i - 1, j + 1};
      }
      else{
        if(dp[i][j] < dp[i - 1][j]){
          dp[i][j] = dp[i - 1][j];
          choice[i][j] = {i - 1, j};
        }
        if(dp[i][j] < dp[i][j + 1]){
          dp[i][j] = dp[i][j + 1];
          choice[i][j] = {i, j + 1};
        }
      }
    }
  }
  string res = "";
  ii x = {n - 1, 0};
  while(x.first >= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  string lmao = res;
  if(dp[n - 1][0] % 2 == 1){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  if(res.size() > 100){
    string a = res.substr(0, 50);
    string b = a;
    reverse(all(b));
    a += b;
    res = a;
  }
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  string lmao = res;
  if(res.size() % 2 == 0){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  if(res.size() > 100){
    string a = res.substr(0, 50);
    string b = a;
    reverse(all(b));
    a += b;
    res = a;
  }
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  if(f(0, n - 1) == 1){
    cout << s[0];
    return 0;
  }
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  //cout << res << endl;
  string lmao = res;
  if(f(0, n - 1) % 2 == 1){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  if(res.size() > 100){
    string a = res.substr(0, 50);
    string b = a;
    reverse(all(b));
    a += b;
    res = a;
  }
  cout << res;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
#include <stack>
#include <iomanip>
using namespace std;
#define all(x) x.begin(), x.end()
typedef vector <int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef long double ld;
const int mod = 1e9 + 7;
const ll inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }

string s;
int n;
const int maxn = 2600;
int dp[maxn][maxn];
ii choice[maxn][maxn];

int f(int i, int j){
  if(i == j){
    choice[i][j] = {i + 1, j - 1};
    return 1;
  }
  if(i > j) return 0;
  if(dp[i][j] != -1) return dp[i][j];
  if(s[i] == s[j]){
    dp[i][j] = 2 + f(i + 1, j - 1);
    choice[i][j] = {i + 1, j - 1};
  }
  else{
    if(dp[i][j] < f(i + 1, j)){
      dp[i][j] = f(i + 1, j);
      choice[i][j] = {i + 1, j};
    }
    if(dp[i][j] < f(i, j - 1)){
      dp[i][j] = f(i, j - 1);
      choice[i][j] = {i, j - 1};
    }
  }
  return dp[i][j];
}

int main(){
  ios_base::sync_with_stdio(false); cin.tie(0);
  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  cin >> s;
  n = s.size();
  if(n >= 2600){
    for(int i = 0; i < 26; i++){
      int cnt = 0;
      for(char c : s){
        if(c == char('a' + i)){
          cnt++;
        }
      }
      if(cnt >= 100){
        for(int j = 0; j < 100; j++){
          cout << char('a' + i);
        }
        return 0;
      }
    }
  }
  memset(dp, -1, sizeof dp);
  f(0, n - 1);
  ii x = {0, n - 1};
  string res = "";
  while(x.first <= x.second){
    if(s[x.first] == s[x.second]){
      res += s[x.first];
    }
    x = choice[x.first][x.second];
  }
  string lmao = res;
  if(res.size() % 2 == 0){
    lmao.pop_back();
  }
  reverse(all(lmao));
  res += lmao;
  cout << res;
}


/* be name khoda */

// #define stream_enable
// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <iomanip>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;

#ifdef stream_enable
#define cin sss
#endif
#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

const ll MOD = 1000000007;
const long long BIG = 1446803456761533460;
const int Big = 336860180;

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

#define debug(x) cout << #x << " -> " << (x) << endl;
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl;
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl;
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl;
#define debugp(x) cout << #x << " -> " << "(" << (x).F << ", " << (x).S << ")" << endl;
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugap(x, n) cout << #x << " ->\n"; fori (i1_dap, n) { cout << "(" << (x)[i1_dap].F << ", " << (x)[i1_dap].S << ")\n"; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl
#define debugav(x, n) cout << #x << " ->\n"; fori (i1_dav, n) { fori (i2_dav, (x)[i1_dav].size()) { cout << (x)[i1_dav][i2_dav] << ' '; } cout << '\n'; } cout << endl
#define debugia(x, n) cout << #x << " ->\n"; fori (i1_dia, n) { cout << i1_dia << " : " << (x)[i1_dia] << '\n'; } cout << endl

#define forifrom(i, s, n) for(ll i = (s); i < (n); ++i)
#define forirto(i, n, e) for(ll i = (n) - 1; i >= (e); --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define Add(a, b) a = (a + (b)) % MOD
#define Mul(a, b) a = (a * (b)) % MOD

stringstream sss;

// -----------------------------------------------------------------------

const ll maxn = 50010;
const ll maxk = 55;
const ll E = 26;

ll n;
string A, res;
vi idxs[E];
ll dp[maxk][maxn];
ll dpi[maxk][maxn];

void MAIN() {

    cin >> A; n = A.size();
    if (n == 2 && A[0] == A[1] || n == 1) {
        cout << A << '\n'; return;
    } else if (n <= 2) {
        cout << A[0] << '\n'; return;
    }
    fori (i, n) {
        idxs[A[i] - 'a'].eb(i);
    }
    memset(dp[0], -1, sizeof dp);
    fori (i, maxk - 1) {
        dp[i + 1][n] = n;
        forir (j, n) {
            dp[i + 1][j] = dp[i + 1][j + 1];
            dpi[i + 1][j] = dpi[i + 1][j + 1];
            auto it = upper_bound(all(idxs[A[j] - 'a']), dp[i][j + 1]);
            if (it != idxs[A[j] - 'a'].end() && *it < j && *it < dp[i + 1][j]) {
                dp[i + 1][j] = *it;
                dpi[i + 1][j] = j;
            }
        }
    }
    forir (i, maxk) {
        fori (j, n - 2) {
            if (i * 2 + 1 <= 100 && dp[i][j + 2] <= j) {
                ll x = dpi[i][j + 2];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res << A[j + 1];
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
        fori (j, n - 1) {
            if (i * 2 <= 100 && dp[i][j + 1] <= j) {
                ll x = dpi[i][j + 1];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res;
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
    }

}

// -----------------------------------------------------------------------

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    sss << R"(
rquwmzexectvnbanemsmdufrg
    )";
    MAIN();
    return 0;
}


/* be name khoda */

// #define stream_enable
// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <iomanip>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;

#ifdef stream_enable
#define cin sss
#endif
#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

const ll MOD = 1000000007;
const long long BIG = 1446803456761533460;
const int Big = 336860180;

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

#define debug(x) cout << #x << " -> " << (x) << endl;
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl;
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl;
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl;
#define debugp(x) cout << #x << " -> " << "(" << (x).F << ", " << (x).S << ")" << endl;
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugap(x, n) cout << #x << " ->\n"; fori (i1_dap, n) { cout << "(" << (x)[i1_dap].F << ", " << (x)[i1_dap].S << ")\n"; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl
#define debugav(x, n) cout << #x << " ->\n"; fori (i1_dav, n) { fori (i2_dav, (x)[i1_dav].size()) { cout << (x)[i1_dav][i2_dav] << ' '; } cout << '\n'; } cout << endl
#define debugia(x, n) cout << #x << " ->\n"; fori (i1_dia, n) { cout << i1_dia << " : " << (x)[i1_dia] << '\n'; } cout << endl

#define forifrom(i, s, n) for(ll i = (s); i < (n); ++i)
#define forirto(i, n, e) for(ll i = (n) - 1; i >= (e); --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define Add(a, b) a = (a + (b)) % MOD
#define Mul(a, b) a = (a * (b)) % MOD

stringstream sss;

// -----------------------------------------------------------------------

const ll maxn = 50010;
const ll maxk = 52;
const ll E = 26;

ll n;
string A, res;
vi idxs[E];
ll dp[maxk][maxn];
ll dpi[maxk][maxn];

void MAIN() {

    cin >> A; n = A.size();
    if (n == 2 && A[0] == A[1] || n == 1) {
        cout << A << '\n'; return;
    } else if (n <= 2) {
        cout << A[0] << '\n'; return;
    }
    fori (i, n) {
        idxs[A[i] - 'a'].eb(i);
    }
    memset(dp[0], -1, sizeof dp);
    fori (i, maxk - 1) {
        dp[i + 1][n] = n;
        forir (j, n) {
            dp[i + 1][j] = dp[i + 1][j + 1];
            dpi[i + 1][j] = dpi[i + 1][j + 1];
            auto it = upper_bound(all(idxs[A[j] - 'a']), dp[i][j + 1]);
            if (it != idxs[A[j] - 'a'].end() && *it < j && *it < dp[i + 1][j]) {
                dp[i + 1][j] = *it;
                dpi[i + 1][j] = j;
            }
        }
    }
    forir (i, maxk) {
        fori (j, n - 2) {
            if (i * 2 + 1 <= 100 && dp[i][j + 2] <= j) {
                ll x = dpi[i][j + 2];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res << A[j + 1];
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
        fori (j, n - 1) {
            if (dp[i][j + 1] <= j) {
                ll x = dpi[i][j + 1];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res;
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
    }

}

// -----------------------------------------------------------------------

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    sss << R"(
rquwmzexectvnbanemsmdufrg
    )";
    MAIN();
    return 0;
}


/* be name khoda */

// #define stream_enable
// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <iomanip>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;

#ifdef stream_enable
#define cin sss
#endif
#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

const ll MOD = 1000000007;
const long long BIG = 1446803456761533460;
const int Big = 336860180;

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

#define debug(x) cout << #x << " -> " << (x) << endl;
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl;
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl;
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl;
#define debugp(x) cout << #x << " -> " << "(" << (x).F << ", " << (x).S << ")" << endl;
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugap(x, n) cout << #x << " ->\n"; fori (i1_dap, n) { cout << "(" << (x)[i1_dap].F << ", " << (x)[i1_dap].S << ")\n"; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl
#define debugav(x, n) cout << #x << " ->\n"; fori (i1_dav, n) { fori (i2_dav, (x)[i1_dav].size()) { cout << (x)[i1_dav][i2_dav] << ' '; } cout << '\n'; } cout << endl
#define debugia(x, n) cout << #x << " ->\n"; fori (i1_dia, n) { cout << i1_dia << " : " << (x)[i1_dia] << '\n'; } cout << endl

#define forifrom(i, s, n) for(ll i = (s); i < (n); ++i)
#define forirto(i, n, e) for(ll i = (n) - 1; i >= (e); --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define Add(a, b) a = (a + (b)) % MOD
#define Mul(a, b) a = (a * (b)) % MOD

stringstream sss;

// -----------------------------------------------------------------------

const ll maxn = 50010;
const ll maxk = 55;
const ll E = 26;

ll n;
string A, res;
vi idxs[E];
ll dp[maxk][maxn];
ll dpi[maxk][maxn];

void MAIN() {

    cin >> A; n = A.size();
    if (n == 2 && A[0] != A[1] || n == 1) {
        cout << A[0] << '\n'; return;
    }
    fori (i, n) {
        idxs[A[i] - 'a'].eb(i);
    }
    memset(dp[0], -1, sizeof dp);
    fori (i, maxk - 1) {
        dp[i + 1][n] = n;
        forir (j, n) {
            dp[i + 1][j] = dp[i + 1][j + 1];
            dpi[i + 1][j] = dpi[i + 1][j + 1];
            auto it = upper_bound(all(idxs[A[j] - 'a']), dp[i][j + 1]);
            if (it != idxs[A[j] - 'a'].end() && *it < j && *it < dp[i + 1][j]) {
                dp[i + 1][j] = *it;
                dpi[i + 1][j] = j;
            }
        }
    }
    forir (i, maxk) {
        fori (j, n - 2) {
            if (i * 2 + 1 <= 100 && dp[i][j + 2] <= j) {
                ll x = dpi[i][j + 2];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x + 1];
                }
                reverse(all(res));
                cout << res << A[j + 1];
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
        fori (j, n - 1) {
            if (i * 2 <= 100 && dp[i][j + 1] <= j) {
                ll x = dpi[i][j + 1];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x + 1];
                }
                reverse(all(res));
                cout << res;
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
    }

}

// -----------------------------------------------------------------------

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    sss << R"(
oitruioueteriotuertoierutoerit
rquwmzexectvnbanemsmdufrg
    )";
    MAIN();
    return 0;
}


/* be name khoda */

// #define stream_enable
// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <iomanip>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;

#ifdef stream_enable
#define cin sss
#endif
#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

const ll MOD = 1000000007;
const long long BIG = 1446803456761533460;
const int Big = 336860180;

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

#define debug(x) cout << #x << " -> " << (x) << endl;
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl;
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl;
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl;
#define debugp(x) cout << #x << " -> " << "(" << (x).F << ", " << (x).S << ")" << endl;
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugap(x, n) cout << #x << " ->\n"; fori (i1_dap, n) { cout << "(" << (x)[i1_dap].F << ", " << (x)[i1_dap].S << ")\n"; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl
#define debugav(x, n) cout << #x << " ->\n"; fori (i1_dav, n) { fori (i2_dav, (x)[i1_dav].size()) { cout << (x)[i1_dav][i2_dav] << ' '; } cout << '\n'; } cout << endl
#define debugia(x, n) cout << #x << " ->\n"; fori (i1_dia, n) { cout << i1_dia << " : " << (x)[i1_dia] << '\n'; } cout << endl

#define forifrom(i, s, n) for(ll i = (s); i < (n); ++i)
#define forirto(i, n, e) for(ll i = (n) - 1; i >= (e); --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define Add(a, b) a = (a + (b)) % MOD
#define Mul(a, b) a = (a * (b)) % MOD

stringstream sss;

// -----------------------------------------------------------------------

const ll maxn = 50010;
const ll maxk = 52;
const ll E = 26;

ll n;
string A, res;
vi idxs[E];
ll dp[maxk][maxn];
ll dpi[maxk][maxn];

void MAIN() {

    cin >> A; n = A.size();
    fori (i, n) {
        idxs[A[i] - 'a'].eb(i);
    }
    memset(dp[0], -1, sizeof dp);
    fori (i, maxk - 1) {
        dp[i + 1][n] = n;
        forir (j, n) {
            dp[i + 1][j] = dp[i + 1][j + 1];
            dpi[i + 1][j] = dpi[i + 1][j + 1];
            auto it = upper_bound(all(idxs[A[j] - 'a']), dp[i][j + 1]);
            if (it != idxs[A[j] - 'a'].end() && *it < j && *it < dp[i + 1][j]) {
                dp[i + 1][j] = *it;
                dpi[i + 1][j] = j;
            }
        }
    }
    forir (i, maxk) {
        fori (j, n - 2) {
            if (i * 2 + 1 <= 100 && dp[i][j + 2] <= j) {
                ll x = dpi[i][j + 2];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res << A[j + 1];
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
        fori (j, n - 1) {
            if (dp[i][j + 1] <= j) {
                ll x = dpi[i][j + 1];
                forir (k, i) {
                    res.pb(A[x]);
                    x = dpi[k][x];
                }
                reverse(all(res));
                cout << res;
                reverse(all(res));
                cout << res << '\n';
                return;
            }
        }
    }

}

// -----------------------------------------------------------------------

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    sss << R"(
rquwmzexectvnbanemsmdufrg
    )";
    MAIN();
    return 0;
}


#include <chrono>

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <cmath>
#include <time.h>
#include <random>
#include <string>
#include <cassert>
#include <vector>
#include <ostream>
#include <istream>
#include <stack>
#include <deque>
#include <queue>
#include <functional>

using namespace std;

#define int long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define pii pair<int, int>
#define ld long double

ostream& operator << (ostream &a, const vector<int> &b) {
    for (auto k : b) cout << k << " ";
    return a;
}

#ifdef LOCAL
    #define dbg(x) cout << #x << " : " << (x) << "\n";
    const int INF = 1e18;
    const int mod = 2600000069;
    const int p = 10;
//    const ld PI = 3.1415926535;
#else
    #define dbg(x)
    const int INF = 1e18;
    const int mod = 2600000069;
    const int p = 179;
//    const ld PI = 3.1415926535;
#endif

//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,sse3,sse4")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("fast-math")
//#pragma GCC target("avx2")
//#pragma GCC optimize("section-anchors")
//#pragma GCC optimize("profile-values,profile-reorder-functions,tracer")
//#pragma GCC optimize("vpt")
//#pragma GCC optimize("rename-registers")
//#pragma GCC optimize("move-loop-invariants")
//#pragma GCC optimize("unswitch-loops")
//#pragma GCC optimize("function-sections")
//#pragma GCC optimize("data-sections")

const int MAXN = 2601;

int dp[MAXN][MAXN];
pii par[MAXN][MAXN];

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #ifdef LOCAL
    #else
//        freopen("capitals.in", "r", stdin);
//        freopen("capitals.out", "w", stdout);
    #endif
    string s;
    cin >> s;
    int n = s.size();
    if (n >= 2600) {
        vector<int> cnt(26, 0);
        for (int i = 0; i < n; i++) cnt[s[i] - 'a']++;
        for (int i = 0; i < 26; i++) {
            if (cnt[i] >= 100) {
                for (int j = 0; j < 100; j++) cout << char('a' + i);
                return 0;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        dp[i][i] = 1;
        par[i][i] = {-1, -1};
        if (s[i] == s[i + 1]) {
            dp[i][i + 1] = 2;
            par[i][i + 1] = {i, i + 1};
        } else {
            dp[i][i + 1] = dp[i][i];
            par[i][i + 1] = par[i][i];
        }
    }
    for (int l = 3; l <= n; l++) {
        for (int i = 0; i < n - l + 1; i++) {
            if (s[i] == s[i + l - 1]) {
                dp[i][i + l - 1] = dp[i + 1][i + l - 2] + 2;
                par[i][i + l - 1] = {i, i + l - 1};
            } else {
                if (dp[i][i + l - 2] >= dp[i + 1][i + l - 1]) {
                    dp[i][i + l - 1] = dp[i][i + l - 2];
                    par[i][i + l - 1] = par[i][i + l - 2];
                } else {
                    dp[i][i + l - 1] = dp[i + 1][i + l - 1];
                    par[i][i + l - 1] = par[i + 1][i + l - 1];
                }
            }
        }
    }
    string ans;
    int l = par[0][n - 1].first, r = par[0][n - 1].second;
    if (l == -1) {
        cout << s[0];
        return 0;
    }
    while (1) {
//        cout << l << " " << r << "\n";
        if (ans.size() == 50 || par[l][r].first == -1 || l > r || l == -1 || r == -1 || l == r) break;
        ans = ans + s[l];
        if (l + 1 == r) {
            l++;
            r--;
            break;
        }
        int nl = par[l + 1][r - 1].first, nr = par[l + 1][r - 1].second;
        if (nl == -1) {
            l++;
            r--;
            break;
        }
        l = nl;
        r = nr;
    }
//    cout << l << " " << r << "\n";
    if (ans.size() == 50 || l > r) {
        cout << ans;
        reverse(all(ans));
        cout << ans;
    } else {
        cout << ans;
        reverse(all(ans));
        cout << s[l];
        cout << ans;
    }
}
/*

*/