Problem:
Score : 1300 points

Problem Statement

Takahashi has a string S of length N consisting of lowercase English letters.
On this string, he will perform the following operation K times:

Let T be the string obtained by reversing S, and U be the string obtained by concatenating S and T in this order.

Let S' be some contiguous substring of U with length N, and replace S with S'.

Among the strings that can be the string S after the K operations, find the lexicographically smallest possible one.

Constraints

1 \leq N \leq 5000

1 \leq K \leq 10^9

|S|=N

S consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

N K
S

Output

Print the lexicographically smallest possible string that can be the string S after the K operations.

Sample Input 1

5 1
bacba

Sample Output 1

aabca

When S=bacba, T=abcab, U=bacbaabcab, and the optimal choice of S' is S'=aabca.

Sample Input 2

10 2
bbaabbbaab

Sample Output 2

aaaabbaabb

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> pi;

#define fi first
#define se second

int read() {
  int res = 0, w = 1; char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') c = getchar(), w = -1;
  while (isdigit(c)) res = (res << 1) + (res << 3) + c - '0', c = getchar();
  return res * w;
}

const int N = 1e4 + 10;

int n, k;
char s[N], m;

bool check1(int p1, int p2, int len) {
  while (len < n) {
    if (s[p1 - len] > s[p2 - len]) return 1;
    if (s[p1 - len] < s[p2 - len]) return 0;
    len++;
  }
  return 0;
}

void trans1() {
  for (int i = 1; i <= n; i++) s[i + n] = s[n - i + 1];
  vector<int> res(0);
  int cur = 0;
  for (int i = 1; i <= 2 * n; i++) {
    if (s[i] == m) {
      int l = i, r = i;
      while (r < 2 * n && s[r + 1] == m) r++;
      int len = r - l + 1;
      if (r > n) {
        if (len > cur) {
          res.clear();
          res.push_back(r);
          cur = len;
        } else if (len == cur) {
          res.push_back(r);
        }
        i = r;
      }
    }
  }
  int tmp = res[0];
  for (int i = 1; i < res.size(); i++)
    if (check1(tmp, res[i], cur)) tmp = res[i];
  for (int i = tmp - n + 1; i <= tmp; i++) s[i - tmp + n] = s[i];
}

bool check2(int p1, int p2, int len) {
  while (len < n) {
    if (s[p1 + len] > s[p2 + len]) return 1;
    if (s[p1 + len] < s[p2 + len]) return 0;
    len++;
  }
  return 0;
}

void trans2() {
  for (int i = 1; i <= n; i++) s[i + n] = s[n - i + 1];
  vector<int> res(0);
  int cur = 0;
  for (int i = 1; i <= 2 * n; i++) {
    if (s[i] == m) {
      int l = i, r = i;
      while (r < 2 * n && s[r + 1] == m) r++;
      int len = r - l + 1;
      if (l <= n) {
        if (len > cur) {
          res.clear();
          res.push_back(l);
          cur = len;
        } else if (len == cur) {
          res.push_back(l);
        }
        i = r;
      }
    }
  }
  int tmp = res[0];
  for (int i = 1; i < res.size(); i++)
    if (check2(tmp, res[i], cur)) tmp = res[i];
  for (int i = tmp; i <= tmp + n - 1; i++) s[i - tmp + 1] = s[i];  
}

int main() {
//  freopen("tst.in", "r", stdin);
  n = read(), k = read();
  scanf("%s", s + 1);
  m = 'z';
  for (int i = 1; i <= n; i++) m = min(m, s[i]);
  for (int i = 1; i < k; i++) {
    trans1();
    bool fg = 0;
    for (int j = 1; j <= n; j++) if (s[j] != m) fg = 1;
    if (!fg) break; 
  }
  trans2();
  for (int i = 1; i <= n; i++) putchar(s[i]);
  puts("");
  return 0;
}