#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{
		if(s1.compare(s2)==0)return true;
		else
		{
			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			 /*  else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }*/
               else return false;

			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				/*else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }*/
			   else return false;
			}
			else return false;

		}

	}

}

int main()
{
	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
			if(s1.size()%2==0)
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3))
			{
				if(fun(str2,str4))
				return true;
			}
			if(fun(str1,str4))
			{
				if(fun(str2,str3))
				return true;

			}
			 return false;

	       }
	       else
	       {
		     if(s1==s2)return true;
	            return false;
	       }
}
int main()
{
//	char a[200001],b[200001];
	string s1,s2;

	cin>>s1>>s2;
	//scanf("%s %s",&a,&b);
	//s1=a;
	//s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	        return (s1==s2);

			else
			{
				int n=s1.size();
			string a1=s1.substr(0,n/2);
			string a2=s1.substr(n/2,n/2);
			string b1=s2.substr(0,n/2);
			string b2=s2.substr(n/2,n/2);
			 return  (fun(a1,b2) and (fun(a2,b1))) or (fun(a1,b1) and	fun(a2,b2));

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;
  int x=fun(s1,s2);
	if(x==1)cout<<"YES\n";
	else cout<<"NO\n";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
			if(s1.size()%2==0)
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3) and	(fun(str2,str4)))
				return true;

			if(fun(str1,str4) and (fun(str2,str3)))
				return true;

			 return false;

	       }
	       else
	       {
		     return (s1==s2);
	       }
}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{
		if(s1.compare(s2)==0)return true;
		else
		{
			if(s1.length()%2==0)
			{

			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			 /*  else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }*/
               else return false;

			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				/*else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }*/
			   else return false;
			}
			else return false;

	}
	else
	{
		if(s1==s2)return true;
		else return false;
	}
		}

	}

}

int main()
{
	char a[200000],b[200000];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
/*
bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	        return (s1==s2);

			else
			{
				int n=s1.size();
			string a1=s1.substr(0,n/2);
			string a2=s1.substr(n/2,n/2);
			string b1=s2.substr(0,n/2);
			string b2=s2.substr(n/2,n/2);
			 return (fun(a1,b1) and	(fun(a2,b2)) or  (fun(a1,b2) and (fun(a2,b1))) );

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;
  int x=fun(s1,s2);
	if(x==1)cout<<"YES";
	else cout<<"NO";

	return 0;
}*/

bool equiv(string a, string b){
    if(a.size()%2==1) return a==b;
    else{
        int n=a.size();
        string a1=a.substr(0,n/2);
        string a2=a.substr(n/2,n/2);
        string b1=b.substr(0,n/2);
        string b2=b.substr(n/2,n/2);
        return ((equiv(a1,b2) and equiv(a2,b1)) or (equiv(a1,b1) and equiv(a2,b2)));
    }
}

int main()
{

    //freopen("in.in","r",stdin);
    string a,b;
    cin>>a>>b;
    int x=equiv(a,b);
    if(x==1) cout<<"YES\n";
    else cout<<"NO\n";
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	       {
		     return (s1==s2);
	       }
			else
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3) and	(fun(str2,str4)))
				return true;

			if(fun(str1,str4) and (fun(str2,str3)))
				return true;

			 return false;

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	        return (s1==s2);

			else
			{
				int n=s1.size();
			string a1=s1.substr(0,n/2);
			string a2=s1.substr(n/2,n/2);
			string b1=s2.substr(0,n/2);
			string b2=s2.substr(n/2,n/2);
			 return (fun(a1,b1) and	fun(a2,b2)) or  (fun(a1,b2) and (fun(a2,b1))) ;

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;
  int x=fun(s1,s2);
	if(x==1)cout<<"YES\n";
	else cout<<"NO\n";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	/*if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{*/
		if(s1.compare(s2)==0)return true;
		else
		{
			if(s1.length()%2==0)
			{

			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			  else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }
               else return false;

			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }
			   else return false;
			}
			else return false;

	}
	else
	{
		if(s1==s2)return true;
		else return false;
	}

	}

}

int main()
{
	char a[200000],b[200000];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	        return (s1==s2);

			else
			{
				int n=s1.size();
			string a1=s1.substr(0,n/2);
			string a2=s1.substr(n/2,n/2);
			string b1=s2.substr(0,n/2);
			string b2=s2.substr(n/2,n/2);
			 return (fun(a1,b1) and	fun(a2,b2)) or  (fun(a1,b2) and (fun(a2,b1))) ;

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;
  int x=fun(s1,s2);
	if(x==1)cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{
		if(s1.compare(s2)==0)return true;
		else
		{
			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
				else return false;
			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				else return false;
			}
			else return false;

		}

	}

}

int main()
{
	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	       {
		     return (s1==s2);
	       }
			else
			{
				int n=s1.size();
			string str1=s1.substr(0,n/2);
			string str2=s1.substr(n/2,n/2);
			string str3=s2.substr(0,n/2);
			string str4=s2.substr(n/2,n/2);
			 if(fun(str1,str3) and	(fun(str2,str4)))
				return true;

			if(fun(str1,str4) and (fun(str2,str3)))
				return true;

			 return false;

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	/*if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{*/
		if(s1.compare(s2)==0)return true;
		else
		{
			if(s1.length()%2==0)
			{

			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);
			/*
			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else*/ if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			 /*  else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }*/
               //else return false;

			}
			if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				/*else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }*/

			}
			 return false;

	}
	else
	{
		if(s1==s2)return true;
		else return false;
	}

	}

}

int main()
{
	char a[200000],b[200000];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{
		if(s1.compare(s2)==0)return true;
		else
		{
			if(s1.length()%2==0)
			{

			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			 /*  else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }*/
               else return false;

			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				/*else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }*/
			   else return false;
			}
			else return false;

	}
	else
	{
		if(s1==s2)return true;
		else return false;
	}
		}

	}

}

