#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <time.h>
#include <bitset>
#include <stdio.h>
#include <numeric>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Fi first
#define Se second
#define ll long long
using namespace std;

int in(int &x,int &y,int &z){return scanf("%d%d%d",&x,&y,&z);}int in(ll &x,ll &y,ll &z){return scanf("%lld%lld%lld",&x,&y,&z);}int in(double &x,double &y,double &z){return scanf("%lf%lf%lf",&x,&y,&z);}int in(int &x,ll &y){return scanf("%d%lld",&x,&y);}int in(ll &x,int &y){return scanf("%lld%d",&x,&y);}int in(int &x,int &y){return scanf("%d%d",&x,&y);}int in(ll &x,ll &y){return scanf("%lld%lld",&x,&y);}int in(char a[],char b[]){return scanf("%s%s",a,b);}int in(double &x,double &y){return scanf("%lf%lf",&x,&y);}int in(char &c){return scanf("%c",&c);}int in(char s[]){return scanf("%s",s);}int in(int &x){return scanf("%d",&x);}int in(ll &x){return scanf("%lld",&x);}int in(double &x){return scanf("%lf",&x);}int in(pair<int,int> &p){return scanf("%d%d",&p.Fi,&p.Se);}int in(pair<ll,ll>&p){return scanf("%lld%lld",&p.Fi,&p.Se);}int in(pair<double,double> &p){return scanf("%lf%lf",&p.Fi,&p.Se);}int in(long double &a){return scanf("%Lf",&a);}int in(int &x,int &y,int &z,int &k){return scanf("%d%d%d%d",&x,&y,&z,&k);}

#define inf 0x3f3f3f3f
#define PN printf("\n")
#define lowbit(x) (x&-x)
#define ull unsigned long long
#define mmin(x,y,z) min(x,min(y,z))
#define mmax(x,y,z) max(x,max(y,z))
#define PP(x) cout<<#x<<"="<<x<<" "
#define debug(x) PP(x),PN;
#define debug2(x,y) PP(x),PP(y),PN;
#define debug3(x,y,z) PP(x),PP(y),PP(z),PN;
#define debug4(x,y,z,k) PP(x),PP(y),PP(z),PP(k),PN;
#define RunTime printf("The run time is:%.3fs\n",(double)clock()/CLOCKS_PER_SEC);
const int N=2e6+10;
const int M=1e3+10;
const int mod=998244353;
ull Hash1[N<<1][2],Hash2[N<<1][2],bin[N<<1][2],seed=13131;//因为是自然溢出所以没必要取模
//seed  131 13131 13331
//另外hash是保留字符只能首字母大写了....
void get_hash(int n,char s[],ull hash[][2])
{
    bin[0][0]=bin[0][1]=1;
    for(int i=1;i<=n;i++) hash[i][0] = hash[i - 1][0]*13331+s[i],bin[i][0]=bin[i-1][0]*13131;
    for(int i=1;i<=n;i++) hash[i][1] = hash[i - 1][1]*131+s[i],bin[i][1]=bin[i-1][1]*131;
    //hash[i - 1]*seed+s[i]-'a' -'a'没有必要都是aaa反而会被卡 所以s[i]不能等于0
}
inline pair<ull,ull> get_sub(int l,int r,ull hash[][2])
{
	if(l>r) return {0,0};
    return {hash[r][0] - hash[l - 1][0] * bin[r - l + 1][0],
        hash[r][1] - hash[l - 1][1] * bin[r - l + 1][1]};
}

int mac[N<<1];

void get_mac(int len,char str[]){
    int mx=0,id;
    for(int i=1;i<=len;i++){
        if(mx>i) mac[i]=min(mac[2*id-i],mx-i);
        else mac[i]=1;
        while(str[i+mac[i]]==str[i-mac[i]])
            mac[i]++;
        if(mac[i]+i>mx)
            mx=mac[i]+i,id=i;
    }
}

// int get_mac(int n,char s[])
// {
//     int ans=1;
//     for(int i=1,p=1,j=0;i<=n;i++)
//     {
//         if(i+mac[(j<<1)-i]>=p)
//         {
//             while(p<=n&&s[p]==s[(i<<1)-p])
//             {
//                 p++;//p++才会产生本质不同回文串
//             }
//             j=i;mac[i]=p-i;
//         }
//         else mac[i]=mac[(j<<1)-i];
//         ans=max(ans,mac[i]-1);
//     }
//     return ans;
// }
char s[N],new_s[N<<1];
int main()
{
	int T;in(T);
	while(T--)
	{
		scanf("%s",s+1);
	    int n=strlen(s+1),cnt=0;
	    new_s[cnt]='~';
	    for(int i=1;i<=n;i++)
	    {
	        new_s[++cnt]='#';new_s[++cnt]=s[i];
	    }
	    new_s[++cnt]='#';new_s[cnt+1]=0;

		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash1);
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash2);

		get_mac(cnt,new_s);
		int mx=0,ans=-1,a1,a2,a3;
		for(int i=1;i<=cnt;i++)
		{
			int l=i-mac[i],r=cnt-(i+mac[i]-1);
			if(get_sub(1,l,Hash1)==get_sub(1,l,Hash2)&&l<=r)
			{
				if(mx<l+mac[i]){
					mx=mac[i]+l;
					ans=i;
					a1=1;a2=i+mac[i]-1;a3=cnt-l;
				}
			}
			if(get_sub(1,r,Hash1)==get_sub(1,r,Hash2)&&r<=l)
			{
				if(mx<r+mac[i]){
					mx=mac[i]+r;
					ans=i;
					a1=1;a2=r;a3=i-mac[i]+1;
				}
			}
		}
		for(int i=a1;i<=a2;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		for(int i=a3;i<=cnt;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		printf("\n");

	}

    return 0;
}
/*
$a$c$b$b$a$
$a$b$b$c$a$

a+回文+b
*/


#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <time.h>
#include <bitset>
#include <stdio.h>
#include <numeric>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Fi first
#define Se second
#define ll long long
using namespace std;

int in(int &x,int &y,int &z){return scanf("%d%d%d",&x,&y,&z);}int in(ll &x,ll &y,ll &z){return scanf("%lld%lld%lld",&x,&y,&z);}int in(double &x,double &y,double &z){return scanf("%lf%lf%lf",&x,&y,&z);}int in(int &x,ll &y){return scanf("%d%lld",&x,&y);}int in(ll &x,int &y){return scanf("%lld%d",&x,&y);}int in(int &x,int &y){return scanf("%d%d",&x,&y);}int in(ll &x,ll &y){return scanf("%lld%lld",&x,&y);}int in(char a[],char b[]){return scanf("%s%s",a,b);}int in(double &x,double &y){return scanf("%lf%lf",&x,&y);}int in(char &c){return scanf("%c",&c);}int in(char s[]){return scanf("%s",s);}int in(int &x){return scanf("%d",&x);}int in(ll &x){return scanf("%lld",&x);}int in(double &x){return scanf("%lf",&x);}int in(pair<int,int> &p){return scanf("%d%d",&p.Fi,&p.Se);}int in(pair<ll,ll>&p){return scanf("%lld%lld",&p.Fi,&p.Se);}int in(pair<double,double> &p){return scanf("%lf%lf",&p.Fi,&p.Se);}int in(long double &a){return scanf("%Lf",&a);}int in(int &x,int &y,int &z,int &k){return scanf("%d%d%d%d",&x,&y,&z,&k);}

