#include <bits/stdc++.h>   using namespace std;   const int MAX = 1e5 + 5;   constexpr int LOGMAX = 31 - __builtin_clz(MAX) + 5;   int N;   char T[MAX];   int sa[MAX], tsa[MAX], ra[MAX], tra[MAX];   int lcp[MAX], plcp[MAX], phi[MAX], c[MAX], st[LOGMAX][MAX];   long long pref[MAX];   void sort(int k) {     memset(c, 0, sizeof c);     for (int i = int(0); i < int(N); i++) {       c[i + k < N ? ra[i + k] : 0]++;     }     int sum = 0, maxi = max(300, N);     for (int i = int(0); i < int(maxi); i++) {       int t = c[i];       c[i] = sum;       sum += t;     }     for (int i = int(0); i < int(N); i++) {       int cur = sa[i] + k < N ? ra[sa[i] + k] : 0;       tsa[c[cur]++] = sa[i];     }     memcpy(sa, tsa, sizeof(int) * N);   }   void build_sa() {     for (int i = int(0); i < int(N); i++) {       ra[i] = T[i];       sa[i] = i;     }     for (int k = 1; k < N; k *= 2) {       sort(k);       sort(0);       int r = tra[sa[0]] = 0;       for (int i = int(1); i < int(N); i++) {         if (ra[sa[i]] == ra[sa[i - 1]]) {           int cur = (sa[i] + k) < N ? ra[sa[i] + k] : 0;           int prev = (sa[i - 1] + k) < N ? ra[sa[i - 1] + k] : 0;           if (cur == prev) {             tra[sa[i]] = r;           } else {             tra[sa[i]] = ++r;           }         } else {           tra[sa[i]] = ++r;         }       }       if (tra[sa[N - 1]] == N - 1) {         break;       }       memcpy(ra, tra, sizeof(int) * N);     }   }   void build_lcp() {     phi[sa[0]] = -1;     for (int i = int(1); i < int(N); i++) {       phi[sa[i]] = sa[i - 1];     }     int l = 0;     for (int i = int(0); i < int(N); i++) {       if (phi[i] == -1) {         plcp[i] = 0;         continue;       }       while (T[i + l] == T[phi[i] + l]) {         l++;       }       plcp[i] = l;       l = max(l - 1, 0);     }     for (int i = int(0); i < int(N); i++) {       lcp[i] = plcp[sa[i]];     }   }   inline long long in_range(int left, int right) {     return pref[right] - pref[left - 1];   }   inline int min_query(int left, int right) {     int sz = right - left + 1;     int lg = 31 - __builtin_clz(sz);     return min(st[lg][left], st[lg][right - (1 << lg) + 1]);   }   string roll(int l, int r, int len, long long k) {     int left = l + 1, right = r;     int edge = l;     while (left <= right) {       int mid = (left + right) / 2;       if (min_query(l + 1, mid) >= len) {         edge = mid;         left = mid + 1;       } else {         right = mid - 1;       }     }     long long total = in_range(l, edge) - 1LL * (len - 1) * (edge - l + 1);     if (total < k) {       return roll(edge + 1, r, len, k - total);     } else if (k > (edge - l + 1)) {       return roll(l, r, len + 1, k - (edge - l + 1));     }     int pos = l + k - 1;     string ans =   ;     for (int i = int(0); i < int(len); i++) {       ans += T[sa[pos] + i];     }     return ans;   }   int main() {     scanf( %s , T);     N = strlen(T);     long long k;     scanf( %lld , &k);     if ((1LL * N * (N + 1)) / 2 < k) {       puts( No such line. );       return 0;     }     T[N++] =  $ ;     build_sa();     build_lcp();     for (int i = int(1); i < int(N); i++) {       pref[i] = pref[i - 1] + N - sa[i] - 1;       st[0][i] = lcp[i];     }     for (int i = int(1); i < int(LOGMAX); i++) {       for (int j = 1; j + (1 << i) - 1 < N; j++) {         st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);       }     }     printf( %s n , roll(1, N - 1, 1, k).c_str());     return 0;   }