Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem G
Do Geese See God?

A palindrome is a sequence of characters which reads the same backward or forward. Famous ones include "dogeeseseegod" ("Do geese see God?"), "amoreroma" ("Amore, Roma.") and "risetovotesir" ("Rise to vote, sir.").

An ancient sutra has been handed down through generations at a temple on Tsukuba foothills. They say the sutra was a palindrome, but some of the characters have been dropped through transcription.

A famous scholar in the field of religious studies was asked to recover the original. After long repeated deliberations, he concluded that no information to recover the original has been lost, and that the original can be reconstructed as the shortest palindrome including all the characters of the current sutra in the same order. That is to say, the original sutra is obtained by adding some characters before, between, and/or behind the characters of the current.

Given a character sequence, your program should output one of the shortest palindromes containing the characters of the current sutra preserving their order. One of the shortest? Yes, more than one shortest palindromes may exist. Which of them to output is also specified as its rank among the candidates in the lexicographical order.

For example, if the current sutra is cdba and 7th is specified, your program should output cdabadc among the 8 candidates, abcdcba, abdcdba, acbdbca, acdbdca, cabdbac, cadbdac, cdabadc and cdbabdc.

Input

The input consists of a single test case. The test case is formatted as follows.

$S$

$k$

The first line contains a string $S$ composed of lowercase letters from 'a' to 'z'. The length of $S$ is greater than 0, and less than or equal to 2000. The second line contains an integer $k$ which represents the rank in the lexicographical order among the candidates of the original sutra. $1 \leq k \leq 10^{18}$.

Output

Output the $k$-th string in the lexicographical order among the candidates of the original sutra. If the number of the candidates is less than $k$, output NONE.

Though the first lines of the Sample Input/Output 7 are folded at the right margin, they are actually single lines.

Sample Input 1

crc
1

Sample Output 1

crc

Sample Input 2

icpc
1

Sample Output 2

icpci

Sample Input 3

hello
1

Sample Output 3

heolloeh

Sample Input 4

hoge
8

Sample Output 4

hogegoh

Sample Input 5

hoge
9

Sample Output 5

NONE

Sample Input 6

bbaaab
2

Sample Output 6

NONE

Sample Input 7

thdstodxtksrnfacdsohnlfuivqvqsozdstwa
szmkboehgcerwxawuojpfuvlxxdfkezprodne
ttawsyqazekcftgqbrrtkzngaxzlnphynkmsd
sdleqaxnhehwzgzwtldwaacfczqkfpvxnalnn
hfzbagzhqhstcymdeijlbkbbubdnptolrmemf
xlmmzhfpshykxvzbjmcnsusllpyqghzhdvljd
xrrebeef
11469362357953500

Sample Output 7

feeberrthdstodxtksrnfacdjsohnlfuivdhq
vqsozhgdqypllstwausnzcmjkboehgcerzvwx
akyhswuojpfhzumvmlxxdfkmezmprlotpndbu
bbkblnjiedttmawsyqazekcftgshqbrhrtkzn
gaxbzfhnnlanxvphyfnkqmzcsdfscaawdleqa
xtnhehwzgzwhehntxaqeldwaacsfdsczmqknf
yhpvxnalnnhfzbxagnzktrhrbqhsgtfckezaq
yswamttdeijnlbkbbubdnptolrpmzemkfdxxl
mvmuzhfpjouwshykaxwvzrecgheobkjmcznsu
awtsllpyqdghzosqvqhdviuflnhosjdcafnrs
ktxdotsdhtrrebeef

Solution in C++ (judge verdict: Accepted)

#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
using namespace std;
typedef long long ll;
const ll inf = 1e18 + 1;
const int maxn = 2011;
int DP[maxn][maxn];
ll num[maxn][maxn];
bool ok[maxn][maxn];
char S[maxn];
int n;

int GetDP(int l, int r){
    if (ok[l][r]) return DP[l][r];
    ok[l][r] = 1;
    if (l == r){
        DP[l][r] = 0;
        num[l][r] = 1;
        return 0;
    }
    if (l == r - 1 && S[l] == S[r]){
        DP[l][r] = 0;
        num[l][r] = 1;
        return 0;
    }
    if (S[l] == S[r]){
        DP[l][r] = GetDP(l+1, r-1);
        num[l][r] = num[l+1][r-1];
        return DP[l][r];
    }
    else{
        int ll = GetDP(l+1, r) + 1, rr = GetDP(l, r-1) + 1;
        DP[l][r] = min(ll, rr);
        if (ll < rr)
            num[l][r] = num[l+1][r];
        else if (rr < ll)
            num[l][r] = num[l][r-1];
        else
            num[l][r] = num[l+1][r] + num[l][r-1];

        num[l][r] = min(inf, num[l][r]);
        return DP[l][r];
    }
}
char ans[maxn*2];
int tot = 0;
void print1(){
    rep(i, 1, tot)
        printf("%c",ans[i]);
}
void print2(){
    for (int i = tot; i >= 1; i--)
        printf("%c",ans[i]);
    printf("\n");
}
void Getans(int l, int r, ll k){
    if (num[l][r] < k){
        printf("NONE\n");
        return;
    }
    if (l == r){
        print1();
        printf("%c",S[l]);
        print2();
        return;
    }
    if (S[l] == S[r] && l == r - 1){
        ans[++tot] = S[l];
        print1();
        print2();
        return;
    }
    if (S[l] == S[r]){
        ans[++tot] = S[l];
        Getans(l + 1, r - 1, k);
    }
    else{
        if (DP[l+1][r] < DP[l][r-1]){
            ans[++tot] = S[l];
            Getans(l+1, r, k);
        }
        else if (DP[l][r-1] < DP[l+1][r]){
            ans[++tot] = S[r];
            Getans(l, r-1, k);
        }
        else{
            if (S[l] < S[r]){
                if (num[l+1][r] >= k){
                    ans[++tot] = S[l];
                    Getans(l+1,r,k);
                }
                else{
                    k -= num[l+1][r];
                    ans[++tot] = S[r];
                    Getans(l,r-1,k);
                }
            }
            else{
                if (num[l][r-1] >= k){
                    ans[++tot] = S[r];
                    Getans(l,r-1,k);
                }
                else{
                    k -= num[l][r-1];
                    ans[++tot] = S[l];
                    Getans(l+1,r,k);
                }
            }
        }
    }
}
int main(){
    scanf("%s", S + 1);
    n = strlen(S + 1);
    ll k;
    cin>>k;
    GetDP(1, n);
    Getans(1, n, k);
    return 0;
}