#include <bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long int ll;
typedef long double ldb;
mt19937 rng(4672627);
const ll mod1=1561035197;
const ll mod2=1871313779;
const ll p1=27386137;
const ll p2=73186173;
int tree[333333], C=160000;
int k, L[3], d, LEN, FINCOUNT;
string s[3], S;
int len_odd[3][55555];
int len_tr[3][111111];
int len_ev[3][55555];
ll hsh1[3][55555];
ll hsh2[3][55555];
ll pt1[55555];
ll pt2[55555];
int LCP[155555];
int SA[155555];
int rk[155555];
int pos[155555];
int tp[155555];
vector<int> POS[3];
vector< pair< pair<int, int>, int> > indx;
// which string, location, length
pair<int, int> fin[155555];
// location in final string in (SA), length
set< pair<ll, ll> > EX; // already inserted hashes
bool cmp(const int U, const int V)
{
if(pos[U]!=pos[V]) return pos[U]<pos[V];
if(U+d<LEN && V+d<LEN) return pos[U+d]<pos[V+d];
return U>V; // okay!
}
void calc_LCPSA(void)
{
int i, j, c; LEN = S.length();
for(i=0 ; i<LEN ; i++) pos[i]=S[i], SA[i]=i;
for(d=1 ; d<=LEN ; d<<=1)
{
sort(SA, SA+LEN, cmp); tp[0]=0;
for(i=1 ; i<LEN ; i++) tp[i]=tp[i-1]+cmp(SA[i-1], SA[i]);
for(i=0 ; i<LEN ; i++) pos[SA[i]]=tp[i];
if(tp[LEN-1]==LEN-1) break;
}
for(i=0 ; i<LEN ; i++) rk[SA[i]]=i;
for(i=0, j=0 ; i<LEN ; i++, j=max(j-1, 0))
{
if(rk[i]==LEN-1) continue; c=SA[rk[i]+1];
for( ; i+j<LEN && c+j<LEN && S[i+j]==S[c+j] ; j++);
LCP[rk[i]]=j;
}
}
void update(int loc, int v)
{
loc+=C; tree[loc]=v;
for( ; loc>1 ; loc>>=1)
tree[loc>>1]=min(tree[loc], tree[loc^1]);
}
int query(int l, int r)
{
int ret=1e9;
for(l+=C, r+=C ; l<r ; l>>=1, r>>=1)
{
if(l&1) ret=min(ret, tree[l++]);
if(r&1) ret=min(ret, tree[--r]);
}
return ret;
}
pair<ll, ll> hasher(int idx, int l, int r)
{
// [l, r] = [0, r] - [0, l-1] * p^(r-l+1)
if(l==0) return make_pair(hsh1[idx][r], hsh2[idx][r]);
ll ret1=(hsh1[idx][r]-(hsh1[idx][l-1]*pt1[r-l+1]%mod1));
if(ret1<0) ret1+=mod1;
ll ret2=(hsh2[idx][r]-(hsh2[idx][l-1]*pt2[r-l+1])%mod2);
if(ret2<0) ret2+=mod2;
return make_pair(ret1, ret2);
}
void get_hash(int idx)
{
ll cur1=0, cur2=0, i;
for(i=0 ; i<s[idx].length() ; i++)
{
hsh1[idx][i]=(cur1*p1+(s[idx][i]-'a'+1))%mod1; cur1=hsh1[idx][i];
hsh2[idx][i]=(cur2*p2+(s[idx][i]-'a'+1))%mod2; cur2=hsh2[idx][i];
}
}
bool isok(int idx, int l, int r)
{
pair<ll, ll> TT = hasher(idx, l, r);
if(EX.count(TT)) return true;
return false;
}
int getloc(int idx, int l)
{
if(idx==0) return l;
if(idx==1) return L[0]+1+l;
if(idx==2) return L[0]+L[1]+2+l;
}
bool isinside(int idx, int RKloc, int goal)
{
int cc=lower_bound(POS[idx].begin(), POS[idx].end(), RKloc)-POS[idx].begin();
// POS[cc], POS[cc-1] trial
if(cc < POS[idx].size())
{
// RKloc ~ cc distance
int rv=query(RKloc, POS[idx][cc]);
if(rv>=goal) return true;
}
if(cc-1 >=0)
{
int rv=query(POS[idx][cc-1], RKloc);
if(rv>=goal) return true;
}
return false;
}
int get_front(int RKloc, int goal)
{
int lef=0; int rig=RKloc-1; int best=RKloc, mid;
while(lef<=rig)
{
mid=(lef+rig)/2;
if(query(mid, RKloc)>=goal) best=mid, rig=mid-1;
else lef=mid+1;
}
return best;
}
void add_work(int idx, int l, int r)
{
// cout<<idx<<" "<<l<<" "<<r<<endl;
pair<ll, ll> TT = hasher(idx, l, r); EX.insert(TT);
// one should contain, other should not
// [l, r] at idx
int mylen=r-l+1; int myloc=rk[getloc(idx, l)];
int others=0;
if(isinside((idx+1)%3, myloc, mylen)) others++;
if(isinside((idx+2)%3, myloc, mylen)) others++;
int newmyloc=get_front(myloc, mylen);
if(others==1)
{
FINCOUNT++;
fin[FINCOUNT]=make_pair(newmyloc, mylen);
}
}
void finwork(int idx)
{
int i, j; // odd insert
for(i=0 ; i<L[idx] ; i++)
{
int lef=1, rig=len_odd[idx][i], mid, best=0;
while(lef<=rig)
{
mid=(lef+rig)/2;
if(isok(idx, i-mid+1, i+mid-1)) best=mid, lef=mid+1;
else rig=mid-1;
}
for(j=best+1 ; j<=len_odd[idx][i] ; j++)
add_work(idx, i-j+1, i+j-1);
}
for(i=0 ; i<L[idx] ; i++)
{
if(len_ev[idx][i]==0) continue;
int lef=1, rig=len_ev[idx][i], mid, best=0;
while(lef<=rig)
{
mid=(lef+rig)/2;
if(isok(idx, i-mid+1, i+mid)) best=mid, lef=mid+1;
else rig=mid-1;
}
for(j=best+1 ; j<=len_ev[idx][i] ; j++)
add_work(idx, i-j+1, i+j);
}
}
// will do [l, r] form
void run_manacher(int idx)
{
int i, l=1, r=1; L[idx]=s[idx].length();
string Ns = "@" + s[idx] + "#";
for(i=1 ; i<=L[idx] ; i++)
{
len_odd[idx][i]=min(r-i, len_odd[idx][l+(r-i)]);
while(Ns[i-len_odd[idx][i]] == Ns[i+len_odd[idx][i]]) len_odd[idx][i]++;
if(i+len_odd[idx][i]>r)
{
l=i-len_odd[idx][i];
r=i+len_odd[idx][i];
}
}
for(i=0 ; i<L[idx] ; i++) len_odd[idx][i]=len_odd[idx][i+1];
string NNs = "{";
for(i=0 ; i<L[idx] ; i++)
{
NNs.push_back(s[idx][i]);
if(i!=L[idx]-1) NNs.push_back('#');
}
NNs.push_back('}'); // {a#b#c}
ll t=NNs.length()-2; l=r=1;
for(i=1 ; i<=t ; i++)
{
len_tr[idx][i]=min(r-i, len_tr[idx][l+(r-i)]);
while(NNs[i-len_tr[idx][i]] == NNs[i+len_tr[idx][i]]) len_tr[idx][i]++;
if(i+len_tr[idx][i]>r)
{
l=i-len_tr[idx][i];
r=i+len_tr[idx][i];
}
}
for(i=2 ; i<=t ; i+=2)
{
int lc=i/2-1;
len_ev[idx][lc]=len_tr[idx][i]/2;
}
}
void solve(void)
{
FINCOUNT=0;
int i, j; EX.clear();
for(i=0 ; i<3 ; i++) POS[i].clear();
memset(tree, 0, sizeof(tree)); indx.clear();
cin>>s[0]>>s[1]>>s[2]>>k;
memset(len_odd, 0, sizeof(len_odd));
memset(len_ev, 0, sizeof(len_ev));
memset(len_tr, 0, sizeof(len_tr));
for(i=0 ; i<3 ; i++) get_hash(i);
for(i=0 ; i<3 ; i++) run_manacher(i);
/* testing manacher
for(i=0 ; i<3 ; i++)
{
for(j=0 ; j<L[i] ; j++) cout<<len_odd[i][j]<<" "; cout<<"\n";
for(j=0 ; j<L[i] ; j++) cout<<len_ev[i][j]<<" "; cout<<"\n";
}
*/
S = s[0] + '}' + s[1] + '}' + s[2];
calc_LCPSA(); LEN=S.length();
for(i=0 ; i<=L[0]-1 ; i++) POS[0].push_back(rk[i]);
for(i=L[0]+1 ; i<=L[0]+L[1] ; i++) POS[1].push_back(rk[i]);
for(i=L[0]+L[1]+2 ; i<=L[0]+L[1]+L[2]+1 ; i++) POS[2].push_back(rk[i]);
for(i=0 ; i<3 ; i++) sort(POS[i].begin(), POS[i].end());
for(i=0 ; i<=LEN-2 ; i++) update(i, LCP[i]);
/* LCP, SA check
for(i=0 ; i<=LEN-1 ; i++)
{
cout<<S.substr(SA[i], S.length())<<"\n";
cout<<LCP[i]<<"\n";
}
*/
//cout<<"FINWORKSTART"<<"\n"; return;
for(i=0 ; i<3 ; i++) finwork(i);
sort(fin+1, fin+FINCOUNT+1);
if(FINCOUNT<k) { cout<<-1<<endl; return; }
int tt1=fin[k].first;
int tt2=fin[k].second;
for(i=0 ; i<tt2 ; i++) cout<<S[SA[tt1]+i];
cout<<endl; return;
}
int main(void)
{
fio; int i, tc; cin>>tc;
pt1[0]=1; pt2[0]=1;
for(i=1 ; i<=55550 ; i++) pt1[i]=(p1*pt1[i-1])%mod1;
for(i=1 ; i<=55550 ; i++) pt2[i]=(p2*pt2[i-1])%mod2;
for(i=1 ; i<=tc ; i++)
{
cout<<"Case #"<<i<<"\n";
solve(); // reset here
}
return 0;
}