Problem:
Score : 1500 points

Problem Statement

Iroha has a sequence of N strings s_1, s_2, ..., s_N.

She will choose some (possibly all) strings from the sequence, then concatenate those strings retaining the relative order, to produce a long string.

Among all strings of length K that she can produce in this way, find the lexicographically smallest one.

Constraints

1 ≦ N ≦ 2000

1 ≦ K ≦ 10^4

For each i, 1 ≦ |s_i| ≦ K.

|s_1| + |s_2| + ... + |s_N| ≦ 10^6

For each i, s_i consists of lowercase letters.

There exists at least one string of length K that Iroha can produce.

Input

The input is given from Standard Input in the following format:

N K
s_1
s_2
:
s_N

Output

Print the lexicographically smallest string of length K that Iroha can produce.

Sample Input 1

3 7
at
coder
codar

Sample Output 1

atcodar

at and codar should be chosen.

Sample Input 2

3 7
coder
codar
at

Sample Output 2

codarat

codar and at should be chosen.

Sample Input 3

4 13
kyuri
namida
zzzzzzz
aaaaaa

Sample Output 3

namidazzzzzzz

namida and zzzzzzz should be chosen.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

//#pragma comment(linker, "/STACK:102400000,102400000") 
#pragma warning(disable:4996)
#include <fstream>
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;

typedef long long ll;
#define eps 1e-10
#define LL_INF 0x33ffffffffffffff
#define INF 0x3f3f3f3f
#define mem(a, b) memset(a, b, sizeof(a))
#define pper(i,n,m) for(int i = n;i >= m; i--)
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
#define mp make_pair
#define ff first
#define ss second
#define pb push_back

const int maxn = 1e6 + 5;
const ll mod = 1e9 + 7;
const double PI = acos(-1.0);

int n, k;
int dp[202][1001];
int good[202][1001];
string s[202];
vector <int> which;
vector <int> pos;
vector <int> next_which;
vector <int> next_pos;

char getBest()
{
	char ret = 'z';
	for (int i = 0; i < which.size(); i++)
	{
		ret = min(ret, s[which[i]][pos[i]]);
	}
	return ret;
}

void updateNext(char c, int remain)
{
	next_which.clear();
	next_pos.clear();
	int firstFinish = n + 1;
	int rate = which.size() / 4000;
	for (int i = 0; i < which.size(); i += (rate + 1))
	{
		if (s[which[i]][pos[i]] == c)
		{
			if (pos[i] == s[which[i]].length() - 1)
			{
				firstFinish = min(firstFinish, which[i]);
			}
			else
			{
				next_which.push_back(which[i]);
				next_pos.push_back(pos[i] + 1);
			}
		}
	}
	for (int i = firstFinish + 1; i <= n; i++)
	{
		if (good[i][remain])
		{
			next_which.push_back(i);
			next_pos.push_back(0);
		}
	}
	which = next_which;
	pos = next_pos;
}

void solve()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
		cin >> s[i];
	memset(dp, 0, sizeof(dp));
	dp[n + 1][0] = true;
	for (int i = n; i >= 1; i--)
	{
		for (int j = 0; j <= k; j++)
		{
			if (dp[i + 1][j] == true)
			{
				dp[i][j] = true;
			}
			if (j - (int)s[i].length() >= 0 && dp[i + 1][j - (int)s[i].length()])
			{
				dp[i][j] = true;
			}
		}
	}
	memset(good, false, sizeof(good));
	for (int i = 1; i <= n; i++)
	{
		for (int j = 0; j <= k; j++)
		{
			if (s[i].length() <= j && dp[i + 1][j - (int)s[i].length()])
			{
				good[i][j] = true;
			}
		}
	}
	int remain = k;
	for (int i = 1; i <= n; i++)
	{
		if (good[i][remain])
		{
			which.push_back(i);
			pos.push_back(0);
		}
	}
	string ret;
	for (int i = 1; i <= k; i++)
	{
		char c = getBest();
		remain--;
		updateNext(c, remain);
		ret += c;
	}
	cout << ret << endl;
}

int main()
{
#ifndef ONLINE_JUDGE  
	freopen("i.txt", "r", stdin);
	freopen("o.txt", "w", stdout);
#endif
	solve();
	return 0;
}