#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef unsigned long long int ull;
#define FastIO      ios_base::sync_with_stdio(false); cin.tie(0);
#define aPrint(a,b,c)for(int i=b;i<=c;i++)cout<<a[i]<<" ";cout<<endl;
#define vPrint(a)   for(int i=0;i<a.size();i++){cout<<a[i];if(i==a.size()-1)cout<<endl;else cout<<" ";}
#define Case(t)     printf("Case %d: ", t)
#define clr(x,a)    memset(x,a,sizeof(x))
#define debug(x)    cerr<<#x<<" = "<<(x)<<"\n"

#define umap        unordered_map
#define plll        pair<ll, pair<ll, ll> >
#define pll         pair<ll, ll>
#define ff          first
#define ss          second
#define mp          make_pair
#define pb          push_back
#define ppb         pop_back
#define sf          scanf
#define pf          printf
#define all(a)      a.begin(),a.end()
#define allr(a)     a.rbegin(),a.rend()
#define Unique(a)   sort(all(a)), a.erase(unique(all(a)),a.end())
template <class T> inline T bigmod(T b,T p,T M){T ret=1;for(;p>0;p>>=1){if(p&1) ret=(ret*b)%M;b=(b*b)%M;}return (T)ret;}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T lcm(T a,T b){return a*b / gcd<T>(a, b);}
template <class T> inline T power(T b,T p){ull x=1;while(p--)x*=b;return x;}
const int mod = 1000000007;

