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: Time Limit Exceeded)

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
	char* start;
	size_t len;
} Substr;

Substr* substrs[25000000];
int substr_found = 0;

bool isLower(Substr* a, Substr* b) {
	if (a == b) return false;
	char astr[5001] = {0};
	char bstr[5001] = {0};
	strncpy(astr, a->start, a->len);
	strncpy(bstr, b->start, b->len);
	
	return (strcmp(astr, bstr) < 0);
}

void sort(int num) {
	if (substr_found < num) return;
	for (int i = 0; i < num && i < substr_found; i++) {
		int cur_top = i;
		for (int j = i+1; j < substr_found; j++) {
			if (isLower(substrs[j], substrs[cur_top])) cur_top = j;
		}
		
		// swap
		Substr* tmp = substrs[i];
		substrs[i] = substrs[cur_top];
		substrs[cur_top] = tmp;
	}
}
	
bool isAlreadyFound(Substr* s) {
	for (int i = 0; i < substr_found; i++) {
		char str_n[5001] = { 0 };
		strncpy(str_n, s->start, s->len);
		char str[5001] = { 0 };
		strncpy(str, substrs[i]->start, substrs[i]->len);
		if (!strcmp(str_n, str)) return true;
	}
	return false;
}

int main() {
	char s[5000 + 1];
	int k;
	scanf("%s %d", s, &k);
	
	if (!substrs) return 0;
	
	
	char* start = s;
	
	size_t len_all = strlen(s);
	
	bool opt_flag = false;
	if (len_all > 50) {
		int a_num = 0;
		for (char* i = s; (i-s) < len_all - 6; i++) 
			if (*i == 'a') a_num++;
		if (a_num) opt_flag = true;
	}
	
	for (; *start; start++) {
		if (len_all > 5 && *start > *s) continue;
		if (opt_flag && *start != 'a') continue;
		size_t slen = strlen(start);
		for (size_t len = 1; len <= slen; len++) {
			Substr* cur = (Substr*) malloc(sizeof(Substr));
			cur->start = start;
			cur->len = len;
			if (!isAlreadyFound(cur)) {
				substrs[substr_found] = cur;
				substr_found++;
			} else free(cur);
		}
	}
	
	sort(k);
	char res[5001] = {0};
	strncpy(res, substrs[k - 1]->start, substrs[k - 1]->len);
	printf("%s", res);
	
	return 0;
}