#define inf 0x3f3f3f3f
#define PN printf("\n")
#define lowbit(x) (x&-x)
#define ull unsigned long long
#define mmin(x,y,z) min(x,min(y,z))
#define mmax(x,y,z) max(x,max(y,z))
#define PP(x) cout<<#x<<"="<<x<<" "
#define debug(x) PP(x),PN;
#define debug2(x,y) PP(x),PP(y),PN;
#define debug3(x,y,z) PP(x),PP(y),PP(z),PN;
#define debug4(x,y,z,k) PP(x),PP(y),PP(z),PP(k),PN;
#define RunTime printf("The run time is:%.3fs\n",(double)clock()/CLOCKS_PER_SEC);
const int N=1e6+10;
const int M=1e3+10;
const int mod=998244353;
ull Hash1[N<<1][2],Hash2[N<<1][2],bin[N<<1][2],seed=13131;//因为是自然溢出所以没必要取模
//seed  131 13131 13331
//另外hash是保留字符只能首字母大写了....
void get_hash(int n,char s[],ull hash[][2])
{
    bin[0][0]=bin[0][1]=1;
    for(int i=1;i<=n;i++) hash[i][0] = hash[i - 1][0]*13331+s[i],bin[i][0]=bin[i-1][0]*13131;
    for(int i=1;i<=n;i++) hash[i][1] = hash[i - 1][1]*131+s[i],bin[i][1]=bin[i-1][1]*131;
    //hash[i - 1]*seed+s[i]-'a' -'a'没有必要都是aaa反而会被卡 所以s[i]不能等于0
}
inline pair<ull,ull> get_sub(int l,int r,ull hash[][2])
{
	if(l>r) return {0,0};
    return {hash[r][0] - hash[l - 1][0] * bin[r - l + 1][0],
        hash[r][1] - hash[l - 1][1] * bin[r - l + 1][1]};
}

int mac[N<<1];
int get_mac(int n,char s[])
{
    int ans=1;
    for(int i=1,p=1,j=0;i<=n;i++)
    {
        if(i+mac[(j<<1)-i]>=p)
        {
            while(p<=n&&s[p]==s[(i<<1)-p])
            {
                p++;//p++才会产生本质不同回文串
            }
            j=i;mac[i]=p-i;
        }
        else mac[i]=mac[(j<<1)-i];
        ans=max(ans,mac[i]-1);
    }
    return ans;
}
char s[N],new_s[N<<1];
int main()
{
	int T;in(T);
	while(T--)
	{
		scanf("%s",s+1);
	    int n=strlen(s+1);
	    int cnt=0;
	    new_s[cnt]='~';
	    for(int i=1;i<=n;i++)
	    {
	        new_s[++cnt]='#';new_s[++cnt]=s[i];
	    }
	    new_s[++cnt]='#';new_s[cnt+1]=0;
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash1);
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash2);

		get_mac(cnt,new_s);
		int mx=0,ans=-1,a1,a2,a3;
		for(int i=1;i<=cnt;i++)
		{
			int l=i-mac[i],r=cnt-(i+mac[i]-1);
			if(get_sub(1,l,Hash1)==get_sub(1,l,Hash2)&&l<=r)
			{
				if(mx<l+mac[i]){
					mx=mac[i]+l;
					ans=i;
					a1=1;a2=i+mac[i]-1;a3=cnt-l;
				}
			}
			if(get_sub(1,r,Hash1)==get_sub(1,r,Hash2)&&r<=l)
			{
				if(mx<r+mac[i]){
					mx=mac[i]+r;
					ans=i;
					a1=1;a2=r;a3=i-mac[i]+1;
				}
			}
		}
		for(int i=a1;i<=a2;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		for(int i=a3;i<=cnt;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		printf("\n");

	}

    return 0;
}
/*
$a$c$b$b$a$
$a$b$b$c$a$

a+回文+b
*/


#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <time.h>
#include <bitset>
#include <stdio.h>
#include <numeric>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Fi first
#define Se second
#define ll long long
using namespace std;

int in(int &x,int &y,int &z){return scanf("%d%d%d",&x,&y,&z);}int in(ll &x,ll &y,ll &z){return scanf("%lld%lld%lld",&x,&y,&z);}int in(double &x,double &y,double &z){return scanf("%lf%lf%lf",&x,&y,&z);}int in(int &x,ll &y){return scanf("%d%lld",&x,&y);}int in(ll &x,int &y){return scanf("%lld%d",&x,&y);}int in(int &x,int &y){return scanf("%d%d",&x,&y);}int in(ll &x,ll &y){return scanf("%lld%lld",&x,&y);}int in(char a[],char b[]){return scanf("%s%s",a,b);}int in(double &x,double &y){return scanf("%lf%lf",&x,&y);}int in(char &c){return scanf("%c",&c);}int in(char s[]){return scanf("%s",s);}int in(int &x){return scanf("%d",&x);}int in(ll &x){return scanf("%lld",&x);}int in(double &x){return scanf("%lf",&x);}int in(pair<int,int> &p){return scanf("%d%d",&p.Fi,&p.Se);}int in(pair<ll,ll>&p){return scanf("%lld%lld",&p.Fi,&p.Se);}int in(pair<double,double> &p){return scanf("%lf%lf",&p.Fi,&p.Se);}int in(long double &a){return scanf("%Lf",&a);}int in(int &x,int &y,int &z,int &k){return scanf("%d%d%d%d",&x,&y,&z,&k);}

#define inf 0x3f3f3f3f
#define PN printf("\n")
#define lowbit(x) (x&-x)
#define ull unsigned long long
#define mmin(x,y,z) min(x,min(y,z))
#define mmax(x,y,z) max(x,max(y,z))
#define PP(x) cout<<#x<<"="<<x<<" "
#define debug(x) PP(x),PN;
#define debug2(x,y) PP(x),PP(y),PN;
#define debug3(x,y,z) PP(x),PP(y),PP(z),PN;
#define debug4(x,y,z,k) PP(x),PP(y),PP(z),PP(k),PN;
#define RunTime printf("The run time is:%.3fs\n",(double)clock()/CLOCKS_PER_SEC);
const int N=2e6+10;
const int M=1e3+10;
const int mod=998244353;
ull Hash1[N<<1][2],Hash2[N<<1][2],bin[N<<1][2],seed=13131;//因为是自然溢出所以没必要取模
//seed  131 13131 13331
//另外hash是保留字符只能首字母大写了....
void get_hash(int n,char s[],ull hash[][2])
{
    bin[0][0]=bin[0][1]=1;
    for(int i=1;i<=n;i++) hash[i][0] = hash[i - 1][0]*13331+s[i],bin[i][0]=bin[i-1][0]*13131;
    for(int i=1;i<=n;i++) hash[i][1] = hash[i - 1][1]*131+s[i],bin[i][1]=bin[i-1][1]*131;
    //hash[i - 1]*seed+s[i]-'a' -'a'没有必要都是aaa反而会被卡 所以s[i]不能等于0
}
inline pair<ull,ull> get_sub(int l,int r,ull hash[][2])
{
	if(l>r) return {0,0};
    return {hash[r][0] - hash[l - 1][0] * bin[r - l + 1][0],
        hash[r][1] - hash[l - 1][1] * bin[r - l + 1][1]};
}

int mac[N<<1];

int get_mac(int n,char s[])
{
    int ans=1;
    for(int i=1,p=1,j=0;i<=n;i++)
    {
        if(i+mac[(j<<1)-i]>=p)
        {
            while(p<=n&&s[p]==s[(i<<1)-p])
            {
                p++;//p++才会产生本质不同回文串
            }
            j=i;mac[i]=p-i;
        }
        else mac[i]=mac[(j<<1)-i];
        ans=max(ans,mac[i]-1);
    }
    return ans;
}
char s[N],new_s[N<<1];
int main()
{
	int T;in(T);
	while(T--)
	{
		scanf("%s",s+1);
	    int n=strlen(s+1),cnt=0;
	    new_s[cnt]='~';
	    for(int i=1;i<=n;i++)
	    {
	        new_s[++cnt]='#';new_s[++cnt]=s[i];
	    }
	    new_s[++cnt]='#';new_s[cnt+1]=0;

		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash1);
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash2);

		get_mac(cnt,new_s);
		int mx=0,ans=-1,a1,a2;
		for(int i=1;i<=cnt;i++)
		{
			int l=i-mac[i],r=cnt-(i+mac[i]-1);
			if(get_sub(1,l,Hash1)==get_sub(1,l,Hash2)&&l<=r)
			{
				if(mx<l+mac[i]){
					mx=mac[i]+l;
					ans=i;
					a1=i+mac[i]-1;a2=cnt-l;
				}
			}
			if(get_sub(1,r,Hash1)==get_sub(1,r,Hash2)&&r<=l)
			{
				if(mx<r+mac[i]){
					mx=mac[i]+r;
					ans=i;
					a1=r;a2=i-mac[i]+1;
				}
			}
		}
        int t=0;
		for(int i=1;i<=a1;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]),t++;
		}
		for(int i=a2;i<=cnt;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]),t++;
		}
		printf("\n");
        if(mx-1!=t) debug2(mx,t)
	}

    return 0;
}
/*
$a$c$b$b$a$
$a$b$b$c$a$

a+回文+b
*/


