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: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TEMPAtCoder2
{
    class Program
    {
        static void Main(string[] args)
        {
            string temp = System.Console.ReadLine();
            string[] temp1 = temp.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            int N = int.Parse(temp1[0]);
            int K = int.Parse(temp1[1]);

            string S = System.Console.ReadLine();

            List<SegmentList> slist = new List<SegmentList>();
            slist.Add(new SegmentList(S));

            //List<SegmentList> slisttmp = new List<SegmentList>();
            for (int i = 0; i < K; ++i)
            {
                List<SegmentList> slisttmp = new List<SegmentList>();
                foreach (var s in slist)
                {
                    slisttmp.AddRange(s.Next());
                }
                int maxnum = 0;
                foreach (var s in slisttmp)
                {
                    if (s.MaxNum > maxnum)
                    {
                        maxnum = s.MaxNum;
                    }
                }
                slist = slisttmp.FindAll(x => x.MaxNum == maxnum).Distinct().ToList();
                //slist.Distinct();
            }


            System.Console.WriteLine(slist.First().MaxNum);
        }

    }

    public class Segment : IEquatable<Segment>
    {
        public int Start { get; set; } = 0;
        public int End { get; set; } = 0;
        public int Num { get; set; } = 0;
        public char Status { get; set; } = '0';

        public Segment()
        {

        }

        public Segment(int start, int end, int num, char status)
        {
            this.Start = start;
            this.End = end;
            this.Num = num;
            this.Status = status;
        }

        public Segment(int start, char status)
        {
            this.Start = start;
            this.Status = status;
        }

        public bool Equals(Segment other)
        {
            //objがnullか、型が違うときは、等価でない
            if (other == null || this.GetType() != other.GetType())
            {
                return false;
            }
            //この型が継承できないクラスや構造体であれば、次のようにできる
            //if (!(obj is TestClass))

            //Numberで比較する
            Segment c = (Segment)other;

            bool flag = true;
            flag &= Start == c.Start;
            flag &= End == c.End;
            flag &= Num == c.Num;
            flag &= Status == c.Status;

            return flag;
        }

        //Equalsがtrueを返すときに同じ値を返す
        public override int GetHashCode()
        {           
            return Start + End + Num + Status;
        }
    }

    public class SegmentList : IEquatable<SegmentList>
    {
        public List<Segment> Segments { get; set; } = new List<Segment>();
        public int MaxNum { get; set; } = 0;
        public bool AlreadyFull { get; set; } = false;

        public SegmentList()
        {

        }

        public SegmentList(string s)
        {
            Segment segment = new Segment();
            int maxnum = 0;
            for(int i = 0; i < s.Length; ++i)
            {
                if(i == 0)
                {
                    segment = new Segment(0, s[i]);
                    if(s.Length == 1)
                    {
                        segment.End = i;
                        segment.Num = 1;
                        this.Segments.Add(segment);
                        if(maxnum < segment.Num && segment.Status == '1')
                        {
                            maxnum = segment.Num;
                        }
                    }
                    //segment.Start = 0;
                    //segment.Status = s[i];
                }
                else if(i == s.Length - 1)
                {
                    if (segment.Status == s[i])
                    {
                        segment.End = i ;
                        segment.Num = i - segment.Start + 1;
                        this.Segments.Add(segment);
                        if(maxnum < segment.Num && segment.Status == '1')
                        {
                            maxnum = segment.Num;
                        }
                    }
                    else
                    {
                        segment.End = i - 1;
                        segment.Num = i - segment.Start;
                        this.Segments.Add(segment);
                        if (maxnum < segment.Num && segment.Status == '1')
                        {
                            maxnum = segment.Num;
                        }
                        segment = new Segment(i, s[i]);
                        segment.End = i;
                        segment.Num = 1;
                        this.Segments.Add(segment);
                        if (maxnum < segment.Num && segment.Status == '1')
                        {
                            maxnum = segment.Num;
                        }
                    }
                }
                else
                {
                    if(segment.Status == s[i])
                    {
                    }
                    else
                    {
                        segment.End = i - 1;
                        segment.Num = i - segment.Start;
                        this.Segments.Add(segment);
                        if (maxnum < segment.Num && segment.Status == '1')
                        {
                            maxnum = segment.Num;
                        }
                        segment = new Segment(i, s[i]);
                    }
                }
                MaxNum = maxnum;
            }
        }

        public SegmentList(List<Segment> segments, int maxnum)
        {
            this.Segments = new List<Segment>(segments);
            this.MaxNum = maxnum;
        }

        public List<SegmentList> Next()
        {
            List<Segment> segments  = new List<Segment>(Segments);
            List<SegmentList> segmentlists = new List<SegmentList>();

            //Already full
            if(Segments.Count == 1 && Segments.ElementAt(0).Status == '1')
            {
                var temp = new SegmentList(Segments, MaxNum);
                temp.AlreadyFull = true;
                segmentlists.Add(temp);

                return segmentlists;
            }

            List<int> indexies = new List<int>(1);
            int maxinvcnt = 0;
            for (int i = 0; i < Segments.Count; ++i)
            {
                if (i == 0)
                {
                    if(segments.ElementAt(i).Status == '0')
                    {
                        if (maxinvcnt <= segments.ElementAt(i).Num + segments.ElementAt(i + 1).Num)
                        {
                            maxinvcnt = segments.ElementAt(i).Num + segments.ElementAt(i + 1).Num;
                            indexies = new List<int>();
                            indexies.Add(i);
                        }
                    }
                }
                else if (i == Segments.Count - 1)
                {
                    if (segments.ElementAt(i).Status == '0')
                    {
                        if (maxinvcnt < segments.ElementAt(i - 1).Num + segments.ElementAt(i).Num )
                        {
                            maxinvcnt = segments.ElementAt(i - 1).Num + segments.ElementAt(i).Num ;
                            indexies = new List<int>();
                            indexies.Add(i);
                        }
                        else if(maxinvcnt == segments.ElementAt(i - 1).Num + segments.ElementAt(i).Num)
                        {
                            indexies.Add(i);
                        }
                    }
                }
                else
                {
                    if (segments.ElementAt(i).Status == '0')
                    {
                        if (maxinvcnt < segments.ElementAt(i-1).Num + segments.ElementAt(i).Num + segments.ElementAt(i+1).Num)
                        {
                            maxinvcnt = segments.ElementAt(i - 1).Num + segments.ElementAt(i).Num + segments.ElementAt(i + 1).Num;
                            indexies = new List<int>();
                            indexies.Add(i);
                        }
                        else if (maxinvcnt == segments.ElementAt(i - 1).Num + segments.ElementAt(i).Num + segments.ElementAt(i + 1).Num)
                        {
                            indexies.Add(i);
                        }
                    }
                }
            }

            foreach (var index in indexies)
            {
                //generate next
                if (index == 0)
                {
                    if (Segments.Count > 1)
                    {
                        Segment seg = new Segment(index, Segments.ElementAt(index + 1).End, Segments.ElementAt(index).Num + Segments.ElementAt(index + 1).Num, '1');
                        Segments.RemoveRange(index, 2);
                        Segments.Insert(index, seg);
                        int maxnum = MaxNum < seg.Num ? seg.Num : MaxNum;
                        segmentlists.Add(new SegmentList(Segments, maxnum));
                    }
                    else
                    {
                        Segments.ElementAt(index).Status = '1';
                        int maxnum = MaxNum ;
                        segmentlists.Add(new SegmentList(Segments, MaxNum));
                    }
                }
                else if (index == Segments.Count - 1)
                {
                    if (Segments.Count > 1)
                    {
                        Segment seg = new Segment(Segments.ElementAt(index - 1).Start, Segments.ElementAt(index).End, Segments.ElementAt(index - 1).Num + Segments.ElementAt(index).Num, '1');
                        Segments.RemoveRange(index - 1, 2);
                        Segments.Insert(index - 1, seg);
                        int maxnum = MaxNum < seg.Num ? seg.Num : MaxNum;
                        segmentlists.Add(new SegmentList(Segments, maxnum));
                    }
                    else
                    {
                        Segments.ElementAt(index).Status = '1';
                        int maxnum = MaxNum;
                        segmentlists.Add(new SegmentList(Segments, MaxNum));
                    }
                }
                else
                {
                    if (Segments.Count > 2)
                    {
                        Segment seg = new Segment(Segments.ElementAt(index - 1).Start, Segments.ElementAt(index + 1).End, Segments.ElementAt(index - 1).Num + Segments.ElementAt(index).Num + Segments.ElementAt(index + 1).Num, '1');
                        Segments.RemoveRange(index - 1, 3);
                        Segments.Insert(index - 1, seg);
                        int maxnum = MaxNum < seg.Num ? seg.Num : MaxNum;
                        segmentlists.Add(new SegmentList(Segments, maxnum));
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
            }

            return segmentlists;
        }

        public bool Equals(SegmentList other)
        {
            //objがnullか、型が違うときは、等価でない
            if (other == null || this.GetType() != other.GetType())
            {
                return false;
            }
            //この型が継承できないクラスや構造体であれば、次のようにできる
            //if (!(obj is TestClass))

            //Numberで比較する
            SegmentList c = (SegmentList)other;

            bool flag = true;
            flag &= MaxNum == c.MaxNum;
            flag &= AlreadyFull == c.AlreadyFull;
            flag &= this.Segments.Count == c.Segments.Count;
            if (flag == false)
            {
                return false;
            }
            for(int i = 0; i < this.Segments.Count; ++i)
            {
                if (!this.Segments.ElementAt(i).Equals(c.Segments.ElementAt(i)))
                {
                    flag = false;
                    break;
                }
            }

            return flag;
            //または、
            //return (this.Number.Equals(c.Number))
        }


        //Equalsがtrueを返すときに同じ値を返す
        public override int GetHashCode()
        {
            int t = AlreadyFull ? 1024 : 256;
            int x = 0;
            Segments.ForEach(y => x += y.Num + y.Start + y.End + y.Status);
            return this.MaxNum +  t + x;
        }
    }
}