#define pi        acos(-1.0)//3.1415926535897932
#define inf       1e9 + 7
#define MAX       1000010
/// 'N'+'A'+'E'+'E'+'E'+'M' ///
/// Hash
string s, t;
ll BASE = 29, MOD = 1000000007;
ll Pow[MAX+5];
ll n, H[MAX+5], revH[MAX+5];
void prePower(){
    Pow[0] = 1LL;
    for(int i = 1; i < MAX; i++){
        Pow[i] = (Pow[i-1] * BASE) % MOD;
    }
}
void Hash(string str){
    H[0] = str[0] - 'a';
    for(int i = 1; i < str.size(); i++){
        H[i] = (H[i-1] * BASE) % MOD;
        H[i] = (H[i] + (str[i] - 'a')) % MOD;
    }
}
void revHash(string str){
    revH[0] = str[0] - 'a';
    for(int i = 1; i < str.size(); i++){
        revH[i] = (revH[i-1] * BASE) % MOD;
        revH[i] = (revH[i] + (str[i] - 'a')) % MOD;
    }
}
ll RollingHash(int l, int r){
    ll R = H[r];
    ll L = (H[l-1] * Pow[r-l+1]) % MOD;
    return (R - L + MOD) % MOD;
}
ll revRollingHash(int l, int r){
    ll R = revH[r];
    ll L = (revH[l-1] * Pow[r-l+1]) % MOD;
    return (R - L + MOD) % MOD;
}
bool isPal(int l, int r) {
    if(r < l) return false;
    return RollingHash(l, r) == revRollingHash(n - r - 1, n - l - 1);
}
int main() {
    #ifndef ONLINE_JUDGE
        clock_t tStart = clock();
        freopen("input.txt", "r", stdin);
        //freopen("output.txt", "w", stdout);
    #endif
    FastIO;

    prePower();

    int tc; cin >> tc; while(tc--) {
        cin >> s;
        t = s; reverse(all(t));
        n = (ll) s.size();

        Hash(s);
        revHash(t);

        int l = 0, r = n - 1;
        while(s[l] == s[r] && l <= r) l++, r--;

        if(l >= r) {
            cout << s << endl;
            continue;
        }

        string A = s.substr(0 , l);
        string C = s.substr(r + 1);
        string B = "";

        int posA = l, posB = r;
        for(int i = l; i <= r; i++) {
            if(isPal(l, i)) posA = i;
        }
        for(int j = r; j >= l; j--) {
            if(isPal(j, r)) posB = j;
        }

        if(posA - l >= r - posB) B = s.substr(l, posA - l + 1);
        else B = s.substr(posB, r - posB + 1);

        cout << A + B + C << endl;
    }

    #ifndef ONLINE_JUDGE
        printf("\n**Time -> %.10fs\n", (double)(clock()-tStart) / CLOCKS_PER_SEC);
    #endif

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
		}
		int i=0;
	    while(i<n&&(n-i-1)>=0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int mirror_i=2*c-j;
        	    arr[j]=min(r-j,arr[mirror_i]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<n1;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+arr[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
			continue;
		}
		int i=0;
	    while(i<n&&(n-i-1)>=0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	    continue;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int pos=2*c-j;
        	    arr[j]=min(r-j,arr[pos]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<n1;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+arr[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
		}
		int i=0;
	    while(i<n&&(n-i)>0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int mirror_i=2*c-j;
        	    arr[j]=min(r-j,arr[mirror_i]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<n1;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+arr[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
string manacher(string targ) {
	if(targ.size()<2)
	 return targ;
	string x="#";
	for(auto &c:targ) {
    	x+=c;
    	x+='#';
	}
	int N=x.size();
	int P[N]={};
	int i=0;
	int c=0,l=0,r=0;
	while(i<N){
    	if(i<r){
        	int mirror_i=2*c-i;
        	P[i]=min(r-i,P[mirror_i]);
    	}
    	int cnt=0;
    	while((i+P[i]+1+cnt)< N&&(i-P[i]-1-cnt)>=0&&(x[i+P[i]+1+cnt])==x[(i-P[i]-1-cnt)])
    		cnt++;
   	    if (i+P[i]+cnt>r){
        	r=i+P[i]+cnt;
        	c=i;
        	l=i-P[i]-cnt;
        	P[i]=r-c;
    	}
    	i++;
    }
	int pmx=1,smx=1;
	for(int i=0;i<N;i++){
    	if(P[i]>pmx){
        	if(i-P[i]==0)
        		pmx=max(pmx,P[i]);
    	}
    	if(P[i]>smx){
        	if(i+P[i]==N-1)
        	 smx=max(smx,P[i]);
    	}
	}
	if(pmx>=smx){
    	return targ.substr(0,pmx);
	}
	else{
    	return targ.substr((int)targ.size()-smx,smx);
	}
}
void solve(string s) {
	int k=0;
	int N=s.size();
	if(N==1){
    	cout<<s<<endl;
    	return;
	}
	while(k<N&&(N-1-k)>=0&&s[k]==s[N-1-k])
		k++;
	if(k==N||k==N-1){
    	cout<<s<<endl;
    	return;
	}
	string ss=s.substr(k,(N-2*k));
	int mxallow=(N-2*k);
	string w=manacher(ss);
	string res=s.substr(0,k)+w+s.substr((N-k),k);
	cout<<res<<endl;
}
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		solve(s);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
			continue;
		}
		int i=0;
	    while(i<n&&(n-i-1)>=0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	    continue;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int mirror_i=2*c-j;
        	    arr[j]=min(r-j,arr[mirror_i]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<n1;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+arr[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
string manacher(string ss) {
	if(ss.size()<2)
	 return ss;
	string x="#";
	for(auto &c:ss) {
    	x+=c;
    	x+='#';
	}
	int N=x.size();
	int P[N]={};
	int i=0;
	int c=0,l=0,r=0;
	while(i<N){
    	if(i<r){
        	int mirror_i=2*c-i;
        	P[i]=min(r-i,P[mirror_i]);
    	}
    	int cnt=0;
    	while((i+P[i]+1+cnt)< N&&(i-P[i]-1-cnt)>=0&&(x[i+P[i]+1+cnt])==x[(i-P[i]-1-cnt)])
    		cnt++;
   	    if (i+P[i]+cnt>r){
        	r=i+P[i]+cnt;
        	c=i;
        	l=i-P[i]-cnt;
        	P[i]=r-c;
    	}
    	i++;
    }
	int pmx=1,smx=1;
	for(int i=0;i<N;i++){
    	if(P[i]>pmx){
        	if(i-P[i]==0)
        		pmx=max(pmx,P[i]);
    	}
    	if(P[i]>smx){
        	if(i+P[i]==N-1)
        	 smx=max(smx,P[i]);
    	}
	}
	if(pmx>=smx){
    	return ss.substr(0,pmx);
	}
	else{
    	return ss.substr((int)ss.size()-smx,smx);
	}
}

int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int k=0;
	int N=s.size();
	if(N==1){
    	cout<<s<<endl;
    	//return;
    	continue;
	}
	while(k<N&&(N-1-k)>=0&&s[k]==s[N-1-k])
		k++;
	if(k==N||k==N-1){
    	cout<<s<<endl;
    	continue;
	}
	string ss=s.substr(k,(N-2*k));
	int mxallow=(N-2*k);
	string w=manacher(ss);
	string res=s.substr(0,k)+w+s.substr((N-k),k);
	cout<<res<<endl;
		//solve(s);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
string manacher(string targ) {
	if(targ.size()<2)
	 return targ;
	string x="#";
	for(auto &c:targ) {
    	x+=c;
    	x+='#';
	}
	int N=x.size();
	int P[N]={};
	int i=0;
	int c=0,l=0,r=0;
	while(i<N){
    	if(i<r){
        	int mirror_i=2*c-i;
        	P[i]=min(r-i,P[mirror_i]);
    	}
    	int cnt=0;
    	while((i+P[i]+1+cnt)< N&&(i-P[i]-1-cnt)>=0&&(x[i+P[i]+1+cnt])==x[(i-P[i]-1-cnt)])
    		cnt++;
   	    if (i+P[i]+cnt>r){
        	r=i+P[i]+cnt;
        	c=i;
        	l=i-P[i]-cnt;
        	P[i]=r-c;
    	}
    	i++;
    }
	int pmx=1,smx=1;
	for(int i=0;i<N;i++){
    	if(P[i]>pmx){
        	if(i-P[i]==0)
        		pmx=max(pmx,P[i]);
    	}
    	if(P[i]>smx){
        	if(i+P[i]==N-1)
        	 smx=max(smx,P[i]);
    	}
	}
	if(pmx>=smx){
    	return targ.substr(0,pmx);
	}
	else{
    	return targ.substr((int)targ.size()-smx,smx);
	}
}

int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int k=0;
	int N=s.size();
	if(N==1){
    	cout<<s<<endl;
    	return;
	}
	while(k<N&&(N-1-k)>=0&&s[k]==s[N-1-k])
		k++;
	if(k==N||k==N-1){
    	cout<<s<<endl;
    	return;
	}
	string ss=s.substr(k,(N-2*k));
	int mxallow=(N-2*k);
	string w=manacher(ss);
	string res=s.substr(0,k)+w+s.substr((N-k),k);
	cout<<res<<endl;
		//solve(s);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
string manacher(string targ) {
	if(targ.size()<2)
	 return targ;
	string x="#";
	for(auto &c:targ) {
    	x+=c;
    	x+='#';
	}
	int N=x.size();
	int P[N]={};
	int i=0;
	int c=0,l=0,r=0;
	while(i<N){
    	if(i<r){
        	int mirror_i=2*c-i;
        	P[i]=min(r-i,P[mirror_i]);
    	}
    	int cnt=0;
    	while((i+P[i]+1+cnt)< N&&(i-P[i]-1-cnt)>=0&&(x[i+P[i]+1+cnt])==x[(i-P[i]-1-cnt)])
    		cnt++;
   	    if (i+P[i]+cnt>r){
        	r=i+P[i]+cnt;
        	c=i;
        	l=i-P[i]-cnt;
        	P[i]=r-c;
    	}
    	i++;
    }
	int pmx=1,smx=1;
	for(int i=0;i<N;i++){
    	if(P[i]>pmx){
        	if(i-P[i]==0)
        		pmx=max(pmx,P[i]);
    	}
    	if(P[i]>smx){
        	if(i+P[i]==N-1)
        	 smx=max(smx,P[i]);
    	}
	}
	if(pmx>=smx){
    	return targ.substr(0,pmx);
	}
	else{
    	return targ.substr((int)targ.size()-smx,smx);
	}
}
void solve(string s) {
	int k=0;
	int N=s.size();
	if(N==1){
    	cout<<s<<endl;
    	return;
	}
	while(k<N&&(N-1-k)>=0&&s[k]==s[N-1-k])
		k++;
	if(k==N||k==N-1){
    	cout<<s<<endl;
    	return;
	}
	string ss=s.substr(k,(N-2*k));
	int mxallow=(N-2*k);
	string w=manacher(ss);
	string res=s.substr(0,k)+w+s.substr((N-k),k);
	cout<<res<<endl;
}
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
		}
		int i=0;
	    while(i<n&&(n-i)>0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int mirror_i=2*c-j;
        	    arr[j]=min(r-j,arr[mirror_i]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<N;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+P[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t;
    cin>>t;
	while(t--){
		string s;
		cin>>s;
		int n=s.size();
		if(n==1){
			cout<<s<<endl;
		}
		int i=0;
	    while(i<n&&(n-i-1)=>0&&s[i]==s[n-i-1])
		    i++;
	    if(i==n||i==n-1){
    	    cout<<s<<endl;
    	}
    	int last=n-i*2;
	    string substring=s.substr(i,last);
	    string res;
	    if(substring.size()<2)
	    	res=substring;
	    string s1="#";
	    for(auto &c:substring){
    	    s1+=c;
    	    s1+='#';
    	}
	    int n1=s1.size();
	    int arr[n1]={};
	    int c=0,l=0,r=0,j=0;
	    while(j<n1){
    	    if(j<r){
        	    int mirror_i=2*c-j;
        	    arr[j]=min(r-j,arr[mirror_i]);
        	}
    	    int count=0;
    	    while((j+arr[j]+count+1)<n1&&(j-arr[j]-count-1)>=0&&(s1[j+arr[j]+count+1])==s1[(j-arr[j]-count-1)])
    		    count++;
   	        if(j+arr[j]+count>r){
        	    r=j+arr[j]+count;
        	    c=j;
        	    l=j-arr[j]-count;
        	    arr[j]=r-c;
        	}
        	j++;
        }
        int a1=1,a2=1;
        for(int k=0;k<n1;k++){
    	    if(arr[k]>a1){
        	    if(k-arr[k]==0)
        		    a1=max(a1,arr[k]);
        	}
        	if(arr[k]>a2){
        	    if(k+arr[k]==n1-1)
        	        a2=max(a2,arr[k]);
        	}
        }
        if(a1>=a2)
    	    res=substring.substr(0,a1);
    	else
    	    res=substring.substr((int)substring.size()-a2,a2);
	    string answer=s.substr(0,i)+res+s.substr((n-i),i);
	    cout<<answer<<endl;
	}
	return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 1000000007

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
bool isPalind(int l, int r) {
    while (l <= r) {
        if (s[l] != s[r]) return false;
        l++;
        r--;
    }
    return true;
}
int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    string a, b, p;
    cin >> t;
    while (t--) {
        cin >> s;
        n = sz(s);
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }
        b = a;
        reverse(all(b));
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 193

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) % MOD;
    left += MOD;
    left %= MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) % MOD;
    right += MOD;
    right %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    memset(hashLeft, 0, sizeof(hashLeft));
    memset(hashRight, 0, sizeof(hashRight));
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = BASE;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }
        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            hashLeft[i] %= MOD;
        }
        // cout << "PALIND" << endl;
        //cout << isPalind(0, 3) << endl;
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]) % MOD);
    ll right = hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]) % MOD);
    while (left < 0) left += MOD;
    while (right < 0) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += (s[i] - 'a');
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += (s[i] - 'a');
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]) % MOD);
    ll right = hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]) % MOD);
    left += MOD;
    right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += (s[i] - 'a');
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += (s[i] - 'a');
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 1000007
#define BASE 3

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    while (left < MOD) left += MOD;
    while (right < MOD) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