int main()
{
	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	        return (s1==s2);

			else
			{
				int n=s1.size();
			string str1=s1.substr(0,n/2);
			string str2=s1.substr(n/2,n/2);
			string str3=s2.substr(0,n/2);
			string str4=s2.substr(n/2,n/2);
			 return (fun(str1,str3) and	(fun(str2,str4)) or  (fun(str1,str4) and (fun(str2,str3))) );

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;
  int x=fun(s1,s2);
	if(x==1)cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
		if(s1.compare(s2)==0)return true;
		else
		{
			if(s1.size()%2==0)
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3))
			{
				if(fun(str2,str4))
				return true;
			}
			if(fun(str1,str4))
			{
				if(fun(str2,str3))
				return true;

			}
			 return false;

	       }
	       else
	       {
		     if(s1==s2)return true;
	            return false;
	       }

	}

}

int main()
{
	char a[200000],b[200000];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
			if(s1.size()%2==0)
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3))
			{
				if(fun(str2,str4))
				return true;
			}
			if(fun(str1,str4))
			{
				if(fun(str2,str3))
				return true;

			}
			 return false;

	       }
	       else
	       {
		     if(s1==s2)return true;
	            return false;
	       }

}

int main()
{
	char a[200000],b[200000];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
			if(s1.size()%2==0)
			{
			string str1=s1.substr(0,s1.size()/2);
			string str2=s1.substr(s1.size()/2,s1.size()/2);
			string str3=s2.substr(0,s2.size()/2);
			string str4=s2.substr(s2.size()/2,s2.size()/2);
			 if(fun(str1,str3))
			{
				if(fun(str2,str4))
				return true;
			}
			if(fun(str1,str4))
			{
				if(fun(str2,str3))
				return true;

			}
			 return false;

	       }
	       else
	       {
		     if(s1==s2)return true;
	            return false;
	       }

}

