//http://blog.csdn.net/snowy_smile
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=2e5+10,M=0,Z=1e9+7,ms63=1061109567;
char s[N];
int num[128];
int main()
{
fre();
while(~scanf("%s",s))
{
MS(num,0);
int l=strlen(s);
for(int i=0;i<l;++i)++num[s[i]];
int h='a';
int t='z';
while(h<t)
{
while(h<t&&num[h]%2==0)++h;
while(h<t&&num[t]%2==0)--t;
++num[h];
--num[t];
}
int p=0;
for(int i='a';i<='z';++i)
{
while(num[i]>=2)
{
s[p]=s[l-1-p]=i;
num[i]-=2;
++p;
}
if(num[i]==1)s[l/2]=i;
}
puts(s);
}
return 0;
}
/*
【题意】
给你一个字符串s,s的长度在[1,2e5]之间。
我们想要修改最少的字符,使得s在重组之后可以得到回文串。
同时,我们还要使得,在满足上面条件的情况下,回文串的字典序尽可能小。
并输出这个回文串。
【类型】
贪心
【分析】
贪心原则已经告诉你了——
1,修改次数尽可能少,这意味着,如果一个字符出现次数为偶数,我们一定不修改。
2,字典序尽可能小,这意味着,对于两个出现次数为奇数的字符,如果修改,我们必然修改字典序大的那个。
于是做法就出来了。
统计每个字符出现的次数。
然后双指针,分别从'a'升序和从'z'降序,完成修改。
最后,我们就按照字典序贪心输出即可。
【时间复杂度&&优化】
O(n)
*/