#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 INF 1e18
#define endl '\n'
#define ff first
#define ss second
#define pb push_back
#define int long long
#define double long double
#define ull unsigned long long
#define mod 1000000007
#define pii 2 * acos(0.0)
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(a) (a).rbegin(),(a).rend()
#define upb(v,k) upper_bound(all(v),k);
#define lob(v,k) lower_bound(all(v),k);
#define deci(x) cout << fixed << setprecision(x);
#define rmv(x,a) x.erase(remove(x.begin(),x.end(),a),x.end())
#define rot(a,x) rotate(a.begin(), a.begin() + x , a.end());
#define unq(x) {sort(all(x));x.erase(unique(x.begin(),x.end()),x.end());}
#define shera() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
//unordered_map anti hash
const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
struct chash {int operator()(int x) const { return x ^ RANDOM; }};
struct pqCompare {bool operator()(const int& lhs, const int& rhs) const {return lhs > rhs;}};
//gp_hash_table<int, int,chash>mp;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
//Number Theory
int fact(int n) {if (n == 0)return 1; int res = 1; for (int i = 2; i <= n; i++)res = res * i; return res;}
int gcd(int a, int b) {if (b == 0)return a; return gcd(b, a % b);}
int lcm(int a, int b) {return (a / gcd(a, b) * b);}
int countDigit(long long n) {return floor(log10(n) + 1);}
int nCr(int n, int r) {return fact(n) / (fact(r) * fact(n - r));}
ull PowMod(ull n) {ull ret = 1; ull a = 2; while (n > 0) {if (n & 1) ret = ret * a % mod; a = a * a % mod; n >>= 1;} return ret;}
int Digit_Sum(int a) {int sum = 0; for (int i = a; i > 0; i /= 10) {sum += i % 10;} return sum;}
int poww(int base, int exp) {int count = 1; for (int i = exp; i >= 0; i--) {if (i == 0) {break;} if (exp == 1) {count = count * base; break;} count = count * base;} return count;}
int get_powers_of_n_fact(int n, int p) {int result = 0; while (n >= p) {n /= p; result += n;} return result;}
//bitmask
int Count_One(int n) {int count = 0; while (n) {count++; n = n & (n - 1);} return count;}
int lastSetBit(int n) {bitset<64>x(n); for (int i = 63; i >= 0; i--)if (x[i] == 1)return i; return 0;}//(n&(-n))
//check
bool is_set(int n, int k) {return n & (1 << k);}
bool isPowerofTwo(int n) {return (n && !(n & (n - 1)));}
bool is_sqr(int x) {int y = (int) (sqrt(x) + 0.5); return y * y == x;}
bool IsPrime(int n) {for (int i = 2; i * i <= n; i++)if (n % i == 0) { return false;} return true;}
bool isPalindrome(string s) {int i = 0, j = s.size() - 1; for (i, j; i <= j; i++, j--) {if (s[i] != s[j]) return 0;} return 1;}
bool cmp(pair<int, int>&p1, pair<int, int>&p2) {if (p1.ff < p2.ff) {return 1;} else if (p1.ff == p2.ff) {return (p1.ss > p2.ss);} return 0;}
char next_char(char& c) {return c = (char)(c - 'a' + 1) % 26 + 'a';}
char prev_char(char& c) {return c = (char)(c - 'a' - 1 + 26) % 26 + 'a';}
#ifndef ONLINE_JUDGE
#define db(x) cerr << #x <<" "; _print(x); cerr << endl;
#else
#define db(x)
#endif
void _print(int t) {cerr << t;}
void _print(string t) {cerr << t;}
void _print(char t) {cerr << t;}
void _print(double t) {cerr << t;}
template <class T, class V> void _print(pair <T, V> p);
template <class T> void _print(vector <T> v);
template <class T> void _print(set <T> v);
template <class T, class V> void _print(map <T, V> v);
template <class T> void _print(multiset <T> v);
template <class T, class V> void _print(pair <T, V> p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";}
template <class T> void _print(vector <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T> void _print(set <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T> void _print(multiset <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T, class V> void _print(map <T, V> v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";}
template<typename T1, typename T2> istream &operator>>(istream &cin, pair<T1, T2> &a) { return cin >> a.first >> a.second; }
template<typename T1> istream &operator>>(istream &cin, vector<T1> &a) { for (auto &x : a) cin >> x; return cin; }
template<typename T1> istream &operator>>(istream &cin, valarray<T1> &a) { for (auto &x : a) cin >> x; return cin; }
template<typename T1, typename T2> ostream &operator<<(ostream &cout, const pair<T1, T2> &a) { return cout << a.first << ' ' << a.second; }
template<typename T1, typename T2> ostream &operator<<(ostream &cout, const vector<pair<T1, T2>> &a) { for (auto &x : a) cout << x << '\n'; return cout; }
template<typename T1> ostream &operator<<(ostream &cout, const vector<T1> &a) { int n = a.size(); if (!n) return cout; cout << a[0]; for (int i = 1; i < n; i++) cout << ' ' << a[i]; return cout; }
template<typename T1, typename T2> bool cmin(T1 &x, const T2 &y) { if (y < x) { x = y; return 1; } return 0; }
template<typename T1, typename T2> bool cmax(T1 &x, const T2 &y) { if (x < y) { x = y; return 1; } return 0; }
template<typename T1> vector<T1> range(T1 l, T1 r, T1 step = 1) { assert(step > 0); int n = (r - l + step - 1) / step, i; vector<T1> res(n); for (i = 0; i < n; i++) res[i] = l + step * i; return res; }
template<typename T1> basic_string<T1> operator*(const basic_string<T1> &s, int m) { auto r = s; m *= s.size(); r.resize(m); for (int i = s.size(); i < m; i++) r[i] = r[i - s.size()]; return r; }
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; // .order_of_key(x) // *.find_by_order(x)
template <typename T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
bool compareLength(string &a, string &b) {
return a.length() < b.length();
}
signed main() {
shera();
#ifndef ONLINE_JUDGE
freopen("Error.txt", "w", stderr);
#endif
int tc; tc = 1;
cin >> tc;
for (int ii = 1; ii <= tc; ii++ ) {
int n, k; cin >> n >> k;
vector<string>v(n); cin >> v;
vector<string>ans;
for (int i = 0; i < n - k ; i++) {
string s = "";
for (int j = i; j < i + k + 1; j++) {
s += v[j];
}
ans.pb(s);
}
sort(all(ans), compareLength);
cout << ans.back() << endl;
}
return 0;
}