#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <time.h>
#include <bitset>
#include <stdio.h>
#include <numeric>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Fi first
#define Se second
#define ll long long
using namespace std;

int in(int &x,int &y,int &z){return scanf("%d%d%d",&x,&y,&z);}int in(ll &x,ll &y,ll &z){return scanf("%lld%lld%lld",&x,&y,&z);}int in(double &x,double &y,double &z){return scanf("%lf%lf%lf",&x,&y,&z);}int in(int &x,ll &y){return scanf("%d%lld",&x,&y);}int in(ll &x,int &y){return scanf("%lld%d",&x,&y);}int in(int &x,int &y){return scanf("%d%d",&x,&y);}int in(ll &x,ll &y){return scanf("%lld%lld",&x,&y);}int in(char a[],char b[]){return scanf("%s%s",a,b);}int in(double &x,double &y){return scanf("%lf%lf",&x,&y);}int in(char &c){return scanf("%c",&c);}int in(char s[]){return scanf("%s",s);}int in(int &x){return scanf("%d",&x);}int in(ll &x){return scanf("%lld",&x);}int in(double &x){return scanf("%lf",&x);}int in(pair<int,int> &p){return scanf("%d%d",&p.Fi,&p.Se);}int in(pair<ll,ll>&p){return scanf("%lld%lld",&p.Fi,&p.Se);}int in(pair<double,double> &p){return scanf("%lf%lf",&p.Fi,&p.Se);}int in(long double &a){return scanf("%Lf",&a);}int in(int &x,int &y,int &z,int &k){return scanf("%d%d%d%d",&x,&y,&z,&k);}

#define inf 0x3f3f3f3f
#define PN printf("\n")
#define lowbit(x) (x&-x)
#define ull unsigned long long
#define mmin(x,y,z) min(x,min(y,z))
#define mmax(x,y,z) max(x,max(y,z))
#define PP(x) cout<<#x<<"="<<x<<" "
#define debug(x) PP(x),PN;
#define debug2(x,y) PP(x),PP(y),PN;
#define debug3(x,y,z) PP(x),PP(y),PP(z),PN;
#define debug4(x,y,z,k) PP(x),PP(y),PP(z),PP(k),PN;
#define RunTime printf("The run time is:%.3fs\n",(double)clock()/CLOCKS_PER_SEC);
const int N=2e6+10;
const int M=1e3+10;
const int mod=998244353;
ull Hash1[N<<1][2],Hash2[N<<1][2],bin[N<<1][2],seed=13131;//因为是自然溢出所以没必要取模
//seed  131 13131 13331
//另外hash是保留字符只能首字母大写了....
void get_hash(int n,char s[],ull hash[][2])
{
    bin[0][0]=bin[0][1]=1;
    for(int i=1;i<=n;i++) hash[i][0] = hash[i - 1][0]*13331+s[i],bin[i][0]=bin[i-1][0]*13131;
    for(int i=1;i<=n;i++) hash[i][1] = hash[i - 1][1]*131+s[i],bin[i][1]=bin[i-1][1]*131;
    //hash[i - 1]*seed+s[i]-'a' -'a'没有必要都是aaa反而会被卡 所以s[i]不能等于0
}
inline pair<ull,ull> get_sub(int l,int r,ull hash[][2])
{
	if(l>r) return {0,0};
    return {hash[r][0] - hash[l - 1][0] * bin[r - l + 1][0],
        hash[r][1] - hash[l - 1][1] * bin[r - l + 1][1]};
}

int mac[N<<1];
int get_mac(int n,char s[])
{
    int ans=1;
    for(int i=1,p=1,j=0;i<=n;i++)
    {
        if(i+mac[(j<<1)-i]>=p)
        {
            while(p<=n&&s[p]==s[(i<<1)-p])
            {
                p++;//p++才会产生本质不同回文串
            }
            j=i;mac[i]=p-i;
        }
        else mac[i]=mac[(j<<1)-i];
        ans=max(ans,mac[i]-1);
    }
    return ans;
}
char s[N],new_s[N<<1];
int main()
{
	int T;in(T);
	while(T--)
	{
		scanf("%s",s+1);
	    int n=strlen(s+1);
	    int cnt=0;
	    new_s[cnt]='~';
	    for(int i=1;i<=n;i++)
	    {
	        new_s[++cnt]='#';new_s[++cnt]=s[i];
	    }
	    new_s[++cnt]='#';new_s[cnt+1]=0;
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash1);
		reverse(new_s+1,new_s+cnt+1);
		get_hash(cnt,new_s,Hash2);

		get_mac(cnt,new_s);
		int mx=0,ans=-1,a1,a2,a3;
		for(int i=1;i<=cnt;i++)
		{
			int l=i-mac[i],r=cnt-(i+mac[i]-1);
			if(get_sub(1,l,Hash1)==get_sub(1,l,Hash2)&&l<=r)
			{
				if(mx<l+mac[i]){
					mx=mac[i]+l;
					ans=i;
					a1=1;a2=i+mac[i]-1;a3=cnt-l;
				}
			}
			if(get_sub(1,r,Hash1)==get_sub(1,r,Hash2)&&r<=l)
			{
				if(mx<r+mac[i]){
					mx=mac[i]+r;
					ans=i;
					a1=1;a2=r;a3=i-mac[i]+1;
				}
			}
		}
		for(int i=a1;i<=a2;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		for(int i=a3;i<=cnt;i++)
		{
			if(new_s[i]!='#') printf("%c",new_s[i]);
		}
		printf("\n");

	}

    return 0;
}
/*
$a$c$b$b$a$
$a$b$b$c$a$

a+回文+b
*/


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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double
#define li __int128

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1, class T2> istream& operator>>(istream& is,pair<T1,T2>& a) {is>>a.f>>a.s;return is;}
template<class T> istream& operator>>(istream& is,vector<T>& a) {for(auto &p:a)is>>p;return is;}
//istream& operator>>(istream& is,__int128& a){string s;is>>s;a=0;for(auto p:s)a=a*10+p-'0';return is;}
//ostream& operator<<(ostream& os,__int128 a){bool neg=false;if(a<0)neg=true,a*=-1;ll high=(a/(__int128)1e18);ll low=(a-(__int128)1e18*high);string res;if(neg)res+='-';if(high>0){res+=to_string(high);string temp=to_string(low);res+=string(18-temp.size(),'0');res+=temp;}else res+=to_string(low);os<<res;return os;}

struct hasher{
	bool isPrime(int i){
		for(int j=2;j*j<=i;j++)
			if(i%j==0)
				return 0;
		return 1;
	}
	vector<int> mod;
	int n,m,a,mxMod=1e9+7;
	vector<vector<int> > pwr;
	vector<vector<int> > h;
	void init(string s,int number_of_mods){
		m=number_of_mods;
		for(;mod.size()<m;mxMod++)
			if(isPrime(mxMod))
				mod.push_back(mxMod);
		n=s.size();
		a=rng()%((int)1e9-250)+256;
		shuffle(all(mod),rng);
		h.resize(m);
		pwr.resize(m);
		for(int i=0;i<m;i++)
			h[i].resize(n),pwr[i].resize(n+1);
		for(int j=0;j<m;j++){
			h[j][0]=s[0]%mod[j];
			pwr[j][0]=1;
			for(int i=1;i<n;i++){
				h[j][i]=((ll)h[j][i-1]*a+s[i])%mod[j],pwr[j][i]=(ll)pwr[j][i-1]*a%mod[j];
			}
			pwr[j][n]=(ll)pwr[j][n-1]*a%mod[j];
		}
	}
	int getHash(int l,int r,int i){
		int hh=h[i][r];
		if(l){
			hh=hh-((ll)pwr[i][r-l+1]*h[i][l-1]%mod[i]);
			if(hh<0)
				hh+=mod[i];
		}
		return hh;
	}
	bool same(int l1,int r1,int l2,int r2){
		if(r1-l1!=r2-l2||l1>r1)
			return 0;
		for(int i=0;i<m;i++)
			if(getHash(l1,r1,i)!=getHash(l2,r2,i))
				return 0;
		return 1;
	}
}h;

