Problem:
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
yswamttdeijnlbkbbubdnptolrpmzemkf
...(truncated)

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

#define LL long long

char s[4010];
char ans[4010];
int tot,len;
LL K;

class rec{
	public:
	int l;
	LL s;
	bool bo;
	rec operator +(const rec &X)const{
		rec C=*this;
		if (C.l>X.l)C.l=X.l,C.s=0,C.bo=0;
		if (C.l==X.l){
			C.s+=X.s;
			C.bo|=X.bo;
			if (C.s>1e18)C.s=0,C.bo=1;
		}
		return C;
	}
	rec operator +(const int &X)const{
		rec C=*this;
		C.l+=X;
		return C;
	}
}f[2010][2010];

int main() {
	
	scanf("%s",s);
	scanf("%lld",&K);
	len=strlen(s);
	for (int i=0;i<len;i++)
		f[i][i]=(rec){1,1,0};
	for (int l=len-1;l>=0;l--)
		for (int r=l+1;r<len;r++)
			if (s[l]==s[r]){
				if (l+1==r)f[l][r]=(rec){2,1,0};
				else
					f[l][r]=f[l+1][r-1]+2;
			}else{
				f[l][r]=f[l+1][r]+2;
				f[l][r]=f[l][r]+(f[l][r-1]+2);
			}
	tot=0;
	int l=0,r=len-1;
	for (;l<=r;){
		if (s[l]==s[r]){
			ans[++tot]=s[l];
			l++;r--;
			continue;
		}
		if (f[l][r].l!=f[l+1][r].l+2){
			ans[++tot]=s[r];
			r--;
			continue;
		}
		if (f[l][r].l!=f[l][r-1].l+2){
			ans[++tot]=s[l];
			l++;
			continue;
		}
		if (s[l]<s[r]){
			if (!f[l+1][r].bo&&f[l+1][r].s<K){
				K-=f[l+1][r].s;
				ans[++tot]=s[r];
				r--;
				continue;
			}else{
				ans[++tot]=s[l];
				l++;
				continue;
			}
		}
		if (s[r]<s[l]){
			if (!f[l][r-1].bo&&f[l][r-1].s<K){
				K-=f[l][r-1].s;
				ans[++tot]=s[l];
				l++;
				continue;
			}else{
				ans[++tot]=s[r];
				r--;
				continue;
			}
		}
	}
	if (K>1)printf("NONE\n");
	else{
		for (int i=f[0][len-1].l;i>tot;i--)
			ans[i]=ans[f[0][len-1].l-i+1];
		printf("%s\n",ans+1);
	}
	return 0;
	
}
accuracy: 1
time_ms: 10
memory_kb: 97124
final_rank: 17

code_snippet: // AOJ #1362
// Do Geese See God? 2025.2.6

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
const ll INF = 1000000000000000001LL;

string S;
int n;
 
vector<vector<int>> dp;
vector<vector<ll>> ways;
 
void compute_dp(){
    n = S.size();
    dp.assign(n, vector<int>(n, 0));
    ways.assign(n, vector<ll>(n, 0));
    
    for (int i = 0; i < n; i++){
        dp[i][i] = 0;
        ways[i][i] = 1;
    }
    for (int len = 2; len <= n; len++){
        for (int i = 0; i + len - 1 < n; i++){
            int j = i + len - 1;
            if(S[i] == S[j]){
                if(i+1 <= j-1){
                    dp[i][j] = dp[i+1][j-1];
                    ways[i][j] = ways[i+1][j-1];
                } else {
                    dp[i][j] = 0;
                    ways[i][j] = 1;
                }
            } else {
                int opt1 = dp[i+1][j];
                int opt2 = dp[i][j-1];
                if(opt1 < opt2){
                    dp[i][j] = opt1 + 1;
                    ways[i][j] = ways[i+1][j];
                } else if(opt1 > opt2){
                    dp[i][j] = opt2 + 1;
                    ways[i][j] = ways[i][j-1];
                } else {
                    dp[i][j] = opt1 + 1;
                    ll sum = ways[i+1][j] + ways[i][j-1];
                    if(sum >= INF) sum = INF;
                    ways[i][j] = sum;
                }
            }
        }
    }
}
 