ll pws[MAXN];
ll prefixHash[MAXN];
ll suffixHash[MAXN];

void clearHashes(int n) {
    for (int i = 0; i <= n; i++) {
        prefixHash[i] = 0;
        suffixHash[i] = 0;
    }
}
void generatePowers() {
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        pws[i] = (pws[i - 1] * BASE) % MOD;
    }
}

void generatePrefixHash(string &s) {
    int n = sz(s);
    prefixHash[0] = s[0] % MOD;
    for (int i = 1; i < n; i++) {
        prefixHash[i] = ((prefixHash[i - 1] * BASE) + s[i]) % MOD;
    }
}

void generateSuffixHash(string &s) {
    int n = sz(s);
    suffixHash[n - 1] = s[n - 1] % MOD;
    for (int i = n - 2; i >= 0; i--) {
        suffixHash[i] = ((suffixHash[i + 1] * BASE) + s[i]) % MOD;
    }
}

ll getPrefixHashValue(int l, int r) {
    return ((prefixHash[r] - ((l - 1 < 0 ? 0 : prefixHash[l - 1]) * pws[r - l + 1]) % MOD) + MOD) % MOD;
}

ll getSuffixHashValue(int l, int r) {
    return ((suffixHash[l] - (suffixHash[r + 1] * pws[r - l + 1]) % MOD) + MOD) % MOD;
}

