Problem:
Score : 400 points

Problem Statement

There are N people standing in a queue from west to east.

Given is a string S of length N representing the directions of the people.
The i-th person from the west is facing west if the i-th character of S is L, and east if that character of S is R.

A person is happy if the person in front of him/her is facing the same direction.
If no person is standing in front of a person, however, he/she is not happy.

You can perform the following operation any number of times between 0 and K (inclusive):

Operation: Choose integers l and r such that 1 \leq l \leq r \leq N, and rotate by 180 degrees the part of the queue: the l-th, (l+1)-th, ..., r-th persons. That is, for each i = 0, 1, ..., r-l, the (l + i)-th person from the west will stand the (r - i)-th from the west after the operation, facing east if he/she is facing west now, and vice versa.

What is the maximum possible number of happy people you can have?

Constraints

N is an integer satisfying 1 \leq N \leq 10^5.

K is an integer satisfying 1 \leq K \leq 10^5.

|S| = N

Each character of S is L or R.

Input

Input is given from Standard Input in the following format:

N K
S

Output

Print the maximum possible number of happy people after at most K operations.

Sample Input 1

6 1
LRLRRL

Sample Output 1

3

If we choose (l, r) = (2, 5), we have LLLRLL, where the 2-nd, 3-rd, and 6-th persons from the west are happy.

Sample Input 2

13 3
LRRLRLRRLRLLR

Sample Output 2

9

Sample Input 3

10 1
LLLLLRRRRR

Sample Output 3

9

Sample Input 4

9 2
RRRLRLRLL

Sample Output 4

7

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

