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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Diagnostics;

namespace CompetitiveProgramming
{
  class Solve
  {
    Dictionary<string, string>[] memo = new Dictionary<string, string>[2001];

    public Solve()
    {
      for (int i = 0; i < 2001; i++)
      {
        memo[i] = new Dictionary<string, string>();
      }
      int N = Scanner.nextInt();
      int K = Scanner.nextInt();
      string[] s = new string[N];
      for (int i = 0; i < N; i++) 
      {
        s[i] = Scanner.nextString();
      }

      Console.WriteLine(rec(N, K, 0, s, string.Empty));
    }

    string rec(int N, int K, int index, string[] s, string str)
    {
      if (memo[index].ContainsKey(str)) 
      {
        return memo[index][str];
      }

      if (str.Length == K)
      {
        return str;
      } 
      if (str.Length > K || index >= N)
      {
        return "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
      }
      string str1 = rec(N, K, index + 1, s, str);
      string str2 = rec(N, K, index + 1, s, str + s[index]);
      if (str1.CompareTo(str2) < 0) {
        return memo[index][str] = str1;
      } 
      else
      {
        return memo[index][str] = str2;
      }
    }

  }

  class Program
  {
    static void Main(string[] args)
    {
        new Solve();
    }
  }

  public class Pair<T, U>
  {
    public Pair()
    {

    }
    public Pair(T first, U second)
    {
      this.first = first;
      this.second = second;
    }
    public T first { get; set; }
    public U second { get; set; }
  }

  class Scanner
  {
    private static List<string> buf = new List<string>();

    private static void next()
    {
      if (buf.Count == 0)
      {
        buf = Console.ReadLine().Split().ToList();
      }
    }

    private static string pop()
    {
      string ret = buf[0];
      buf.RemoveAt(0);
      return ret;
    }

    public static int nextInt()
    {
      next();
      return int.Parse(pop());
    }
    public static long nextLong()
    {
      next();
      return long.Parse(pop());
    }
    public static string nextString()
    {
      next();
      return pop();
    }
    public static double nextDouble()
    {
      next();
      return double.Parse(pop());
    }
  }
}