#include using namespace std; #define rep(i,n) for(ll i=0;i=0;i--) #define perl(i,r,l) for(ll i=r-1;i>=l;i--) #define all(x) (x).begin(),(x).end() #define CST(x) cout<> #define rev(x) reverse(x); using ll=long long; using vl=vector; using vvl=vector>; using pl=pair; using vpl=vector; using vvpl=vector; const ll MOD=1000000007; const ll MOD9=998244353; const int inf=1e9+10; const ll INF=4e18; const ll dy[9]={1,0,-1,0,1,1,-1,-1,0}; const ll dx[9]={0,1,0,-1,1,-1,1,-1,0}; template inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; } template inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } class SuffixArray{ using vi=vector; vi S; int N; vi sa_is(const vi &str,const int k){ const int n=str.size(); vector isS(n),isLMS(n); vi LMSs; isS[n-1]=true; for(int i=n-2;i>=0;i--){ isS[i]=str[i]1)pseudo_sa[orderedLMSs[1]]=++rank; repl(i,1,orderedLMSs.size()-1){ bool isdiff=false; rep(j,n){ int p=orderedLMSs[i]+j; int q=orderedLMSs[i+1]+j; if(str[p]!=str[q]||isLMS[p]!=isLMS[q]){ isdiff=true;break; } if(j>0&&isLMS[p])break; } pseudo_sa[orderedLMSs[i+1]]=isdiff? ++rank:rank; } vi newstr(LMSs.size()); index=0; rep(i,n){ if(isLMS[i])newstr[index++]=pseudo_sa[i]; } vi LMS_sa; if(rank+1==LMSs.size())LMS_sa=orderedLMSs; else { LMS_sa=sa_is(newstr,rank+1); for(auto& x:LMS_sa)x=LMSs[x]; } return induced_sort(str,LMS_sa,isS,k); } vi induced_sort(const vi& str,const vi& LMSs,const vector& isS,const int k){ int n=str.size(); vi buckets(n); vi chars(k+1); for(auto c:str)chars[c+1]++; rep(i,k)chars[i+1]+=chars[i]; vi count(k); for(int i=LMSs.size()-1;i>=0;i--){ int c=str[LMSs[i]]; buckets[chars[c+1]-1-count[c]++]=LMSs[i]; } count=vi(k); rep(i,n){ if(buckets[i]==0||isS[buckets[i]-1])continue; int c=str[buckets[i]-1]; buckets[chars[c]+count[c]++]=buckets[i]-1; } count=vi(k); for(int i=n-1;i>=0;i--){ if(buckets[i]==0||!isS[buckets[i]-1])continue; int c=str[buckets[i]-1]; buckets[chars[c+1]-1-count[c]++]=buckets[i]-1; } return buckets; } public: vi sa,lcp; SuffixArray(vector s):S(s),N(s.size()){ //S+="$"; vi str(N+1); rep(i,N) str[i]=S[i]; str[N]=0; sa=sa_is(str,200010); sa.erase(sa.begin()); } /*bool search(string t){ int l=0,r=N; while(r-l>1){ int mid=(l+r)/2; if(S.substr(sa[mid],t.size())<=t)l=mid; else r=mid; } return S.substr(sa[l],t.size())==t; }*/ void construct_lcp(){//lcp[i]:S.substr(sa[i])とS.substr(sa[i+1])のLCP; lcp=vi(N); vi rank(N); rep(i,N)rank[sa[i]]=i; for(int i=0,h=0;i0)h--; } } } }; struct node{ ll l,r,w;//SAの[l,r)に所属する、文字数w分のかたまり。 vector to; node(ll l, ll r,ll w): l(l),r(r),w(w) {} }; void solve(){ ll n,k;cin >> n >> k; vector a(n);rep(i,n)cin >> a[i]; auto s=SuffixArray(a); s.construct_lcp(); /*rep(i,n)cout << s.sa[i] <<" ";cout << endl; rep(i,n)cout << s.lcp[i] <<" ";cout << endl;*/ vector tree; tree.emplace_back(0,n,0); stack st; st.push(0); int nw=0; //return; rep(i,n){ int w=n-s.sa[i];//何文字? if(nwvoid { ll cnt=(tree[i].r-tree[i].l)*tree[i].w; //cout << cnt << endl; if(p=k){ ans=tree[i].l; height=h+(k-p+tree[i].r-tree[i].l-1)/(tree[i].r-tree[i].l); } p+=cnt; h+=tree[i].w; for(auto p:tree[i].to){ self(self,p,h); } }; dfs(dfs,0,0); ans=s.sa[ans]; //cout << ans <<" " << height << " " << p << endl; rep(i,height)cout << a[i+ans] <<" ";cout << endl; } int main(){ ios::sync_with_stdio(false); std::cin.tie(nullptr); ll t;cin >> t; while(t--)solve(); }