namespace AtCoder
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using static System.Console;
    using static System.Math;
    using static Util;

    class AtCoder
    {
        /*------------------------------------------------------------------*/
        void Solve()
        {
            int N, K;
            string S;
            io.i(out N, out K, out S);

            if (N == 1)
            {
                0.Prt();
                return;
            }

            var SS = "_" + S + "_";
            var chains = new List<int>();
            var chain = 0;
            FOR(1, N + 1, i =>
               {
                   if (SS[i - 1] == SS[i])
                   {
                       chain++;
                   }
                   if (SS[i - 1] != SS[i] || i == N)
                   {
                       chains.Add(chain);
                       chain = 0;
                   }
               });

            var add2 = 0;
            var add1 = 0;
            if (S[0] != S[1]) add1++;
            if (S[N - 1] != S[N - 2]) add1++;
            FOR(1, N - 1, i =>
            {
                if (S[i - 1] != S[i] && S[i] != S[i + 1])
                {
                    add2++;
                }
                else if (S[i - 1] != S[i] || S[i] != S[i + 1])
                {
                    add1++;
                }
            });

            var take2 = Min(K, add2);
            var take1 = Min(K - take2, add1);
            var ans = chains.Sum() + 2 * take2 + take1;
            ans.Prt();

        }

        /*------------------------------------------------------------------*/
        void Test()
        {
            //--- TEST ---//
        }

        public static void Main(string[] _) => new AtCoder().Stream();
        IO io = new IO();

        private void Stream()
        {
            /*
            var exStdIn = new System.IO.StreamReader("stdin.txt");
            SetIn(exStdIn);
            Test();
            */
            Solve();
            io.Flush();
        }
    }

    class IO
    {
        #region INPUT

        #region FastRead

        private const int Size = 1 << 12;
        private readonly Stream _stream = OpenStandardInput();
        private readonly byte[] _buffer = new byte[Size];
        private int _ptr = 0, _buffLen = 0;

        private bool HasNextByte()
        {
            if (_ptr < _buffLen) return true;
            _ptr = 0;
            _buffLen = _stream.Read(_buffer, 0, Size);
            return _buffLen > 0;
        }

        private byte ReadByte()
        {
            if (HasNextByte()) return _buffer[_ptr++];
            else
                //inputの末尾の改行がないとerror
                throw new EndOfStreamException();
        }

        private bool IsAscii(int c) => '!' <= c && c <= '~';

        private char NextChar()
        {
            var b = ReadByte();
            while (!IsAscii(b)) b = ReadByte();
            return (char)b;
        }

        private string Next()
        {
            var sb = new StringBuilder();
            for (var b = NextChar(); IsAscii(b); b = (char)ReadByte()) sb.Append(b);
            return sb.ToString();
        }

        public string String => Next();
        public char Char => NextChar();
        public int Int => int.Parse(Next());
        public long Long => long.Parse(Next());
        public double Double => double.Parse(Next());

        #endregion

        #region LazyRead

        private void scan<T>(ref T x)
        {
            if (x is int) __refvalue(__makeref(x), int) = int.Parse(Next());
            else if (x is long) __refvalue(__makeref(x), long) = long.Parse(Next());
            else if (x is double) __refvalue(__makeref(x), double) = double.Parse(Next());
            else if (x is char) __refvalue(__makeref(x), char) = NextChar();
            else __refvalue(__makeref(x), string) = Next();
        }

        public void i<T>(out T t)
        {
            t = default(T);
            scan(ref t);
        }

        public void i<T, TU>(out T t, out TU u)
        {
            i(out t);
            i(out u);
        }

        public void i<T, TU, TV>(out T t, out TU u, out TV v)
        {
            i(out t, out u);
            i(out v);
        }

        public void i<T, TU, TV, TW>(out T t, out TU u, out TV v, out TW w)
        {
            i(out t, out u);
            i(out v, out w);
        }

        public void i<T, TU, TV, TW, TX>(out T t, out TU u, out TV v, out TW w, out TX x)
        {
            i(out t, out u, out v);
            i(out w, out x);
        }

        public void i<T, TU, TV, TW, TX, TY>(out T t, out TU u, out TV v, out TW w, out TX x, out TY y)
        {
            i(out t, out u, out v);
            i(out w, out x, out y);
        }

        public void ini<T>(out T[] a, int n)
        {
            a = new T[n];
            for (int i = 0; i < n; ++i) i<T>(out a[i]);
        }

        public void ini<T, TU>(out T[] a, out TU[] b, int n)
        {
            a = new T[n];
            b = new TU[n];
            for (int i = 0; i < n; ++i) i<T, TU>(out a[i], out b[i]);
        }

        public void ini<T, TU, TV>(out T[] a, out TU[] b, out TV[] c, int n)
        {
            a = new T[n];
            b = new TU[n];
            c = new TV[n];
            for (var i = 0; i < n; ++i) i<T, TU, TV>(out a[i], out b[i], out c[i]);
        }

        public void ini<T>(out T[,] a, int h, int w)
        {
            a = new T[h, w];
            for (int i = 0; i < h; ++i)
                for (int j = 0; j < w; ++j)
                    i<T>(out a[i, j]);
        }

        #endregion

        #endregion

        #region OUTPUT

        private readonly StreamWriter _sw = new StreamWriter(OpenStandardOutput())
        {
#if DEBUG
            AutoFlush = true
#else
        AutoFlush = false
#endif
        };

        public void Flush() => Out.Flush();
        public void YN(bool f) => yn(f, "YES", "NO");
        public void Yn(bool f) => yn(f, "Yes", "No");
        public void yn(bool f, string y = "yes", string n = "no") => WriteLine(f ? y : n);


        #endregion

        public IO()
        {
            SetOut(_sw);
        }
    }

    static class Util
    {
        public static void FOR(int a, int b, Action<int> f) => FOR(a, b, 1, f);
        public static void FOR(int a, int b, int n, Action<int> f)
        {
            for (int i = a; i < b; i += n) f(i);
        }
        public static void REP(int a, Action<int> f) => FOR(0, a, f);
        public static void REPEQ(int a, Action<int> f) => FOR(0, a + 1, f);
        public static IEnumerable<TResult> ZIP<T1, T2, TResult>(IEnumerable<T1> xs, IEnumerable<T2> ys,
            Func<T1, T2, TResult> f = null)
        {
            using (var e1 = xs.GetEnumerator())
            using (var e2 = ys.GetEnumerator())
                while (e1.MoveNext() && e2.MoveNext())
                    yield return f(e1.Current, e2.Current);
        }

        public static IEnumerable<Tuple<T1, T2>> ZIP<T1, T2>(IEnumerable<T1> xs, IEnumerable<T2> ys)
            => ZIP(xs, ys, (x, y) => new Tuple<T1, T2>(x, y));

        public static IEnumerable<TResult> ZIP<T1, T2, T3, TResult>(IEnumerable<T1> xs, IEnumerable<T2> ys,
            IEnumerable<T3> zs, Func<T1, T2, T3, TResult> f)
        {
            using (var e1 = xs.GetEnumerator())
            using (var e2 = ys.GetEnumerator())
            using (var e3 = zs.GetEnumerator())
                while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
                    yield return f(e1.Current, e2.Current, e3.Current);
        }

        public static IEnumerable<Tuple<T1, T2, T3>> ZIP<T1, T2, T3>(IEnumerable<T1> xs, IEnumerable<T2> ys,
            IEnumerable<T3> zs) => ZIP(xs, ys, zs, (x, y, z) => new Tuple<T1, T2, T3>(x, y, z));

        public static bool ODD(int x) => x % 2 != 0;
        public static bool ODD(long x) => x % 2L != 0L;

        public static int SUM(params int[] xs) => xs.Sum();
        public static long SUM(params long[] xs) => xs.Sum();
        public struct IndexedItem<T>
        {
            public int Idx;
            public T Val;
            public IndexedItem(int idx, T val)
            {
                Idx = idx;
                Val = val;
            }
        }
        public class Counts<T> : Dictionary<T, int>
        {
            public Counts() { }
            public Counts(params T[] xs) : this() { Add(xs); }
            public new int this[T key] {
                get {
                    int v;
                    return this.TryGetValue(key, out v) ? v : 0;
                }
            }
            public void Add(T key)
            {
                if (!base.ContainsKey(key)) base.Add(key, 0);
                base[key]++;
            }
            public void Add(params T[] xs) => xs.Iter(Add);
            public void SortByCount(bool isAsc) => (isAsc ? (this.OrderBy(kp => kp.Value)) : (this.OrderByDescending(kp => kp.Value))).ThenBy(kp => kp.Key);
        }
        public class PriorityQueue<T> where T : IComparable<T>
        {
            private List<T> heap;
            private readonly bool isAsc;
            private int size;
            public T Peek => heap[0];
            public int Count => size;
            public bool Any => size > 0;
            public bool Empty => !Any;

            public IEnumerable<T> Values => heap;

            public PriorityQueue(bool isAsc = true)
            {
                this.isAsc = isAsc;
                size = 0;
                heap = new List<T>();
            }

            public void Enqueue(T item)
            {
                heap.Add(item);
                var i = size++;
                while (i > 0)
                {
                    var p = (i - 1) / 2;
                    if (Compare(heap[p], item) <= 0) break;
                    heap[i] = heap[p];
                    i = p;
                }
                heap[i] = item;
            }

            public T Dequeue()
            {
                var ret = heap[0];
                var x = heap[--size];
                var i = 0;
                while ((i << 1) + 1 < size)
                {
                    var a = (i << 1) + 1;
                    var b = (i << 1) + 2;
                    if (b < size && Compare(heap[b], heap[a]) < 0) a = b;
                    if (Compare(heap[a], x) >= 0) break;
                    heap[i] = heap[a];
                    i = a;
                }
                heap[i] = x;
                heap.RemoveAt(size);
                return ret;
            }

            private int Compare(T x, T y) => isAsc ? x.CompareTo(y) : y.CompareTo(x);
        }
    }

    static class Ex
    {
        public static Tuple<IEnumerable<T>, IEnumerable<T>> Split<T>(this IEnumerable<T> xs, Func<T, bool> f)
        {
            var ys = xs.Where(f);
            var zs = xs.Where(x => !f(x));
            return Tuple.Create(ys, zs);
        }
        public static void Iter<T>(this IEnumerable<T> xs, Action<T> f)
        {
            foreach (var x in xs) f(x);
        }
        public static void Prt<T>(this T x) => WriteLine(x);
        public static void Prt<T>(this IEnumerable<T> xs) => xs.Iter(x => WriteLine(x));

        public static IEnumerable<IndexedItem<T>> Indexed<T>(this IEnumerable<T> xs) => xs.Select((x, idx) => new IndexedItem<T>(idx, x));
        public static IEnumerable<T> UnIndexed<T>(this IEnumerable<IndexedItem<T>> xs) => xs.Select(x => x.Val);

        public static IEnumerable<Tuple<T, T>> Pairwise<T>(this IEnumerable<T> xs) => ZIP(xs, xs.Skip(1));
    }
}