bool isPalind(int l, int r) {
    ll left = getPrefixHashValue(l, r);
    ll right = getSuffixHashValue(l, r);
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    string a, b, p, s;
    cin >> t;
    generatePowers();
    while (t--) {
        cin >> s;
        n = sz(s);
        clearHashes(n + 1);
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        generatePrefixHash(s);
        generateSuffixHash(s);
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 1000000007
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    while (left < MOD) left += MOD;
    while (right < MOD) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += (s[i] - 'a');
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += (s[i] - 'a');
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 89

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
ll pws[MAXN];
ll prefixHash[MAXN];
ll suffixHash[MAXN];

void clearHashes(int n) {
    for (int i = 0; i <= n; i++) {
        prefixHash[i] = 0;
        suffixHash[i] = 0;
    }
}
void generatePowers() {
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        pws[i] = (pws[i - 1] * BASE) % MOD;
    }
}

void generatePrefixHash(string &s) {
    int n = sz(s);
    prefixHash[0] = s[0] % MOD;
    for (int i = 1; i < n; i++) {
        prefixHash[i] = ((prefixHash[i - 1] * BASE) + s[i]) % MOD;
    }
}

void generateSuffixHash(string &s) {
    int n = sz(s);
    suffixHash[n - 1] = s[n - 1] % MOD;
    for (int i = n - 2; i >= 0; i--) {
        suffixHash[i] = ((suffixHash[i + 1] * BASE) + s[i]) % MOD;
    }
}

ll getPrefixHashValue(int l, int r) {
    return ((prefixHash[r] - ((l - 1 < 0 ? 0 : prefixHash[l - 1]) * pws[r - l + 1]) % MOD) + MOD) % MOD;
}

ll getSuffixHashValue(int l, int r) {
    return ((suffixHash[l] - (suffixHash[r + 1] * pws[r - l + 1]) % MOD) + MOD) % MOD;
}

bool isPalind(int l, int r) {
    ll left = getPrefixHashValue(l, r);
    ll right = getSuffixHashValue(l, r);
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    string a, b, p, s;
    cin >> t;
    generatePowers();
    while (t--) {
        cin >> s;
        n = sz(s);
        clearHashes(n + 1);
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        generatePrefixHash(s);
        generateSuffixHash(s);
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]) % MOD);
    ll right = hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]) % MOD);
    left += MOD;
    right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 10008
#define BASE 19

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    while (left < MOD) left += MOD;
    while (right < MOD) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 193

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    left += MOD;
    left %= MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    right += MOD;
    right %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    memset(hashLeft, 0, sizeof(hashLeft));
    memset(hashRight, 0, sizeof(hashRight));
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = BASE;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }
        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            hashLeft[i] %= MOD;
        }
        // cout << "PALIND" << endl;
        //cout << isPalind(0, 3) << endl;
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]) % MOD);
    ll right = hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]) % MOD);
    while (left < 0) left += MOD;
    while (right < 0) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += (s[i] - 'a');
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
         string p1 = "", p2 = "";
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += (s[i] - 'a');
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }

        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 1000000007
#define BASE 31

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]) % MOD);
    ll right = hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]) % MOD);
    while (left < 0) left += MOD;
    while (right < 0) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * 31) % MOD;
            hashRight[i] += (s[i] - 'a');
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * 31) % MOD;
            hashLeft[i] += (s[i] - 'a');
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 1000007
#define BASE 19

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    while (left < MOD) left += MOD;
    while (right < MOD) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }

        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            if (hashRight[i] >= MOD)
                hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            if (hashLeft[i] >= MOD)
                hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 1000007
#define MOD 998244353
#define BASE 193

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
string s;
ll pws[MAXN];
ll hashLeft[MAXN];
ll hashRight[MAXN];
bool isPalind(int l, int r) {
    int n = sz(s);
    ll left = (hashLeft[r] - (((l - 1 < 0 ? 0 : hashLeft[l - 1]) * pws[r - l + 1]))) + MOD;
    ll right = (hashRight[l] - (((r + 1 >= n ? 0 : hashRight[r + 1]) * pws[r - l + 1]))) + MOD;
    while (left < MOD) left += MOD;
    while (right < MOD) right += MOD;
    right %= MOD;
    left %= MOD;
    return left == right;
}

int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t, n;
    ll cur = 1;
    string a, b, p;
    cin >> t;
    pws[0] = 1;
    for (int i = 1; i < MAXN; i++) {
        cur *= BASE;
        cur %= MOD;
        pws[i] = cur;
    }

    while (t--) {
        cin >> s;
        n = sz(s);
        for (int i = 0; i <= n; i++) hashLeft[i] = hashRight[i] = 0;
        a = "";
        b = "";
        p = "";
        int l = 0, r = n - 1;
        string add = "";
        while (l <= r) {
            if (s[l] == s[r]) {
                if (l == r)
                    add = s[l];
                else
                    a += s[l];
                l++;
                r--;
            } else {
                break;
            }
        }
        b = a;
        reverse(all(b));
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1)
                hashRight[i] = (hashRight[i + 1] * BASE) % MOD;
            hashRight[i] += s[i];
            hashRight[i] %= MOD;
        }
        for (int i = 0; i < n; i++) {
            if (i > 0)
                hashLeft[i] = (hashLeft[i - 1] * BASE) % MOD;
            hashLeft[i] += s[i];
            hashLeft[i] %= MOD;
        }
        string p1 = "", p2 = "";
        for (int i = r; i >= l; i--) {
            if (isPalind(l, i)) {
                for (int j = l; j <= i; j++) p1 += s[j];
                break;
            }
        }
        for (int i = l; i <= r; i++) {
            if (isPalind(i, r)) {
                for (int j = i; j <= r; j++) p2 += s[j];
                break;
            }
        }
        p = (sz(p1) > sz(p2)) ? p1 : p2;
        cout << (a + add + p + b) << "\n";
    }

    return 0;
}


#include <bits/stdc++.h>

#ifdef ONLINE_JUDGE
#define endl "\n"
#endif
using namespace std;
typedef unsigned long long int lu;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> v;
typedef vector<v> vv;
typedef vector<ld> vld;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
const ll MOD = 1e9 + 7;
const v dx = {1, -1, 0, 0};
const v dy = {0, 0, 1, -1};
#define yes cout << "YES\n";
#define no cout << "NO\n";
#define yesno(f) \
    if (f)       \
        yes else no;
#define noo \
    { no return; }
#define amax(x, y) \
    if (y > x)     \
        x = y;
#define amin(x, y) \
    if (y < x)     \
        x = y;
#define sz(x) (ll) x.size()
#define sq(x) ((x) * (x))

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

template<typename T = ll>
vector<T> ga(ll n, bool oneIndexed = false) {
    vector<T> a = vector<T>(n + oneIndexed);

    for (ll i = 0; i < n; i++) {
        T p;
        cin >> p;
        a[i + oneIndexed] = p;
    }

    return move(a);
}

ll n;
string s;

ll len = 1;
pll x = {1, 0};

ll maxCommon = 0;

