Problem:
Score : 400 points

Problem Statement

N people are arranged in a row from left to right.

You are given a string S of length N consisting of 0 and 1, and a positive integer K.

The i-th person from the left is standing on feet if the i-th character of S is 0, and standing on hands if that character is 1.

You will give the following direction at most K times (possibly zero):

Direction: Choose integers l and r satisfying 1 \leq l \leq r \leq N, and flip the l-th, (l+1)-th, ..., and r-th persons. That is, for each i = l, l+1, ..., r, the i-th person from the left now stands on hands if he/she was standing on feet, and stands on feet if he/she was standing on hands.

Find the maximum possible number of consecutive people standing on hands after at most K directions.

Constraints

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

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

The length of the string S is N.

Each character of the string S is 0 or 1.

Input

Input is given from Standard Input in the following format:

N K
S

Output

Print the maximum possible number of consecutive people standing on hands after at most K directions.

Sample Input 1

5 1
00010

Sample Output 1

4

We can have four consecutive people standing on hands, which is the maximum result, by giving the following direction:

Give the direction with l = 1, r = 3, which flips the first, second and third persons from the left.

Sample Input 2

14 2
11101010110011

Sample Output 2

8

Sample Input 3

1 1
1

Sample Output 3

1

No directions are necessary.

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

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace AtCoder.D
{
    public class Program
    {
        public static void Main() { var r = GetResult(); Debug.WriteLine(r); Console.Write(r); }

        private static object GetResult()
        {
            var inputs = ReadLongs();
            var N = inputs[0];
            var K = inputs[1];
            var S = ReadText();

            var blocks = GetBlocks(N, S);

            // すべてひっくり返しきれるケース
            if (blocks.Count(x => !x.IsSakadati) <= K) return N;

            for (int k = 0; k < K; k++)
            {
                // 一度は操作可能なため
                if (blocks.Count == 2) return N;

                var bestPoint = -1;
                var bestContinuous = 0L;
                for (int i = 0; i < blocks.Count; i++)
                {
                    var currentBlock = blocks[i];
                    if (currentBlock.IsSakadati)
                    {
                        bestContinuous = Math.Max(bestContinuous, currentBlock.Count);
                        continue;
                    }

                    var preContinuous = i == 0 ? 0 : blocks[i - 1].Count;
                    var nextContinuous = i == blocks.Count - 1 ? 0 : blocks[i + 1].Count;

                    if (bestContinuous <= currentBlock.Count + preContinuous + nextContinuous)
                    {
                        bestContinuous = currentBlock.Count + preContinuous + nextContinuous;
                        bestPoint = i;
                    }
                }

                if (bestPoint != -1)
                {
                    if (bestPoint == 0)
                    {
                        blocks[1].Count += blocks[0].Count;
                        blocks.RemoveAt(0);
                    }
                    else if (bestPoint == blocks.Count - 1)
                    {
                        blocks[blocks.Count - 2].Count += blocks[blocks.Count - 1].Count;
                        blocks.RemoveAt(blocks.Count - 1);
                    }
                    else
                    {
                        blocks[bestPoint - 1].Count +=
                            blocks[bestPoint].Count
                            + blocks[bestPoint + 1].Count;

                        blocks.RemoveAt(bestPoint + 1);
                        blocks.RemoveAt(bestPoint);
                    }

                }
            }

            return blocks.Max(x => x.IsSakadati ? x.Count : 0);
        }

        private static List<Block> GetBlocks(long N, string S)
        {
            var blocks = new List<Block>();
            var pre = S[0];
            var currentCount = 0L;
            for (int i = 0; i < N; i++)
            {
                if (pre == S[i])
                {
                    currentCount++;
                }
                else
                {
                    blocks.Add(new Block
                    {
                        IsSakadati = pre == '1',
                        Count = currentCount,
                    });

                    pre = S[i];
                    currentCount = 1L;
                }
            }

            // 最後の一つを足す
            blocks.Add(new Block
            {
                IsSakadati = pre == '1',
                Count = currentCount,
            });
            return blocks;
        }

        #region Console

        public static string ReadText() { return Console.ReadLine(); }
        public static List<string> ReadTexts() { return Console.ReadLine().Split(' ').ToList(); }
        public static long ReadLong() { return long.Parse(Console.ReadLine()); }
        public static List<long> ReadLongs() { return Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToList(); }

        #endregion
    }

    class Block
    {
        public bool IsSakadati { get; set; }
        public long Count { get; set; }
    }
}