import math
# Define a constant for maximum size
mxN = 10**5 + 5
# Arrays for suffix array, position, temporary, and longest common prefix
sa = [0] * mxN
pos = [0] * mxN
tmp = [0] * mxN
lcp = [0] * mxN
# Variables for gap and size of the string
gap = 0
N = 0
# Input string
S = ""
# Function to compare two positions in the suffix array
def comp(x, y):
global pos, gap, N
# Compare positions based on their values in the pos array
if pos[x] != pos[y]:
return pos[x] < pos[y]
# If pos[x] == pos[y], compare their positions with a gap
x += gap
y += gap
# If within bounds, return comparison result based on pos array;
# otherwise, return comparison of x and y
return pos[x] < pos[y] if (x < N and y < N) else x > y
# Function to construct the suffix array
def suffix():
global sa, pos, tmp, gap, N
# Initialize sa and pos arrays with initial values
for i in range(N):
sa[i] = i
pos[i] = ord(S[i])
# Loop for different gap values
gap = 1
while True:
# Sort the suffix array based on the comparison function comp
sa.sort(key=lambda x: (pos[x], pos[x + gap] if x + gap < N else -1))
# Update temporary array tmp
tmp[0] = 0
for i in range(1, N):
tmp[i] = tmp[i - 1] + comp(sa[i - 1], sa[i])
# Update pos array
for i in range(N):
pos[sa[i]] = tmp[i]
# If all suffixes are sorted, break the loop
if tmp[N - 1] == N - 1:
break
gap *= 2
# Function to construct the longest common prefix array
def build_lcp():
global lcp, pos, N
k = 0
for i in range(N):
if pos[i] != N - 1:
j = sa[pos[i] + 1]
while i + k < N and j + k < N and S[i + k] == S[j + k]:
k += 1
lcp[pos[i]] = k
if k > 0:
k -= 1
# Segment tree related functions for efficient range queries and updates Segment tree array
seg = [(0, 0)] * (mxN * 10)
# Array to mark updates
mark = [0] * (mxN * 10)
# Function to push updates down the segment tree
def push(k):
global seg, mark
if mark[k]:
mark[k] = 0
seg[2 * k] = seg[2 * k + 1] = (seg[k][0] // 2, 0)
mark[2 * k] = mark[2 * k + 1] = 1
# Function to update values in the segment tree
def update(v, a, b, k, x, y):
global seg
if b < x or a > y:
return
if a <= x and b >= y:
seg[k] = (seg[k][0], seg[k][1] + v)
return
h = min(b, y) - max(a, x) + 1
push(k)
seg[k] = (seg[k][0] + h * v, seg[k][1])
d = (x + y) // 2
update(v, a, b, 2 * k, x, d)
update(v, a, b, 2 * k + 1, d + 1, y)
# Function to assign values in the segment tree
def assign(v, a, b, k, x, y):
global seg, mark
if b < x or a > y:
return seg[k][0] + (y - x + 1) * seg[k][1]
if a <= x and b >= y:
seg[k] = ((y - x + 1) * v, 0)
mark[k] = 1
return seg[k][0]
push(k)
d = (x + y) // 2
seg[2 * k] = (seg[k][0], seg[2 * k][1] + seg[k][1])
seg[2 * k + 1] = (seg[k][0], seg[2 * k + 1][1] + seg[k][1])
seg[k] = assign(v, a, b, 2 * k, x, d) + assign(v, a, b, 2 * k + 1, d + 1, y)
return seg[k][0]
# Function to calculate sum in a range using segment tree
def _sum(a, b, k, x, y):
global seg
if b < x or a > y:
return 0
if a <= x and b >= y:
return seg[k][0] + (y - x + 1) * seg[k][1]
push(k)
seg[k] = (seg[k][0] + (y - x + 1) * seg[k][1], seg[k][1])
seg[2 * k] = (seg[2 * k][0], seg[2 * k][1] + seg[k][1])
seg[2 * k + 1] = (seg[2 * k + 1][0], seg[2 * k + 1][1] + seg[k][1])
d = (x + y) // 2
return _sum(a, b, 2 * k, x, d) + _sum(a, b, 2 * k + 1, d + 1, y)
# Input string
S = input().strip()
# Size of the string
N = len(S)
# Construct suffix array
suffix()
# Construct longest common prefix array
build_lcp()
# Given k value for substring extraction
k = int(input())
# Calculate the k-th smallest lexicographically suffix
# Calculate the position from the last
k = N * (N + 1) // 2 - k + 1
# Construct a segment tree
# Calculate the size of the segment tree array
K = 1 << (math.ceil(math.log2(N + 1)))
# Initialize current position
cur = 0
for i in range(N - 1, -1, -1):
# Update the segment tree
update(1, 1, N - sa[i], 1, 0, K - 1)
# Get the previous longest common prefix
prev = lcp[i - 1] if i > 0 else 0
# Set the search range for the binary search
l, r = prev + 1, N - sa[i]
# Initialize answer variable
ans = -1
# Binary search to find the longest common prefix that satisfies the condition
while l <= r:
m = (l + r) // 2
if cur + _sum(m, N - sa[i], 1, 0, K - 1) >= k:
ans = m
r = m - 1
else:
l = m + 1
# If answer is found, print the substring and exit the loop
if ans != -1:
print(S[sa[i]:sa[i] + ans])
break
# Update the current position and mark the segment tree
cur += _sum(prev + 1, N - sa[i], 1, 0, K - 1)
assign(0, prev + 1, N - sa[i], 1, 0, K - 1)