//vector<int> findLongestPalindromicString(string &s) {
//    int N = s.size();
//    if (N == 0)
//        return vector<int>(0);
//    N = 2 * N + 1; //Position count
//    vector<int> L(N); //LPS Length Array
//    L[0] = 0;
//    L[1] = 1;
//    int C = 1; //centerPosition
//    int R = 2; //centerRightPosition
//    int i = 0; //currentRightPosition
//    int iMirror; //currentLeftPosition
//    int maxLPSLength = 0;
//    int maxLPSCenterPosition = 0;
//    int start = -1;
//    int end = -1;
//    int diff = -1;
//
//    //Uncomment it to print LPS Length array
//    //printf("%d %d ", L[0], L[1]);
//    for (i = 2; i < N; i++) {
//        //get currentLeftPosition iMirror for currentRightPosition i
//        iMirror = 2 * C - i;
//        L[i] = 0;
//        diff = R - i;
//        //If currentRightPosition i is within centerRightPosition R
//        if (diff > 0)
//            L[i] = min(L[iMirror], diff);
//
//        //Attempt to expand palindrome centered at currentRightPosition i
//        //Here for odd positions, we compare characters and
//        //if match then increment LPS Length by ONE
//        //If even position, we just increment LPS by ONE without
//        //any character comparison
//        while (((i + L[i]) < N && (i - L[i]) > 0) &&
//               (((i + L[i] + 1) % 2 == 0) ||
//                (s[(i + L[i] + 1) / 2] == s[(i - L[i] - 1) / 2]))) {
//            L[i]++;
//        }
//
//        if (L[i] > maxLPSLength)  // Track maxLPSLength
//        {
//            maxLPSLength = L[i];
//            maxLPSCenterPosition = i;
//        }
//
//        //If palindrome centered at currentRightPosition i
//        //expand beyond centerRightPosition R,
//        //adjust centerPosition C based on expanded palindrome.
//        if (i + L[i] > R) {
//            C = i;
//            R = i + L[i];
//        }
//    }
//
//}

class KMPstring {
public:
    string pattern;
    v lps;

    explicit KMPstring(const string &pattern) {
        this->pattern = pattern;
        ll m = pattern.size();
        lps = v(m + 1, 0);
        ll i = 0, j = -1;
        lps[0] = -1;
        while (i < m) {
            while (j >= 0 && pattern[i] != pattern[j])
                j = lps[j];
            i++, j++;
            lps[i] = j;
        }
    }

    v match(const string &text) {
        ll n = text.size(), m = pattern.size();
        v matches, m_length(n);
        ll i = 0, j = 0;
        while (i < n) {
            while (j >= 0 && text[i] != pattern[j])
                j = lps[j];
            i++, j++;
            m_length[i - 1] = j;
            if (j == m) {
                matches.push_back(i - m);
                j = lps[j];
            }
        }
        return move(matches);  // or m_length
    }
};

void solve() {
    cin >> s;
    n = sz(s);

    maxCommon = 0;
    while (maxCommon < n) {
        if (s[maxCommon] == s[n - maxCommon - 1]) {
            maxCommon++;
        } else break;
    }
    x = {maxCommon, maxCommon};

    string s2;
    for (ll i = maxCommon; i < n; i++) {
        s2 += s[i];
    }
    for (ll i = n - 1; i >= maxCommon; i--) {
        s2 += s[i];
    }

    KMPstring kmp(s2);
    ll prefixExtra = kmp.lps.back();

    s2 = "";
    for (ll i = n - maxCommon - 1; i >= 0; i--) {
        s2 += s[i];
    }

    for (ll i = 0; i <= n - maxCommon - 1; i++) {
        s2 += s[i];
    }
    KMPstring k2(s2);
    ll suffixExtra = k2.lps.back();

    KMPstring k3(s);
    ll d1 = k3.lps.back();
    string s4 = s;
    reverse(all(s4));
    KMPstring k4(s4);
    ll d2 = k4.lps.back();

    if (d1 > 2 * maxCommon) {
        x = {d1, 0};
    }
    if (d2 > d1) {
        x = {0, d2};
    }
    len = x.first + x.second;

    ll p1 = 2 * maxCommon + prefixExtra;
    ll p2 = 2 * maxCommon + suffixExtra;
    if (len >= n) {
        x = {n / 2, n / 2};
        if (n & 1) {
            x.first++;
        }
        goto end;
    }

    if (p1 <= n && p1 > p2 && p1 > len) x.first += prefixExtra;
    else if (p2 <= n && p2 > len) x.second += suffixExtra;

    end:;
    for (ll i = 0; i < x.first; i++) cout << s[i];
    for (ll i = n - x.second; i < n; i++) cout << s[i];
    cout << endl;
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}


// forked from ninja_28
// for testing kmp

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
using namespace std;
// using namespace __gnu_pbds;
#define ll long long int
#define lli long long int
#define v vector<long long>
#define llu unsigned long long int
#define fr(va, beg, end) for (lli va = beg; va < end; va++)
#define pb push_back
#define rt return 0
#define endln "\n"
#define all(x) x.begin(), x.end()
#define sz(x) (lli)(x.size())
const lli MOD = 1e9 + 7;
// cout << fixed << setprecision(0) << pi <<endl;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
//              tree_order_statistics_node_update>
//     new_data_set;
// for multiset
// typedef tree<int, null_type, less_equal<int>, rb_tree_tag,
//              tree_order_statistics_node_update>
//     new_data_set;
// order_of_key(val): returns the number of values less than val
// find_by_order(k): returns an iterator to the kth largest element (0-based)

class KMPstring {

   public:
    string pattern;
    v lps;
    explicit KMPstring(const string &pattern) {
        this->pattern = pattern;
        ll m = pattern.size();
        lps = v(m + 1, 0);
        ll i = 0, j = -1;
        lps[0] = -1;
        while (i < m) {
            while (j >= 0 && pattern[i] != pattern[j])
                j = lps[j];
            i++, j++;
            lps[i] = j;
        }
    }
    v match(const string &text) {
        ll n = text.size(), m = pattern.size();
        v matches, m_length(n);
        ll i = 0, j = 0;
        while (i < n) {
            while (j >= 0 && text[i] != pattern[j])
                j = lps[j];
            i++, j++;
            m_length[i - 1] = j;
            if (j == m) {
                matches.push_back(i - m);
                j = lps[j];
            }
        }
        return move(matches);  // or m_length
    }
};

