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 Rust (1.15.1) (judge verdict: Time Limit Exceeded)

#![allow(unused)]

use cmp::Ordering::{Equal, Greater, Less};
use collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use io::{Read, Write};
use std::{cmp, collections, fmt, io, iter, ops, str};

#[cfg(feature = "debug")]
macro_rules! debug {
    ($fmt: expr) => { eprintln!($fmt) };
    ($fmt: expr, $($args: tt)*) => { eprintln!($fmt, $($args)*) };
}

#[cfg(not(feature = "debug"))]
macro_rules! debug {
    ($fmt:expr) => {};
    ($fmt:expr, $($args:tt)*) => {};
}

macro_rules! vmax {
    ($x: expr, $y: expr) => { cmp::max($x, $y) };
    ($x: expr, $($args: expr),*) => { cmp::max($x, vmax!($($args),*)) };
}

macro_rules! vmin {
    ($x: expr, $y: expr) => { cmp::min($x, $y) };
    ($x: expr, $($args: expr),*) => { cmp::min($x, vmin!($($args),*)) };
}

fn main() {
    let s = read_line();
    let k = parse_line::<usize>();

    let mut char_pos = BTreeMap::new();

    for (i, c) in s.chars().enumerate() {
        let substr = Substring(c.to_string());
        let mut entry = char_pos.entry(substr).or_insert(vec![]);
        entry.push(i);
    }

    let mut first = true;
    for (c, pos) in char_pos.clone() {
        for len in 2..(s.len() + 1) {
            for &p in &pos {
                let end = p + len;
                if end > s.len() {
                    continue;
                }

                let substr = Substring(s[p..end].to_string());
                let mut entry = char_pos.entry(substr).or_insert(vec![]);
                entry.push(p);
            }
        }

        if !first && char_pos.len() >= k {
            break;
        }

        first = false;
    }

    debug!("{}, {:?}", char_pos.len(), char_pos);
    println!("{}", (char_pos.iter().nth(k - 1).unwrap().0).0);
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Substring(String);

impl ops::Deref for Substring {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

// impl PartialOrd for Substring {
//     fn partial_cmp(&self, rhs: &Substring) -> Option<cmp::Ordering> {
//         for (x, y) in self.chars().zip(rhs.chars()) {
//             if x == y {
//                 continue;
//             }
//
//             return Some(x.cmp(&y));
//         }
//
//         Some(self.len().cmp(&rhs.len()))
//     }
// }

// impl Ord for Substring {
//     fn cmp(&self, rhs: &Substring) -> cmp::Ordering {
//         self.partial_cmp(rhs).unwrap()
//     }
// }

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test() {
        assert_eq!(lexico_order("a", "ab"), cmp::Ordering::Less);
        assert_eq!(lexico_order("ab", "a"), cmp::Ordering::Greater);

        assert_eq!(lexico_order("ab", "ac"), cmp::Ordering::Less);
        assert_eq!(lexico_order("ac", "ab"), cmp::Ordering::Greater);

        assert_eq!(lexico_order("abc", "abc"), cmp::Ordering::Equal);
    }
}

fn read_line() -> String {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.trim().to_owned()
}

fn read_word() -> String {
    const CAPACITY: usize = 16;

    let mut stdin = io::stdin();
    let mut byte: [u8; 1] = [0];

    loop {
        let mut buf = Vec::with_capacity(CAPACITY);

        loop {
            let res = stdin.read(&mut byte);

            if res.unwrap_or(0) == 0 || byte[0] <= b' ' {
                break;
            } else {
                buf.push(byte[0]);
            }
        }

        if buf.len() > 0 {
            return String::from_utf8(buf).unwrap();
        }
    }
}

fn parse_line<T: str::FromStr>() -> T {
    read_line().parse().ok().unwrap()
}

fn parse_word<T: str::FromStr>() -> T {
    read_word().parse().ok().unwrap()
}

fn parse_vec<T: str::FromStr>() -> Vec<T> {
    read_line()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

fn flush() {
    io::stdout().flush();
}

fn next_prime(x: i32) -> i32 {
    for i in (x + 1).. {
        if is_prime(i) {
            return i;
        }
    }

    panic!("attempt to add with overflow");
}

fn is_prime(x: i32) -> bool {
    let ceil = (x as f64).sqrt().ceil() as i32;
    x == 2 || (2..(ceil + 1)).all(|i| x % i != 0)
}