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.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABC124_D
{
    class Program
    {
        class Node : IComparable
        {
            //public int index;
            public int leftCount;
            public int rightCount;
            public int myCount;
            public int sum;
            //public Node prevNode;
            //public Node nextNode;
            public Node prevOtherNode;
            public Node nextOtherNode;
            //public int nodeIndex;

            public bool current01Flag;

            public int CompareTo(object obj)
            {
                Node other = (Node)obj;
                if (other.sum > sum)
                {
                    return -1;
                }
                else if (other.sum < sum)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
        }

        static void Main(string[] args)
        {
            string[] strs = Console.ReadLine().Split(' ');
            int n = int.Parse(strs[0]);
            int k = int.Parse(strs[1]);

            string s = Console.ReadLine();

            var node0 = new Node[50000];
            var node1 = new Node[50000];

            Node firstNode = null;
            Node lastNode = null;

            int katamari0StartIndex = -1;
            int katamari0Count = 0;
            int katamari1StartIndex = -1;
            int katamari1Count = 0;
            bool current01Flag = true;
            bool prev01Flag = true;

#if false //TN
            int node0Index = 0;
            int node1Index = 0;
#endif
            Node currentNode0 = null;
            Node currentNode1 = null;

            int maxCount = 0;

            if (s[0] == '1')
            {
                prev01Flag = true;
                katamari1StartIndex = 0;
                katamari1Count = 1;

                currentNode1 = new Node();
                currentNode1.current01Flag = true;
#if false //TN
                node1[node1Index] = currentNode1;
                node1[node1Index].nodeIndex = node1Index;
                ++node1Index;
                currentNode1.index = katamari1StartIndex;
#endif
                firstNode = currentNode1;

                current01Flag = true;
            }
            else
            {
                prev01Flag = false;
                katamari0StartIndex = 0;
                katamari0Count = 1;

                currentNode0 = new Node();
                currentNode0.current01Flag = false;
#if false //TN
                node0[node0Index] = currentNode0;
                node0[node0Index].nodeIndex = node0Index;
                ++node0Index;
                currentNode0.index = katamari0StartIndex;
#endif
                firstNode = currentNode0;

                current01Flag = false;
            }

            // 0または1のかたまりを探す
            for (int i = 1; i < n; ++i)
            {
                if (s[i] == '1')
                {
                    current01Flag = true;

                    if (prev01Flag != current01Flag)
                    {
                        currentNode0.myCount = katamari0Count;

                        katamari1StartIndex = i;
                        katamari1Count = 1;

                        var prevNode = currentNode1;

                        currentNode1 = new Node();
                        currentNode1.current01Flag = true;
#if false //TN
                        node1[node1Index] = currentNode1;
                        node1[node1Index].nodeIndex = node1Index;
                        ++node1Index;
                        currentNode1.index = katamari1StartIndex;

                        if (prevNode != null)
                        {
                            prevNode.nextNode = currentNode1;
                            currentNode1.prevNode = prevNode;
                        }
#endif
                        currentNode0.nextOtherNode = currentNode1;
                        currentNode1.prevOtherNode = currentNode0;
                    }
                    else
                    {
                        ++katamari1Count;
                    }
                }
                else
                {
                    current01Flag = false;

                    if (prev01Flag != current01Flag)
                    {
                        currentNode1.myCount = katamari1Count;
                        if (maxCount < katamari1Count)
                        {
                            maxCount = katamari1Count;
                        }
                        katamari0StartIndex = i;
                        katamari0Count = 1;

                        var prevNode = currentNode0;

                        currentNode0 = new Node();
                        currentNode0.current01Flag = false;
#if false //TN
                        node0[node0Index] = currentNode0;
                        node0[node0Index].nodeIndex = node0Index;
                        ++node0Index;
                        currentNode0.index = katamari0StartIndex;

                        if (prevNode != null)
                        {
                            prevNode.nextNode = currentNode0;
                            currentNode0.prevNode = prevNode;
                        }
#endif
                        currentNode1.nextOtherNode = currentNode0;
                        currentNode0.prevOtherNode = currentNode1;
                    }
                    else
                    {
                        ++katamari0Count;
                    }
                }

                prev01Flag = current01Flag;
            }

            if (current01Flag)
            {
                currentNode1.myCount = katamari1Count;
                if (maxCount < katamari1Count)
                {
                    maxCount = katamari1Count;
                }

                lastNode = currentNode1;
            }
            else
            {
                currentNode0.myCount = katamari0Count;

                lastNode = currentNode0;
            }

#if false //TN
            int node0Count = node0Index;
            int node1Count = node1Index;

            node0Index = 0;
            node1Index = 0;
#endif
            {
                Node currentNode = firstNode;
                Node[] nodeBuffer = new Node[k];
                int nodeBufferIndex = 0;
                int nodeBufferSum = 0;
                //for (int i = 0; i < node0Count + node1Count; ++i)
                while (currentNode != null)
                {
                    currentNode.leftCount = nodeBufferSum;

                    if (nodeBuffer[nodeBufferIndex] != null)
                    {
                        nodeBufferSum -= nodeBuffer[nodeBufferIndex].myCount;
                    }
                    nodeBuffer[nodeBufferIndex] = currentNode;
                    nodeBufferSum += currentNode.myCount;
                    nodeBufferIndex = (nodeBufferIndex + 1) % k;

                    currentNode = currentNode.nextOtherNode;
                }
            }

            // kの数が奇数の時は0のかたまりのところに、偶数の時は1のかたまりのところに合計数を書き込む
            bool write01Flag = (k % 2 == 0);

            {
                Node currentNode = lastNode;
                Node[] nodeBuffer = new Node[k];
                int nodeBufferIndex = 0;
                int nodeBufferSum = 0;

                //for (int i = 0; i < node0Count + node1Count; ++i)
                while (currentNode != null)
                {
                    currentNode.rightCount = nodeBufferSum;
                    if (write01Flag == currentNode.current01Flag)
                    {
                        currentNode.sum = currentNode.leftCount + currentNode.myCount + currentNode.rightCount;
                        if (maxCount < currentNode.sum)
                        {
                            maxCount = currentNode.sum;
                        }
                    }

                    if (nodeBuffer[nodeBufferIndex] != null)
                    {
                        nodeBufferSum -= nodeBuffer[nodeBufferIndex].myCount;
                    }
                    nodeBuffer[nodeBufferIndex] = currentNode;
                    nodeBufferSum += currentNode.myCount;
                    nodeBufferIndex = (nodeBufferIndex + 1) % k;

                    currentNode = currentNode.prevOtherNode;
                }
            }

            Console.WriteLine("{0}", maxCount);
        }
    }
}