ll longest_palindrome_prefix(const string &x){
    string y = x;
    reverse(all(y));
    KMPstring k(x + "#" + y);
    return k.lps.back();
}

void solve() {
    ll n, a;
    string st;
    cin>>st;
    lli beg = 0,end = st.length()-1;
    string part1="";

    while(beg <= end){
        if(st[beg] == st[end]){
            part1.pb(st[beg]);
            beg++;
            end--;
        }
        else{
            break;
        }
    }

    if(st[beg] == st[end]){
        cout<<st<<endl;
        return;
    }

    string st1 = st.substr(beg,end-beg+1);
    string st2 = st1;
    reverse(all(st2));
    string part3;

    lli aa = longest_palindrome_prefix(st1);
    lli bb = longest_palindrome_prefix(st2);

    if(aa > bb){
        part3 = st.substr(beg,aa);
    }
    else{
        part3 = st.substr(end-bb+1,bb);
    }

    string part2 = part1;
    reverse(part2.begin(),part2.end());
    string an = part1 + part3 + part2;
    cout<<an<<endl;
}

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    lli t; cin >> t; while(t--)
    solve();
    rt;
}


#include <bits/stdc++.h>

#ifdef ONLINE_JUDGE
#define endl "\n"
#endif
using namespace std;
typedef unsigned long long int lu;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> v;
typedef vector<v> vv;
typedef vector<ld> vld;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
const ll MOD = 1e9 + 7;
const v dx = {1, -1, 0, 0};
const v dy = {0, 0, 1, -1};
#define yes cout << "YES\n";
#define no cout << "NO\n";
#define yesno(f) \
    if (f)       \
        yes else no;
#define noo \
    { no return; }
#define amax(x, y) \
    if (y > x)     \
        x = y;
#define amin(x, y) \
    if (y < x)     \
        x = y;
#define sz(x) (ll) x.size()
#define sq(x) ((x) * (x))

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

template<typename T = ll>
vector<T> ga(ll n, bool oneIndexed = false) {
    vector<T> a = vector<T>(n + oneIndexed);

    for (ll i = 0; i < n; i++) {
        T p;
        cin >> p;
        a[i + oneIndexed] = p;
    }

    return move(a);
}

ll n;
string s;

ll len = 1;
pll x = {1, 0};

ll maxCommon = 0;

//vector<int> findLongestPalindromicString(string &s) {
//    int N = s.size();
//    if (N == 0)
//        return vector<int>(0);
//    N = 2 * N + 1; //Position count
//    vector<int> L(N); //LPS Length Array
//    L[0] = 0;
//    L[1] = 1;
//    int C = 1; //centerPosition
//    int R = 2; //centerRightPosition
//    int i = 0; //currentRightPosition
//    int iMirror; //currentLeftPosition
//    int maxLPSLength = 0;
//    int maxLPSCenterPosition = 0;
//    int start = -1;
//    int end = -1;
//    int diff = -1;
//
//    //Uncomment it to print LPS Length array
//    //printf("%d %d ", L[0], L[1]);
//    for (i = 2; i < N; i++) {
//        //get currentLeftPosition iMirror for currentRightPosition i
//        iMirror = 2 * C - i;
//        L[i] = 0;
//        diff = R - i;
//        //If currentRightPosition i is within centerRightPosition R
//        if (diff > 0)
//            L[i] = min(L[iMirror], diff);
//
//        //Attempt to expand palindrome centered at currentRightPosition i
//        //Here for odd positions, we compare characters and
//        //if match then increment LPS Length by ONE
//        //If even position, we just increment LPS by ONE without
//        //any character comparison
//        while (((i + L[i]) < N && (i - L[i]) > 0) &&
//               (((i + L[i] + 1) % 2 == 0) ||
//                (s[(i + L[i] + 1) / 2] == s[(i - L[i] - 1) / 2]))) {
//            L[i]++;
//        }
//
//        if (L[i] > maxLPSLength)  // Track maxLPSLength
//        {
//            maxLPSLength = L[i];
//            maxLPSCenterPosition = i;
//        }
//
//        //If palindrome centered at currentRightPosition i
//        //expand beyond centerRightPosition R,
//        //adjust centerPosition C based on expanded palindrome.
//        if (i + L[i] > R) {
//            C = i;
//            R = i + L[i];
//        }
//    }
//
//}

class KMPstring {
public:
    string pattern;
    v lps;

    explicit KMPstring(const string &pattern) {
        this->pattern = pattern;
        ll m = pattern.size();
        lps = v(m + 1, 0);
        ll i = 0, j = -1;
        lps[0] = -1;
        while (i < m) {
            while (j >= 0 && pattern[i] != pattern[j])
                j = lps[j];
            i++, j++;
            lps[i] = j;
        }
    }

    v match(const string &text) {
        ll n = text.size(), m = pattern.size();
        v matches, m_length(n);
        ll i = 0, j = 0;
        while (i < n) {
            while (j >= 0 && text[i] != pattern[j])
                j = lps[j];
            i++, j++;
            m_length[i - 1] = j;
            if (j == m) {
                matches.push_back(i - m);
                j = lps[j];
            }
        }
        return move(matches);  // or m_length
    }
};

void solve() {
    cin >> s;
    n = sz(s);

    maxCommon = 0;
    while (maxCommon < n) {
        if (s[maxCommon] == s[n - maxCommon - 1]) {
            maxCommon++;
        } else break;
    }
    x = {maxCommon, maxCommon};

    string s2;
    for (ll i = maxCommon; i < n; i++) {
        s2 += s[i];
    }
    for (ll i = n - 1; i >= maxCommon; i--) {
        s2 += s[i];
    }

    KMPstring kmp(s2);
    ll prefixExtra = kmp.lps.back();

    s2 = "";
    for (ll i = n - maxCommon - 1; i >= 0; i--) {
        s2 += s[i];
    }

    for (ll i = 0; i <= n - maxCommon - 1; i++) {
        s2 += s[i];
    }
    KMPstring k2(s2);
    ll suffixExtra = k2.lps.back();

    KMPstring k3(s);
    ll d1 = k3.lps.back();
    string s4 = s;
    reverse(all(s4));
    KMPstring k4(s4);
    ll d2 = k4.lps.back();

    if (d1 > 2 * maxCommon) {
        x = {d1, 0};
    }
    if (d2 > d1 && d2 > 2 * maxCommon) {
        x = {0, d2};
    }
    len = x.first + x.second;

    ll p1 = 2 * maxCommon + prefixExtra;
    ll p2 = 2 * maxCommon + suffixExtra;
    if (len >= n) {
        x = {n / 2, n / 2};
        if (n & 1) {
            x.first++;
        }
        goto end;
    }

    if (p1 <= n && p1 > p2 && p1 > len) x.first += prefixExtra;
    else if (p2 <= n && p2 > len) x.second += suffixExtra;

    end:;
    for (ll i = 0; i < x.first; i++) cout << s[i];
    for (ll i = n - x.second; i < n; i++) cout << s[i];
    cout << endl;
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}


