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 Go (1.6) (judge verdict: Accepted)

package main
import "fmt"
var n,k int
var s [][]rune
var dp [][]bool
var ok []bool
var ans []rune
func main() {
  fmt.Scan(&n,&k)
  s = make([][]rune,n)
  for i:=0;i<n;i++ {
    var tmp string
    fmt.Scan(&tmp)
    s[i] = []rune(tmp)
  }
  preprocess()
  process()
  fmt.Println(string(ans))
}
func preprocess() {
  dp = make([][]bool,n+1)
  for i:=0;i<n+1;i++ { dp[i] = make([]bool,k+1) }
  dp[n][0] = true
  for i:=n-1;i>=0;i-- {
    l := len(s[i])
    for j:=0;j<=k;j++ {
      dp[i][j] = dp[i+1][j]
      if j >= l { dp[i][j] = dp[i][j] || dp[i+1][j-l] }
    }
  }
}
func process() {
  ans = make([]rune,k)
  for i:=0;i<k;i++ { ans[i] = '{' }
  ok = make([]bool,k+1)
  ok[0] = true
  for i:=0;i<n;i++ {
    l := len(s[i])
    x,d := -1,-1
    z := z_algorithm(string(s[i])+"."+string(ans))
    z = z[l+1:]
    for j:=0;j<=k-l;j++ {
      if !(ok[j] && dp[i+1][k-l-j]) { continue }
      if z[j] < l && j+z[j] < k && s[i][z[j]] < ans[j+z[j]] {
        x = j
        break
      }
    }
    if x < 0 { continue }
    y := x+l
    for j:=0;j<l;j++ {
      if d < 0 && ans[x+j] != s[i][j] { d = x+j }
      ans[x+j] = s[i][j]
    }
    for j:=y;j<k;j++ { ans[j] = '{' }
    for j:=d+1;j<=k;j++ { ok[j] = false }
    ok[y] = true
  }
}
func z_algorithm(s string) []int {
  n := len(s)
  z := make([]int,n)
  z[0] = n
  for i,j:=1,0;i<n; {
    for i+j < n && s[j:j+1] == s[i+j:i+j+1] { j++ }
    z[i] = j
    if j == 0 { i++;continue }
    k := 1
    for ;i+k<n&&k+z[k]<j;k++ { z[i+k] = z[k] }
    i,j = i+k,j-k
  }
  return z
}