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# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Linq;
using CompLib.Util;

public class Program
{
    private int N, K;
    private string S;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        K = sc.NextInt();
        S = sc.Next();

        // 最初1回
        // 最小の文字が最後になるように切る

        // 次から
        // 最小の文字が2倍になる
        // N = 5000でも14回あれば全部最小

        char min = S.Min();

        char[] ans = new char[N];
        for (int i = 0; i < N; i++)
        {
            ans[i] = 'z';
        }

        char[] u = new char[2 * N];
        for (int i = 0; i < N; i++)
        {
            u[i] = S[i];
            u[2 * N - 1 - i] = S[i];
        }

        if (K == 1)
        {
            for (int i = 0; i <= N; i++)
            {
                var tmp = new char[N];
                for (int j = 0; j < N; j++)
                {
                    tmp[j] = u[i + j];
                }

                ChMin(ref ans, tmp);
            }

            Console.WriteLine(new string(ans));
            return;
        }

        for (int i = 0; i <= N; i++)
        {
            // 最初
            if (u[i + N - 1] != min)
            {
                continue;
            }

            char[] tmp = new char[N];
            for (int j = 0; j < N; j++)
            {
                tmp[j] = u[i + j];
            }

            int last = 0;
            for (int j = N - 1; j >= 0; j--)
            {
                if (tmp[j] == min) last++;
                else break;
            }


            // K-2回
            for (int j = 0; j < K - 2; j++)
            {
                var tmpU = new char[2 * N];
                for (int k = 0; k < N; k++)
                {
                    tmpU[k] = tmp[k];
                    tmpU[2 * N - 1 - k] = tmp[k];
                }

                if (last * 2 >= N)
                {
                    Console.WriteLine(new string(min, N));
                    return;
                }

                var next = new char[N];
                for (int k = 0; k < N; k++)
                {
                    next[k] = tmpU[k + last];
                }

                // Console.WriteLine(next);

                tmp = next;
                last *= 2;
            }

            if (last * 2 >= N)
            {
                Console.WriteLine(new string(min, N));
                return;
            }

            var result = new char[N];
            for (int j = 0; j < last; j++) result[j] = min;
            for (int j = 0; j < N - last; j++)
            {
                result[j + last] = tmp[N - j - 1];
            }

            ChMin(ref ans, result);
        }

        Console.WriteLine(new string(ans));
    }

    void ChMin(ref char[] s, char[] ar)
    {
        for (int i = 0; i < N; i++)
        {
            if (ar[i] < s[i])
            {
                s = ar;
                return;
            }

            if (ar[i] > s[i])
            {
                return;
            }
        }
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}