#include <bits/stdc++.h>

#ifdef ONLINE_JUDGE
#define endl "\n"
#endif
using namespace std;
typedef unsigned long long int lu;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> v;
typedef vector<v> vv;
typedef vector<ld> vld;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
const ll MOD = 1e9 + 7;
const v dx = {1, -1, 0, 0};
const v dy = {0, 0, 1, -1};
#define yes cout << "YES\n";
#define no cout << "NO\n";
#define yesno(f) \
    if (f)       \
        yes else no;
#define noo \
    { no return; }
#define amax(x, y) \
    if (y > x)     \
        x = y;
#define amin(x, y) \
    if (y < x)     \
        x = y;
#define sz(x) (ll) x.size()
#define sq(x) ((x) * (x))

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

template<typename T = ll>
vector<T> ga(ll n, bool oneIndexed = false) {
    vector<T> a = vector<T>(n + oneIndexed);

    for (ll i = 0; i < n; i++) {
        T p;
        cin >> p;
        a[i + oneIndexed] = p;
    }

    return move(a);
}

ll n;
string s;

ll len = 1;
pll x = {1, 0};

ll maxCommon = 0;

//vector<int> findLongestPalindromicString(string &s) {
//    int N = s.size();
//    if (N == 0)
//        return vector<int>(0);
//    N = 2 * N + 1; //Position count
//    vector<int> L(N); //LPS Length Array
//    L[0] = 0;
//    L[1] = 1;
//    int C = 1; //centerPosition
//    int R = 2; //centerRightPosition
//    int i = 0; //currentRightPosition
//    int iMirror; //currentLeftPosition
//    int maxLPSLength = 0;
//    int maxLPSCenterPosition = 0;
//    int start = -1;
//    int end = -1;
//    int diff = -1;
//
//    //Uncomment it to print LPS Length array
//    //printf("%d %d ", L[0], L[1]);
//    for (i = 2; i < N; i++) {
//        //get currentLeftPosition iMirror for currentRightPosition i
//        iMirror = 2 * C - i;
//        L[i] = 0;
//        diff = R - i;
//        //If currentRightPosition i is within centerRightPosition R
//        if (diff > 0)
//            L[i] = min(L[iMirror], diff);
//
//        //Attempt to expand palindrome centered at currentRightPosition i
//        //Here for odd positions, we compare characters and
//        //if match then increment LPS Length by ONE
//        //If even position, we just increment LPS by ONE without
//        //any character comparison
//        while (((i + L[i]) < N && (i - L[i]) > 0) &&
//               (((i + L[i] + 1) % 2 == 0) ||
//                (s[(i + L[i] + 1) / 2] == s[(i - L[i] - 1) / 2]))) {
//            L[i]++;
//        }
//
//        if (L[i] > maxLPSLength)  // Track maxLPSLength
//        {
//            maxLPSLength = L[i];
//            maxLPSCenterPosition = i;
//        }
//
//        //If palindrome centered at currentRightPosition i
//        //expand beyond centerRightPosition R,
//        //adjust centerPosition C based on expanded palindrome.
//        if (i + L[i] > R) {
//            C = i;
//            R = i + L[i];
//        }
//    }
//
//}

class KMPstring {
public:
    string pattern;
    v lps;

    explicit KMPstring(const string &pattern) {
        this->pattern = pattern;
        ll m = pattern.size();
        lps = v(m + 1, 0);
        ll i = 0, j = -1;
        lps[0] = -1;
        while (i < m) {
            while (j >= 0 && pattern[i] != pattern[j])
                j = lps[j];
            i++, j++;
            lps[i] = j;
        }
    }

    v match(const string &text) {
        ll n = text.size(), m = pattern.size();
        v matches, m_length(n);
        ll i = 0, j = 0;
        while (i < n) {
            while (j >= 0 && text[i] != pattern[j])
                j = lps[j];
            i++, j++;
            m_length[i - 1] = j;
            if (j == m) {
                matches.push_back(i - m);
                j = lps[j];
            }
        }
        return move(matches);  // or m_length
    }
};

void solve() {
    cin >> s;
    n = sz(s);

    maxCommon = 0;
    while (maxCommon < n) {
        if (s[maxCommon] == s[n - maxCommon - 1]) {
            maxCommon++;
        } else break;
    }

    len = maxCommon * 2;

    string s2;
    for (ll i = maxCommon; i < n; i++) {
        s2 += s[i];
    }

    for (ll i = n - 1; i >= maxCommon; i--) {
        s2 += s[i];
    }

    KMPstring kmp(s2);
    ll prefixExtra = kmp.lps.back();

    s2 = "";
    for (ll i = n - maxCommon - 1; i >= 0; i--) {
        s2 += s[i];
    }

    for (ll i = 0; i <= n - maxCommon - 1; i++) {
        s2 += s[i];
    }
    KMPstring k2(s2);
    ll suffixExtra = k2.lps.back();

//    stack <ll> st;
//    ll num = 1;
//    v has(n, 0);

    if (len >= n) {
        x = {n / 2, n / 2};
        if (n & 1) {
            x.first++;
        }
        goto end;
    }

    x = {maxCommon, maxCommon};
    if (prefixExtra > suffixExtra) x.first += prefixExtra;
    else x.second += suffixExtra;

//    for (ll i = maxCommon; i < n; i++) {
//        while (!st.empty() && s[st.top()] == s[i]) {
//            has[i] = num;
//            has[st.top()] = num;
//            num++;
//            st.pop();
//            i++;
//        }
//        st.push(i);
//    }

    end:;
    for (ll i = 0; i < x.first; i++) cout << s[i];
    for (ll i = n - x.second; i < n; i++) cout << s[i];
    cout << endl;
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}