int main()
{
	char a[200001],b[200001];
	string s1,s2;

	//cin>>s1>>s2;
	scanf("%s %s",&a,&b);
	s1=a;
	s2=b;
	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	       {
		     return (s1==s2);
	       }
			else
			{
				int n=s1.size();
			string str1=s1.substr(0,n/2);
			string str2=s1.substr(n/2,n/2);
			string str3=s2.substr(0,n/2);
			string str4=s2.substr(n/2,n/2);
			 return (fun(str1,str3) and	(fun(str2,str4)) or  (fun(str1,str4) and (fun(str2,str3))) )

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	       {
		     return (s1==s2);
	       }
			else
			{
				int n=s1.size();
			string str1=s1.substr(0,n/2);
			string str2=s1.substr(n/2,n/2);
			string str3=s2.substr(0,n/2);
			string str4=s2.substr(n/2,n/2);
			 if(fun(str1,str3) and	(fun(str2,str4)) or  (fun(str1,str4) and (fun(str2,str3))) )
				return true;

			 return false;

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	if(s1.length()==1 && s2.length()==1)
	{
		if(s1.compare(s2)==0)return true;
		else return false;
	}
	else
	{
		if(s1.compare(s2)==0)return true;
		else
		{
			string str1=s1.substr(0,s1.length()/2);
			string str2=s1.substr(s1.length()/2,s1.length()/2);
			string str3=s2.substr(0,s2.length()/2);
			string str4=s2.substr(s2.length()/2,s2.length()/2);

			if(str1==str3)
			{
				if(fun(str2,str4))return true;
				else return false;
			}
			else if(str1==str4)
			{
				if(fun(str2,str3))return true;
				else return false;
			}
			else if(str2==str3)
			{
				if(fun(str1,str4))return true;
				else return false;
			}
			else if(str2==str4)
			{
				if(fun(str1,str3))return true;
				else return false;
			}
			else if(fun(str1,str3))
			{
				if(fun(str2,str4))
				{
					return true;
				}
			   else if(fun(str1,str4))
			   {
				if(fun(str2,str3))
				{
					return true;
				}
			    else return false;
               }
               else return false;

			}
			else if(fun(str1,str4))
			{
				if(fun(str2,str3))
				{
					return true;
				}
				else if(fun(str1,str3))
			   {
				if(fun(str2,str4))
				{
					return true;
				}
			    else return false;
			   }
			   else return false;
			}
			else return false;

		}

	}

}

int main()
{
	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))cout<<"YES";
	else cout<<"NO";

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

bool fun(string s1,string s2)
{
	       if(s1.size()%2==1)
	       {
		     return (s1==s2);
	       }
			else
			{
				int n=s1.size();
			string str1=s1.substr(0,n/2);
			string str2=s1.substr(n/2,n/2);
			string str3=s2.substr(0,n/2);
			string str4=s2.substr(n/2,n/2);
			 return (fun(str1,str3) and	(fun(str2,str4)) or  (fun(str1,str4) and (fun(str2,str3))) );

	       }

}
int main()
{

	string s1,s2;

	cin>>s1>>s2;

	if(fun(s1,s2))printf("YES");
	else printf("NO");

	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//maths functions
double areaa(int x1,int x2,int x3,int y1,int y2,int y3);// calculate area of triangle given its coordinates.
int gcd(int x,int y);
int lcm(int x,int y);
int egcd(int a, int b, int& x, int& y); ////
vector<int> prime_possible_factors(int n);
vector<int> primes_included(int n,int m); // between n and m;
map<int, int> factor(int N);//gives all prime factors of N
bool isPrime(int N);//indicates whether the number is prime with the most efficient time

int charType(char c);
double areaa(int x1,int x2,int x3,int y1,int y2,int y3)
{
    double area=abs((x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/4.0);
    return area;
}

int gcd(int x,int y) //euclidean algorithm.
{
    return y == 0 ? x:gcd(y,x%y);
}

int lcm(int x,int y)
{
    return (x*y/gcd(x,y));
}

int egcd(int a, int b, int& x, int& y) //also solves gcd(a,b) = a*x+b*y
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        int d = egcd(b, a % b, x, y);
        x -= a / b * y;
        swap(x, y);
        return d;
    }
}

vector<int> prime_possible_factors(int n)
{
    bool *isPrime = new bool[n];
    for(int i = 0; i < n; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i*i <= n; ++i)
    {
        if(isPrime[i])
        {
            primes.push_back(i);
            for(int j = i; j < n; j += i) isPrime[j] = false;
        }
    }
    return primes;
}

vector<int> primes_included(int n,int m)
{
    bool *isPrime = new bool[m];
    for(int i = 0; i < m; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i < m; ++i)
    {
        if(isPrime[i])
        {
            if(i >= n)
                primes.push_back(i);
            for(int j = i ; j < m; j += i) isPrime[j] = false;
        }
    }
    return primes;
}
map<int, int> factor(int N)
{
    vector<int> primes;
    primes = primes_included(0,N);
    map<int, int> factors;
    for(int i = 0; i < primes.size(); ++i)
    {
        int prime = primes[i], power = 0;
        while(N % prime == 0)
        {
            power++;
            N /= prime;
        }

        factors[prime] = power;

    }
    return factors;
}
bool isPrime(int N)
{
    vector<int> check = prime_possible_factors(N);
    for(int i = 0; i<check.size(); i++)
    {
        if(N%check[i] == 0)
        {
            return false;
        }
    }
    return true;
}
bool equivalent(string a,string b)
{
//base case.
    if(a.length() == 1)
    {
        return (a.compare(b) == 0);
    }
    if(a.compare(b) == 0)
    {
        return true;
    }
    return((equivalent(a.substr(0,a.length()/2),b.substr(0,b.length()/2)) &&equivalent(a.substr(a.length()/2,a.length()/2),b.substr(b.length()/2,b.length()/2)))||(equivalent(a.substr(0,a.length()/2),b.substr(b.length()/2,b.length()/2)) &&equivalent(a.substr(a.length()/2,a.length()/2),b.substr(0,b.length()/2))));
}

int main()
{
    string a,b;
    cin>>a>>b;
    if(equivalent(a,b)){
        cout<<"YES";
    }else
    cout<<"NO";
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//maths functions
double areaa(int x1,int x2,int x3,int y1,int y2,int y3);// calculate area of triangle given its coordinates.
int gcd(int x,int y);
int lcm(int x,int y);
int egcd(int a, int b, int& x, int& y); ////
vector<int> prime_possible_factors(int n);
vector<int> primes_included(int n,int m); // between n and m;
map<int, int> factor(int N);//gives all prime factors of N
bool isPrime(int N);//indicates whether the number is prime with the most efficient time

int charType(char c);
double areaa(int x1,int x2,int x3,int y1,int y2,int y3)
{
    double area=abs((x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/4.0);
    return area;
}

int gcd(int x,int y) //euclidean algorithm.
{
    return y == 0 ? x:gcd(y,x%y);
}

int lcm(int x,int y)
{
    return (x*y/gcd(x,y));
}

int egcd(int a, int b, int& x, int& y) //also solves gcd(a,b) = a*x+b*y
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        int d = egcd(b, a % b, x, y);
        x -= a / b * y;
        swap(x, y);
        return d;
    }
}

vector<int> prime_possible_factors(int n)
{
    bool *isPrime = new bool[n];
    for(int i = 0; i < n; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i*i <= n; ++i)
    {
        if(isPrime[i])
        {
            primes.push_back(i);
            for(int j = i; j < n; j += i) isPrime[j] = false;
        }
    }
    return primes;
}

vector<int> primes_included(int n,int m)
{
    bool *isPrime = new bool[m];
    for(int i = 0; i < m; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i < m; ++i)
    {
        if(isPrime[i])
        {
            if(i >= n)
                primes.push_back(i);
            for(int j = i ; j < m; j += i) isPrime[j] = false;
        }
    }
    return primes;
}
map<int, int> factor(int N)
{
    vector<int> primes;
    primes = primes_included(0,N);
    map<int, int> factors;
    for(int i = 0; i < primes.size(); ++i)
    {
        int prime = primes[i], power = 0;
        while(N % prime == 0)
        {
            power++;
            N /= prime;
        }

        factors[prime] = power;

    }
    return factors;
}
bool isPrime(int N)
{
    vector<int> check = prime_possible_factors(N);
    for(int i = 0; i<check.size(); i++)
    {
        if(N%check[i] == 0)
        {
            return false;
        }
    }
    return true;
}
string finalString(string s)
{
    if(s.length()%2)
        return s;
    string s1 = s.substr(0,s.length()/2);
    string s2 = s.substr(s.length()/2,s.length()/2);
    return max(s1+s2,s2+s1);
}

int main()
{
    string a,b;
    cin>>a>>b;
    if(finalString(a).compare(finalString(b))==0){
        cout<<"YES";
    }else
    cout<<"NO";
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//maths functions
double areaa(int x1,int x2,int x3,int y1,int y2,int y3);// calculate area of triangle given its coordinates.
int gcd(int x,int y);
int lcm(int x,int y);
int egcd(int a, int b, int& x, int& y); ////
vector<int> prime_possible_factors(int n);
vector<int> primes_included(int n,int m); // between n and m;
map<int, int> factor(int N);//gives all prime factors of N
bool isPrime(int N);//indicates whether the number is prime with the most efficient time

int charType(char c);
double areaa(int x1,int x2,int x3,int y1,int y2,int y3)
{
    double area=abs((x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/4.0);
    return area;
}

int gcd(int x,int y) //euclidean algorithm.
{
    return y == 0 ? x:gcd(y,x%y);
}

int lcm(int x,int y)
{
    return (x*y/gcd(x,y));
}

int egcd(int a, int b, int& x, int& y) //also solves gcd(a,b) = a*x+b*y
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        int d = egcd(b, a % b, x, y);
        x -= a / b * y;
        swap(x, y);
        return d;
    }
}

vector<int> prime_possible_factors(int n)
{
    bool *isPrime = new bool[n];
    for(int i = 0; i < n; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i*i <= n; ++i)
    {
        if(isPrime[i])
        {
            primes.push_back(i);
            for(int j = i; j < n; j += i) isPrime[j] = false;
        }
    }
    return primes;
}

vector<int> primes_included(int n,int m)
{
    bool *isPrime = new bool[m];
    for(int i = 0; i < m; i++)
    {
        isPrime[i] = true;
    }
    vector<int> primes;
    for(int i = 2; i < m; ++i)
    {
        if(isPrime[i])
        {
            if(i >= n)
                primes.push_back(i);
            for(int j = i ; j < m; j += i) isPrime[j] = false;
        }
    }
    return primes;
}
map<int, int> factor(int N)
{
    vector<int> primes;
    primes = primes_included(0,N);
    map<int, int> factors;
    for(int i = 0; i < primes.size(); ++i)
    {
        int prime = primes[i], power = 0;
        while(N % prime == 0)
        {
            power++;
            N /= prime;
        }

        factors[prime] = power;

    }
    return factors;
}
bool isPrime(int N)
{
    vector<int> check = prime_possible_factors(N);
    for(int i = 0; i<check.size(); i++)
    {
        if(N%check[i] == 0)
        {
            return false;
        }
    }
    return true;
}
bool equivalent(string a,string b)
{
//base case.
    if(a.length() == 1)
    {
        return (a[0] == b[0]);
    }
    if(a.compare(b) == 0)
    {
        return true;
    }
    if(a.length()%2){
        return false;
    }
    bool a1_eq_b1 = equivalent(a.substr(0,a.length()/2),b.substr(0,b.length()/2));
    bool a2_eq_b2 =equivalent(a.substr(a.length()/2,a.length()/2),b.substr(b.length()/2,b.length()/2));
    if(a1_eq_b1 && a2_eq_b2){
        return true;
    }
    bool a1_eq_b2 =equivalent(a.substr(0,a.length()/2),b.substr(b.length()/2,b.length()/2));
    bool a2_eq_b1 =   equivalent(a.substr(a.length()/2,a.length()/2),b.substr(0,b.length()/2));
    return(a1_eq_b2 && a2_eq_b1);
}

int main()
{
    string a,b;
    cin>>a>>b;
    if(equivalent(a,b)){
        cout<<"YES";
    }else
    cout<<"NO";
    return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, 1e9};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur > mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, 1e9};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur > mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
				if(cur == mx){
					f |= (dp[i][k][2] - i) > 1;
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, 1e9};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 50){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur > mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, -1};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		if(!j) mn[0][i][j] = {n, -1};
		else mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur == mx){
					mx = cur;
					f |= ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, -1};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		if(!j) mn[0][i][j] = {n, -1};
		else mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(db && cur == 99){
					cout << "WTFFF" << endl;
					cout << dp[i][k][2] - i << endl;
				}
				if(cur == mx){
					f |= ((dp[i][k][2] - i) > 1);
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[i][j] = {n, 0};
		else mn[i][j] = {1e9, -1};
	}
	rep(i, n){
		vi p;
		int v = s[i] - 'a';
		rep(j, 26) if(v != j) p.pb(j);
		p.pb(v);
		for(int len = 49; len >= 0; len--) rep(j1, 26) if(mn[p[j1]][len].fi != 1e9){
			int j = p[j1];
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[v][1].fi == 1e9 || mn[v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[v][len + 1].fi == 1e9 || mn[v][len + 1].fi < g[v][l]){
						mn[v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[v][len + 1].fi;
						dp[i][len + 1][3] = mn[j][len].se;
					}
				}
			}
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur == mx){
					mx = cur;
					f |= ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, -1};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(db && cur == 99 && (dp[i][k][2] - i) > 1){
					cout << "WTFFF" << endl;
				}
				if(cur == mx){
					f |= ((dp[i][k][2] - i) > 1);
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, -1};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		if(!j) mn[0][i][j] = {n, -1};
		else mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(db && cur == 98){
					cout << "WTFFF" << endl;
					cout << dp[i][k][2] - i << endl;
				}
				if(cur == mx){
					f |= ((dp[i][k][2] - i) > 1);
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, n};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 50){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur >= mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k + ((dp[i][k][2] - i) > 1);
				if(cur >= mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {0, 1e9};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(cur == mx){
					f |= (dp[i][k][2] - i) > 1;
				}
				if(cur > mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[mxN][27][51];
short dp[mxN][27][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(j, 27) rep(k, 51) rep(l, 4) dp[i][j][k][l] = 0;
	rep(k, n + 1) rep(i, 26) rep(j, 51){
		if(!j) mn[k][i][j] = {n, k};
		else mn[k][i][j] = {1e9, -1};
	}
	rep(i, n){
		rep(j, 26) rep(len, 50) if(mn[i][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[i + 1][v][1].fi == 1e9 || mn[i + 1][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[i + 1][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][v][1][0] = 1;
						dp[i][v][1][1] = -1;
						dp[i][v][1][2] = mn[i + 1][v][1].fi;
						dp[i][v][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[i][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[i + 1][v][len + 1].fi == 1e9 || mn[i + 1][v][len + 1].fi < g[v][l]){
						mn[i + 1][v][len + 1] = {g[v][l], i};
						dp[i][v][len + 1][0] = 1;
						dp[i][v][len + 1][1] = j;
						dp[i][v][len + 1][2] = mn[i + 1][v][len + 1].fi;
						dp[i][v][len + 1][3] = mn[i][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 50){
			if(mn[i + 1][j][len].fi > mn[i][j][len].fi) mn[i + 1][j][len] = mn[i][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(j, 27) rep(k, 51){
		if(dp[i][j][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 3> bst = {-1, -1, -1};
		rep(i, n) rep(j, 27) rep(k, 51){
			if(dp[i][j][k][0]){
				int cur = k;
				if(cur >= mx){
					mx = cur;
					bst = {i, j, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += (char)('a' + bst[1]);
				int ct = bst[1];
				bst[1] = dp[bst[0]][bst[1]][bst[2]][1];
				bst[0] = dp[bst[0]][ct][bst[2]][3], bst[2]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 3> bst = {-1, -1, -1};
		int f = 0;
		rep(i, n) rep(j, 27) rep(k, 51){
			if(dp[i][j][k][0]){
				int cur = k + ((dp[i][j][k][2] - i) > 1);
				if(cur >= mx){
					mx = cur;
					f = (dp[i][j][k][2] - i) > 1;
					bst = {i, j, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += (char)('a' + bst[1]);
				int ct = bst[1];
				bst[1] = dp[bst[0]][bst[1]][bst[2]][1];
				bst[0] = dp[bst[0]][ct][bst[2]][3], bst[2]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, -1};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		if(!j) mn[0][i][j] = {n, -1};
		else mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				if(db && cur == 98){
					cout << "WTFFF" << endl;
					cout << dp[i][k][2] - i << endl;
				}
				if(cur == mx){
					f |= ((dp[i][k][2] - i) > 1);
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	int db = 0;
	if(s.size() > 3 && s[0] == 'm' && s[1] == 'a' && s[2] == 'a') db = 1;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {0, 1e9};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 51){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur > mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = 2 * k + ((dp[i][k][2] - i) > 1);
				//if(db && cur == 49 && (dp[i][k][2] - i) > 1){
				//	cout << "WTFFF" << endl;
				//}
				if(cur == mx){
					f |= ((dp[i][k][2] - i) > 1);
				}
				if(cur > mx){
					mx = cur;
					f = ((dp[i][k][2] - i) > 1);
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(db && f) cout << "! " << s[st + 1] << endl;
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[mxN][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(k, n + 1) rep(i, 26) rep(j, 51){
		if(!j) mn[k][i][j] = {n, k};
		else mn[k][i][j] = {1e9, -1};
	}
	rep(i, n){
		rep(j, 26) rep(len, 50) if(mn[i][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[i + 1][v][1].fi == 1e9 || mn[i + 1][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[i + 1][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[i + 1][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[i][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[i + 1][v][len + 1].fi == 1e9 || mn[i + 1][v][len + 1].fi < g[v][l]){
						mn[i + 1][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[i + 1][v][len + 1].fi;
						dp[i][len + 1][3] = mn[i][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 50){
			if(mn[i + 1][j][len].fi > mn[i][j][len].fi) mn[i + 1][j][len] = mn[i][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur >= mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k + ((dp[i][k][2] - i) > 1);
				if(cur >= mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 5e4 + 1;

template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }

vi g[27];
pi mn[2][27][51];
int dp[mxN][51][4];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.in", "r", stdin);
	//freopen("output.out", "w", stdout);
	string s;
	cin >> s;
	int n = s.size();
	rep(i, n) g[s[i] - 'a'].pb(i);
	rep(i, n) rep(k, 51) rep(l, 4) dp[i][k][l] = 0;
	rep(i, 26) rep(j, 51){
		if(!j) mn[1][i][j] = {n, n};
		else mn[1][i][j] = {1e9, -1};
	}
	rep(i, 26) rep(j, 51){
		if(!j) mn[0][i][j] = {n, n};
		else mn[0][i][j] = {1e9, -1};
	}
	rep(i, n){
		int cr = i & 1;
		int pr = 1 - (i & 1);
		rep(j, 26) rep(len, 50) if(mn[pr][j][len].fi != 1e9){
			int v = s[i] - 'a';
			if(!len){
				if(g[v][(int)g[v].size() - 1] > i){
					if(mn[cr][v][1].fi == 1e9 || mn[cr][v][1].fi < g[v][(int)g[v].size() - 1]){
						mn[cr][v][1] = {g[v][g[v].size() - 1], i};
						dp[i][1][0] = 1;
						dp[i][1][1] = -1;
						dp[i][1][2] = mn[cr][v][1].fi;
						dp[i][1][3] = -1;
					}
				}
			}
			else{
				int l = 0, r = g[v].size() - 1;
				while(l < r){
					int mid = (l + r + 1) / 2;
					if(g[v][mid] < mn[pr][j][len].fi) l = mid;
					else r = mid - 1;
				}
				if(g[v][l] > i){
					if(mn[cr][v][len + 1].fi == 1e9 || mn[cr][v][len + 1].fi < g[v][l]){
						mn[cr][v][len + 1] = {g[v][l], i};
						dp[i][len + 1][0] = 1;
						dp[i][len + 1][1] = j;
						dp[i][len + 1][2] = mn[cr][v][len + 1].fi;
						dp[i][len + 1][3] = mn[pr][j][len].se;
					}
				}
			}
		}
		rep(j, 26) rep(len, 50){
			if(mn[cr][j][len].fi > mn[pr][j][len].fi) mn[cr][j][len] = mn[pr][j][len];
		}
	}
	int ans = 0;
	rep(i, n) rep(k, 51){
		if(dp[i][k][0]) ans = max(ans, k);
	}
	if(ans == 50){
		//we found a big one
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k;
				if(cur >= mx){
					mx = cur;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		cout << res1 << res << endl;
	}
	else{
		int mx = 0;
		array<int, 2> bst = {-1, -1};
		int f = 0;
		rep(i, n) rep(k, 51){
			if(dp[i][k][0]){
				int cur = k + ((dp[i][k][2] - i) > 1);
				if(cur >= mx){
					mx = cur;
					f = (dp[i][k][2] - i) > 1;
					bst = {i, k};
				}
			}
		}
		if(bst[0] == -1){
			cout << s[0] << endl;
			return 0;
		}
		int st = bst[0];
		if(f) mx--;
		string res = "";
		while(mx--){
			if(bst[1] == -1) break;
			else if(bst[0] == -1) break;
			else{
				res += s[bst[0]];
				bst[0] = dp[bst[0]][bst[1]][3], bst[1]--;
			}
		}
		string res1 = res;
		reverse(all(res1));
		if(f) cout << res1 << s[st + 1] << res << endl;
		else cout << res1 << res << endl;
	}
	return 0;
}
/*
Things to look out for:
	- Integer overflows
	- Array bounds
	- Special cases
Be careful!
*/


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define maxn 50010
#define maxl 101
#define inf 1e8
#define pii pair<int, int>

const int alphalen = 'z' - 'a' + 1;

vector<int> occur[alphalen];

int dp[maxn][maxl];

char tmps[maxn];
string s;
int n;

pii lpslen()
{
	for (int l = 0; l < maxl; l++)
	{
		dp[n][l] = -1;
	}
	int ans = 1;
	int start = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		dp[i][0] = i - 1;
		dp[i][1] = i;
		for (int l = 2; l < maxl; l++)
		{
			if (dp[i + 1][l - 2] == -1)
			{
				dp[i][l] = -1;
			}
			else
			{
				char ch = s[i];
				auto tmpvec = occur[ch - 'a'];
				auto p = upper_bound(tmpvec.begin(), tmpvec.end(), dp[i + 1][l - 2]) - tmpvec.begin();
				if (p == tmpvec.size())
				{
					dp[i][l] = dp[i + 1][l];
				}
				else
				{
					dp[i][l] = min(tmpvec[p], dp[i + 1][l] == -1 ? n : dp[i + 1][l]);
					if (l > ans)
					{
						ans = l;
						start = i;
					}
				}
			}
		}
	}
	return make_pair(ans, start);
}

int main()
{
	scanf("%s", tmps);
	s = tmps;
	n = s.size();
	for (int i = 0; i < s.size(); i++)
	{
		char ch = s[i];
		occur[ch - 'a'].pb(i);
	}
	pii ans = lpslen();
	string lps;
	int l = ans.first;
	int i = ans.second;
	char center = '\0';
	while (i < n and l > 0)
	{
		if (dp[i + 1][l] != dp[i][l])
		{
			if (l == 1)
			{
				center = s[i];
				break;
			}
			else
			{
				lps += s[i];
				i += 1;
				l -= 2;
			}
		}
		else
		{
			i += 1;
		}
	}
	// printf("%s", (center ? lps + center : lps));
	printf("%s", (center ? (lps + center).c_str() : lps.c_str()));
	reverse(lps.begin(), lps.end());
	printf("%s\n", lps.c_str());
	// printf("%s\n", lps);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define maxn 50010
#define maxl 101
#define inf 1e8
#define pii pair<int, int>

const int alphalen = 'z' - 'a' + 1;

vector<int> occur[alphalen];

int dp[maxn][maxl];

string s;
int n;

pii lpslen()
{
	for (int l = 0; l < maxl; l++)
	{
		dp[n][l] = -1;
	}
	int ans = 1;
	int start = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		dp[i][0] = i - 1;
		dp[i][1] = i;
		for (int l = 2; l < maxl; l++)
		{
			if (dp[i + 1][l - 2] == -1)
			{
				dp[i][l] = -1;
			}
			else
			{
				char ch = s[i];
				auto tmpvec = occur[ch - 'a'];
				auto p = upper_bound(tmpvec.begin(), tmpvec.end(), dp[i + 1][l - 2]) - tmpvec.begin();
				if (p == tmpvec.size())
				{
					dp[i][l] = dp[i + 1][l];
				}
				else
				{
					dp[i][l] = min(tmpvec[p], dp[i + 1][l] == -1 ? n : dp[i + 1][l]);
					if (l > ans)
					{
						ans = l;
						start = i;
					}
				}
			}
		}
	}
	return make_pair(ans, start);
}

int main()
{
	cin >> s;
	n = s.size();
	for (int i = 0; i < s.size(); i++)
	{
		char ch = s[i];
		occur[ch - 'a'].pb(i);
	}
	pii ans = lpslen();
	string lps;
	int l = ans.first;
	int i = ans.second;
	char center = '\0';
	while (i < n and l > 0)
	{
		if (dp[i + 1][l] != dp[i][l])
		{
			if (l == 1)
			{
				center = s[i];
				break;
			}
			else
			{
				lps += s[i];
				i += 1;
				l -= 2;
			}
		}
		else
		{
			i += 1;
		}
	}
	cout << (center ? lps + center : lps);
	reverse(lps.begin(), lps.end());
	cout << lps << endl;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define maxn 50010
#define maxl 101
#define inf 1e8
#define pii pair<int, int>

const int alphalen = 'z' - 'a' + 1;

vector<int> occur[alphalen];

int dp[maxn][maxl];

string s;
int n;

pii lpslen()
{
	for (int l = 0; l < maxl; l++)
	{
		dp[n][l] = -1;
	}
	int ans = 1;
	int start = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		dp[i][0] = i - 1;
		dp[i][1] = i;
		for (int l = 2; l < maxl; l++)
		{
			if (dp[i + 1][l - 2] == -1)
			{
				dp[i][l] = -1;
			}
			else
			{
				char ch = s[i];
				auto p = upper_bound(occur[ch - 'a'].begin(), occur[ch - 'a'].end(), dp[i + 1][l - 2]) - occur[ch - 'a'].begin();
				if (p == occur[ch - 'a'].size())
				{
					dp[i][l] = dp[i + 1][l];
				}
				else
				{
					dp[i][l] = min(occur[ch - 'a'][p], dp[i + 1][l] == -1 ? n : dp[i + 1][l]);
					if (l > ans)
					{
						ans = l;
						start = i;
					}
				}
			}
		}
	}
	return make_pair(ans, start);
}

int main()
{
	cin >> s;
	n = s.size();
	for (int i = 0; i < s.size(); i++)
	{
		char ch = s[i];
		occur[ch - 'a'].pb(i);
	}
	pii ans = lpslen();
	string lps;
	int l = ans.first;
	int i = ans.second;
	char center = '\0';
	while (i < n and l > 0)
	{
		if (dp[i + 1][l] != dp[i][l])
		{
			if (l == 1)
			{
				center = s[i];
				break;
			}
			else
			{
				lps += s[i];
				i += 1;
				l -= 2;
			}
		}
		else
		{
			i += 1;
		}
	}
	cout << (center ? lps + center : lps);
	reverse(lps.begin(), lps.end());
	cout << lps << endl;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define maxn 50010
#define maxl 101
#define inf 1e8
#define pii pair<int, int>

const int alphalen = 'z' - 'a' + 1;

vector<int> occur[alphalen];

int dp[maxn][maxl];

char tmps[maxn];
string t;
int n;

int lpslen(int *s)
{
	fill(dp[n], dp[n]+maxl, n);
	// for (int l = 0; l < maxl; l++)
	// {
	// 	dp[n][l] = n;
	// }
	for (int i = n - 1; i >= 0; i--)
	{
		dp[i][0] = i - 1;
		dp[i][1] = i;
		for (int l = 2; l < maxl; l++)
		{
			// if (dp[i + 1][l - 2] == n)
			// {
			// 	dp[i][l] = n;
			// }
			// else
			// {
			auto p = *lower_bound(occur[s[i]].begin(), occur[s[i]].end(), dp[i + 1][l - 2] + 1);
			dp[i][l] = min(p, dp[i + 1][l]);
			// }
		}
	}
	int ans = 1;
	for (int l = 1; l < maxl; l++)
	{
		if (dp[0][l] != n)
		{
			ans = l;
		}
	}
	return ans;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie();
	scanf("%s", tmps);
	t = tmps;
	n = t.size();
	int s[n];
	for (int i = 0; i < n; i++)
	{
		char ch = t[i];
		s[i] = ch - 'a';
		occur[s[i]].pb(i);
	}
	for (int i = 0; i < alphalen; i++)
	{
		occur[i].pb(n + 1);
	}
	// for(int i = 0; )
	int ans = lpslen(s);
	string lps;
	int l = ans;
	int i = 0;
	char center = '\0';
	while (i < n and l > 0)
	{
		if (dp[i + 1][l] != dp[i][l])
		{
			if (l == 1)
			{
				center = s[i] + 'a';
				break;
			}
			else
			{
				lps += s[i] + 'a';
				i += 1;
				l -= 2;
			}
		}
		else
		{
			i += 1;
		}
	}
	// cout << (center ? (lps + center) : lps);
	printf("%s", (center ? (lps + center).c_str() : lps.c_str()));
	reverse(lps.begin(), lps.end());
	printf("%s\n", lps.c_str());
	// cout << lps << endl;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define maxn 50010
#define maxl 101
#define inf 1e8
#define pii pair<int, int>

const int alphalen = 'z' - 'a' + 1;

vector<int> occur[alphalen];

int dp[maxn][maxl];

char tmps[maxn];
string t;
int n;

int lpslen(int *s)
{
	fill(dp[n], dp[n]+maxl, n);
	// for (int l = 0; l < maxl; l++)
	// {
	// 	dp[n][l] = n;
	// }
	for (int i = n - 1; i >= 0; i--)
	{
		dp[i][0] = i - 1;
		dp[i][1] = i;
		for (int l = 2; l < maxl; l++)
		{
			// if (dp[i + 1][l - 2] == n)
			// {
			// 	dp[i][l] = n;
			// }
			// else
			// {
			auto p = *lower_bound(occur[s[i]].begin(), occur[s[i]].end(), dp[i + 1][l - 2] + 1);
			dp[i][l] = min(p, dp[i + 1][l]);
			// }
		}
	}
	int ans = 1;
	for (int l = 1; l < maxl; l++)
	{
		if (dp[0][l] != -1)
		{
			ans = l;
		}
	}
	return ans;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie();
	scanf("%s", tmps);
	t = tmps;
	n = t.size();
	int s[n];
	for (int i = 0; i < n; i++)
	{
		char ch = t[i];
		s[i] = ch - 'a';
		occur[s[i]].pb(i);
	}
	for (int i = 0; i < alphalen; i++)
	{
		occur[i].pb(n + 1);
	}
	// for(int i = 0; )
	int ans = lpslen(s);
	string lps;
	int l = ans;
	int i = 0;
	char center = '\0';
	while (i < n and l > 0)
	{
		if (dp[i + 1][l] != dp[i][l])
		{
			if (l == 1)
			{
				center = s[i] + 'a';
				break;
			}
			else
			{
				lps += s[i] + 'a';
				i += 1;
				l -= 2;
			}
		}
		else
		{
			i += 1;
		}
	}
	// cout << (center ? (lps + center) : lps);
	printf("%s", (center ? (lps + center).c_str() : lps.c_str()));
	reverse(lps.begin(), lps.end());
	printf("%s\n", lps.c_str());
	// cout << lps << endl;
	return 0;
}


#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

const int N = 26 * 99 + 5;
int dp[N][N];
int par[N][N];

int main()
{   string n;
    cin >> n;
    for (char c = 'a'; c <= 'z'; c++) {
        int a=0;
        for (int i=0;i<n.length();i++){
            if (n[i] == c){
                a++;
            }
        }
        if (a >= 100){
            for (int i = 0; i < 100; i++){
                cout << c;
            }
            return 0;
        }
    }
    for (int i = 0; i < n.length(); i++)
        dp[1][i] = 1;
    for (int i = 2; i <= n.length(); i++){
        for (int j = 0; j <= n.length()-i; j++){
            if (n[j]==n[j+i-1]){
                dp[i][j]=dp[i-2][j+1]+2;
                par[i][j] = 1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
                if (dp[i][j] == dp[i-1][j])
                    par[i][j] = 2;
                else
                    par[i][j] = 3;
            }

        }
    }

    int i = n.length();
    int j = 0;
    string ans = "";

    while (par[i][j])
    {
        if (par[i][j] == 1){
            ans.push_back(n[j]);
            j++;
            i -= 2;
        } else if (par[i][j] == 2) {
            i--;
        } else {
            i--;
            j++;
        }
    }
    ans.resize(min(50, (int)ans.length()));
    cout << ans;
    if (ans.length() < 50 && i == 1)
        cout << n[j];
    reverse(ans.begin(), ans.end());
    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

const int N = 26 * 99 + 5;
int dp[N][N];
int par[N][N];

int main()
{   string n;
    cin >> n;
    for (char c = 'a'; c <= 'z'; c++) {
        int a=0;
        for (int i=0;i<n.length();i++){
            if (n[i] == c){
                a++;
            }
        }
        if (a >= 100){
            for (int i = 0; i < 100; i++){
                cout << c;
            }
            return 0;
        }
    }
    for (int i = 2; i <= n.length(); i++){
        for (int j = 0; j <= n.length()-i; j++){
            if (n[j]==n[j+i-1]){
                dp[i][j]=dp[i-2][j+1]+2;
                par[i][j] = 1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]);
                if (dp[i][j] == dp[i-1][j])
                    par[i][j] = 2;
                else
                    par[i][j] = 3;
            }

        }
    }

    int i = n.length();
    int j = 0;
    string ans = "";

    while (par[i][j])
    {
        if (par[i][j] == 1){
            ans.push_back(n[j]);
            j++;
            i -= 2;
        } else if (par[i][j] == 2) {
            i--;
        } else {
            i--;
            j++;
        }
    }
    ans.resize(min(50, (int)ans.length()));
    cout << ans;
    if (ans.length() < 50 && i == 1)
        cout << n[j];
    reverse(ans.begin(), ans.end());
    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define all(v)			((v).begin()), ((v).end())
#define SZ(v)			((int)((v).size()))
#define clr(v, d)		memset(v, d, sizeof(v))
#define pb			    push_back

typedef long long ll;

string s;
int n, cnt[26];
int dp[2666][2666];

int calc (int st, int ed) {
	if (st > ed)
		return 0;
	if (st == ed)
		return 1;
	int &ret = dp[st][ed];
	if (~ret)
		return ret;
	ret = 0;
	if (s[st] == s[ed])
		ret = 2+calc(st+1, ed-1);
	ret = max(ret, calc(st+1, ed));
	ret = max(ret, calc(st, ed-1));
	return ret;
}

string s1, s2;

void print (int st, int ed, int cc) {
	if (st > ed || cc == 100)
		return;
	if (st == ed) {
		s2 += s[st];
		return;
	}
	int r1 = INT_MIN;
	if (s[st] == s[ed])
		r1 = calc(st+1, ed-1) + 2;
	int r2 = calc(st+1, ed);
	int r3 = calc(st, ed-1);
	if (r1 >= r2 && r1 >= r3) {
		s1 += s[st];
		print(st+1, ed-1, cc+2);
	} else if (r2 >= r1 && r2 >= r3) {
		print(st+1, ed, cc+1);
	} else {
		print(st, ed-1, cc+1);
	}
}

int main() {

	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> s;
	int n = SZ(s);
	for (int i = 0; i < n; ++i) {
		cnt[s[i] - 'a']++;
		if (cnt[s[i] - 'a'] == 100) {
			cout << string(100, s[i]) << endl;
			return 0;
		}
	}
	clr(dp, -1);
	s1 = s2 = "";
	print(0, n-1, 0);
	cout << s1 << s2;
	reverse(all(s1));
	cout << s1;
	cout << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define all(v)			((v).begin()), ((v).end())
#define SZ(v)			((int)((v).size()))
#define clr(v, d)		memset(v, d, sizeof(v))
#define pb			    push_back

typedef long long ll;

string s;
int n, cnt[26];
int dp[2666][2666];

int calc (int st, int ed) {
	if (st > ed)
		return 0;
	if (st == ed)
		return 1;
	int &ret = dp[st][ed];
	if (~ret)
		return ret;
	ret = 0;
	if (s[st] == s[ed])
		ret = 2+calc(st+1, ed-1);
//	ret = max(ret, calc(st+1, ed));
//	ret = max(ret, calc(st, ed-1));
	ret = max({ret, calc(st+1, ed), calc(st, ed-1)});
	return ret;
}

string s1, s2;

void print (int st, int ed, int cc) {
	if (st > ed || cc == 100)
		return;
	if (st == ed) {
		s2 += s[st];
		return;
	}
	int r1 = -1e9+9;
	if (s[st] == s[ed])
		r1 = calc(st+1, ed-1) + 2;
	int r2 = calc(st+1, ed);
	int r3 = calc(st, ed-1);
	if (r1 >= r2 && r1 >= r3) {
		s1 += s[st];
		print(st+1, ed-1, cc+2);
	} else if (r2 >= r1 && r2 >= r3) {
		print(st+1, ed, cc);
	} else {
		print(st, ed-1, cc);
	}
}

int main() {

	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> s;
	int n = SZ(s);
	for (int i = 0; i < n; ++i) {
		cnt[s[i] - 'a']++;
		if (cnt[s[i] - 'a'] == 100) {
			cout << string(100, s[i]) << endl;
			return 0;
		}
	}
	clr(dp, -1);
	s1 = s2 = "";
	print(0, n-1, 0);
	cout << s1 << s2;
	reverse(all(s1));
	cout << s1;
	cout << endl;

	return 0;
}


// in the name of Allah ;
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 4e3 + 10 ;
int arr[maxn] , dp[maxn][maxn] ,ind[maxn][maxn] , n ;
pair < int , int > par[maxn][maxn] ;
string s , ans = "" ;
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 ;
		}

	for ( int i = 0 ; i < n ; i++ )
		dp[i][i] = 1  ;
	for ( int i = n-1 ; i >= 0 ; i-- )
		for ( int j = i+1 ; 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 l = 0 , r = n , len = 0 ;
	while ( l+1 < r )
	{
		if ( len == 100 )
			break ;

		auto tmp = par[l][r] ;
		if ( tmp == make_pair ( 1 , 1 )  )
			ans += s[l] , len += 2 ;
		l += tmp.first , r -= tmp.second ;
	}
	cout << ans  ;
	if ( l + 1 == r && len != 100 )
		cout << s[l] ;
	reverse ( ans.begin() , ans.end() ) ;
	cout << ans << endl;
}