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;
using System.Diagnostics;

public class Program
{
    public static readonly int Mod = 1000000007;

    public static void Main(string[] args)
    {
        int N = Scanner.Int;
        int K = Scanner.Int;
        string S = Scanner.String;
        bool[] isReverseMan = new bool[N + 1];
        foreach(int i in Enumerable.Range(0, N))
        {
            isReverseMan[i] = S[i] == '1';
        }
        isReverseMan[N] = true;

        int start = 0;
        int end = 0;
        int cnt = 0;
        int max = 0;
        bool beforeReverse = true;
        foreach(int i in Enumerable.Range(0, N))
        {
            if(!isReverseMan[i] && isReverseMan[i + 1])
            {
                cnt++;
            }

            if(cnt > K)
            {
                cnt--;

                bool a = false;
                foreach(int j in Enumerable.Range(start, N - start))
                {
                    if (!isReverseMan[j]) a = true;
                    if(isReverseMan[j] && a)
                    {
                        start = j;
                        break;
                    }
                }
            }

            beforeReverse = isReverseMan[i];

            F.ChMax(ref max, i - start + 1);
        }

        Console.WriteLine(max);
        Console.ReadLine();
    }
}

/// <summary>
/// スキャナ
/// </summary>
public static class Scanner
{
    public static char[] separator = new char[] { ' ' };

    private static IEnumerator<string> enumerator = Enumerator();
    private static IEnumerator<string> Enumerator()
    {
        while (true)
        {
            foreach (string s in Console.ReadLine().Split(separator))
            {
                yield return s;
            }
        }
    }

    public static IEnumerable<string> StringLine
    {
        get
        {
            return Console.ReadLine().Split(separator);
        }
    }
    public static IEnumerable<int> IntLine
    {
        get
        {
            return StringLine.Select(int.Parse);
        }
    }
    public static IEnumerable<long> LongLine
    {
        get
        {
            return StringLine.Select(long.Parse);
        }
    }
    public static IEnumerable<double> DoubleLine
    {
        get
        {
            return StringLine.Select(double.Parse);
        }
    }
    public static IEnumerable<char> CharLine
    {
        get
        {
            return StringLine.Select(char.Parse);
        }
    }

    public static string String
    {
        get
        {
            return enumerator.Next();
        }
    }
    public static int Int
    {
        get
        {
            return String.Int();
        }
    }
    public static long Long
    {
        get
        {
            return String.Long();
        }
    }
    public static double Double
    {
        get
        {
            return String.Double();
        }
    }
    public static char Char
    {
        get
        {
            return char.Parse(String);
        }
    }

    public static Tuple<int, int> IntTuple
    {
        get
        {
            return new Tuple<int, int>(Int, Int);
        }
    }

}

/// <summary>
/// Linq拡張
/// </summary>
public static class LinqExtension
{
    /// <summary>
    /// 二分探索
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="self"></param>
    /// <param name="solve"></param>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public static T LeftBinarySearch<T>(this IEnumerable<T> self, Func<T, bool> solve, T min, T max)
    {
        int index = self.LeftBinarySearchIndex(solve);

        return self.Get(index, min, max);
    }

    /// <summary>
    /// 二分探索
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="self"></param>
    /// <param name="solve"></param>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public static T RightBinarySearch<T>(this IEnumerable<T> self, Func<T, bool> solve, T min, T max)
    {
        int index = self.RightBinarySearchIndex(solve);

        return self.Get(index, min, max);
    }

    /// <summary>
    /// <para>二分探索</para>
    /// <para>渡されたラムダ式の条件を満たすものの中で、一番左側のもの(インデックスが小さい)</para>
    /// </summary>
    /// <typeparam name="T">IEnumerable</typeparam>
    /// <param name="solve"></param>
    /// <returns>一番左側のインデックス</returns>
    public static int LeftBinarySearchIndex<T>(this IEnumerable<T> self, Func<T, bool> solve)
    {
        int ng = -1;
        int ok = self.Count();

        while (Math.Abs(ok - ng) > 1)
        {
            int mid = (ok + ng) / 2;

            if (solve(self.ElementAt(mid)))
            {
                ok = mid;
            }
            else
            {
                ng = mid;
            }
        }

        return ok;
    }

    /// <summary>
    /// <para>二分探索</para>
    /// <para>渡されたラムダ式の条件を満たすものの中で、一番右側のもの(インデックスが大きい)</para>
    /// </summary>
    /// <typeparam name="T">IEnumerable</typeparam>
    /// <param name="solve"></param>
    /// <returns>一番右側のインデックス</returns>
    public static int RightBinarySearchIndex<T>(this IEnumerable<T> self, Func<T, bool> solve)
    {
        int ng = self.Count();
        int ok = -1;

        while (Math.Abs(ok - ng) > 1)
        {
            int mid = (ok + ng) / 2;

            if (solve(self.ElementAt(mid)))
            {
                ok = mid;
            }
            else
            {
                ng = mid;
            }
        }

        return ok;
    }

    /// <summary>
    /// OutOfRange対応
    /// </summary>
    /// <typeparam name="T">型T</typeparam>
    /// <param name="self">IEnumerable</param>
    /// <param name="index">対象のインデックス</param>
    /// <param name="min">0未満のインデックスの時</param>
    /// <param name="max">配列のサイズ以上の時</param>
    /// <returns>型Tの値</returns>
    public static T Get<T>(this IEnumerable<T> self, int index, T min, T max)
    {
        if (index < 0) return min;
        if (index >= self.Count()) return max;

        return self.ElementAt(index);
    }