#include <bits/stdc++.h>

#ifdef ONLINE_JUDGE
#define endl "\n"
#endif
using namespace std;
typedef unsigned long long int lu;
typedef long long int ll;
typedef long double ld;
typedef vector<ll> v;
typedef vector<v> vv;
typedef vector<ld> vld;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
const ll MOD = 1e9 + 7;
const v dx = {1, -1, 0, 0};
const v dy = {0, 0, 1, -1};
#define yes cout << "YES\n";
#define no cout << "NO\n";
#define yesno(f) \
    if (f)       \
        yes else no;
#define noo \
    { no return; }
#define amax(x, y) \
    if (y > x)     \
        x = y;
#define amin(x, y) \
    if (y < x)     \
        x = y;
#define sz(x) (ll) x.size()
#define sq(x) ((x) * (x))

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

template<typename T = ll>
vector<T> ga(ll n, bool oneIndexed = false) {
    vector<T> a = vector<T>(n + oneIndexed);

    for (ll i = 0; i < n; i++) {
        T p;
        cin >> p;
        a[i + oneIndexed] = p;
    }

    return move(a);
}

ll n;
string s;

ll len = 1;
pll x = {1, 0};

ll maxCommon = 0;

//vector<int> findLongestPalindromicString(string &s) {
//    int N = s.size();
//    if (N == 0)
//        return vector<int>(0);
//    N = 2 * N + 1; //Position count
//    vector<int> L(N); //LPS Length Array
//    L[0] = 0;
//    L[1] = 1;
//    int C = 1; //centerPosition
//    int R = 2; //centerRightPosition
//    int i = 0; //currentRightPosition
//    int iMirror; //currentLeftPosition
//    int maxLPSLength = 0;
//    int maxLPSCenterPosition = 0;
//    int start = -1;
//    int end = -1;
//    int diff = -1;
//
//    //Uncomment it to print LPS Length array
//    //printf("%d %d ", L[0], L[1]);
//    for (i = 2; i < N; i++) {
//        //get currentLeftPosition iMirror for currentRightPosition i
//        iMirror = 2 * C - i;
//        L[i] = 0;
//        diff = R - i;
//        //If currentRightPosition i is within centerRightPosition R
//        if (diff > 0)
//            L[i] = min(L[iMirror], diff);
//
//        //Attempt to expand palindrome centered at currentRightPosition i
//        //Here for odd positions, we compare characters and
//        //if match then increment LPS Length by ONE
//        //If even position, we just increment LPS by ONE without
//        //any character comparison
//        while (((i + L[i]) < N && (i - L[i]) > 0) &&
//               (((i + L[i] + 1) % 2 == 0) ||
//                (s[(i + L[i] + 1) / 2] == s[(i - L[i] - 1) / 2]))) {
//            L[i]++;
//        }
//
//        if (L[i] > maxLPSLength)  // Track maxLPSLength
//        {
//            maxLPSLength = L[i];
//            maxLPSCenterPosition = i;
//        }
//
//        //If palindrome centered at currentRightPosition i
//        //expand beyond centerRightPosition R,
//        //adjust centerPosition C based on expanded palindrome.
//        if (i + L[i] > R) {
//            C = i;
//            R = i + L[i];
//        }
//    }
//
//}

class KMPstring {
public:
    string pattern;
    v lps;

    explicit KMPstring(const string &pattern) {
        this->pattern = pattern;
        ll m = pattern.size();
        lps = v(m + 1, 0);
        ll i = 0, j = -1;
        lps[0] = -1;
        while (i < m) {
            while (j >= 0 && pattern[i] != pattern[j])
                j = lps[j];
            i++, j++;
            lps[i] = j;
        }
    }

    v match(const string &text) {
        ll n = text.size(), m = pattern.size();
        v matches, m_length(n);
        ll i = 0, j = 0;
        while (i < n) {
            while (j >= 0 && text[i] != pattern[j])
                j = lps[j];
            i++, j++;
            m_length[i - 1] = j;
            if (j == m) {
                matches.push_back(i - m);
                j = lps[j];
            }
        }
        return move(matches);  // or m_length
    }
};

void solve() {
    cin >> s;
    n = sz(s);

    maxCommon = 0;
    while (maxCommon < n) {
        if (s[maxCommon] == s[n - maxCommon - 1]) {
            maxCommon++;
        } else break;
    }

    string s2;
    for (ll i = maxCommon; i < n; i++) {
        s2 += s[i];
    }
    s2 += "#";
    for (ll i = n - 1; i >= maxCommon; i--) {
        s2 += s[i];
    }

    KMPstring kmp(s2);
    ll prefixExtra = kmp.lps.back();

    s2 = "";
    for (ll i = n - maxCommon - 1; i >= 0; i--) {
        s2 += s[i];
    }
    s2 += "#";

    for (ll i = 0; i <= n - maxCommon - 1; i++) {
        s2 += s[i];
    }
    KMPstring k2(s2);
    ll suffixExtra = k2.lps.back();

    string s4 = s;
    reverse(all(s4));
    KMPstring k3(s + "#" + s4);
    ll d1 = k3.lps.back();
    KMPstring k4(s4 + "#" + s);
    ll d2 = k4.lps.back();

    pll x1 = {maxCommon + prefixExtra, maxCommon};
    pll x2 = {maxCommon, suffixExtra + maxCommon};
    pll x3 = {d1, 0};
    pll x4 = {0, d2};

    vpll vec = {x1, x2, x3, x4};
    len = 0;
    for (auto z : vec) {
        ll sum = z.first + z.second;
        if (sum > len && sum <= n) {
            len = sum;
            x = z;
        }
    }

    if (len >= n) {
        x = {n , 0};
    }

    for (ll i = 0; i < x.first; i++) cout << s[i];
    for (ll i = n - x.second; i < n; i++) cout << s[i];
    cout << endl;
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    ll t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}