Problem:
Score : 300 points

Problem Statement

You are given a string s.
Among the different substrings of s, print the K-th lexicographically smallest one.

A substring of s is a string obtained by taking out a non-empty contiguous part in s.
For example, if s = ababc, a, bab and ababc are substrings of s, while ac, z and an empty string are not.
Also, we say that substrings are different when they are different as strings.

Let X = x_{1}x_{2}...x_{n} and Y = y_{1}y_{2}...y_{m} be two distinct strings. X is lexicographically larger than Y if and only if Y is a prefix of X or x_{j} > y_{j} where j is the smallest integer such that x_{j} \neq y_{j}.

Constraints

1 ≤ |s| ≤ 5000

s consists of lowercase English letters.

1 ≤ K ≤ 5

s has at least K different substrings.

Partial Score

200 points will be awarded as a partial score for passing the test set satisfying |s| ≤ 50.

Input

Input is given from Standard Input in the following format:

s
K

Output

Print the K-th lexicographically smallest substring of K.

Sample Input 1

aba
4

Sample Output 1

b

s has five substrings: a, b, ab, ba and aba.
Among them, we should print the fourth smallest one, b.
Note that we do not count a twice.

Sample Input 2

atcoderandatcodeer
5

Sample Output 2

andat

Sample Input 3

z
1

Sample Output 3

z

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace debug
{
    class main
    {
        static void Main(string[] args)
        {
            //問題クラスを展開
            ProgramC a = new ProgramC();
            a.main();//実行する

        }

    }

    class ProgramA
    {
        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split(' ');
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int c = int.Parse(s[2]);
            int d = int.Parse(s[3]);


            if (Math.Abs(a-b)<= d && Math.Abs(c - b) <= d)
                Console.WriteLine("Yes");
            else if(Math.Abs(c - a) <= d)
                Console.WriteLine("Yes");
            else
                Console.WriteLine("No");

        }
    }

    class ProgramB
    {
        public void main()
        {
            //入力
            int x = int.Parse(Console.ReadLine());

            for (int i = x; i > 0; i--)
            {
                for(int j = 2; j <= Math.Sqrt(x);j++)
                {
                    if(i % j == 0)
                    {
                        int t = i;
                        while (t % j == 0)
                            t /= j;

                        if(t == 1)
                        {
                            Console.WriteLine(i);
                            return;
                        }
                    }
                }

            }


            Console.WriteLine(1);
        }

        
    }

    class ProgramC
    {
        public void main()
        {

            //入力
            string s = Console.ReadLine();
            int k = int.Parse(Console.ReadLine());

            List<string> ans = new List<string>();


            for(int j = 1; j <= 5;j++)
                for (int i = 0;i < s.Length + 1 - j;i++)
                {
                    if(!ans.Contains(s.Substring(i, j)))
                        ans.Add(s.Substring(i, j));
                }
            
            ans.Sort();

            //答え出力
            Console.WriteLine(ans[k -1]);

        }

        
    }



    class ProgramD
    {
        public void main()
        {

            //入力
            string[] input = Console.ReadLine().Split(' ');
            int n = int.Parse(input[0]);
            int m = int.Parse(input[1]);

            int[] a = new int[n];

            UnionFind tree = new UnionFind();//UnionFindクラスを設定
            tree.par = new int[n];
            tree.temp = new int[n];
            tree.reset(n);

            string[] input3 = Console.ReadLine().Split(' ');
            for (int i = 0; i < n; i++)
                a[i] = int.Parse(input3[i]);

            //Union-find法
            for (int i = 0; i < m; i++)
            {
                string[] input2 = Console.ReadLine().Split(' ');
                int x = int.Parse(input2[0]);
                int y = int.Parse(input2[1]);
                tree.unite(x - 1, y - 1); // xの木とyの木を併合する

                
            }
            int count = 0;
            //要素数-1を足し合わせる。（前のところで友だちは除いているので友だち候補のみ残る）
            for (int i = 0; i < n; i++)
            {
                if (tree.same(a[i] - 1, i) == true)
                    count++;
            }


            //答
            Console.WriteLine(count);
        }
    }

    /*UnionFind法のクラス*/
    class UnionFind
    {

        public int[] par;
        public int[] temp;


        //マイナスは根を示す。
        public void reset(int n)
        {
            for (int i = 0; i < n; i++)
                par[i] = -1;
        }

        //マイナスならそれはまだ属していないので根である。そうでないならさかのぼる
        public int root(int x)
        {
            if (par[x] < 0)
                return x;
            else
                return root(par[x]);
        }

        //根の併合を行い、根には要素数を足す（マイナスの値）
        public void unite(int x, int y)
        { // xとyの木を併合
            int rx = root(x); //xの根をrx
            int ry = root(y); //yの根をry
            if (rx == ry)
                return; //xとyの根が同じ(=同じ木にある)時はそのまま
            if (par[ry] > par[rx])
            {
                int temp = ry;
                ry = rx;
                rx = temp;
            }
            par[ry] += par[rx];
            par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        }

        // 2つのデータx, yが属する木が同じならtrueを返す
        public bool same(int x, int y)
        {
            int rx = root(x);
            int ry = root(y);
            return rx == ry;
        }


        //根の元に入っている
        public int size(int x)
        {
            return -par[root(x)];
        }
    }


}