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 <bits/stdc++.h>
#define rep(i,l,r) for (int i=l,i##end=r;i<=i##end;++i)
#define per(i,r,l) for (int i=r,i##end=l;i>=i##end;--i)
using namespace std;
const int N=1e4+4;
bool f[N][N],tag[N];
string s[N],str,a;
int z[2*N],l[N];
void exKMP(string s){
    int n=s.length(),l=0,r=0; z[0]=n;
    rep(i,1,n-1){
        z[i]=i<=r?min(z[i-l+1],r-i+1):0;
        while (i+z[i]<n&&s[i+z[i]]==s[z[i]]) ++z[i];
        if (i+z[i]-1>r) l=i,r=i+z[i]-1;
    }
}
int cmps(int x,int y){//[x,x+y-1]<[0,y-1]
    return z[x]>=y?0:(a[x+z[x]]<a[z[x]]?-1:1);
}
struct data{ int x,y; }cur[N];
bool cmp(data p,data q,int i){//p>q
    if (!p.y&&!q.y) return false;
    if (p.x>q.x){
        if (!q.y) return false;
        if (!p.y) return cmps(q.x+l[i],min(p.x-q.x,l[i]))>0;
        int t=cmps(q.x+l[i],min(p.x-q.x,l[i]));
        return t>0||t==0&&cmps(p.x-q.x,l[i]-(p.x-q.x))<0;
    }
    else{
        if (!p.y) return false;
        if (!q.y) return cmps(p.x+l[i],min(q.x-p.x,l[i]))<0;
        int t=cmps(p.x+l[i],min(q.x-p.x,l[i]));
        return t<0||t==0&&cmps(q.x-p.x,l[i]-(q.x-p.x))>0;
    }
}
int main(){
    int n,k; cin>>n>>k;
    rep(i,1,n){ cin>>s[i]; l[i]=s[i].length(); }
    f[n+1][0]=1;
    per(i,n,1) per(j,k,0) f[i][j]=f[i+1][j]||(j>=l[i]?f[i+1][j-l[i]]:0);
    tag[0]=true;
    rep(i,1,n){
        a=s[i]+str; exKMP(a);
        rep(j,0,k) if (tag[j]) cur[j]={j,0};
        data mx={-1,0};
        per(j,k,1){
            if (!f[i+1][k-j]){ tag[j]=false; continue; }
            if (tag[j]) cur[j]={j,0};
            if (j>=l[i]&&tag[j-l[i]]){
                if (tag[j]&&cmp(cur[j],{j-l[i],1},i)) cur[j]={j-l[i],1};
                else if (!tag[j]) tag[j]=true,cur[j]={j-l[i],1};
            }
            if (mx.x==-1&&tag[j]) mx=cur[j];
        }
        if (mx.x==-1) continue;
        per(j,k,1) if (tag[j]&&cmp(mx,cur[j],i)) mx=cur[j];
        rep(j,1,k) if (cmp(cur[j],mx,i)) tag[j]=false;
        per(j,k,1)
            if (tag[j]){
                str=str.substr(0,cur[j].x)+(cur[j].y?s[i]:"");
                break;
            }
    }
    cout<<str<<endl;
    return 0;
}