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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <cstdio>
#include <string>
#include <ctime>
#include <vector>
#include <iterator>
#include <algorithm> // #include <iostream> // using namespace std; srand(time(NULL))
#include <iostream>
#include <set>

std::vector<std::string> compare (std::vector<std::string> n1, std::vector<std::string> n2,bool unt){
    std::vector<std::string> compare_result;
    
    std::size_t n1_size = n1.size();
    std::size_t n2_size = n2.size();

    // n1について，n2におけるどの位置に値するかを記録しておくvector配列
    std::vector<int> n1_iterator(n1_size);
    int width_number = 0;
    bool forEnd = false;
    for(int i = 0; i < n1_size; i++){
        forEnd = false;
        for(int j = 0; j < n2_size; j++){
            
            // 分岐させる
            width_number = 0;
            while (true) {
              //
                if ((width_number + 1) > n1[n1_size-1-i].size() || (width_number + 1) > n2[j].size()) {
                  if (width_number == n1[n1_size-1-i].size()) {
                    n1_iterator[n1_size-1-i] = j;   
                    forEnd = true;                                   
                  }
                  break;
                }
                if(n1[n1_size-1-i][width_number] < n2[j][width_number]) {
                  n1_iterator[n1_size-1-i] = j;
                  forEnd = true;
                  break;
                }
                else {
                  if (n1[n1_size-1-i][width_number] > n2[j][width_number]) {
                    break;
                  }
                }
                width_number++;
                if (width_number == 5 && unt == false) {
                  break;
                }
              //
                
                // atcoderandatcodeer
              // //
                // if (n1[n1_size-i-1][0] < n2[j][0]) {
                //   n1_iterator[n1_size-1-i] = j;
                //   forEnd = true;
                // }
                // break;
              //
            }
            if(forEnd){
                break;  
            }
            if(j == n2_size-1){
                n1_iterator[n1_size-1-i] = n2_size;
            }
        }
        // if(forEnd){
        //     break;  
        // }
    }

    // n1_which，n2_which：各々についてのiterator
    int n1_which = 0;
    int n2_which = 0;
    
    // n1_iteratorの末尾が0であるときに関して，n1_iteratorの全要素が0になるのでそれを代入する．
    if(n1_iterator[n1_size - 1] == 0){
        for(int j = 0; j <n1_size; j++){
            n1_iterator[j] = 0;
        }
    }

    while((n2_which <= n2_size - 1) || (n1_which <= n1_size - 1)){
        if(n1_which != n1_size) {
            if (n1_iterator[n1_which] > n2_which ){
                compare_result.push_back(n2[n2_which]);
                n2_which++;
            }
            else {
                compare_result.push_back(n1[n1_which]);
                n1_which++;
            }
        }
        else{
            compare_result.push_back(n2[n2_which]);
            n2_which++; 
        }
    }
    // for (int i = 0; i < compare_result.size(); i++ ) {
    //   if ( i == 0 ) {
    //     std::cout << "HOGE" << std::endl;
    //   }
    //   std::cout << compare_result[i] <<std::endl;
    // }
    return compare_result;
}

std::vector<std::string> merge (std::vector<std::string> n,bool unt){ // int merge (string *s, int N, std::vector<int> n){

    int width_number = 0;
    std::size_t n_size = n.size();
    if (n_size <= 2){
        if (n_size != 1) {
            while(true){
              // //
                if ((width_number + 1) > n[0].size() || (width_number + 1) > n[1].size()) {
                  if (width_number == n[1].size() && n[0][width_number-1] == n[1][width_number-1]) {
                    std::iter_swap(n.begin(),n.begin()+1);                    
                  }
                  break;
                }
                if (n[0][width_number] > n[1][width_number]) {
                  std::iter_swap(n.begin(),n.begin()+1);
                  break;                  
                }
                if (n[0][width_number] < n[1][width_number]) {
                  break;
                }
                width_number++;
                if (width_number == 5 && unt == false) {
                  break;
                }
                // //
                // if (n[0][0] > n[1][0]) {
                //   std::iter_swap(n.begin(),n.begin()+1);
                // }
                // break;
                // 先頭と最後尾を交換している.
            }
        } 
        return n;
    } 
    else {
        std::vector<std::string> n1,n2;
        copy(n.begin(), std::next(n.begin(), (int) n_size/2), back_inserter(n1));
        int xx = n_size /2;
        copy(std::next(n.begin(), xx), n.end(), back_inserter(n2));
        // return n2;
        return compare(merge(n1,unt), merge(n2,unt),unt);
    }
}

int main () {
  std::vector<std::string> list_sub;
  std::vector<std::string> list;
  std::string s;
  std::cin >> s;
  int X;
  std::cin >> X;


  for (int i = 0; i < s.size(); i++ ) {
    list_sub.push_back(s.substr(i,s.length()-i));
  }

  // listの中で, 最初でもっとも小さいアルファベットを求める式
  int alphabet[26];
  for (int i = 0; i < 26; i++) {
    alphabet[i] = 0;
  }
  for (int i = 0; i < list_sub.size(); i++) {
    if (alphabet[((int) list_sub[i][0] - 97)] == 0 ) {
      alphabet[((int) list_sub[i][0] - 97)] = 1;
    }
  }
  std::vector<int> iterator_push;
  int j = 0;
  for (int i = 0; i < 26; i++ ) {
    if (j == X) {
      break;
    }
    if (alphabet[i] == 1) {
      iterator_push.push_back(i);
      j++;
    }
  }

  bool yes = false;
  for (int i = 0; i < list_sub.size(); i++ ) {
    if ((int) list_sub[i][0] == (iterator_push[0] + 97)) {
      if (list_sub[i].size() >= X) {
        yes = true;
      }
    }

  }
  for (int i = 0; i < list_sub.size(); i++) {
    if (yes == false) {
      for (int j = 0; j < X; j++ ) {
        if ((int) list_sub[i][0] == (iterator_push[j] + 97)) {
          list.push_back(list_sub[i]);
          break;
        }
      }
    }
    else {
      if ((int) list_sub[i][0] == (iterator_push[0] + 97)) {
          list.push_back(list_sub[i]);        
      }
    }
  }


  list = merge(list,false);
  // for (int i = 0; i < list.size(); i++) {
  //   std::cout << list[i] << std::endl;
  // }
  j = -1;
  if (list[0].size() >= X) {
    std::cout << list[0].substr(0,X) << std::endl;
  }
  else {
    j++;
    while (true) {
      j++;
      if (list.size() == j) {
        j--;
        break;
      }
      if (list[j].size() >= X) {
        break;
      }
    }
  }
  std::vector<std::string> set;
  for (int i = 0; i <= j; i++) {
    for(int m = 0; m < list[i].size(); m++) {
      for (int q = 0; q < list[i].size(); q++) {
        if (q + m > list[i].size()) {
          break;
        }
        set.push_back(list[i].substr(m,q+1));
      }
    }
  }
  if (j == -1) {

  }
  else {
    set = merge(set,false);
    std::cout << set[0] << std::endl;
    return 0;
    if (X == 1) {
      std::cout << set[0] << std::endl;
    }
    else {
      int ii = 1;
      for (int i = 1; i < set.size(); i++) {
        if (set[i] == set[i-1]) {
        }
        else {
          ii++;
        }
        if (X == ii) {
          std::cout << set[i] << std::endl;
          break;
        }
      }
    }
  }
}