    /// <summary>
    /// リストを埋める
    /// </summary>
    /// <typeparam name="T">型T</typeparam>
    /// <param name="self">リスト</param>
    /// <param name="func">(index) => T</param>
    /// <returns>リストの参照</returns>
    public static IList<T> Fill<T>(this IList<T> self, Func<int, T> func)
    {
        for (int i = 0; i < self.Count; i++)
        {
            self[i] = func(i);
        }

        return self;
    }

    /// <summary>
    /// リストを埋める
    /// </summary>
    /// <typeparam name="T">型T</typeparam>
    /// <param name="self">リスト</param>
    /// <param name="value">型Tの値</param>
    /// <returns>リストの参照</returns>
    public static IList<T> Fill<T>(this IList<T> self, T value)
    {
        for (int i = 0; i < self.Count; i++)
        {
            self[i] = value;
        }

        return self;
    }

    public static T Next<T>(this IEnumerator<T> self)
    {
        self.MoveNext();
        return self.Current;
    }

    public static void Write(this IEnumerable<bool> self)
    {
        StringBuilder sb = new StringBuilder();
        foreach(bool b in self)
        {
            sb.Append(b ? "□" : "■");
        }
        Console.WriteLine(sb.ToString());
    }

    public static U[] SelectArray<T, U>(this IEnumerable<T> self, Func<T, U> func)
    {
        U[] array = new U[self.Count()];

        int i = 0;
        foreach(T t in self)
        {
            array[i] = func(t);
            i++;
        }

        return array;
    }

    public static List<U> SelectList<T, U>(this IEnumerable<T> self, Func<T, U> func)
    {
        List<U> list = new List<U>(self.Count());

        foreach (T t in self)
        {
            list.Add(func(t));
        }

        return list;
    }
}

/// <summary>
/// Int拡張
/// </summary>
public static class IntExtensiton
{
    /// <summary>
    /// 階上
    /// </summary>
    /// <param name="self"></param>
    /// <returns></returns>
    public static long Factorial(this int self)
    {
        if (self == 1) return 1L;
        return self * (self - 1).Factorial();
    }

    /// <summary>
    /// 階上
    /// </summary>
    /// <param name="self"></param>
    /// <returns></returns>
    public static long Factorial(this int self, int c)
    {
        if (c == 0 || self == 1) return 1L;
        return self * Factorial(self - 1, c - 1);
    }

    public static int BitCount(this int bit, int digit = 32)
    {
        int count = 0;
        for (int i = (digit - 1); i >= 0; i--)
        {
            if (bit.GetBit(i)) count++;
        }
        return count;
    }

    public static bool GetBit(this int bit, int digit)
    {
        int mask = (1 << digit);
        return (bit & mask) == mask;
    }

    public static int SetBit(this int bit, int digit)
    {
        return (bit | (1 << digit));
    }

    public static string BitToString(this int bit, int digit = 32)
    {
        StringBuilder sb = new StringBuilder();

        for (int i = (digit - 1); i >= 0; i--)
        {
            sb.Append(bit.GetBit(i) ? "1" : "0");
        }

        return sb.ToString();
    }

    public static bool IsDivisor(this int self, int target)
    {
        return self % target == 0;
    }

    public static IEnumerable<int> Divisors(this int self)
    {
        for (int i = 1; i * i <= self; i++)
        {
            if (self % i == 0)
            {
                yield return i;
                if (i * i != self) yield return self / i;
            }
        }
    }

    public static bool NeighboringBit(this int self, int digit = 32)
    {
        if (digit < 2) return false;
        return Enumerable.Range(0, digit - 1).Where(j => self.GetBit(j) && self.GetBit(j + 1)).Any();
    }
}

/// <summary>
/// Long拡張
/// </summary>
public static class LongExtensition
{
    public static long BitCount(this long bit, int digit = 64)
    {
        long count = 0;
        for (int i = (digit - 1); i >= 0; i--)
        {
            if (bit.GetBit(i)) count++;
        }
        return count;
    }

    public static bool GetBit(this long bit, int digit)
    {
        long mask = (1L << digit);
        return (bit & mask) == mask;
    }

    public static long SetBit(this long bit, int digit)
    {
        return bit | (1L << digit);
    }

    public static string BitToString(this long bit, int digit = 64)
    {
        StringBuilder sb = new StringBuilder();

        for (int i = (digit - 1); i >= 0; i--)
        {
            sb.Append(bit.GetBit(i) ? "1" : "0");
        }

        return sb.ToString();
    }

    public static bool IsDivisor(this long self, int target)
    {
        return self % target == 0;
    }
}

/// <summary>
/// String拡張
/// </summary>
public static class StringExtensiton
{
    public static void Print(this string str) => Console.WriteLine(str);
    public static int Int(this string str) => int.Parse(str);
    public static long Long(this string str) => long.Parse(str);
    public static double Double(this string str) => double.Parse(str);
}

/// <summary>
/// 便利関数
/// </summary>
public static class F
{
    public static bool ChMax<T>(ref T x, T y) where T : IComparable
    {
        if (x.CompareTo(y) < 0)
        {
            x = y;
            return true;
        }
        return false;
    }

    public static void ChMin<T>(ref T x, T y) where T : IComparable
    {
        if (x.CompareTo(y) > 0)
        {
            x = y;
        }
    }

    public static void Swap<T>(ref T x, ref T y)
    {
        T tmp = x;

        x = y;
        y = tmp;
    }
}