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 left1Count;
            public int right1Count;
            public int my0Count;
            public int sum1;
            public Node prevNode;
            public Node nextNode;
            public int nodeIndex;

            public int CompareTo(object obj)
            {
                Node other = (Node)obj;
                if (other.sum1 > sum1)
                {
                    return -1;
                }
                else if (other.sum1 < sum1)
                {
                    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 node = new Node[100000];

            int katamari0StartIndex = -1;
            int katamari0Count = 0;
            int katamari1StartIndex = -1;
            int katamari1Count = 0;
            bool currentFlag = true;
            bool prevFlag = true;

            int nodeIndex = 0;
            Node currentNode = null;

            int max1Count = 0;

            if (s[0] == '1')
            {
                prevFlag = true;
                katamari1StartIndex = 0;
                katamari1Count = 1;
            }
            else
            {
                prevFlag = false;
                katamari0StartIndex = 0;
                katamari0Count = 1;

                currentNode = new Node();
                node[nodeIndex] = currentNode;
                node[nodeIndex].nodeIndex = nodeIndex;
                ++nodeIndex;
                currentNode.index = katamari0StartIndex;
            }

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

                    if (prevFlag != currentFlag)
                    {
                        currentNode.my0Count = katamari0Count;
                        currentNode.left1Count = katamari1Count;

                        katamari1StartIndex = i;
                        katamari1Count = 1;
                    }
                    else
                    {
                        ++katamari1Count;
                    }
                }
                else
                {
                    currentFlag = false;

                    if (prevFlag != currentFlag)
                    {
                        katamari0StartIndex = i;
                        katamari0Count = 1;

                        if (currentNode != null)
                        {
                            currentNode.right1Count = katamari1Count;
                            if (max1Count < katamari1Count)
                            {
                                max1Count = katamari1Count;
                            }
                            currentNode.sum1 = currentNode.left1Count + currentNode.my0Count + currentNode.right1Count;
                        }
                        var prevNode = currentNode;

                        currentNode = new Node();
                        node[nodeIndex] = currentNode;
                        node[nodeIndex].nodeIndex = nodeIndex;
                        ++nodeIndex;
                        currentNode.index = katamari0StartIndex;

                        if (prevNode != null)
                        {
                            prevNode.nextNode = currentNode;
                            currentNode.prevNode = prevNode;
                        }
                    }
                    else
                    {
                        ++katamari0Count;
                    }
                }

                prevFlag = currentFlag;
            }

            if (currentFlag)
            {
                if (currentNode != null)
                {
                    currentNode.right1Count = katamari1Count;
                    if (max1Count < katamari1Count)
                    {
                        max1Count = katamari1Count;
                    }
                    currentNode.sum1 = currentNode.left1Count + currentNode.my0Count + currentNode.right1Count;
                }
            }
            else
            {
                currentNode.right1Count = 0;
                currentNode.my0Count = katamari0Count;
                currentNode.left1Count = katamari1Count;
                if (max1Count < katamari1Count)
                {
                    max1Count = katamari1Count;
                }
                currentNode.sum1 = currentNode.left1Count + currentNode.my0Count;
            }

            int nodeCount = nodeIndex;
            nodeIndex = 0;


            Treap<Node> treap = new Treap<Node>();

            for (int i = 0; i < nodeCount; ++i)
            {
                treap.Insert(node[i]);
            }

            for (int i = 0; i < k; ++i)
            {
                if (nodeCount == 0)
                {
                    break;
                }

                Node maxSum = treap[nodeCount - 1];

                treap.Erase(maxSum);
                node[maxSum.nodeIndex] = null;
                --nodeCount;

                if (maxSum.prevNode != null)
                {
                    treap.Erase(maxSum.prevNode);

                    maxSum.prevNode.nextNode = maxSum.nextNode;
                    maxSum.prevNode.right1Count += maxSum.my0Count + maxSum.right1Count;
                    if (max1Count < maxSum.prevNode.right1Count)
                    {
                        max1Count = maxSum.prevNode.right1Count;
                    }
                    maxSum.prevNode.sum1 += maxSum.my0Count + maxSum.right1Count;
                    treap.Insert(maxSum.prevNode);
                }
                if (maxSum.nextNode != null)
                {
                    treap.Erase(maxSum.nextNode);

                    maxSum.nextNode.prevNode = maxSum.prevNode;
                    maxSum.nextNode.left1Count += maxSum.my0Count + maxSum.left1Count;
                    if (max1Count < maxSum.nextNode.left1Count)
                    {
                        max1Count = maxSum.nextNode.left1Count;
                    }
                    maxSum.nextNode.sum1 += maxSum.my0Count + maxSum.left1Count;
                    treap.Insert(maxSum.nextNode);
                }
            }

            int ans;
            if (nodeCount == 0)
            {
                ans = n;
            }
            else
            {
                ans = max1Count;
            }

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

        class Treap<T> where T : IComparable
        {
            private class Node
            {
                private static Random g_rand = new Random();
                private readonly int m_rank = g_rand.Next();
                private readonly T m_value;
                private Node m_lch;
                private Node m_rch;
                private int m_count;

                public Node(T value)
                {
                    m_value = value;
                    m_count = 1;
                }

                public /*private*/ static int Count(Node node)
                {
                    return (node != null) ? node.m_count : 0;
                }

                private Node Update()
                {
                    m_count = Count(m_lch) + Count(m_rch) + 1;
                    return this;
                }

                public static Node Merge(Node a, Node b)
                {
                    if (a == null) { return b; }
                    if (b == null) { return a; }
                    //a.Update();
                    //b.Update();
                    if (a.m_rank < b.m_rank)
                    {
                        a.m_rch = Merge(a.m_rch, b);
                        return a.Update();
                    }
                    else
                    {
                        b.m_lch = Merge(a, b.m_lch);
                        return b.Update();
                    }
                }

                public static Tuple<Node, Node> Split(Node t, int k)
                {
                    if (t == null) { return new Tuple<Node, Node>(null, null); }
                    //t.Update();
                    if (k <= Count(t.m_lch))
                    {
                        var pair = Split(t.m_lch, k);
                        t.m_lch = pair.Item2;
                        return new Tuple<Node, Node>(pair.Item1, t.Update());
                    }
                    else
                    {
                        var pair = Split(t.m_rch, k - Count(t.m_lch) - 1);
                        t.m_rch = pair.Item1;
                        return new Tuple<Node, Node>(t.Update(), pair.Item2);
                    }
                }

                public int FindIndex(T value)
                {
                    int L = Count(m_lch);
                    if (value.CompareTo(m_value) < 0)
                    {
                        return (m_lch != null) ? m_lch.FindIndex(value) : 0;
                    }
                    else if (value.CompareTo(m_value) > 0)
                    {
                        return (m_rch != null) ? m_rch.FindIndex(value) + L + 1 : L + 1;
                    }
                    else
                    {
                        return L;
                    }
                }
#if false
                public int FindIndexPerfect(T value)
                {
                    int L = Count(m_lch);
                    if (value.CompareTo(m_value) < 0)
                    {
                        return (m_lch != null) ? m_lch.FindIndex(value) : -1;
                    }
                    else if (value.CompareTo(m_value) > 0)
                    {
                        return (m_rch != null) ? m_rch.FindIndex(value) + L + 1 : -1;
                    }
                    else
                    {
                        return L;
                    }
                }
#endif
                public T this[int i]
                {
                    get
                    {
                        int L = Count(m_lch);
                        if (i < L)
                        {
                            return m_lch[i];
                        }
                        else if (i > L)
                        {
                            return m_rch[i - L - 1];
                        }
                        else
                        {
                            return m_value;
                        }
                    }
                }
            }

            private Node node;

            public void Insert(T value)
            {
                if (node != null)
                {
                    int k = node.FindIndex(value);
                    var pair = Node.Split(node, k);
                    node = Node.Merge(Node.Merge(pair.Item1, new Node(value)), pair.Item2);
                }
                else
                {
                    node = new Node(value);
                }
            }

            public void Erase(T value)
            {
                if (node != null)
                {
                    int k = node.FindIndex(value);
#if false
#if true
                    if (node[k].CompareTo(value) != 0)
                    {
                        return;
                    }
#endif
                    if (k == 0)
                    {
                    }
                    if (k == Count() - 1)
                    {
                    }
#endif
                    var pair = Node.Split(node, k);
                    var pair2 = Node.Split(pair.Item2, 1);
                    node = Node.Merge(pair.Item1, pair2.Item2);
                }
            }

            public int Count()
            {
                return Node.Count(node);
            }

            public int FindIndex(T value)
            {
                return node.FindIndex(value);
            }

            public T this[int i]
            {
                get
                {
                    return node[i];
                }
            }
        }
    }
}