string rec(int i, int j, ll k) {
    if(i > j) return "";
    if(i == j) {
        string ret;
        ret.push_back(S[i]);
        return ret;
    }
    if(S[i] == S[j]){
        ll cnt = (i+1 <= j-1 ? ways[i+1][j-1] : 1LL);
        string mid = rec(i+1, j-1, k);
        string ret;
        ret.push_back(S[i]);
        ret += mid;
        ret.push_back(S[j]);
        return ret;
    } else {
        ll ways1 = 0, ways2 = 0;
        if(dp[i+1][j] + 1 == dp[i][j]) ways1 = ways[i+1][j];
        if(dp[i][j-1] + 1 == dp[i][j]) ways2 = ways[i][j-1];
 
        int order[2];
        if(S[i] < S[j]) order[0] = 1, order[1] = 2;
        else            order[0] = 2, order[1] = 1;
 
        if(order[0] == 1) {
            if(k <= ways1) {
                string mid = rec(i+1, j, k);
                string ret;
                ret.push_back(S[i]);
                ret += mid;
                ret.push_back(S[i]);
                return ret;
            } else {
                k -= ways1;
                string mid = rec(i, j-1, k);
                string ret;
                ret.push_back(S[j]);
                ret += mid;
                ret.push_back(S[j]);
                return ret;
            }
        } else {
            if(k <= ways2) {
                string mid = rec(i, j-1, k);
                string ret;
                ret.push_back(S[j]);
                ret += mid;
                ret.push_back(S[j]);
                return ret;
            } else {
                k -= ways2;
                string mid = rec(i+1, j, k);
                string ret;
                ret.push_back(S[i]);
                ret += mid;
                ret.push_back(S[i]);
                return ret;
            }
        }
    }
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> S;
    ll k;
    cin >> k;
 
    compute_dp();
    if(k > ways[0][n-1]){
        cout << "NONE" << endl;
        return 0;
    }
    string ans = rec(0, n-1, k);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 50824
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmin(ll &a, ll b) { a = min(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    string s;
    cin >> s;
    int n = s.size();
    ll k; cin >> k;
    vector dplen(n + 1, vector(n + 1, INF));
    vector dpcnt(n + 1, vector(n + 1, 0LL));
    rep(i, n) {
        dplen[i][i + 1] = 1;
        dpcnt[i][i + 1] = 1;
    }
    rep(i, n + 1) {
        dplen[i][i] = 0;
        dpcnt[i][i] = 1;
    }
    for(int l = 2; l <= n; l ++) {
        for(int i = 0; i <= n; i ++) {
            int j = i + l;
            if(j > n) break;
            if(s[i] == s[j - 1]) {
                dplen[i][j] = dplen[i + 1][j - 1] + 2;
                dpcnt[i][j] += dpcnt[i + 1][j - 1];
            } else {
                if(dplen[i + 1][j] <= dplen[i][j - 1]) {
                    dplen[i][j] = dplen[i + 1][j] + 2;
                    dpcnt[i][j] += dpcnt[i + 1][j];
                }
                if(dplen[i + 1][j] >= dplen[i][j - 1]) {
                    dplen[i][j] = dplen[i][j - 1] + 2;
                    dpcnt[i][j] += dpcnt[i][j - 1];
                }
            }
            chmin(dpcnt[i][j], INF);
        }
    }
    if(dpcnt[0][n] < k) {
        cout << "NONE" << endl;
        return 0;
    }
    int le = 0, ri = n;
    string ans = "";
    while(ri - le > 0) {
        if(s[ri - 1] == s[le]) {
            ans += s[le];
            le ++;
            ri --;
        } else {
            if(dplen[le + 1][ri] == dplen[le][ri - 1]) {
                if(s[le] > s[ri - 1]) {
                    if(dpcnt[le][ri - 1] < k) {
                        ans += s[le];
                        k -= dpcnt[le][ri - 1];
                        le ++;
                    } else {
                        ans += s[ri - 1];
                        ri --;
                    }
                } else {
                    if(dpcnt[le + 1][ri] < k) {
                        ans += s[ri - 1];
                        k -= dpcnt[le + 1][ri];
                        ri --;
                    } else {
                        ans += s[le];
                        le ++;
                    }
                }
            } else if(dplen[le + 1][ri] < dplen[le][ri - 1]) {
                ans += s[le];
                le ++;
            } else {
                ans += s[ri - 1];
                ri --;
            }
        }
    }
    if(dplen[0][n] & 1) {
        auto t = ans;
        t.pop_back();
        reverse(all(t));
        ans += t;
    } else {
        auto t = ans;
        reverse(all(t));
        ans += t;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 65932
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9 + 10;
const ll INFL = 4e18;

int main() {
    string S;
    ll K;
    cin >> S >> K;
    int N = S.size();

    vector<vector<int>> dp(N + 1, vector<int>(N + 1, 0));
    for (int i = 0; i < N; i++) dp[i][i + 1] = 1;
    for (int len = 2; len <= N; len++) {
        for (int l = 0; l < N && l + len <= N; l++) {
            int r = l + len;
            if (S[l] == S[r - 1]) {
                dp[l][r] = dp[l + 1][r - 1] + 2;
            } else {
                dp[l][r] = min(dp[l][r - 1] + 2, dp[l + 1][r] + 2);
            }
        }
    }

    vector<vector<ll>> dp2(N + 1, vector<ll>(N + 1, 0));
    for (int i = 0; i < N; i++) dp2[i][i + 1] = 1;
    for (int len = 2; len <= N; len++) {
        for (int l = 0; l < N && l + len <= N; l++) {
            int r = l + len;
            if (S[l] == S[r - 1]) {
                if (l + 1 < r - 1) {
                    dp2[l][r] = min(INFL, dp2[l][r] + dp2[l + 1][r - 1]);
                } else {
                    dp2[l][r] = 1;
                }
            } else {
                if (dp[l][r] == dp[l][r - 1] + 2) dp2[l][r] = min(INFL, dp2[l][r] + dp2[l][r - 1]);
                if (dp[l][r] == dp[l + 1][r] + 2) dp2[l][r] = min(INFL, dp2[l][r] + dp2[l + 1][r]);
            }
        }
    }

    if (dp2[0][N] < K) return cout << "NONE" << endl, 0;

    auto rec = [&](auto&& rec, int l, int r, ll k) -> deque<char> {
        deque<char> ret;
        if (l == r - 1) return ret.push_back(S[l]), ret;
        if (l >= r) return ret;
        if (S[l] == S[r - 1]) {
            ret = rec(rec, l + 1, r - 1, k);
            ret.push_front(S[l]);
            ret.push_back(S[r - 1]);
        } else if (S[l] < S[r - 1]) {
            if (dp[l][r] != dp[l + 1][r] + 2 || dp2[l + 1][r] < k) {
                // S[r-1] ...S[l]S[r-1]
                ll nk = k;
                if (dp[l][r] == dp[l + 1][r] + 2) nk -= dp2[l + 1][r];
                ret = rec(rec, l, r - 1, nk);
                ret.push_front(S[r - 1]);
                ret.push_back(S[r - 1]);
            } else {
                // S[l] ...S[r-1]S[l]
                ret = rec(rec, l + 1, r, k);
                ret.push_front(S[l]);
                ret.push_back(S[l]);
            }
        } else {
            if (dp[l][r] != dp[l][r - 1] + 2 || dp2[l][r - 1] < k) {
                ll nk = k;
                if (dp[l][r] == dp[l][r - 1] + 2) nk -= dp2[l][r - 1];
                ret = rec(rec, l + 1, r, nk);
                ret.push_front(S[l]);
                ret.push_back(S[l]);
            } else {
                ret = rec(rec, l, r - 1, k);
                ret.push_front(S[r - 1]);
                ret.push_back(S[r - 1]);
            }
        }
        return ret;
    };

    auto res = rec(rec, 0, N, K);
    string ans(res.begin(), res.end());
    cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 52448
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

ll LINF = 1LL<<61;
ll MAX = 1e18;

int main(){
	string S; cin >> S;
	ll K; cin >> K;
	ll N = S.size();
	vector<vector<ll>> min_len(N+1 , vector<ll>(N+1,LINF));
	for(int i = 0; i < N; i++)min_len[i][i] = 0;
	for(int l = 1; l <= N; l++){
		for(int i = 0; i < N; i++){
			int j = i + l;
			if(j > N)continue;
			if(l == 1)min_len[i][j] = 1;
			else if(S[i] == S[j-1])min_len[i][j] = min_len[i+1][j-1] + 2;
			else{
				min_len[i][j] = min(min_len[i+1][j] , min_len[i][j-1]) + 2;
			}
		}
	}
	vector<vector<ll>> min_len_cnt(N+1 , vector<ll>(N+1,0));
	for(int i = 0; i < N; i++)min_len_cnt[i][i] = 1;
	for(int l = 1; l <= N; l++){
		for(int i = 0; i < N; i++){
			int j = i + l;
			if(j > N)continue;
			if(l == 1)min_len_cnt[i][j] = 1;
			else if(S[i] == S[j-1])min_len_cnt[i][j] = min_len_cnt[i+1][j-1];
			else{
				if(min_len[i][j] == min_len[i+1][j] + 2)min_len_cnt[i][j] += min_len_cnt[i+1][j];
				if(min_len[i][j] == min_len[i][j-1] + 2)min_len_cnt[i][j] += min_len_cnt[i][j-1];
			}
			min_len_cnt[i][j] = min(min_len_cnt[i][j] , MAX);
		}
	}
	if(min_len_cnt[0][N] < K){
		cout << "NONE" << endl;
		return 0;
	}
	auto f = [&](auto f, int l, int r, ll k) -> string{
		if(l == r)return "";
		if(l+1 == r){
			string ret;
			ret += S[l];
			return ret;
		}
		if(S[l] == S[r-1]){
			return string(S[l] + f(f, l+1 , r-1, k) + S[l]);
		}
		if(S[l] < S[r-1]){
			if(min_len[l+1][r] + 2 == min_len[l][r]){
				if(k < min_len_cnt[l+1][r]){
					return string(S[l] + f(f, l+1, r, k) + S[l]); 
				}
				else{
					return string(S[r-1] + f(f, l, r-1, k - min_len_cnt[l+1][r]) + S[r-1]);
				}
			}
			else{
				return string(S[r-1] + f(f, l, r-1, k) + S[r-1]);
			}
		}
		else{
			if(min_len[l][r-1] + 2 == min_len[l][r]){
				if(k < min_len_cnt[l][r-1]){
					return string(S[r-1] + f(f, l, r-1, k) + S[r-1]);
				}
				else{
					return string(S[l] + f(f, l+1, r, k - min_len_cnt[l][r-1]) + S[l]);
				}
			}
			else{
				return string(S[l] + f(f, l+1, r, k) + S[l]);
			}
		}
		return "";
	};
	--K;
	cout << f(f, 0, N, K) << endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 66212
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rrep(i, a, b) for (ll i = (ll)(b)-1; i >= (ll)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    string S;
    ll X;
    cin >> S >> X;
    int N = S.size();
    vector Len(N+1, vector<ll>(N+1,INF)), Count(N+1, vector<ll>(N+1,0));
    rep(i,0,N+1) Len[i][i] = 0, Count[i][i] = 1;
    rep(i,0,N) Len[i][i+1] = 1, Count[i][i+1] = 1;
    rep(k,2,N+1) {
        rep(i,0,N+1) {
            int j = i+k;
            if (j > N) break;
            if (S[i] == S[j-1]) {
                Len[i][j] = Len[i+1][j-1] + 2;
                Count[i][j] = Count[i+1][j-1];
            }
            else {
                if (Len[i][j-1] <= Len[i+1][j]) {
                    Len[i][j] = Len[i][j-1] + 2;
                    Count[i][j] += Count[i][j-1];
                }
                if (Len[i][j-1] >= Len[i+1][j]) {
                    Len[i][j] = Len[i+1][j] + 2;
                    Count[i][j] += Count[i+1][j];
                }
            }
            chmin(Count[i][j], INF);
        }
    }
    if (Count[0][N] < X) {
        cout << "NONE" << endl;
        return 0;
    }
    string ANS = "";
    int L = 0, R = N;
    while(R-L > 0) {
        if (S[L] == S[R-1]) {
            ANS += S[L];
            L++, R--;
        }
        else if (S[L] < S[R-1]) {
            ll C = (Len[L+1][R] <= Len[L][R-1] ? Count[L+1][R] : 0LL);
            if (X <= C) {
                ANS += S[L];
                L++;
            }
            else {
                ANS += S[R-1];
                X -= C;
                R--;
            }
        }
        else {
            ll C = (Len[L][R-1] <= Len[L+1][R] ? Count[L][R-1] : 0LL);
            if (X <= C) {
                ANS += S[R-1];
                R--;
            }
            else {
                ANS += S[L];
                X -= C;
                L++;
            }
        }
    }
    if (Len[0][N] % 2 == 0) {
        cout << ANS;
        reverse(ALL(ANS));
        cout << ANS << endl;
    }
    else {
        cout << ANS;
        ANS.pop_back();
        reverse(ALL(ANS));
        cout << ANS << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 65944
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template <typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }
TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }
TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    string s;
    ll k;
    cin >> s >> k;
    int n = sz(s);
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1));
    queue<pii> que;
    auto upd = [&](int i, int j, int d) {
        if (dp[i][j] == -1)
            dp[i][j] = d, que.emplace(i, j);
    };
    rep(i, n + 1) upd(i, i, 0);
    rep(i, n) upd(i, i + 1, 1);
    while (sz(que)) {
        auto [i, j] = que.front();
        que.pop();
        if (i > 0)
            upd(i - 1, j, dp[i][j] + 2);
        if (j < n)
            upd(i, j + 1, dp[i][j] + 2);
        if (i > 0 && j < n && s[i - 1] == s[j])
            upd(i - 1, j + 1, dp[i][j] + 2);
    }
    vector<vector<bool>> vis(n + 1, vector<bool>(n + 1, false));
    vector<vector<ll>> cnt(n + 1, vector<ll>(n + 1, 0));
    auto dfs = [&](int l, int r, auto &&dfs) ->ll {
        if (!vis[l][r]) {
            vis[l][r] = true;
            if (l + 1 >= r)
                cnt[l][r] = 1;
            else if (s[l] == s[r - 1])
                cnt[l][r] = dfs(l + 1, r - 1, dfs);
            else {
                if (dp[l][r] == dp[l + 1][r] + 2)
                    cnt[l][r] += dfs(l + 1, r, dfs);
                if (dp[l][r] == dp[l][r - 1] + 2)
                    cnt[l][r] += dfs(l, r - 1, dfs);
                chmin(cnt[l][r], k + 1);
            }
        }
        return cnt[l][r];
    };
    dfs(0, n, dfs);
    int l = 0, r = n;
    string sl, sr;
    k--;
    if (cnt[0][n] <= k) {
        cout << "NONE" << endl;
        return 0;
    }
    while (1) {
        if (l + 1 >= r) {
            if (l + 1 == r)
                sl += s[l];
            break;
        }
        if (s[l] == s[r - 1])
            sl += s[l], sr += s[l], l++, r--;
        else {
            char c1 = s[l], c2 = s[r - 1];
            ll v1 = (dp[l][r] == dp[l + 1][r] + 2 ? cnt[l + 1][r] : 0), v2 = (dp[l][r] == dp[l][r - 1] + 2 ? cnt[l][r - 1] : 0);
            bool fl = (s[l] < s[r - 1]);
            if (!fl)
                swap(c1, c2), swap(v1, v2);
            if (v1 > k) {
                sl += c1, sr += c1;
                if (fl)
                    l++;
                else
                    r--;
            }
            else {
                k -= v1;
                sl += c2, sr += c2;
                if (fl)
                    r--;
                else
                    l++;
            }
        }
    }
    reverse(all(sr));
    cout << sl + sr << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 50872
final_rank: 7

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll=long long;

void solve(){
    string s;cin>>s;
    ll k;cin>>k;
    int n=s.size();
    const ll INF=1001002003004005006;
    using P=pair<ll,ll>;
    vector dp(n+1,vector<P>(n+1,{INF,INF}));
    for (int i = 0; i <=n; ++i) {
        dp[i][i]={0,1};
        if(i)dp[i][i-1]={0,1};
    }
    auto upd=[&](P &a, P b){
        if(a.first>b.first){
            a=b;
        }
        else if(a.first==b.first){
//            a.second+=b.second;
            if(a.second>INF-b.second){
                a.second=INF;
            }
            else{
                a.second+=b.second;
            }
//            a.second=min(a.second,INF);
        }
    };
    auto cand=[&](int l,int r){
        vector<char>v;
        if(l>=0)v.emplace_back(s[l]);
        if(r<n and s[r]!=s[l])v.emplace_back(s[r]);
        std::sort(v.begin(), v.end());
        return v;
    };
    for(int r=0;r<=n;r++){
        for(int l=n;l>=0;l--){
            if(l>=r)continue;
            for(auto c:cand(l,r-1)){
                auto l2=l,r2=r;
                if(s[l2]==c)l2++;
                if(s[r2-1]==c)r2--;
                if(dp[l2][r2].first==INF)continue;
                ll cost=(l==r-1)?1:2;
//                cerr<<"l: "<<l<<" r: "<<r<<" l2: "<<l2<<" r2: "<<r2<<" \n";
                upd(dp[l][r],{dp[l2][r2].first+cost,dp[l2][r2].second});
            }
        }
    }
//    cerr<<dp[0][n].first<<"\n";
//    cerr<<dp[0][n].second<<"\n";
    if(dp[0][n].second<k){
        cout<<"NONE\n";
        return;
    }
    int l=0,r=n;
    string ans="";
    k--;
    while(l<r){
//        cerr<<"l: "<<l<<" r: "<<r<<" k: "<<k<<"\n";
        for(auto c:cand(l,r-1)){
            auto l2=l,r2=r;
            if(s[l2]==c)l2++;
            if(s[r2-1]==c)r2--;
            if(dp[l2][r2].first==INF)continue;
            ll cost=(l==r-1)?1:2;
            if(dp[l2][r2].first+cost==dp[l][r].first){
                if(dp[l2][r2].second<=k){
                    k-=dp[l2][r2].second;
                }
                else{
                    ans+=c;
                    l=l2,r=r2;
                    break;
                }
            }
        }
    }
    auto copy=ans;
    if(l==r){
        std::reverse(copy.begin(), copy.end());
        ans+=copy;
    }
    else{
        copy.pop_back();
        std::reverse(copy.begin(), copy.end());
        ans+=copy;
    }
    cout<<ans<<"\n";
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t=1;
//    cin>>t;
    while(t--){
        solve();
    }
}
accuracy: 1
time_ms: 110
memory_kb: 65904
final_rank: 14

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll=long long;

void solve(){
    string s;cin>>s;
    ll k;cin>>k;
    int n=s.size();
    const ll INF=1001002003004005006;
    using P=pair<ll,ll>;
    vector dp(n+1,vector<P>(n+1,{INF,INF}));
    string ans="";
    string ans2="";
    auto upd=[&](P &a,P b){
        if(a.first>b.first){
            a=b;
        }
        else if(a.first==b.first){
            if(a.second>INF-b.second){
                a.second=INF;
            }
            else{
                a.second+=b.second;
            }
        }
    };
    auto f=[&](auto self,int l,int r)->P{
        if(dp[l][r].first!=INF)return dp[l][r];
        if(l>=r){
            return dp[l][r]={0,1};
        }
        P ret={INF,INF};
        for(char c='a';c<='z';c++){
            if(s[l]!=c and s[r-1]!=c)continue;
            auto l2=l,r2=r;
            if(s[l]==c)l2++;
            if(s[r-1]==c)r2--;
            ll cost=(l==r-1)?1:2;
            auto tmp=self(self,l2,r2);
            if(tmp.first==INF)continue;
//            cerr<<"l: "<<l<<" r: "<<r<<" "<<"l2: "<<l2<<" r2: "<<r2<<" c: "<<c<<"\n";
            upd(ret,{tmp.first+cost,tmp.second});
        }
        return dp[l][r]=ret;
    };
    f(f,0,n);
    if(dp[0][n].second<k){
        cout<<"NONE\n";
        return;
    }
    k--;
    int l=0,r=n;
    while(l<r){
        for(char c='a';c<='z';c++){
            if(s[l]!=c and s[r-1]!=c)continue;
            auto l2=l,r2=r;
            if(s[l]==c)l2++;
            if(s[r-1]==c)r2--;
            ll cost=(l==r-1)?1:2;
            if(dp[l2][r2].first+cost==dp[l][r].first){
                if(k>=dp[l2][r2].second){
                    k-=dp[l2][r2].second;
                }
                else{
                    ans+=c;
                    if(l2<=r2)ans2+=c;
                    l=l2,r=r2;
                    break;
                }
            }
        }
    }
    std::reverse(ans2.begin(), ans2.end());
    ans+=ans2;
    cout<<ans<<"\n";
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t=1;
//    cin>>t;
    while(t--){
        solve();
    }
}
accuracy: 1
time_ms: 110
memory_kb: 66196
final_rank: 15

code_snippet: #include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

struct info {
	int len;
	long long ways;
};

int main() {
	const int INF = 1012345678;
	string S; long long K;
	cin >> S >> K;
	int N = S.size();
	vector<vector<info> > dp(N + 1);
	auto merge = [&](const info& f1, const info& f2) -> info {
		if (f1.len != f2.len) {
			return (f1.len < f2.len ? f1 : f2);
		}
		return info{f1.len, min(f1.ways + f2.ways, K + 1)};
	};
	dp[0] = { info{0, 1} };
	for (int r = 1; r <= N; r++) {
		dp[r].resize(r + 1, info{INF, 0});
		dp[r][r] = info{0, 1};
		dp[r][r - 1] = info{1, 1};
		for (int l = r - 2; l >= 0; l--) {
			if (S[l] == S[r - 1]) {
				dp[r][l] = dp[r - 1][l + 1];
				dp[r][l].len += 2;
			}
			else {
				dp[r][l] = merge(dp[r - 1][l], dp[r][l + 1]);
				dp[r][l].len += 2;
			}
		}
	}
	if (dp[N][0].ways < K) {
		cout << "NONE" << endl;
	}
	else {
		string subanswer;
		long long rem = K;
		int cl = 0, cr = N;
		while (cr - cl >= 2) {
			if (S[cl] == S[cr - 1]) {
				subanswer += S[cl];
				cl += 1;
				cr -= 1;
			}
			else if (dp[cr - 1][cl].len < dp[cr][cl + 1].len) {
				subanswer += S[cr - 1];
				cr -= 1;
			}
			else if (dp[cr - 1][cl].len > dp[cr][cl + 1].len) {
				subanswer += S[cl];
				cl += 1;
			}
			else if (S[cl] > S[cr - 1]) {
				if (dp[cr - 1][cl].ways < K) {
					K -= dp[cr - 1][cl].ways;
					subanswer += S[cl];
					cl += 1;
				}
				else {
					subanswer += S[cr - 1];
					cr -= 1;
				}
			}
			else {
				if (dp[cr][cl + 1].ways < K) {
					K -= dp[cr][cl + 1].ways;
					subanswer += S[cr - 1];
					cr -= 1;
				}
				else {
					subanswer += S[cl];
					cl += 1;
				}
			}
		}
		string revanswer = subanswer;
		reverse(revanswer.begin(), revanswer.end());
		string answer;
		if (cr - cl == 1) {
			answer = subanswer + S[cl] + revanswer;
		}
		else {
			answer = subanswer + revanswer;
		}
		cout << answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 34820
final_rank: 1

code_snippet: /*
    Author: Cupids_Bow
    Time: 2022-08-25 00:04:13
*/
#include<bits/stdc++.h>
using namespace std;

using ll=long long;

constexpr int N=2e3+5;

int n,len;
ll k;
char s[N];
int dp[N][N];
ll g[N][N];
vector<char> ans;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin>>s+1;
    n=strlen(s+1);
    cin>>k;
    
    memset(dp,0x3f,sizeof(dp));
    for(int i=1;i<=n;i++) dp[i][i]=1,g[i][i]=1;
    for(int i=2;i<=n;i++) dp[i][i-1]=0,g[i][i-1]=1;
    for(int l=2;l<=n;l++)
        for(int i=1;i+l-1<=n;i++){
            int j=i+l-1;
            if(s[i]==s[j]){
                dp[i][j]=dp[i+1][j-1]+2;
                g[i][j]+=g[i+1][j-1];
                if(g[i][j]>1e18) g[i][j]=1e18+1;
            }
            else{
                dp[i][j]=min(dp[i+1][j],dp[i][j-1])+2;
                if(dp[i+1][j]==dp[i][j-1]){
                    g[i][j]+=g[i+1][j];
                    if(g[i][j]>1e18) g[i][j]=1e18+1;
                    g[i][j]+=g[i][j-1];
                    if(g[i][j]>1e18) g[i][j]=1e18+1;
                }
                else if(dp[i+1][j]<dp[i][j-1]){
                    g[i][j]+=g[i+1][j];
                    if(g[i][j]>1e18) g[i][j]=1e18+1;
                }
                else if(dp[i+1][j]>dp[i][j-1]){
                    g[i][j]+=g[i][j-1];
                    if(g[i][j]>1e18) g[i][j]=1e18+1;
                }
            }
        }
    len=dp[1][n];

    if(g[1][n]<k){
        cout<<"NONE\n";
        return true&&false;
    }

    function<void(int,int,ll)> dfs=[&](int l,int r,ll k){
        if(l>r) return;
        if(l==r){
            ans.push_back(s[l]+k-1);
            return;
        }
        if(s[l]==s[r]){
            ans.push_back(s[l]);
            dfs(l+1,r-1,k);
        }
        else{
            if(dp[l+1][r]==dp[l][r-1]){
                if(s[l]<s[r]){
                    if(k<=g[l+1][r]){
                        ans.push_back(s[l]);
                        dfs(l+1,r,k);
                    }
                    else{
                        ans.push_back(s[r]);
                        dfs(l,r-1,k-g[l+1][r]);
                    }
                }
                else if(s[l]>s[r]){
                    if(k<=g[l][r-1]){
                        ans.push_back(s[r]);
                        dfs(l,r-1,k);
                    }
                    else{
                        ans.push_back(s[l]);
                        dfs(l+1,r,k-g[l][r-1]);
                    }
                }
            }
            else if(dp[l+1][r]<dp[l][r-1]){
                ans.push_back(s[l]);
                dfs(l+1,r,k);
            }
            else if(dp[l+1][r]>dp[l][r-1]){
                ans.push_back(s[r]);
                dfs(l,r-1,k);
            }
        }
    };

    dfs(1,n,k);
    for(auto c:ans) cout<<c;
    if(len&1) ans.pop_back();
    reverse(ans.begin(),ans.end());
    for(auto c:ans) cout<<c;
    cout<<"\n";

    return true&&false;
}
/*
thdstodxtksrnfacdsohnlfuivqvqsozdstwaszmkboehgcerwxawuojpfuvlxxdfkezprodnettawsyqazekcftgqbrrtkzngaxzlnphynkmsdsdleqaxnhehwzgzwtldwaacfczqkfpvxnalnnhfzbagzhqhstcymdeijlbkbbubdnptolrmemfxlmmzhfpshykxvzbjmcnsusllpyqghzhdvljdxrrebeef
11469362357953500

*/
accuracy: 1
time_ms: 10
memory_kb: 50860
final_rank: 2

code_snippet: #include <bits/stdc++.h>

#ifdef _MSC_VER
#  include <intrin.h>
#else
#  include <x86intrin.h>
#endif

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<unsigned int> { using type = unsigned long long; };
template <>
struct safely_multipliable<unsigned long int> { using type = __uint128_t; };
template <>
struct safely_multipliable<unsigned long long> { using type = __uint128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

template <typename T, typename = void>
struct rec_value_type {
    using type = T;
};
template <typename T>
struct rec_value_type<T, std::void_t<typename T::value_type>> {
    using type = typename rec_value_type<typename T::value_type>::type;
};
template <typename T>
using rec_value_type_t = typename rec_value_type<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) std::begin(iterable), std::end(iterable)
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

#ifdef LOCAL
#  define debug(...) debug_internal(#__VA_ARGS__, __VA_ARGS__)

template <class T, class... Args>
void debug_internal(const char* s, T&& first, Args&&... args) {
    constexpr const char* prefix = "[\033[32mDEBUG\033[m] ";
    constexpr const char* open_brakets = sizeof...(args) == 0 ? "" : "(";
    constexpr const char* close_brakets = sizeof...(args) == 0 ? "" : ")";
    std::cerr << prefix << open_brakets << s << close_brakets << ": " << open_brakets << std::forward<T>(first);
    ((std::cerr << ", " << std::forward<Args>(args)), ...);
    std::cerr << close_brakets << "\n";
}

#else
#  define debug(...) void(0)
#endif

// ! I/O utilities

// __int128_t
std::ostream& operator<<(std::ostream& dest, __int128_t value) {
    std::ostream::sentry s(dest);
    if (s) {
        __uint128_t tmp = value < 0 ? -value : value;
        char buffer[128];
        char* d = std::end(buffer);
        do {
            --d;
            *d = "0123456789"[tmp % 10];
            tmp /= 10;
        } while (tmp != 0);
        if (value < 0) {
            --d;
            *d = '-';
        }
        int len = std::end(buffer) - d;
        if (dest.rdbuf()->sputn(d, len) != len) {
            dest.setstate(std::ios_base::badbit);
        }
    }
    return dest;
}
// __uint128_t
std::ostream& operator<<(std::ostream& dest, __uint128_t value) {
    std::ostream::sentry s(dest);
    if (s) {
        char buffer[128];
        char* d = std::end(buffer);
        do {
            --d;
            *d = "0123456789"[value % 10];
            value /= 10;
        } while (value != 0);
        int len = std::end(buffer) - d;
        if (dest.rdbuf()->sputn(d, len) != len) {
            dest.setstate(std::ios_base::badbit);
        }
    }
    return dest;
}

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
// array
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& out, const std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head& head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

__int128_t parse_i128(std::string& s) {
    __int128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    if (s[0] == '-') ret = -ret;
    return ret;
}
__uint128_t parse_u128(std::string& s) {
    __uint128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    return ret;
}
// __int128_t
std::istream& operator>>(std::istream& in, __int128_t& v) {
    std::string s;
    in >> s;
    v = parse_i128(s);
    return in;
}
// __uint128_t
std::istream& operator>>(std::istream& in, __uint128_t& v) {
    std::string s;
    in >> s;
    v = parse_u128(s);
    return in;
}
// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U>& a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
// array
template <typename T, size_t N>
std::istream& operator>>(std::istream& in, std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    (std::cin >> ... >> args);
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u64(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> -1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x) { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable& iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}
template <typename T>
auto generate_range_vector(T l, T r) {
    return generate_vector(r - l, [l](int i) { return l + i; });
}
template <typename T>
auto generate_range_vector(T n) {
    return generate_range_vector(0, n);
}

template <typename T>
void sort_unique_erase(std::vector<T>& a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

template <typename InputIterator, typename BiConsumer>
auto foreach_adjacent_values(InputIterator first, InputIterator last, BiConsumer f) -> decltype(f(*first++, *last), void()) {
    if (first != last) for (auto itr = first, itl = itr++; itr != last; itl = itr++) f(*itl, *itr);
}
template <typename Container, typename BiConsumer>
auto foreach_adjacent_values(Container c, BiConsumer f) -> decltype(c.begin(), c.end(), void()) {
    foreach_adjacent_values(c.begin(), c.end(), f);
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T& x, const T& y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T& x, const T& y) {
    if (y <= x) return false;
    x = y;
    return true;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::string bin(T val, int bit_num = -1) {
    std::string res;
    if (bit_num >= 0) {
        for (int bit = bit_num; bit-- > 0;) res += '0' + ((val >> bit) & 1);
    } else {
        for (; val; val >>= 1) res += '0' + (val & 1);
        std::reverse(res.begin(), res.end());
    }
    return res;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_low_to_high(T val, T base = 10) {
    std::vector<T> res;
    for (; val; val /= base) res.push_back(val % base);
    if (res.empty()) res.push_back(T{ 0 });
    return res;
}
template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_high_to_low(T val, T base = 10) {
    auto res = digits_low_to_high(val, base);
    std::reverse(res.begin(), res.end());
    return res;
}

template <typename T>
std::string join(const std::vector<T>& v, const std::string& sep, const std::string& end) {
    std::ostringstream ss;
    for (auto it = v.begin(); it != v.end();) {
        ss << *it;
        if (++it != v.end()) ss << sep;
    }
    ss << end;
    return ss.str();
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_ {};

// ! code from here

constexpr int inf_cost = numeric_limits<int>::max() / 2;

constexpr long long inf = numeric_limits<long long>::max() / 2;

int main() {
    input(string, s);
    input(long long, k);
    const int n = s.size();

    vector dp_len(n + 1, vector<int>(n + 1, inf_cost));
    rep(i, n + 1) dp_len[i][i] = 0;
    rep(i, n) dp_len[i][i + 1] = 0;

    rep(r, n + 1) rrep(l, r - 1) {
        if (s[l] == s[r - 1]) {
            chmin(dp_len[l][r], dp_len[l + 1][r - 1]);
        } else {
            chmin(dp_len[l][r], dp_len[l + 1][r] + 1);
            chmin(dp_len[l][r], dp_len[l][r - 1] + 1);
        }
    }

    const int min_cost = dp_len[0][n];
    debug(min_cost);

    vector dp_cnt(n + 1, vector<long long>(n + 1, -1));

    auto dfs_cnt = [&](auto dfs_cnt, int l, int r) -> long long {
        if (r - l <= 1) {
            return dp_cnt[l][r] = 1;
        }
        if (dp_cnt[l][r] >= 0) return dp_cnt[l][r];
        if (s[l] == s[r - 1]) {
            return dp_cnt[l][r] = dfs_cnt(dfs_cnt, l + 1, r - 1);
        } else {
            dp_cnt[l][r] = 0;
            bool ok_l = dp_len[l + 1][r] + 1 == dp_len[l][r];
            bool ok_r = dp_len[l][r - 1] + 1 == dp_len[l][r];
            if (ok_l and ok_r) {
                return dp_cnt[l][r] = min(inf, dfs_cnt(dfs_cnt, l + 1, r) + dfs_cnt(dfs_cnt, l, r - 1));
            } else if (ok_l) {
                return dp_cnt[l][r] = dfs_cnt(dfs_cnt, l + 1, r);
            } else if (ok_r) {
                return dp_cnt[l][r] = dfs_cnt(dfs_cnt, l, r - 1);
            } else assert(false);
        }
    };
    dfs_cnt(dfs_cnt, 0, n);

    --k;
    string ans;
    auto dfs = [&](auto dfs, int l, int r) -> void {
        if (r - l <= 0) return;
        if (s[l] == s[r - 1]) {
            ans += s[l];
            dfs(dfs, l + 1, r - 1);
        } else {
            dp_cnt[l][r] = 0;
            bool ok_l = dp_len[l + 1][r] + 1 == dp_len[l][r];
            bool ok_r = dp_len[l][r - 1] + 1 == dp_len[l][r];
            if (ok_l and ok_r) {
                if (s[l] < s[r - 1]) {
                    if (dp_cnt[l + 1][r] <= k) {
                        k -= dp_cnt[l + 1][r];
                        ans += s[r - 1];
                        dfs(dfs, l, r - 1);
                    } else {
                        ans += s[l];
                        dfs(dfs, l + 1, r);
                    }
                } else {
                    if (dp_cnt[l][r - 1] <= k) {
                        k -= dp_cnt[l][r - 1];
                        ans += s[l];
                        dfs(dfs, l + 1, r);
                    } else {
                        ans += s[r - 1];
                        dfs(dfs, l, r - 1);
                    }
                }
            } else if (ok_l) {
                ans += s[l];
                dfs(dfs, l + 1, r);
            } else if (ok_r) {
                ans += s[r - 1];
                dfs(dfs, l, r - 1);
            } else assert(false);
        }
    };
    dfs(dfs, 0, n);

    if (k == 0) {
        string ans_rev = ans;
        reverse(all(ans_rev));
        if ((n + min_cost) & 1) {
            ans.pop_back();
        }
        print(ans + ans_rev);
    } else {
        print("NONE");
    }

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 50344
final_rank: 3

code_snippet: #line 1 "a.cpp"
/*	author:  Kite_kuma
	created: 2022.06.15 14:49:09 */

#line 2 "SPJ-Library/template/kuma.hpp"

#line 2 "SPJ-Library/template/basic_func.hpp"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	assert(n >= 0LL);
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 1LL) {
		if(n & 1LL) res *= a;
		a *= a;
		n >>= 1;
	}
	return res * a;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#line 7 "SPJ-Library/template/io.hpp"

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
		if(it != v.begin()) std::cerr << ' ';
		os << *it;
	}
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;
#line 7 "SPJ-Library/template/kuma.hpp"

using namespace std;
#line 5 "a.cpp"

int main() {
	string s;
	cin >> s;
	const ll large = INF + 10;
	const int n = int(s.size());
	vector<vector<ll>> ways(n + 1, vll(n + 1, 1));	// count_ways
	vector<vector<int>> minlength(n + 1, vi(n + 1, inf));
	rep(l, n + 1) {
		minlength[l][l] = 0;
		if(l < n) minlength[l][l + 1] = 1;
	}
	for(int len = 2; len <= n; len++) {
		for(int left = 0; left < n; left++) {
			const int right = left + len;
			if(right > n) break;
			ll &res = ways[left][right];
			int &ml = minlength[left][right];
			const char lch = s[left];
			const char rch = s[right - 1];
			if(lch == rch) {
				res = ways[left + 1][right - 1];
				ml = minlength[left + 1][right - 1] + 2;
				continue;
			}
			const int len_erase_left = minlength[left + 1][right];
			const int len_erase_right = minlength[left][right - 1];
			const ll lerase_way = ways[left + 1][right];
			const ll rerase_way = ways[left][right - 1];
			ml = min(len_erase_left, len_erase_right);
			res = 0;
			if(ml == len_erase_left) res += lerase_way;
			if(ml == len_erase_right) res += rerase_way;
			ml += 2;
			chmin(res, large);
		}
	}

	string fromfront, fromback;
	auto add_char = [&](char c) {
		fromfront += c;
		fromback += c;
		return;
	};
	auto dfs = [&](auto dfs, int left, int right, ll rank) -> void {
		const int len = right - left;
		if(len < 2) {
			if(rank > 0) {
				assert(false);
				fromfront = "-1";
				fromback = "";
				return;
			}
			fromfront += s.substr(left, len);
			return;
		}
		const char lch = s[left];
		const char rch = s[right - 1];
		if(lch == rch) {
			add_char(lch);
			dfs(dfs, left + 1, right - 1, rank);
			return;
		}
		ll l_ways = ways[left + 1][right];
		ll r_ways = ways[left][right - 1];
		const int l_len = minlength[left + 1][right];
		const int r_len = minlength[left][right - 1];
		if(l_len > r_len)
			l_ways = 0;
		else if(l_len < r_len)
			r_ways = 0;

		if(lch < rch) {
			if(rank < l_ways) {
				add_char(lch);
				dfs(dfs, left + 1, right, rank);
				return;
			} else {
				add_char(rch);
				dfs(dfs, left, right - 1, rank - l_ways);
			}
		} else {  // rch < lch
			if(rank < r_ways) {
				add_char(rch);
				dfs(dfs, left, right - 1, rank);
				return;
			} else {
				add_char(lch);
				dfs(dfs, left + 1, right, rank - r_ways);
			}
		}
		return;
	};

	debug(s);
	debug(ways);
	debug(minlength);
	ll rank;
	cin >> rank;
	--rank;
	// debug(s);
	if(rank >= ways.front().back()) drop("NONE");
	dfs(dfs, 0, n, rank);
	reverse(all(fromback));
	foa(c, fromback) fromfront.push_back(c);
	drop(fromfront);

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 50864
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18 + 10;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

ll add(ll a,ll b){
    if((double)a+b>=(double)INFLL*2)return INFLL;
    return a + b;
}

string func(){
    string str = in<string>();
    int n = str.size();
    ll k = in();
    vvector<int> shortest_dp(n,vector<int>(n,-1));
    method(shortest,int,int l,int r){
        if(l==r)return 1;
        if(l>r)return 0;
        int &it = shortest_dp[l][r];
        if(it >= 0)return it;
        it = INF;
        chmin(it,shortest(l+1,r)+2);
        chmin(it,shortest(l,r-1)+2);
        if(str[l]==str[r])chmin(it,shortest(l+1,r-1)+2);
        return it;
    };
    vvector<ll> dp(n,vector<ll>(n,-1));
    method(rec,ll,int l,int r){
        if(l>=r)return 1;
        ll &it = dp[l][r];
        if(it >= 0)return it;
        it = 0;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            it = add(it,rec(nl,nr));
        }
        return it;
    };
    string left = "";
    int l = 0;
    int r = n-1;
    while(l < r){
        bool flag = false;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            if(rec(nl,nr) < k){
                k -= rec(nl,nr);
            }else{
                left += c;
                l = nl;
                r = nr;
                flag = true;
                break;
            }
        }
        if(not flag)return "NONE";
    }
    if(k!=1)return "NONE";
    string res = "";
    if(l==r){
        res = left + str[l] + reversed(left);
    }else{
        res = left + reversed(left);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 50340
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18 + 10;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

ll add(ll a,ll b){
    if((double)a+b>=(double)INFLL*2)return INFLL;
    return a + b;
}

string func(){
    string str = in<string>();
    int n = str.size();
    ll k = in();
    vvector<int> shortest_dp(n,vector<int>(n,-1));
    method(shortest,int,int l,int r){
        if(l==r)return 1;
        if(l>r)return 0;
        int &it = shortest_dp[l][r];
        if(it >= 0)return it;
        it = INF;
        chmin(it,shortest(l+1,r)+2);
        chmin(it,shortest(l,r-1)+2);
        if(str[l]==str[r])chmin(it,shortest(l+1,r-1)+2);
        return it;
    };
    vvector<ll> dp(n,vector<ll>(n,-1));
    method(rec,ll,int l,int r){
        if(l>=r)return 1;
        ll &it = dp[l][r];
        if(it >= 0)return it;
        it = 0;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            it = add(it,rec(nl,nr));
        }
        return it;
    };
    string left = "";
    int l = 0;
    int r = n-1;
    while(l < r){
        bool flag = false;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            if(rec(nl,nr) < k){
                k -= rec(nl,nr);
            }else{
                left += c;
                l = nl;
                r = nr;
                flag = true;
                break;
            }
        }
        if(not flag)return "NONE";
    }
    string res = "";
    if(l==r){
        res = left + str[l] + reversed(left);
    }else{
        res = left + reversed(left);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 0.3090909090909091
time_ms: 330
memory_kb: 42348
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

ll add(ll a,ll b){
    if((double)a+b>=INFLL*2)return INFLL;
    return a + b;
}

string func(){
    string str = in<string>();
    int n = str.size();
    ll k = in();
    vvector<int> shortest_dp(n,vector<int>(n,-1));
    method(shortest,int,int l,int r){
        if(l==r)return 1;
        if(l>r)return 0;
        int &it = shortest_dp[l][r];
        if(it >= 0)return it;
        it = INF;
        chmin(it,shortest(l+1,r)+2);
        chmin(it,shortest(l,r-1)+2);
        if(str[l]==str[r])chmin(it,shortest(l+1,r-1)+2);
        return it;
    };
    vvector<ll> dp(n,vector<ll>(n,-1));
    method(rec,ll,int l,int r){
        if(l>=r)return 1;
        ll &it = dp[l][r];
        if(it >= 0)return it;
        it = 0;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            it = add(it,rec(nl,nr));
        }
        return it;
    };
    string left = "";
    int l = 0;
    int r = n-1;
    while(l < r){
        bool flag = false;
        rep(c,'a','z'+1){
            int nl = str[l] == c ? l + 1 : l;
            int nr = str[r] == c ? r - 1 : r;
            if(shortest(l,r)!=shortest(nl,nr) + 2)continue;
            if(rec(nl,nr) < k){
                k -= rec(nl,nr);
            }else{
                left += c;
                l = nl;
                r = nr;
                flag = true;
                break;
            }
        }
        if(not flag)return "NONE";
    }
    string res = "";
    if(l==r){
        res = left + str[l] + reversed(left);
    }else{
        res = left + reversed(left);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 0.3090909090909091
time_ms: 330
memory_kb: 42388
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

ll add(ll x, ll y) {
  if (LLINF - x < y) return LLINF;
  return x + y;
}

void solve() {
  string S;
  cin >> S;
  int N = S.size();
  ll K;
  cin >> K;
  K--;

  auto len = vect(N + 1, vect(N + 1, -1));
  auto dp = vect(N + 1, vect(N + 1, -1ll));

  // [l, r)
  function<int(int, int)> calc_len = [&](int l, int r) {
    if (len[l][r] != -1ll) return len[l][r];

    // empty string
    if (r - l == 0) { return len[l][r] = 0; }

    // only one character is palindrome
    if (r - l == 1) { return len[l][r] = 1; }

    if (S[l] == S[r - 1]) { return len[l][r] = calc_len(l + 1, r - 1) + 2; }

    return len[l][r] = min(calc_len(l + 1, r) + 2, calc_len(l, r - 1) + 2);
  };

  function<ll(int, int)> rec = [&](int l, int r) {
    if (dp[l][r] != -1ll) return dp[l][r];

    if (r - l == 0) { return dp[l][r] = 1ll; }

    if (r - l == 1) { return dp[l][r] = 1ll; }

    if (S[l] == S[r - 1]) { return dp[l][r] = rec(l + 1, r - 1); }

    dp[l][r] = 0ll;

    if (calc_len(l, r) == calc_len(l + 1, r) + 2)
      dp[l][r] = add(dp[l][r], rec(l + 1, r));
    if (calc_len(l, r) == calc_len(l, r - 1) + 2)
      dp[l][r] = add(dp[l][r], rec(l, r - 1));

    return dp[l][r];
  };

  dmp(calc_len(0, N));
  dmp(rec(0, N));

  if (rec(0, N) <= K) {
    cout << "NONE" << endl;
    return;
  }

  function<string(int, int, ll)> query = [&](int l, int r, ll k) {
    if (r - l == 0) return string();
    if (r - l == 1) return S.substr(l, 1);
    string sl = S.substr(l, 1);
    string sr = S.substr(r - 1, 1);
    if (S[l] == S[r - 1]) { return sl + query(l + 1, r - 1, k) + sr; }

    bool use_left = (calc_len(l, r) == calc_len(l + 1, r) + 2);
    bool use_right = (calc_len(l, r) == calc_len(l, r - 1) + 2);

    if (use_left && !use_right) { return sl + query(l + 1, r, k) + sl; }
    if (!use_left && use_right) { return sr + query(l, r - 1, k) + sr; }

    if (S[l] < S[r - 1]) {
      if (k < rec(l + 1, r))
        return sl + query(l + 1, r, k) + sl;
      else
        return sr + query(l, r - 1, k - rec(l + 1, r)) + sr;
    } else {
      if (k < rec(l, r - 1))
        return sr + query(l, r - 1, k) + sr;
      else
        return sl + query(l + 1, r, k - rec(l, r - 1)) + sl;
    }
  };

  cout << query(0, N, K) << endl;
  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 50864
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

using P = pair<long long, long long>;

long long k, n;
string s;
vector<vector<P>> dp;

string solve();
P calc_dp(int l, int r);
P calc_nxt(int l, int r, char c);

int main() {
  cin >> s >> k;
  cout << solve() << endl;
  return 0;
}

string solve() {
  n = s.size();
  dp.assign(n, vector<P>(n + 1, P(-1, -1)));
  if (calc_dp(0, n).second < k) return "NONE";
  int l = 0, r = n, len = calc_dp(0, n).first;
  string res, rev;
  while (r - l > 1) {
    set<char> st;
    st.insert(s[l]), st.insert(s[r - 1]);
    for (auto c : st) {
      auto [nl, nr] = calc_nxt(l, r, c);
      auto [tolen, cnt] = calc_dp(nl, nr);
      if (tolen + 2 != len) continue;
      if (cnt >= k) {
        res += c, l = nl, r = nr;
        break;
      }
      k -= cnt;
    }
    len -= 2;
  }
  rev = res;
  reverse(rev.begin(), rev.end());
  if (l + 1 == r) res += s[l];
  res += rev;
  return res;
}

P calc_dp(int l, int r) {
  if (dp[l][r].first >= 0) return dp[l][r];
  if (l + 1 >= r) return P(r - l, 1);
  P res(2 * n, 0);
  set<char> st;
  st.insert(s[l]), st.insert(s[r - 1]);
  for (auto c : st) {
    auto [nl, nr] = calc_nxt(l, r, c);
    P now = calc_dp(nl, nr);
    if (now.first < res.first) res = P(now.first, 0);
    if (now.first == res.first) res.second = min(res.second + now.second, k);
  }
  res.first += 2;
  return dp[l][r] = res;
}

P calc_nxt(int l, int r, char c) {
  if (s[l] == c) ++l;
  if (s[r - 1] == c) --r;
  return P(l, r);
}
accuracy: 1
time_ms: 130
memory_kb: 66512
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define POPCOUNT(x) __builtin_popcount(x)
template <typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void chmax(T &a, const T &b) { a = max(a, b); }

const ll INF = 1LL << 60;

struct FastIO {
    FastIO() {
        cin.tie(0);
        ios::sync_with_stdio(0);
    }
} fastiofastio;

const ull MOD = 1e9 + 7;

// BEGIN CUT
ll modpow(ll x, ll y, ll m) {
    ll a = 1, p = x;
    while (y > 0) {
        if (y % 2 == 0) {
            p = (p * p) % m;
            y /= 2;
        } else {
            a = (a * p) % m;
            y--;
        }
    }
    return a;
}
// END CUT

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

int dp[2001][2001];
ll dp2[2001][2001];

int main() {
    string S;
    cin >> S;
    int N = S.size();
    ll K;
    cin >> K;
    K--;
    ll M = 1e18;
    fill((int *)dp, (int *)(dp + 2001), 1 << 30);
    for (int i = 0; i < N; i++) {
        dp[i][i] = 0;
        dp[i][i + 1] = 1;
    }
    for (int len = 2; len <= N; len++) {
        for (int i = 0; i + len <= N; i++) {
            if (S[i] == S[i + len - 1]) {
                chmin(dp[i][i + len], dp[i + 1][i + len - 1] + 2);
            }
            chmin(dp[i][i + len], dp[i + 1][i + len] + 2);
            chmin(dp[i][i + len], dp[i][i + len - 1] + 2);
        }
    }
    for (int i = 0; i < N; i++) {
        dp2[i][i] = dp2[i][i + 1] = 1;
    }
    for (int len = 2; len <= N; len++) {
        for (int i = 0; i + len <= N; i++) {
            if (S[i] == S[i + len - 1] &&
                dp[i + 1][i + len - 1] + 2 == dp[i][i + len]) {
                dp2[i][i + len] =
                    min(dp2[i][i + len] + dp2[i + 1][i + len - 1], M);
                continue;
            }
            if (dp[i + 1][i + len] + 2 == dp[i][i + len]) {
                dp2[i][i + len] = min(dp2[i][i + len] + dp2[i + 1][i + len], M);
            }
            if (dp[i][i + len - 1] + 2 == dp[i][i + len]) {
                dp2[i][i + len] = min(dp2[i][i + len] + dp2[i][i + len - 1], M);
            }
        }
    }
    if (dp2[0][N] <= K) {
        cout << "NONE" << endl;
        return 0;
    }
    int best = dp[0][N];
    string ans(best, '_');
    int l = 0, r = N;
    for (int i = 0; i < (best + 1) / 2; i++) {
        if (S[l] == S[r - 1]) {
            ans[i] = ans[best - i - 1] = S[l];
            l++;
            r--;
            continue;
        }
        if (dp[l + 1][r] + 2 != dp[l][r]) {
            ans[i] = ans[best - i - 1] = S[r - 1];
            r--;
            continue;
        }
        if (dp[l][r - 1] + 2 != dp[l][r]) {
            ans[i] = ans[best - i - 1] = S[l];
            l++;
            continue;
        }
        if (S[l] < S[r - 1]) {
            if (K < dp2[l + 1][r]) {
                ans[i] = ans[best - i - 1] = S[l];
                l++;
            } else {
                K -= dp2[l + 1][r];
                ans[i] = ans[best - i - 1] = S[r - 1];
                r--;
            }
        } else {
            if (K < dp2[l][r - 1]) {
                ans[i] = ans[best - i - 1] = S[r - 1];
                r--;
            } else {
                K -= dp2[l][r - 1];
                ans[i] = ans[best - i - 1] = S[l];
                l++;
            }
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 50384
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    string S;
    cin >> S;
    int N = S.size();
    ll k;
    cin >> k;
    --k;
    vector<vector<pair<int, ll>>> dp(N, vector<pair<int, ll>>(N+1, {1e9, 0}));
    rep(i, 0, N) {
        dp[i][i] = {0, 1};
        dp[i][i+1] = {1, 1};
    }
    rep(l, 2, N+1) {
        rep(i, 0, N-l+1) {
            int j = i + l;
            if (S[i] == S[j-1]) {
                int nv = dp[i+1][j-1].first + 2;
                if (dp[i][j].first == nv) {
                    dp[i][j].second = min(dp[i][j].second + dp[i+1][j-1].second, (ll)2e18);
                } else if (dp[i][j].first > nv) {
                    dp[i][j] = {nv, dp[i+1][j-1].second};
                }
            } else {
                int nv = dp[i+1][j].first + 2;
                if (dp[i][j].first == nv) {
                    dp[i][j].second = min(dp[i][j].second + dp[i+1][j].second, (ll)2e18);
                } else if (dp[i][j].first > nv) {
                    dp[i][j] = {nv, dp[i+1][j].second};
                }
                nv = dp[i][j-1].first + 2;
                if (dp[i][j].first == nv) {
                    dp[i][j].second = min(dp[i][j].second + dp[i][j-1].second, (ll)2e18);
                } else if (dp[i][j].first > nv) {
                    dp[i][j] = {nv, dp[i][j-1].second};
                }
            }
        }
    }
    if (dp[0][N].second <= k) {
        cout << "NONE" << endl;
        return 0;
    }
    string a = "", b = "";
    int l = 0, r = N;
    while (l < r - 1) {
        if (S[l] == S[r-1]) {
            a += S[l++];
            b += S[--r];
        } else if (dp[l+1][r].first < dp[l][r-1].first) {
            a += S[l];
            b += S[l++];
        } else if (dp[l+1][r].first > dp[l][r-1].first) {
            a += S[--r];
            b += S[r];
        } else {
            if (S[l] < S[r-1]) {
                if (dp[l+1][r].second <= k) {
                    k -= dp[l+1][r].second;
                    a += S[--r];
                    b += S[r];
                } else {
                    a += S[l];
                    b += S[l++];
                }
            } else {
                if (dp[l][r-1].second <= k) {
                    k -= dp[l][r-1].second;
                    a += S[l];
                    b += S[l++];
                } else {
                    a += S[--r];
                    b += S[r];
                }
            }
        }
    }
    if (l + 1 == r) {
        a += S[l];
    }
    reverse(b.begin(), b.end());
    cout << a + b << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 65676
final_rank: 10