#include <bits/stdc++.h>   using namespace std;   const int MAX = 100020;   const long long MOD = (int)1e9 + 7;   const int INF = 1e9;   const long long LLINF = 0x3f3f3f3f3f3f3f3f;   const long double EPS = 1e-7;   int logv[MAX + 1];   void make_log() {     logv[1] = 0;     for (int i = 2; i <= MAX; i++) logv[i] = logv[i / 2] + 1;   }   struct Sparse {     int n;     vector<vector<int> > st;     Sparse(vector<int>& v) {       n = v.size();       int k = logv[n];       st.assign(n + 1, vector<int>(k + 1, 0));       for (int i = 0; i < (int)n; i++) {         st[i][0] = v[i];       }       for (int j = 1; j <= k; j++) {         for (int i = 0; i + (1 << j) <= n; i++) {           st[i][j] = f(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);         }       }     }     int f(int a, int b) { return min(a, b); }     int query(int l, int r) {       int k = logv[r - l + 1];       return f(st[l][k], st[r - (1 << k) + 1][k]);     }   };   void radix_sort(vector<pair<int, int> >& rnk, vector<int>& ind) {     auto counting_sort = [](vector<pair<int, int> >& rnk, vector<int>& ind) {       int n = ind.size(), maxx = -1;       for (auto p : rnk) maxx = max(maxx, p.first);       vector<int> cnt(maxx + 1, 0), pos(maxx + 1), ind_new(n);       for (auto p : rnk) cnt[p.first]++;       pos[0] = 0;       for (int i = 1; i <= maxx; i++) {         pos[i] = pos[i - 1] + cnt[i - 1];       }       for (auto idx : ind) {         int val = rnk[idx].first;         ind_new[pos[val]] = idx;         pos[val]++;       }       swap(ind, ind_new);     };     for (int i = 0; i < (int)rnk.size(); i++) swap(rnk[i].first, rnk[i].second);     counting_sort(rnk, ind);     for (int i = 0; i < (int)rnk.size(); i++) swap(rnk[i].first, rnk[i].second);     counting_sort(rnk, ind);   }   vector<int> suffix_array(string s) {     int n = s.size();     vector<pair<int, int> > rnk(n, make_pair(0, 0));     vector<int> ind(n);     for (int i = 0; i < (int)n; i++) {       rnk[i].first = (s[i] ==  $ ) ? 0 : s[i] -  a  + 1;       ind[i] = i;     }     for (int k = 1; k <= n; k = (k << 1)) {       for (int i = 0; i < n; i++) {         if (ind[i] + k >= n) {           rnk[ind[i]].second = 0;         } else {           rnk[ind[i]].second = rnk[ind[i] + k].first;         }       }       radix_sort(rnk, ind);       vector<pair<int, int> > tmp = rnk;       tmp[ind[0]] = make_pair(1, 0);       for (int i = 1; i < n; i++) {         tmp[ind[i]].first = tmp[ind[i - 1]].first;         if (rnk[ind[i]] != rnk[ind[i - 1]]) {           tmp[ind[i]].first++;         }       }       swap(rnk, tmp);     }     return ind;   }   vector<int> lcp_array(string s, vector<int> sarray) {     vector<int> inv(s.size());     for (int i = 0; i < (int)s.size(); i++) {       inv[sarray[i]] = i;     }     vector<int> lcp(s.size());     int k = 0;     for (int i = 0; i < (int)s.size() - 1; i++) {       int pi = inv[i];       if (pi - 1 < 0) continue;       int j = sarray[pi - 1];       while (s[i + k] == s[j + k]) k++;       lcp[pi] = k;       k = max(k - 1, 0);     }     return vector<int>(lcp.begin() + 1, lcp.end());   }   int solve(int i, int n, int sz, Sparse& st) {     int res = 1;     int l = i + 1, r = n - 1;     while (l <= r) {       int mid = (l + r) / 2;       if (st.query(i, mid - 1) >= sz) {         res = mid - i + 1;         l = mid + 1;       } else {         r = mid - 1;       }     }     return res;   }   int32_t main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     cout.tie(NULL);     ;     make_log();     int k, n;     string s, res =  No such line. n ;     cin >> s;     cin >> k;     n = s.size();     vector<int> sa = suffix_array(s);     vector<int> lcp = lcp_array(s, sa);     Sparse st = Sparse(lcp);     int cur = 0;     bool win = false;     for (int i = 0; i < sa.size() and !win; i++) {       int idx = sa[i];       int maxsz = s.size() - idx;       int sz = 1;       if (i > 0) sz = lcp[i - 1] + 1;       while (sz <= maxsz and !win) {         int qt = solve(i, n, sz, st);         if (cur + qt >= k) {           res = s.substr(idx, sz);           win = true;         }         cur += qt;         sz++;       }     }     cout << res <<   n ;     return 0;   }