/*
	Author: Vo Minh Long
	Codeforces: mncuchiinhuttt
	CBT '25
*/

#include <iostream>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <numeric>
#include <functional>
#include <bitset>
#include <unordered_set>

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>

#define long        long long

#define FastIO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define yuri ios::sync_with_stdio(0);
#define is cin.tie(0);
#define dabet cout.tie(0);
#define showTime() cerr << '\n' << "Running time: " << (1.0 * clock() / CLOCKS_PER_SEC) << "s\n";
#define len(a) (int)(a.size())
#define all(a) (a).begin(), (a).end()

const int N = 2e5 + 7;
const int BASE = 307;
const int INT_inf = 2e9;
const long LL_inf = 9e18;
const double eps = 1e-6;
const short dx[] = {1, 0, -1, 0};
const short dy[] = {0, 1, 0, -1};
const pair<long, long> MOD = {1e9 + 7, 998244353};

template<typename T1, typename T2> bool maximize(T1& a, T2 b){if(a < b) return a = b, 1; return 0;}
template<typename T1, typename T2> bool minimize(T1& a, T2 b){if(a > b) return a = b, 1; return 0;}
template<typename T1> T1 abs(T1 a){return a < 0 ? -a : a;}
template<typename T1> T1 sqr(T1 a){ return a * a; }

inline char getChar() { static char buf[1 << 16]; static size_t len = 0, pos = 0; if (pos == len) pos = 0, len = fread(buf, 1, sizeof(buf), stdin); return pos == len ? -1 : buf[pos++]; }
inline int readInt() { char c; int ans = 0; while ((c = getChar()) < '0' or c > '9'); ans = c - '0'; while ((c = getChar()) >= '0' and c <= '9') ans = ans * 10 + c - '0'; return ans; }

int n, k, L, R, maxLen, ansID;
int len[51];
pair<long, long> pw[N], hashing[51][N];
string s[51];

void setData();
void solve();

int main()
{
	setData();
	solve(); 
}

inline pair<long, long> add(pair<long, long> a, pair<long, long> b)
{
	return {(a.first + b.first) % MOD.first, (a.second + b.second) % MOD.second};
}

inline pair<long, long> dash(pair<long, long> a)
{
	return {(MOD.first - a.first) % MOD.first, (MOD.second - a.second) % MOD.second};
}

inline pair<long, long> mul(pair<long, long> a, pair<long, long> b)
{
	return {(a.first * b.first) % MOD.first, (a.second * b.second) % MOD.second};
}

inline pair<long, long> get(int id, int l, int r)
{
	return add(hashing[id][r], dash(mul(hashing[id][l - 1], pw[r - l + 1])));
}

void setData()
{
	yuri is dabet
	#define NAME "thuyvan"
	if (fopen(NAME".INP", "r"))
		freopen(NAME".INP", "r", stdin),
		freopen(NAME".OUT", "w", stdout);
	cin >> n >> k;
	pw[0] = {1, 1};
	for (int i = 1; i < N; ++i)
		pw[i] = mul(pw[i - 1], {BASE, BASE});
	for (int i = 0; i < n; ++i)
	{
		cin >> s[i];
		maximize(maxLen, len[i] = len(s[i]));
		for (int j = 0; j < len[i]; ++j)
			hashing[i][j + 1] = add(mul(hashing[i][j], {BASE, BASE}), {s[i][j], s[i][j]});
	}
}

bool check(int len)
{
	vector<pair<long, long> > hash;
	for (int i = 0; i < n; ++i)
	{
		vector<pair<long, long> > tmp;
		for (int j = 0; j + len <= ::len[i]; ++j)
			tmp.push_back(get(i, j + 1, j + len));
		sort(all(tmp));
		tmp.erase(unique(all(tmp)), tmp.end());
		for (const pair<long, long>& x : tmp)
			hash.push_back(x);
	}
	sort(all(hash));
	int maxLen = 0, cnt = 1;
	pair<long, long> hashKey = hash[0];
	for (int i = 1; i < len(hash); ++i)
	{
		if (hash[i] == hash[i - 1])
			++cnt;
		else
		{
			if (maximize(maxLen, cnt))
				hashKey = hash[i - 1];
			cnt = 1;
		}
	}
	if (maximize(maxLen, cnt))
		hashKey = hash[len(hash) - 1];
	if (maxLen < k)
		return 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j + len <= ::len[i]; ++j)
			if (get(i, j + 1, j + len) == hashKey)
			{
				ansID = i;
				L = j;
				R = j + len - 1;
				return 1;
			}
	return 0;
}

void solve()
{
	for (int l = 1, r = maxLen; l <= r;)
	{
		int mid = (l + r) >> 1;
		if (check(mid))
			l = mid + 1;
		else 
			r = mid - 1;
	}
	for (int i = L; i <= R; ++i)
		cout << s[ansID][i];
}

/* Some notes:

*/
