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)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <utility>
#include <deque>
#include <stack>
#include <bitset>
#include <ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
#define rep(i,n) for (int i=0;i<n;++i)
#define REP(i,n) for (int i=1;i<=n;++i)
#define all(x) x.begin(),x.end()
#define mp make_pair
#define pb push_back
#define pf push_front
#define F first
#define S second
#define read(x) scanf("%d",&x)
const ll H=13131;
const ll MOD=1e9+7;
int n,k;
ll Pow[10005];
string S[2005],s[2005];
ll HashS[10005];
ll Hash[10005];
int len[2005];
int Len;
int path[10005];// which string occupies the position
bool term[10005];//terminate
bitset<10005> can[2005];
inline void printAns(int l){
	if (l==0) return;
	printAns(l-len[path[l]]);
	if (path[l]==0) exit(1);
	cout<<S[path[l]];
}
int main(){
	ios::sync_with_stdio(false);
	Pow[0]=1;
	for (int i=1;i<10005;++i) Pow[i]=Pow[i-1]*H%MOD;
	cin>>n>>k;
	for (int i=1;i<=n;++i) cin>>S[i],len[i]=S[i].size(),s[i]="."+S[i];
	for (int i=0;i<2005;++i) can[i].reset();
	can[n][k]=1;
	for (int i=n;i>=1;--i){
		for (int j=k;j>=len[i];--j) if (can[i][j]) can[i-1][j]=can[i-1][j-len[i]]=1;
	}
	term[0]=1;Len=0;
	for (int i=1;i<=n;++i){
		for (int j=1;j<=len[i];++j) HashS[j]=(HashS[j-1]+s[i][j])*H%MOD;
		for (int j=0;j+len[i]<=k&&j<=Len;++j){
			if (!term[j]||!can[i][j+len[i]]) continue;
			if (j==Len){// directly add this string
				for (int p=j+1;p<=j+len[i];++p) Hash[p]=(Hash[p-1]+s[i][p-j])*H%MOD;
				term[Len+=len[i]]=1;
				path[Len]=i;
				continue;
			}
			int L=j,R=j+len[i];//L:must same;  R:must diff
			if (Hash[R]==(Hash[j]*Pow[len[i]]+HashS[len[i]])%MOD) continue;//completely the same
			while(L<R-1){
				int M=L+R>>1;
				if (Hash[M]==(Hash[j]*Pow[M-j]+HashS[M-j])%MOD) L=M;
				else R=M;
			}
			if (R>Len){//the original is a prefix
				// add this string as answer won't get worse
				for (int p=R;p<=j+len[i];++p) Hash[p]=(Hash[p-1]+s[i][p-j])*H%MOD;
				for (int p=Len;p<j+len[i];++p) term[p]=0;
				term[Len=j+len[i]]=1;
				path[Len]=i;
				continue;
			}
			int oldchar,curchar=s[i][R-j];
			for (int ch='a';ch<='z';++ch) if (Hash[R]==(Hash[L]+ch)*H%MOD) oldchar=ch;
			if (curchar<oldchar){
				// add this string
				for (int p=R;p<=j+len[i];++p) Hash[p]=(Hash[p-1]+s[i][p-j])*H%MOD;
				for (int p=j+1;p<=Len;++p) term[p]=0;
				term[Len=j+len[i]]=1;
				path[Len]=i;
				continue;
			}
		}
	}
	printAns(k);
	cout<<endl;
	return 0; 
}