void test(){
	string s;
	cin >> s;
	int n=s.size();
	int poc=0;
	for(int i=0;i<n/2;i++){
		if(s[i]==s[n-1-i])
			poc++;
		else
			break;
	}
	string po=s.substr(0,poc);
	s=s.substr(poc,n-2*poc);
	n-=2*poc;
	if(n==0){
		for(auto p:po)
			printf("%c",p);
		reverse(all(po));
		for(auto p:po)
			printf("%c",p);
		printf("\n");
		return;
	}
	string rr=s;
	reverse(all(rr));
	s+=rr;
	h.init(s,15);
	for(int i=n;;i--){
		int a=0,b=i-1;
		if(h.same(a,b,n-1-b+n,n-1-a+n)){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		a=n-i,b=n-1;
		if(h.same(a,b,n-1-b+n,n-1-a+n)){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
	}
}
int main()
{
	int t;
	cin >> t;
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+9,puta=26+(rng()%10); //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		int poc=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-1-i])
				poc++;
			else
				break;
		}
		string po=s.substr(0,poc);
		s=s.substr(poc,n-2*poc);
		n-=2*poc;
		if(n==0){
			for(auto p:po)
				printf("%c",p);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		for(int i=n;;i--){
			int a=0,b=i-1;
			int pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			int su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
			a=n-i,b=n-1;
			pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

#define int long long
const int mod=573428957424123,puta=26; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
	cin >> s;
	int n=s.size();
	int poc=0;
	for(int i=0;i<n/2;i++){
		if(s[i]==s[n-1-i])
			poc++;
		else
			break;
	}
	string po=s.substr(0,poc);
	s=s.substr(poc,n-2*poc);
	n-=2*poc;
	if(n==0){
		for(auto p:po)
			printf("%c",p);
		reverse(all(po));
		for(auto p:po)
			printf("%c",p);
		printf("\n");
		return;
	}
	vector<int> pre(n),suf(n);
	pre[0]=s[0]-'a';
	suf[n-1]=s[n-1]-'a';
	for(int i=1;i<n;i++){
		pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
	}
	for(int i=n-2;i>=0;i--){
		suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
	}
	for(int i=n;;i--){
		int a=0,b=i-1;
		int pr=pre[b];
		if(a)
			pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
		int su=suf[a];
		if(b!=n-1)
			su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
		if(pr==su){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		a=n-i,b=n-1;
		pr=pre[b];
		if(a)
			pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
		su=suf[a];
		if(b!=n-1)
			su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
		if(pr==su){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
	}
}
#undef int
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	cin >> t;
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+7,puta=26; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		int ans=0;
		vector<int> sol(n,1);
		for(int i=0;i<n;i++){
			int l=1,r=min(i+1,n-i);
			while(l<r){
				int m=(l+r+1)>>1;
				int a=i-m+1,b=i+m-1;
				int pr=pre[b];
				if(a)
					pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
				int su=suf[a];
				if(b!=n-1)
					su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
				if(pr==su){
					l=m;
				}
				else{
					r=m-1;
				}
			}
			int a=i-l+1,b=i+l-1;
			if(a==0){
				ans=max(ans,2*l-1);
			}
			else{
				if(i<n/2)
					sol[a-1]=max(sol[a-1],2*l-1);
			}
			if(b==n-1){
				ans=max(ans,2*l-1);
			}
			else{
				if(i>=n/2)
					sol[b+1]=max(sol[b+1],2*l-1);
			}
			//printf("%i:  %i  %i\n",i,a,b);
		}
		for(int i=0;i<n-1;i++){
			int l=0,r=min(i+1,n-i-1);
			while(l<r){
				int m=(l+r+1)>>1;
				int a=i-m+1,b=i+m;
				int pr=pre[b];
				if(a)
					pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
				int su=suf[a];
				if(b!=n-1)
					su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
				if(pr==su){
					l=m;
				}
				else{
					r=m-1;
				}
			}
			if(l==0)
				continue;
			int a=i-l+1,b=i+l;
			if(a==0){
				ans=max(ans,2*l);
			}
			else{
				if(i<n/2)
					sol[a-1]=max(sol[a-1],2*l);
			}
			if(b==n-1){
				ans=max(ans,2*l);
			}
			else{
				if(i>=n/2)
					sol[b+1]=max(sol[b+1],2*l);
			}
			//printf("%i:  %i  %i\n",i,a,b);
		}
		for(int i=0;i<n/2;i++){
			if(s[i]!=s[n-i-1])
				break;
			int tra=2*(i+1)+sol[i];
			ans=max(ans,tra);
			int trb=2*(i+1)+sol[n-1-i];
			ans=max(ans,trb);
		}
		//printf("%i!\n",ans);
		for(int i=0;i<n;i++){
			int l=1,r=min(i+1,n-i);
			while(l<r){
				int m=(l+r+1)>>1;
				int a=i-m+1,b=i+m-1;
				int pr=pre[b];
				if(a)
					pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
				int su=suf[a];
				if(b!=n-1)
					su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
				if(pr==su){
					l=m;
				}
				else{
					r=m-1;
				}
			}
			int a=i-l+1,b=i+l-1;
			if(a==0){
				if(ans==2*l-1){
					for(int i=a;i<=b;i++)
						printf("%c",s[i]);
					printf("\n");
					return;
				}
			}
			if(b==n-1){
				if(ans==2*l-1){
					for(int i=a;i<=b;i++)
						printf("%c",s[i]);
					printf("\n");
					return;
				}
			}
			//printf("%i:  %i  %i\n",i,a,b);
		}
		for(int i=0;i<n-1;i++){
			int l=0,r=min(i+1,n-i-1);
			while(l<r){
				int m=(l+r+1)>>1;
				int a=i-m+1,b=i+m;
				int pr=pre[b];
				if(a)
					pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
				int su=suf[a];
				if(b!=n-1)
					su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
				if(pr==su){
					l=m;
				}
				else{
					r=m-1;
				}
			}
			if(l==0)
				continue;
			int a=i-l+1,b=i+l;
			if(a==0){
				if(ans==2*l){
					for(int i=a;i<=b;i++)
						printf("%c",s[i]);
					printf("\n");
					return;
				}
			}
			if(b==n-1){
				if(ans==2*l){
					for(int i=a;i<=b;i++)
						printf("%c",s[i]);
					printf("\n");
					return;
				}
			}
			//printf("%i:  %i  %i\n",i,a,b);
		}
		for(int i=0;i<n/2;i++){
			if(s[i]!=s[n-i-1])
				break;
			int tra=2*(i+1)+sol[i];
			if(ans==tra){
				for(int j=0;j<tra-i-1;j++)
					printf("%c",s[j]);
				for(int j=n-i-1;j<n;j++)
					printf("%c",s[j]);
				printf("\n");
				return;
			}
			int trb=2*(i+1)+sol[n-1-i];
			if(ans==trb){
				for(int j=0;j<=i;j++)
					printf("%c",s[j]);
				for(int j=n-trb+i+1;j<n;j++)
					printf("%c",s[j]);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


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

    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define f first
    #define s second
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()

    using namespace std;
    using namespace __gnu_pbds;

    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
    template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
    template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
    template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
    template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
    template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
    template<class T1,class T2> ostream& operator<<(ostream& os, const gp_hash_table<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

    int a = 26;
    ll p = 1e9 + 9;
    ll p2 = 1e9 + 7;

    ll aNaK[1000020];
    ll aNaK2[1000020];

    ll add(ll a, ll b, ll mod)
    {
        return (a+b) % mod;
    }

    ll multiply(ll a, ll b, ll mod)
    {
        return (a*b) % mod;
    }

    ll init(ll i)
    {
        if(aNaK[i] != 0)
            return aNaK[i];

        if(i == 0)
        {
            aNaK[i] = 1;
            return 1;
        }

        else if(i == 1)
        {
            aNaK[i] = a;
            return a;
        }

        aNaK[i] =  (a*init(i-1))%p;
        return aNaK[i];

    }

    ll init2(ll i)
    {
        if(aNaK2[i] != 0)
            return aNaK2[i];

        if(i == 0)
        {
            aNaK2[i] = 1;
            return 1;
        }

        else if(i == 1)
        {
            aNaK2[i] = a;
            return a;
        }

        aNaK2[i] =  (a*init(i-1))%p2;
        return aNaK2[i];

    }

    string palindrome(string s)
    {
        //cout << "STRING " << s << endl;
        ll prehash = 0;
        ll sufhash = 0;
        ll prehash2 = 0;
        ll sufhash2 = 0;
        ll resL=0;
        ll resD= 0;
        string inverse = "";
        for(int i = s.size()-1; i >=0; i--)
            inverse += s[i];

        for(int i = 0; i <= s.size()-1; i++)
        {
            prehash = add(multiply(prehash, a,p), s[i],p);
            sufhash = add(sufhash, multiply(inverse[s.size()-1-i], init(i),p),p);
             prehash2 = add(multiply(prehash2, a,p2), s[i],p2);
            sufhash2 = add(sufhash2, multiply(inverse[s.size()-1-i], init2(i),p2),p2);

            if(prehash == sufhash && prehash2 == sufhash2)
                resL = i;
        }

        prehash=0;
        sufhash=0; prehash2=0;
        sufhash2=0;

         for(int i = 0; i <= s.size()-1; i++)
        {
            prehash = add(multiply(prehash, a,p), inverse[i],p);
            sufhash = add(sufhash, multiply(s[s.size()-1-i], init(i),p),p);

            prehash2 = add(multiply(prehash2, a,p2), inverse[i],p2);
            sufhash2 = add(sufhash2, multiply(s[s.size()-1-i], init2(i),p2),p2);

            if(prehash == sufhash && prehash2 == sufhash2)
                resD = i;
        }

        if(resL>resD)
            return s.substr(0, resL+1);
            else
              return inverse.substr(0, resD+1);
    }

    int main()
    {
	    ios_base::sync_with_stdio(false);
    	cin.tie(NULL);

        int t;
        cin >> t;

        while(t--)
        {
            string s;
            cin >> s;

            ll l = 0, r = s.size()-1;

            while(l < r && s[l] == s[r])
            {
                l++; r--;

            }
            l--;
            r++;

            //cout << l << " " << r << endl;

            string res = s.substr(0, l+1);
            if(s.size()-2*(l+1) >= 1)
                res += palindrome(s.substr(l+1, s.size()-2*(l+1)));
            res += s.substr(r, s.size()-r);

            cout << res << endl;

        }

        return 0;
    }


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+7,puta=26+rng()%10; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		int poc=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-1-i])
				poc++;
			else
				break;
		}
		string po=s.substr(0,poc);
		s=s.substr(poc,n-2*poc);
		n-=2*poc;
		if(n==0){
			for(auto p:po)
				printf("%c",p);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		for(int i=n;;i--){
			int a=0,b=i-1;
			int pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			int su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
			a=n-i,b=n-1;
			pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+7,puta=26+rng()%3; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		int poc=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-1-i])
				poc++;
			else
				break;
		}
		string po=s.substr(0,poc);
		s=s.substr(poc,n-2*poc);
		n-=2*poc;
		if(n==0){
			for(auto p:po)
				printf("%c",p);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		for(int i=n;;i--){
			int a=0,b=i-1;
			int pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			int su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
			a=n-i,b=n-1;
			pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double
#define li __int128

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1, class T2> istream& operator>>(istream& is,pair<T1,T2>& a) {is>>a.f>>a.s;return is;}
template<class T> istream& operator>>(istream& is,vector<T>& a) {for(auto &p:a)is>>p;return is;}
//istream& operator>>(istream& is,__int128& a){string s;is>>s;a=0;for(auto p:s)a=a*10+p-'0';return is;}
//ostream& operator<<(ostream& os,__int128 a){bool neg=false;if(a<0)neg=true,a*=-1;ll high=(a/(__int128)1e18);ll low=(a-(__int128)1e18*high);string res;if(neg)res+='-';if(high>0){res+=to_string(high);string temp=to_string(low);res+=string(18-temp.size(),'0');res+=temp;}else res+=to_string(low);os<<res;return os;}

struct hasher{
	vector<int> mod={(int)1e9+7,(int)1e9+9,(int)1e9+21,(int)1e9+33,(int)1e9+87,(int)1e9+93,(int)1e9+97,(int)1e9+103,(int)1e9+123,(int)1e9+181};
	int n,m,a;
	vector<vector<int> > pwr;
	vector<vector<int> > h;
	void init(string s,int N){
		m=min(10,N);
		n=s.size();
		a=rng()%((int)1e9-249)+255;
		shuffle(all(mod),rng);
		h.resize(m);
		pwr.resize(m);
		for(int i=0;i<m;i++)
			h[i].resize(n),pwr[i].resize(n+1);
		for(int j=0;j<m;j++){
			h[j][0]=s[0]%mod[j];
			pwr[j][0]=1;
			for(int i=1;i<n;i++){
				h[j][i]=((ll)h[j][i-1]*a+s[i])%mod[j],pwr[j][i]=(ll)pwr[j][i-1]*a%mod[j];
			}
			pwr[j][n]=(ll)pwr[j][n-1]*a%mod[j];
		}
	}
	bool same(int l1,int r1,int l2,int r2){
		if(r1-l1!=r2-l2||l1>r1)
			return 0;
		for(int i=0;i<m;i++){
			int h1=h[i][r1];
			if(l1){
				h1=h1-((ll)pwr[i][r1-l1+1]*h[i][l1-1]%mod[i]);
				if(h1<0)
					h1+=mod[i];
			}
			int h2=h[i][r2];
			if(l2){
				h2=h2-((ll)pwr[i][r2-l2+1]*h[i][l2-1]%mod[i]);
				if(h2<0)
					h2+=mod[i];
			}
			if(h1!=h2)
				return 0;
		}
		return 1;
	}
}h;

void test(){
	string s;
	cin >> s;
	int n=s.size();
	int poc=0;
	for(int i=0;i<n/2;i++){
		if(s[i]==s[n-1-i])
			poc++;
		else
			break;
	}
	string po=s.substr(0,poc);
	s=s.substr(poc,n-2*poc);
	n-=2*poc;
	if(n==0){
		for(auto p:po)
			printf("%c",p);
		reverse(all(po));
		for(auto p:po)
			printf("%c",p);
		printf("\n");
		return;
	}
	string rr=s;
	reverse(all(rr));
	s+=rr;
	h.init(s,10);
	for(int i=n;;i--){
		int a=0,b=i-1;
		if(h.same(a,b,n-1-b+n,n-1-a+n)){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		a=n-i,b=n-1;
		if(h.same(a,b,n-1-b+n,n-1-a+n)){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
	}
}
int main()
{
	int t;
	cin >> t;
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+9,puta=26+rng()%3; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		int poc=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-1-i])
				poc++;
			else
				break;
		}
		string po=s.substr(0,poc);
		s=s.substr(poc,n-2*poc);
		n-=2*poc;
		if(n==0){
			for(auto p:po)
				printf("%c",p);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		for(int i=n;;i--){
			int a=0,b=i-1;
			int pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			int su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
			a=n-i,b=n-1;
			pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod=1e9+7,puta=26; //998244353
int add(int a,int b){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b){
    return (long long)a*b%mod;
}
int pwrmod(int x,int k){
    int ans=1;
    for(;k;k>>=1,x=mul(x,x))
        if(k&1)
            ans=mul(ans,x);
    return ans;
}
const int N=1e6+1;
vector<int> pwrs(1,1);
void test(){
	string s;
		cin >> s;
		int n=s.size();
		int poc=0;
		for(int i=0;i<n/2;i++){
			if(s[i]==s[n-1-i])
				poc++;
			else
				break;
		}
		string po=s.substr(0,poc);
		s=s.substr(poc,n-2*poc);
		n-=2*poc;
		if(n==0){
			for(auto p:po)
				printf("%c",p);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		vector<int> pre(n),suf(n);
		pre[0]=s[0]-'a';
		suf[n-1]=s[n-1]-'a';
		for(int i=1;i<n;i++){
			pre[i]=add(mul(pre[i-1],puta),s[i]-'a');
		}
		for(int i=n-2;i>=0;i--){
			suf[i]=add(mul(suf[i+1],puta),s[i]-'a');
		}
		for(int i=n;;i--){
			int a=0,b=i-1;
			int pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			int su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
			a=n-i,b=n-1;
			pr=pre[b];
			if(a)
				pr=sub(pr,mul(pre[a-1],pwrs[b-a+1]));
			su=suf[a];
			if(b!=n-1)
				su=sub(su,mul(suf[b+1],pwrs[b-a+1]));
			if(pr==su){
				for(auto p:po)
					printf("%c",p);
				for(int i=a;i<=b;i++)
					printf("%c",s[i]);
				reverse(all(po));
				for(auto p:po)
					printf("%c",p);
				printf("\n");
				return;
			}
		}
}
int main()
{
	for(int i=1;i<N;i++)
		pwrs.pb(mul(pwrs.back(),puta));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


// Problem : D2. Prefix-Suffix Palindrome (Hard version)
// Contest : Codeforces Global Round 7
// URL : http://codeforces.com/contest/1326/problem/D2
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

const int mod1=1e9+7,mod2=1e9+9; //998244353
int puta;
int add(int a,int b,int mod){
    a+=b;
    if(a>=mod)
        a-=mod;
    return a;
}
int sub(int a,int b,int mod){
    a-=b;
    if(a<0)
        a+=mod;
    return a;
}
int mul(int a,int b,int mod){
    return (long long)a*b%mod;
}
const int N=1e6+1;
vector<int> pwrs1(1,1),pwrs2(1,1);
void test(){
	string s;
	cin >> s;
	int n=s.size();
	int poc=0;
	for(int i=0;i<n/2;i++){
		if(s[i]==s[n-1-i])
			poc++;
		else
			break;
	}
	string po=s.substr(0,poc);
	s=s.substr(poc,n-2*poc);
	n-=2*poc;
	if(n==0){
		for(auto p:po)
			printf("%c",p);
		reverse(all(po));
		for(auto p:po)
			printf("%c",p);
		printf("\n");
		return;
	}
	vector<int> pre1(n),pre2(n),suf1(n),suf2(n);
	pre1[0]=pre2[0]=s[0]-'a';
	suf1[n-1]=suf2[n-1]=s[n-1]-'a';
	for(int i=1;i<n;i++){
		pre1[i]=add(mul(pre1[i-1],puta,mod1),s[i]-'a',mod1);
		pre2[i]=add(mul(pre2[i-1],puta,mod2),s[i]-'a',mod2);
	}
	for(int i=n-2;i>=0;i--){
		suf1[i]=add(mul(suf1[i+1],puta,mod1),s[i]-'a',mod1);
		suf2[i]=add(mul(suf2[i+1],puta,mod2),s[i]-'a',mod2);
	}
	for(int i=n;;i--){
		int a=0,b=i-1;
		int pr1=pre1[b],pr2=pre2[b];
		if(a)
			pr1=sub(pr1,mul(pre1[a-1],pwrs1[b-a+1],mod1),mod1),pr2=sub(pr2,mul(pre2[a-1],pwrs2[b-a+1],mod2),mod2);
		int su1=suf1[a],su2=suf2[a];
		if(b!=n-1)
			su1=sub(su1,mul(suf1[b+1],pwrs1[b-a+1],mod1),mod1),su2=sub(su2,mul(suf2[b+1],pwrs2[b-a+1],mod2),mod2);
		if(pr1==su1&&pr2==su2){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
		a=n-i,b=n-1;
		pr1=pre1[b],pr2=pre2[b];
		if(a)
			pr1=sub(pr1,mul(pre1[a-1],pwrs1[b-a+1],mod1),mod1),pr2=sub(pr2,mul(pre2[a-1],pwrs2[b-a+1],mod2),mod2);
		su1=suf1[a],su2=suf2[a];
		if(b!=n-1)
			su1=sub(su1,mul(suf1[b+1],pwrs1[b-a+1],mod1),mod1),su2=sub(su2,mul(suf2[b+1],pwrs2[b-a+1],mod2),mod2);
		if(pr1==su1&&pr2==su2){
			for(auto p:po)
				printf("%c",p);
			for(int i=a;i<=b;i++)
				printf("%c",s[i]);
			reverse(all(po));
			for(auto p:po)
				printf("%c",p);
			printf("\n");
			return;
		}
	}
}
int main()
{
	puta=rng()%10+26;
	for(int i=1;i<N;i++)
		pwrs1.pb(mul(pwrs1.back(),puta,mod1));
	for(int i=1;i<N;i++)
		pwrs2.pb(mul(pwrs2.back(),puta,mod2));
	int t;
	scanf("%i",&t);
	while(t--){
		test();
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str, ret;

void manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	ret.resize(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
}

void solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		manacher(saux);

		//cout << "saux " << saux << endl;

		vector<int> par(ret.size()/2), impar((ret.size()+1)/2);
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar[i/2] = ret[i];
			else par[i/2] = ret[i];
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {

					mid = saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {

					mid = saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	cout << pref << mid;

	for(int i = suf.size()-1; i>=0; i--) cout << suf[i];
	cout << endl;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		solve();
	}

	exit(0);
}


 #include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

string pal(int l, int r) {
	string ans, aux;

	for(int i=r; i>=l; i--) {
		bool flag = true;

		aux.clear();

		int laux = l, raux = i;
		while(laux < raux) {
			if(str[laux] == str[raux]) {
				aux.pb(str[laux]);
				laux++; raux--;
			}
			else {
				flag = false;
				break;
			}
		}
		if(flag) {
			int szaux = aux.size();
			if(laux == raux) {
				aux.pb(str[laux]);
				laux++;
			}

			for(int j=szaux-1; j>=0; j--) {
				aux.pb(aux[j]);
			}

			if(aux.size() > ans.size()) {
				ans = aux;
			}
			break;
		}
	}

	for(int i=l; i<=r; i++) {
		bool flag = true;

		aux.clear();

		int laux = i, raux = r;
		while(laux < raux) {
			if(str[laux] == str[raux]) {
				aux.pb(str[laux]);
				laux++; raux--;
			}
			else {
				flag = false;
				break;
			}
		}
		if(flag) {
			int szaux = aux.size();
			if(laux == raux) {
				aux.pb(str[laux]);
				laux++;
			}
			for(int j=szaux-1; j>=0; j--) {
				aux.pb(aux[j]);
			}

			if(aux.size() > ans.size()) ans = aux;

			break;
		}
	}

	return ans;
}

string solve() {
	int l = 0, r = str.size()-1;

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			//r--; l++;
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	//cout << "suf " << suf << endl;
	//cout << "pre " << pref << endl;

	mid = pal(l, r);

	//cout << "mid " << mid << endl;

	string ans = pref + mid;
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str, ret;

void manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	ret.resize(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
}

void solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		manacher(saux);

		vector<int> par(ret.size()/2), impar((ret.size()+1)/2);
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar[i/2] = ret[i];
			else par[i/2] = ret[i];
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {

					mid = saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {

					mid = saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	cout << pref << mid;

	for(int i = suf.size()-1; i>=0; i--) cout << suf[i];
	cout << endl;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		solve();
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

void solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		int maxi = 0, pos;
		bool flag = false;
		for(int i=0; i<(ret.size()+1)/2; i++) {
			if(ret[i*2]/2 == i or ret[i*2]/2+1 == saux.size()-i) {
				if(ret[i*2] > maxi) {
					pos = i;
					flag = true;
					maxi = ret[i*2];
				}
			}
		}

		if(flag) mid = saux.substr(pos-(ret[pos*2]/2), ret[pos*2]);

		flag = false;
		for(int i=0; i<ret.size()/2; i++) {
			if(ret[i*2+1]/2 == i+1 or ret[i*2+1]/2 == saux.size()-i-1) {
				if(ret[i*2+1] > maxi) {
					flag = true;
					pos = i;
					maxi = ret[i*2+1];
				}
			}
		}

		if(flag) mid = saux.substr(pos-(ret[pos*2+1]/2)+1, ret[pos*2+1]);
	}

	cout << pref << mid;

	for(int i = suf.size()-1; i>=0; i--) cout << suf[i];
	cout << endl;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		solve();
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

string solve() {
	int l = 0, r = str.size()-1, n = str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			//r--; l++;
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		vector<int> par, impar;
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar.pb(ret[i]);
			else par.pb(ret[i]);
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	string ans = pref + mid;
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


 #include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

string pal(int l, int r) {
	string ans, aux;

	for(int i=r; i>=l; i--) {
		bool flag = true;

		aux.clear();

		int laux = l, raux = i;
		while(laux < raux) {
			if(str[laux] == str[raux]) {
				aux.pb(str[laux]);
				laux++; raux--;
			}
			else {
				flag = false;
				break;
			}
		}
		if(flag) {
			int szaux = aux.size();
			if(laux == raux) {
				aux.pb(str[laux]);
				laux++;
			}

			for(int j=szaux-1; j>=0; j--) {
				aux.pb(aux[j]);
			}

			if(aux.size() > ans.size()) {
				ans = aux;
			}
		}
	}

	for(int i=l; i<=r; i++) {
		bool flag = true;

		aux.clear();

		int laux = i, raux = r;
		while(laux < raux) {
			if(str[laux] == str[raux]) {
				aux.pb(str[laux]);
				laux++; raux--;
			}
			else {
				flag = false;
				break;
			}
		}
		if(flag) {
			int szaux = aux.size();
			if(laux == raux) {
				aux.pb(str[laux]);
				laux++;
			}
			for(int j=szaux-1; j>=0; j--) {
				aux.pb(aux[j]);
			}

			if(aux.size() > ans.size()) ans = aux;
		}
	}

	return ans;
}

string solve() {
	int l = 0, r = str.size()-1;

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			//r--; l++;
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	//cout << "suf " << suf << endl;
	//cout << "pre " << pref << endl;

	mid = pal(l, r);

	//cout << "mid " << mid << endl;

	string ans = pref + mid;
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

string solve() {
	int l = 0, r = str.size()-1, n = str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		//cout << "saux " << saux << endl;

		vector<int> par(ret.size()/2), impar((ret.size()+1)/2);
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar[i/2] = ret[i];
			else par[i/2] = ret[i];
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	string ans = pref + mid;
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ //_

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

string solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		//cout << "saux " << saux << endl;

		vector<int> par(ret.size()/2), impar((ret.size()+1)/2);
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar[i/2] = ret[i];
			else par[i/2] = ret[i];
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {

					mid = saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {

					mid = saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	string ans = pref + mid;
	/*int all = 0, i;
	for(i=0; i<pref.size(); i++) ans[i] = pref[i];
	all = i;
	for(i=0; i<mid.size(); i++) ans[i+all] = mid[i];
	all = i;*/
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

void solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		//cout << "saux " << saux << endl;

		vector<int> par(ret.size()/2), impar((ret.size()+1)/2);
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar[i/2] = ret[i];
			else par[i/2] = ret[i];
		}

		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {

					mid = saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {

					mid = saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	cout << pref << mid;

	for(int i = suf.size()-1; i>=0; i--) cout << suf[i];
	cout << endl;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		solve();
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = (int) s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

void solve() {
	int l = 0, r = str.size()-1, n = (int) str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		int maxi = 0;
		for(int i=0; i<(ret.size()+1)/2; i++) {
			if(ret[i*2]/2 == i or ret[i*2]/2+1 == saux.size()-i) {
				if(ret[i*2] > maxi) {

					mid = saux.substr(i-(ret[i*2]/2), ret[i*2]);
					maxi = ret[i*2];
				}
			}
		}
		for(int i=0; i<ret.size()/2; i++) {
			if(ret[i*2+1]/2 == i+1 or ret[i*2+1]/2 == saux.size()-i-1) {
				if(ret[i*2+1] > maxi) {

					mid = saux.substr(i-(ret[i*2+1]/2)+1, ret[i*2+1]);
					maxi = ret[i*2+1];
				}
			}
		}
	}

	cout << pref << mid;

	for(int i = suf.size()-1; i>=0; i--) cout << suf[i];
	cout << endl;
}

int main(){ _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		solve();
	}

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;

string str;

vector<int> manacher(string &s){
	int l = 0, r = -1, n = s.size();
	vector<int> d1(n), d2(n);
	for (int i = 0; i < n; i++){
		int k = i > r ? 1 : min(d1[l+r-i], r-i);
		while(i+k<n && i-k >= 0 && s[i+k] == s[i-k]) k++;
		d1[i] = k--;
		if(i+k > r) l = i-k, r = i+k;
	}
	l = 0; r=-1;
	for (int i = 0; i < n; i++){
		int k = i > r ? 0 : min(d2[l+r-i+1], r-i+1); k++;
		while(i+k<=n && i-k >= 0 && s[i+k-1] == s[i-k]) k++;
		d2[i] = --k ;
		if(i+k-1 > r) l = i-k, r = i+k-1;
	}
	vector<int> ret(2*n-1);
	for (int i = 0; i < n; i++)
		ret[2*i] = 2*d1[i]-1;
	for (int i = 0; i < n-1; i++)
		ret[2*i+1] = 2*d2[i+1];
	return ret;
}

string solve() {
	int l = 0, r = str.size()-1, n = str.size();

	string pref, suf, mid;

	while(l < r) {
		if(str[l] == str[r]) {
			pref.pb(str[l]);
			suf.pb(str[r]);
			r--; l++;
		}
		else {
			//r--; l++;
			break;
		}
	}
	if(l == r) {
		pref.pb(str[l]);
		l++;
	}

	//cout << "suf " << suf << endl;
	//cout << "pre " << pref << endl;

	string saux;
	for(int i = l; i<=r; i++) saux.pb(str[i]);

	if(saux.size()) {
		vector<int> ret(2*saux.size() - 1);
		ret = manacher(saux);

		vector<int> par, impar;
		for(int i=0; i<ret.size(); i++) {
			if(i%2==0) impar.pb(ret[i]);
			else par.pb(ret[i]);
		}

		/*cout << "par" << endl;
		for(auto u:par) cout << u << " ";
		cout << endl;
		cout << "impar"  << endl;
		for(auto u : impar) cout << u << " ";
		cout << endl;

		cout << "saux " << saux << endl;
		*/
		int maxi = 0;
		for(int i=0; i<impar.size(); i++) {
			//cout << "CONTA " << impar[i]/2+1 << " " << saux.size()-i << endl;
			if(impar[i]/2 == i or impar[i]/2+1 == saux.size()-i) {
				if(impar[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(impar[i]/2), impar[i]);
					maxi = impar[i];
				}
			}
		}
		for(int i=0; i<par.size(); i++) {
			if(par[i]/2 == i+1 or par[i]/2 == saux.size()-i-1) {
				if(par[i] > maxi) {
					mid = "";

					mid += saux.substr(i-(par[i]/2)+1, par[i]);
					maxi = par[i];
				}
			}
		}
	}

	string ans = pref + mid;
	for(int i = suf.size()-1; i>=0; i--) ans.pb(suf[i]);

	return ans;
}

int main(){ // _

	int t; cin >> t;

	while(t--) {
		cin >> str;

		cout << solve() << endl;
	}

	exit(0);
}


/*================= *\
|  ID : aman__guta__ |
|      LANG: C++     |
\*==================*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define ld long double
#define pb push_back
#define mk make_pair
#define fs first
#define sc second
#define mod 1000000007
#define sp <<" "<<
#define JOKER ios_base::sync_with_stdio (false) ; cin.tie(0) ; cout.tie(0) ;
int spf[10000001];
long long int fac[200005];
void sieve(int n)
{
    spf[1]=1;
    for(int i=2;i<=n;i++) spf[i]=i;
    for(int i=4;i<=n;i+=2) spf[i]=2;
    for(int i=3;i*i<=n;i++)
    {
        if(spf[i]==i)
        {
            for(int j=i*i;j<=n;j+=i)
            {
                if(spf[j]==j) spf[j]=i;
            }
        }
    }
}
long long int power(long long int x, long long int y, long long int p)
{
    long long int res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;
        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}
long long int modInverse(long long int n, long long int p)
{
    return power(n, p-2, p);
}
long long int nCrModPFermat(long long int n, long long int r, long long int p)
{
   if (r==0)
      return 1;
    return (fac[n]* modInverse(fac[r], p) % p *
            modInverse(fac[n-r], p) % p) % p;
}
string s;
int longestPrefixSuffix()
{
    int n = s.size();
    int lps[n];
    lps[0] = 0;
    int len = 0;
    int i = 1;
    while (i < n)
    {
        if (s[i] == s[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
    int res = lps[n-1];
    return res;
}
main()
{
    JOKER
    int t;
    cin>>t;
    while(t--)
    {
        cin>>s;
        int i=0;
        int j=s.size()-1;
        string a="",b="";
        while(i<j)
        {
            if(s[i]==s[j])
            {
                a+=s[i];
                b+=s[j];
                i++;
                j--;
            }
            else break;
        }
        string s1="";
        for(i=(int)a.size(); i<(int)s.size()-(int)b.size(); i++)
        {
            s1+=s[i];
        }
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int x=s1.size();
        // cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        x=min(x,longestPrefixSuffix());
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int y=s1.size();
        // cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        y=min(y,longestPrefixSuffix());
        reverse(b.begin(),b.end());
        if(x>=y)
        {

            cout<<a;
            for(int i=0; i<x; i++)
                cout<<s1[i];
            cout<<b<<endl;
        }
        else
        {
            cout<<a;
            for(int i=(int)s1.size()-1; i>(int)s1.size()-1-y; i--)
                cout<<s1[i];
            cout<<b<<endl;
        }
    }
    cerr<<"Time elapsed : "<<clock()*1000.0/CLOCKS_PER_SEC<<"ms"<<'\n';
    return 0;
}


/*================= *\
|  ID : aman__guta__ |
|      LANG: C++     |
\*==================*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define ld long double
#define pb push_back
#define mk make_pair
#define fs first
#define sc second
#define mod 1000000007
#define sp <<" "<<
#define JOKER ios_base::sync_with_stdio (false) ; cin.tie(0) ; cout.tie(0) ;
int spf[10000001];
long long int fac[200005];
void sieve(int n)
{
    spf[1]=1;
    for(int i=2;i<=n;i++) spf[i]=i;
    for(int i=4;i<=n;i+=2) spf[i]=2;
    for(int i=3;i*i<=n;i++)
    {
        if(spf[i]==i)
        {
            for(int j=i*i;j<=n;j+=i)
            {
                if(spf[j]==j) spf[j]=i;
            }
        }
    }
}
long long int power(long long int x, long long int y, long long int p)
{
    long long int res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;
        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}
long long int modInverse(long long int n, long long int p)
{
    return power(n, p-2, p);
}
long long int nCrModPFermat(long long int n, long long int r, long long int p)
{
   if (r==0)
      return 1;
    return (fac[n]* modInverse(fac[r], p) % p *
            modInverse(fac[n-r], p) % p) % p;
}
string s;
int longestPrefixSuffix()
{
    int n = s.size();
    int lps[n]={};
    lps[0] = 0;
    int len = 0;
    int i = 1;
    while (i < n)
    {
        if (s[i] == s[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
    int res = lps[n-1];
    return res;
}
main()
{
    JOKER
    int t;
    cin>>t;
    while(t--)
    {
        cin>>s;
        int i=0;
        int j=s.size()-1;
        string a="",b="";
        while(i<j)
        {
            if(s[i]==s[j])
            {
                a+=s[i];
                b+=s[j];
                i++;
                j--;
            }
            else break;
        }
        string s1="";
        for(i=(int)a.size(); i<(int)s.size()-(int)b.size(); i++)
        {
            s1+=s[i];
        }
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int x=s1.size();
        // cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        x=min(x,longestPrefixSuffix());
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int y=s1.size();
        // cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        y=min(y,longestPrefixSuffix());
        reverse(b.begin(),b.end());
        if(x>=y)
        {

            cout<<a;
            for(int i=0; i<x; i++)
                cout<<s1[i];
            cout<<b<<endl;
        }
        else
        {
            cout<<a;
            for(int i=(int)s1.size()-1; i>(int)s1.size()-1-y; i--)
                cout<<s1[i];
            cout<<b<<endl;
        }
    }
    cerr<<"Time elapsed : "<<clock()*1000.0/CLOCKS_PER_SEC<<"ms"<<'\n';
    return 0;
}


/*================= *\
|  ID : aman__guta__ |
|      LANG: C++     |
\*==================*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define ld long double
#define pb push_back
#define mk make_pair
#define fs first
#define sc second
#define mod 1000000007
#define sp <<" "<<
#define JOKER ios_base::sync_with_stdio (false) ; cin.tie(0) ; cout.tie(0) ;
int spf[10000001];
long long int fac[200005];
void sieve(int n)
{
    spf[1]=1;
    for(int i=2;i<=n;i++) spf[i]=i;
    for(int i=4;i<=n;i+=2) spf[i]=2;
    for(int i=3;i*i<=n;i++)
    {
        if(spf[i]==i)
        {
            for(int j=i*i;j<=n;j+=i)
            {
                if(spf[j]==j) spf[j]=i;
            }
        }
    }
}
long long int power(long long int x, long long int y, long long int p)
{
    long long int res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;
        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}
long long int modInverse(long long int n, long long int p)
{
    return power(n, p-2, p);
}
long long int nCrModPFermat(long long int n, long long int r, long long int p)
{
   if (r==0)
      return 1;
    return (fac[n]* modInverse(fac[r], p) % p *
            modInverse(fac[n-r], p) % p) % p;
}
string s;
int longestPrefixSuffix()
{
    int n = s.size();
    int lps[n];
    lps[0] = 0;
    int len = 0;
    int i = 1;
    while (i < n)
    {
        if (s[i] == s[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
    int res = lps[n-1];
    return res;
}
main()
{
    JOKER
    int t;
    cin>>t;
    while(t--)
    {
        cin>>s;
        int i=0;
        int j=s.size()-1;
        string a="",b="";
        while(i<j)
        {
            if(s[i]==s[j])
            {
                a+=s[i];
                b+=s[j];
                i++;
                j--;
            }
            else break;
        }
        string s1="";
        for(i=(int)a.size(); i<(int)s.size()-(int)b.size(); i++)
        {
            s1+=s[i];
        }
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int x=s1.size();
        cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        x=min(x,longestPrefixSuffix());
        s=s1;
        reverse(s1.begin(),s1.end());
        s+=s1;
        int y=s1.size();
        cout<<s<<endl;
        // cout<<longestPrefixSuffix()<<endl;
        y=min(y,longestPrefixSuffix());
        reverse(b.begin(),b.end());
        if(x>=y)
        {

            cout<<a;
            for(int i=0; i<x; i++)
                cout<<s1[i];
            cout<<b<<endl;
        }
        else
        {
            cout<<a;
            for(int i=(int)s1.size()-1; i>(int)s1.size()-1-y; i--)
                cout<<s1[i];
            cout<<b<<endl;
        }
    }
    cerr<<"Time elapsed : "<<clock()*1000.0/CLOCKS_PER_SEC<<"ms"<<'\n';
    return 0;
}