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

namespace Codeforces9_AnatolyAndCockroaches {
    class Program {
        static void Main( string[] args ) {
            //In one turn he can either swap any two cockroaches, or take any single cockroach and change it's color.
            int inputLength = int.Parse( Console.ReadLine() );
            string inputValue = Console.ReadLine();
            char[] chars = inputValue.ToCharArray();
            if ( chars.Length != inputLength ) {
                InputWrong();
                return;
            }

            Console.WriteLine( Math.Min( GetCount( 'r', chars ), GetCount( 'b', chars ) ) );
            Console.Read();
        }

        private static int GetCount( char headChar, char[] chars ) {
            int rCount = 0;
            int bCount = 0;
            for ( int i = 0; i < chars.Length; ++i ) {
                if ( chars[i] != ( i % 2 == 0 ? headChar : ( headChar == 'r' ? 'b' : 'r' ) ) ) {
                    if ( chars[i] == 'r' )
                        rCount++;
                    else bCount++;
                }
            }

            return rCount > bCount ? rCount : bCount;
        }

        private static void InputWrong() {
            Console.WriteLine( "input wrong!" );
            Console.Read();
        }
    }
}


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

namespace Codeforces9_AnatolyAndCockroaches {
    class Program {
        static void Main( string[] args ) {
            //In one turn he can either swap any two cockroaches, or take any single cockroach and change it's color.
            int inputLength = int.Parse( Console.ReadLine() );
            string inputValue = Console.ReadLine();
            char[] chars = inputValue.ToCharArray();
            if ( chars.Length != inputLength ) {
                InputWrong();
                return;
            }

            Console.WriteLine( Math.Min( GetCount( 'r', chars ), GetCount( 'b', chars ) ) );
            Console.Read();
        }

        private static int GetCount( char headChar, char[] chars ) {
            int rCount = 0;
            int bCount = 0;
            char temp = headChar;
            for ( int i = 0; i < chars.Length; ++i ) {
                if ( chars[i] != temp ) {
                    if ( temp == 'r' ) rCount++;
                    else bCount++;
                }
                temp = temp == 'r' ? 'b' : 'r';
            }

            return rCount > bCount ? rCount : bCount;
        }

        private static void InputWrong() {
            Console.WriteLine( "input wrong!" );
            Console.Read();
        }
    }
}


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

namespace Codeforces9_AnatolyAndCockroaches {
    class Program {
        static void Main( string[] args ) {
            //In one turn he can either swap any two cockroaches, or take any single cockroach and change it's color.
            int charsLength = int.Parse( Console.ReadLine() );
            string inputValue = Console.ReadLine();
            char[] chars = inputValue.ToCharArray();
            if ( chars.Length != charsLength ) {
                InputWrong();
                return;
            }

            Console.WriteLine( Math.Min( GetTurnCount( 'r', chars ), GetTurnCount( 'b', chars ) ) );
            Console.Read();
        }

        private static int GetTurnCount( char headChar, char[] chars ) {
            int rCount = 0;
            int bCount = 0;
            for ( int i = 0; i < chars.Length; ++i ) {
                if ( chars[i] != ( i % 2 == 0 ? headChar : ( headChar == 'r' ? 'b' : 'r' ) ) ) {
                    if ( chars[i] == 'r' ) rCount++;
                    else bCount++;
                }
            }
            return rCount > bCount ? rCount : bCount;
        }

        private static void InputWrong() {
            Console.WriteLine( "input wrong!" );
            Console.Read();
        }
    }
}


#[allow(unused_imports)]
use std::io;
use std::cmp::{min, max};
use std::mem;
use std::str::FromStr;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

pub struct Scanner<B> {
    reader: B,
    buffer: Vec<String>,
}

impl<B: io::BufRead> Scanner<B> {
    pub fn new(reader: B) -> Scanner<B> {
        Scanner {
            reader: reader,
            buffer: Vec::new(),
        }
    }

    /// Use "turbofish" syntax next::<T>() to select data type of next token.
    pub fn next<T: ::std::str::FromStr>(&mut self) -> T
        where
            T::Err: ::std::fmt::Debug,
    {
        if let Some(front) = self.buffer.pop() {
            front.parse::<T>().expect(&front)
        } else {
            let mut input = String::new();
            self.reader.read_line(&mut input).expect("Line not read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
            self.next()
        }
    }

    pub fn next_vec<T: ::std::str::FromStr>(&mut self, len: usize) -> Vec<T>
        where
            T::Err: ::std::fmt::Debug,
    {
        (0..len).map(|_| self.next::<T>()).collect::<Vec<T>>()
    }
}

fn main1() {
    let stdin = io::stdin();
    let mut input = Scanner::new(stdin.lock());
    let n = input.next::<usize>();
    let s = input.next::<String>();
    let mut bToRWithBStart = 0;
    let mut rToBWithBStart = 0;
    let mut bToRWithRStart = 0;
    let mut rToBWithRStart = 0;
    for (index, val) in s.chars().enumerate() {
        if index % 2 == 0 {
            if val == 'b' {
                bToRWithRStart += 1;
            } else {
                rToBWithBStart += 1;
            }
        } else {
            if val == 'b' {
                bToRWithBStart += 1;
            } else {
                rToBWithRStart += 1;
            }
        }
    }
    let answer = min(max(bToRWithBStart, rToBWithBStart), max(bToRWithRStart, rToBWithRStart));
    println!("{}", answer);
}

fn main() {
    std::thread::Builder::new().stack_size(50 << 20)
        .spawn(main1).unwrap().join().unwrap();
}


#[allow(unused_imports)]
use std::cmp::{min, max};

const RED: isize = 0;
const BLACK: isize = 1;

fn main(){
    let n: i64 = readln();
    let cs: Vec<char> = get_line().chars().collect();

    let mut res = 0;
    let mut red = 0;
    let mut black = 0;
    let mut next = RED;
    for &c in &cs{
        if next == RED && c == 'b' {
            if red > 0 {
                red = red - 1;
            } else {
                res += 1;
                black += 1;
            }
        }

        if next == BLACK && c == 'r' {
            if black > 0 {
                black = black - 1;
            } else {
                res += 1;
                red += 1;
            }
        }

        next = 1 - next
    }

    let mut resR = res;

    res = 0;
    red = 0;
    black = 0;
    next = BLACK;
    for &c in &cs{
        if next == RED && c == 'b' {
            if red > 0 {
                red = red - 1;
            } else {
                res += 1;
                black += 1;
            }
        }

        if next == BLACK && c == 'r' {
            if black > 0 {
                black = black - 1;
            } else {
                res += 1;
                red += 1;
            }
        }

        next = 1 - next
    }

    let mut resB = res;

    println!("{}", min(resR, resB));

}

#[allow(dead_code)]
fn get_line() -> String{
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_string()
}

#[allow(dead_code)]
fn readln<T: Read>() -> T{
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    T::read(buf.trim_right())
}

trait Read{
    fn read(s: &str) -> Self;
}

macro_rules! read_impl{
    ($($t:ty)*) => ($(
        impl Read for $t {
            fn read(s: &str) -> $t{
                s.parse().unwrap()
            }
        }
    )*)
}
read_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

impl<T: Read> Read for Vec<T>{
    fn read(s: &str) -> Self {
        s.split_whitespace().map(T::read).collect()
    }
}

impl<A: Read, B: Read> Read for (A, B){
    fn read(s: &str) -> Self {
        let tokens: Vec<_> = s.split_whitespace().collect();
        (A::read(tokens[0]), B::read(tokens[1]))
    }
}

impl<A: Read, B: Read, C: Read> Read for (A, B, C){
    fn read(s: &str) -> Self {
        let tokens: Vec<_> = s.split_whitespace().collect();
        (A::read(tokens[0]), B::read(tokens[1]), C::read(tokens[2]))
    }
}


// Author: Xu Zhao (i@xuzhao.net)
// Date: Nov 25, 2016

//! Codeforces 719B
use std::cmp;
use std::io::stdin;
use std::str::Chars;

fn get_type(first: char, index: usize) -> char {
  if first == 'r' { // first is 'r'
    if index % 2 == 1 {
      'b'
    } else {
      'r'
    }
  } else {
    if index % 2 == 1 {
      'r'
    } else {
      'b'
    }
  }
}

fn solve(cs: &Vec<char>, start: char) -> i32 {
  let mut should_r_but_b = 0;
  let mut should_b_but_r = 0;
  let mut index = 0;
  loop {
    if index == cs.len() {
      break;
    }
    let should_char = get_type(start, index);
    if cs[index] == 'r' && should_char == 'b' {
      should_b_but_r += 1;
    }
    if cs[index] == 'b' && should_char == 'r' {
      should_r_but_b += 1;
    }
    index += 1;
  }
  let ret = cmp::max(should_r_but_b, should_b_but_r);
  ret
}

fn main() {
  let stdin = stdin();
  let mut first_line = String::new();
  stdin.read_line(&mut first_line);
  let cnt = first_line.trim().parse::<i32>().ok();
  let mut cur = String::new();
  stdin.read_line(&mut cur);
  let mut cs: Vec<char> = cur.chars().collect::<Vec<char>>();
  let mut left_index = 0;
  let mut right_index = cur.len() - 1;
  let step1 = solve(&cs, 'r');
  let step2 = solve(&cs, 'b');
  let x = cmp::min(step1, step2);
  println!("{}", x);
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func I(t interface{}, delim string) {
	fmt.Fscanf(r, "%v"+delim, t)
}

func O(o interface{}, delim string) {
	fmt.Fprintf(w, "%v"+delim, o)
}

var r *bufio.Reader
var w *bufio.Writer

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func abs(a int) int {
	if a > 0 {
		return a
	}
	return -a
}

func main() {
	r = bufio.NewReader(os.Stdin)
	w = bufio.NewWriter(os.Stdout)
	defer w.Flush()

	var a, b, ra, ba, rb, bb, n int

	I(&n, "\n")
	var s string
	I(&s, "\n")
	for i := 0; i < n; i++ {
		if (s[i] != 'r' && i%2 == 0) || (s[i] != 'b' && i%2 == 1) {
			if s[i] == 'r' {
				ra++
			} else {
				ba++
			}
		}
		if (s[i] != 'b' && i%2 == 0) || (s[i] != 'r' && i%2 == 1) {
			if s[i] == 'r' {
				rb++
			} else {
				bb++
			}
		}
	}
	a = abs(ra-ba) + min(ra, ba)
	b = abs(rb-bb) + min(rb, bb)
	O(min(a, b), "\n")
}


package main

import "fmt"
import "bufio"
import "os"

var bufin *bufio.Reader
var bufout *bufio.Writer

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func cost(from int, to int) int {
	if from == to {
		return 0
	}
	return 1
}

func main() {
	bufin = bufio.NewReader(os.Stdin)
	bufout = bufio.NewWriter(os.Stdout)
	defer bufout.Flush()

	var n int
	fmt.Fscanf(bufin, "%d\n", &n)

	a := make([]byte, n)
	fmt.Fscanf(bufin, "%s\n", &a)

	c := make([]int, n+1)
	for i := 0; i < n; i++ {
		if a[i] == 'r' {
			c[i+1] = 0
		} else {
			c[i+1] = 1
		}
	}

	f := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		f[i] = make([]int, 2)
		f[i][0] = n
		f[i][1] = n
	}
	f[0][0] = 0
	f[0][1] = 0

	for i := 1; i <= n; i++ {
		for j := 0; j < 2; j++ {
			f[i][j] = min(f[i][j], f[i-1][1-j]+cost(c[i], j))
			if i >= 2 {
				f[i][j] = min(f[i][j], f[i-2][j]+cost(c[i-1], j)+cost(c[i], 1-j)+1)
				f[i][j] = min(f[i][j], f[i-1][j]+cost(c[i], 1-j)+1)
			}
		}
	}

	res := min(f[n][0], f[n][1])
	fmt.Fprintf(bufout, "%d\n", res)
}


package main

import "fmt"
import "bufio"
import "os"

var bufin *bufio.Reader
var bufout *bufio.Writer

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func cost(from int, to int) int {
	if from == to {
		return 0
	}
	return 1
}

func main() {
	bufin = bufio.NewReader(os.Stdin)
	bufout = bufio.NewWriter(os.Stdout)
	defer bufout.Flush()

	var n int
	fmt.Fscanf(bufin, "%d\n", &n)

	a := make([]byte, n)
	fmt.Fscanf(bufin, "%s\n", &a)

	c := make([]int, n+1)
	for i := 0; i < n; i++ {
		if a[i] == 'r' {
			c[i+1] = 0
		} else {
			c[i+1] = 1
		}
	}

	f := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		f[i] = make([]int, 2)
		f[i][0] = n
		f[i][1] = n
	}
	f[0][0] = 0
	f[0][1] = 0

	for i := 1; i <= n; i++ {
		for j := 0; j < 2; j++ {
			f[i][j] = min(f[i][j], f[i-1][1-j]+cost(c[i], j))
			if (i >= 2) && (c[i-1] == j) && (c[i] == 1-j) {
				f[i][j] = min(f[i][j], f[i-2][j]+1)
			}
		}
	}

	res := min(f[n][0], f[n][1])
	fmt.Fprintf(bufout, "%d\n", res)
}


package main

import "fmt"
import "bufio"
import "os"

var bufin *bufio.Reader
var bufout *bufio.Writer

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func cost(c []int, n int, color int) int {
	diff := make([]int, 2)
	for i := 0; i < n; i++ {
		if c[i] != color {
			diff[c[i]]++
		}
		color = 1 - color
	}

	ret := min(diff[0], diff[1])
	return ret + diff[0] - ret + diff[1] - ret
}

func main() {
	bufin = bufio.NewReader(os.Stdin)
	bufout = bufio.NewWriter(os.Stdout)
	defer bufout.Flush()

	var n int
	fmt.Fscanf(bufin, "%d\n", &n)

	a := make([]byte, n)
	fmt.Fscanf(bufin, "%s\n", &a)

	c := make([]int, n)
	for i := 0; i < n; i++ {
		if a[i] == 'r' {
			c[i] = 0
		} else {
			c[i] = 1
		}
	}

	res := n
	for color := 0; color < 2; color++ {
		res = min(res, cost(c, n, color))
	}

	fmt.Fprintf(bufout, "%d\n", res)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func abs(a int) int {
	if a < 0 {return -a}
	return a
}

func max(a, b int) int {
	if a > b {return a}
	return b
}

func min(a, b int) int {
	if a < b {return a}
	return b
}

func main() {
	var n int

	input := bufio.NewReader(os.Stdin)
	fmt.Fscanln(input, &n)

	if n == 1 {
		fmt.Println(0)
		return
	}

	even := make(map[rune]int)
	odd := make(map[rune]int)

	for i := 0; i < n; i++ {
		var t rune
		fmt.Fscanf(input, "%c", &t)
		if i % 2 == 0 {
			even[t]++
		} else {
			odd[t]++
		}

	}

	x1, x2 := even['b'] - odd['r'], odd['b'] - even['r']
	y1, y2 := even['r'] - odd['b'], odd['r'] - even['b']

	ans, ansy := 0, 0
	if (x1 <= 0 && x2 <= 0) || (x1 >= 0 && x2 >= 0) {
		ans = (x1 + x2) / 2
	} else {
		ans = min(abs(x1), abs(x2)) + (abs(x1 + x2) / 2)

	}

	if (y1 <= 0 && y2 <= 0) || (y1 >= 0 && y2 >= 0) {
		ansy = (y1 + y2) / 2
	} else {
		ansy = min(abs(y1), abs(y2)) + (abs(y1 + y2) / 2)

	}

	if ans < ansy {
		fmt.Println(ans)
	} else {
		fmt.Println(ansy)
	}

}


// http://codeforces.com/problemset/problem/719/B
package main

import (
	"bufio"
	"fmt"
	"os"
)

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	var n int

	input := bufio.NewReader(os.Stdin)
	fmt.Fscanln(input, &n)

	if n == 1 {
		fmt.Println(0)
		return
	}

	even := make(map[rune]int)
	odd := make(map[rune]int)

	for i := 0; i < n; i++ {
		var t rune
		fmt.Fscanf(input, "%c", &t)
		if i % 2 == 0 {
			even[t]++
		} else {
			odd[t]++
		}
	}

	// Solve
	// b - odd, r - even
	swaps := min(even['b'], odd['r'])
	y := max(even['b'], odd['r'])
	p1 := swaps + (y - swaps)

	// b - even, r - odd
	swaps = min(even['r'], odd['b'])
	y = max(even['r'], odd['b'])
	p2 := swaps + (y - swaps)

	fmt.Println(min(p1, p2))
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)
	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		moves := [2]int{}
		l := [2][]int{make([]int, n), make([]int, n)}

		for i, c := range s {
			if c == 'r' {
				l[0][i] = 1
				l[1][i] = 1
			} else if c == 'b' {
				l[0][i] = 0
				l[1][i] = 0
			}
		}

		no_disorder := [2][2]bool{}
		for i := 0; i < n; i++ {
			for j := 0; j < 2; j++ {
				if l[j][i] != (i+j)%2 {
					moves[j] += 1
					swap := false
					if !no_disorder[j][(i+1)%2] {
						for k := i + 1; k < n; k += 2 { // Swap with k
							if l[j][k] != (k+j)%2 {
								l[j][i], l[j][k] = l[j][k], l[j][i]
								swap = true
								break
							}
						}
					}
					if !swap { // Change color
						no_disorder[j][(i+1)%2] = true
						l[j][i] = (i + j) % 2
					}
				}
			}
		}

		if moves[0] < moves[1] {
			fmt.Println(moves[0])
		} else {
			fmt.Println(moves[1])
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)
	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		moves := [2]int{}
		l := [2][]int{make([]int, n), make([]int, n)}

		for i, c := range s {
			if c == 'r' {
				l[0][i] = 1
				l[1][i] = 1
			} else if c == 'b' {
				l[0][i] = 0
				l[1][i] = 0
			}
		}

		for j := 0; j < 2; j++ {
			for i := 0; i < n; i++ {
				if l[j][i] != (i+j)%2 {
					moves[j] += 1
					swap := false
					for k := i + 1; k < n; k++ {
						if l[j][k] != (k+j)%2 {
							l[j][i], l[j][k] = l[j][k], l[j][i]
							swap = true
							break
						}
					}
					if !swap { // Change color
						l[j][i] = (i + j) % 2
					}
				}
			}
		}

		if moves[0] < moves[1] {
			fmt.Println(moves[0])
		} else {
			fmt.Println(moves[1])
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)
	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		moves := [2]int{}
		l := [2][]int{make([]int, n), make([]int, n)}

		for i, c := range s {
			if c == 'r' {
				l[0][i] = 1
				l[1][i] = 1
			} else if c == 'b' {
				l[0][i] = 0
				l[1][i] = 0
			}
		}

		for j := 0; j < 2; j++ {
			for i := 0; i < n; i++ {
				if l[j][i] != (i+j)%2 {
					moves[j] += 1
					swap := false
					for k := i + 1; k < n; k += 2 {
						if l[j][k] != (k+j)%2 {
							l[j][i], l[j][k] = l[j][k], l[j][i]
							swap = true
							break
						}
					}
					if !swap { // Change color
						l[j][i] = (i + j) % 2
					}
				}
			}
		}

		if moves[0] < moves[1] {
			fmt.Println(moves[0])
		} else {
			fmt.Println(moves[1])
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)
	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		moves := [2]int{}
		l := [2][]int{make([]int, n), make([]int, n)}

		for i, c := range s {
			if c == 'r' {
				l[0][i] = 1
				l[1][i] = 1
			} else if c == 'b' {
				l[0][i] = 0
				l[1][i] = 0
			}
		}

		disorder_start := [2][2]int{}
		for i := 0; i < n; i++ {
			for j := 0; j < 2; j++ {
				if l[j][i] != (i+j)%2 {
					moves[j] += 1
					swap := false
					if disorder_start[j][(i+1)%2] < n {
						for k := max(disorder_start[j][(i+1)%2], i+1); k < n; k += 2 { // Swap with k
							if l[j][k] != (k+j)%2 {
								l[j][i], l[j][k] = l[j][k], l[j][i]
								swap = true
								for f := k + 2; f < n; f += 2 {
									if l[j][f] != (f+j)%2 {
										disorder_start[j][(i+1)%2] = f
										break
									}
								}
								break
							}
						}
					}
					if !swap { // Change color
						disorder_start[j][(i+1)%2] = n
						l[j][i] = (i + j) % 2
					}
				}
			}
		}

		if moves[0] < moves[1] {
			fmt.Println(moves[0])
		} else {
			fmt.Println(moves[1])
		}
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)
	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		moves := [2]int{}
		l := [2][]int{make([]int, n), make([]int, n)}

		for i, c := range s {
			if c == 'r' {
				l[0][i] = 1
				l[1][i] = 1
			} else if c == 'b' {
				l[0][i] = 0
				l[1][i] = 0
			}
		}

		for i := 0; i < n; i++ {
			for j := 0; j < 2; j++ {
				if l[j][i] != (i+j)%2 {
					moves[j] += 1
					if i < n-1 && l[j][i+1] != (i+j+1)%2 { // Swap
						l[j][i], l[j][i+1] = l[j][i+1], l[j][i]
					} else { // Change color
						l[j][i] = (i + j) % 2
					}
				}
			}
		}

		if moves[0] < moves[1] {
			fmt.Println(moves[0])
		} else {
			fmt.Println(moves[1])
		}
	}
}


<?php

###### IO ######
error_reporting(E_ALL);
error_reporting(0);

function readString($f) {
	$r = array(
		"\r" => '',
		"\n" => '',
	);
	return strtr(fgets($f), $r);
}

function readNumString($f) {
	return trim(fgets($f));
}

function stringToArray($str) {
	return str_split($str);
}

function readNum($f, $is_int = false) {
	$v = readNumString($f);
	return $is_int ? intval($v) : floatval($v);
}

function readStringExplode($f, $delimiter = ' ') {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = 'trim';
	return array_map($callf, $return);
}

function readStringExplodeNum($f, $delimiter = ' ', $is_int = false) {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = $is_int ? 'intval' : 'floatval';
	return array_map($callf, $return);
}

###### /IO ######

function getAnswer($is_test = false, $f = false) {
	if ($is_test === false) {
		$f = STDIN;
	}
	/* begin body */
	readNum($f);
	$path = trim(readString($f));
	$n = strlen($path);

	$b = $r = array(0,0);
	for ($i = 0; $i < $n; $i++) {
		if ($path[$i] == 'r') {
			$r[$i % 2] ++;
		} else {
			$b[$i % 2] ++;
		}
	}
	echo min(max($r[0], $b[1]), max($r[1], $b[0]));
	/* / end body */
}

if (empty($is_test))
	getAnswer();


<?php

###### IO ######
error_reporting(E_ALL);
#error_reporting(0);

function readString($f) {
	$r = array(
		"\r" => '',
		"\n" => '',
	);
	return strtr(fgets($f), $r);
}

function readNumString($f) {
	return trim(fgets($f));
}

function stringToArray($str) {
	return str_split($str);
}

function readNum($f, $is_int = false) {
	$v = readNumString($f);
	return $is_int ? intval($v) : floatval($v);
}

function readStringExplode($f, $delimiter = ' ') {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = 'trim';
	return array_map($callf, $return);
}

function readStringExplodeNum($f, $delimiter = ' ', $is_int = false) {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = $is_int ? 'intval' : 'floatval';
	return array_map($callf, $return);
}

###### /IO ######

function getAnswer($is_test = false, $f = false) {
	if ($is_test === false) {
		$f = STDIN;
	}
	/* begin body */
	$n = readNum($f);
	$path = trim(readString($f));

	$actionCount = 0;
	for ($i = 1; $i < $n; $i++) {
		if ($path[$i] != $path[$i - 1]) {
			continue;
		}
		$doublePos = false;
		for ($j = $i + 2; $j < $n; $j++) {
			if ($path[$i] != $path[$j] && $path[$j] == $path[$j - 1]) {
				$doublePos = $j - 1;
				break;
			}
		}
		if ($doublePos !== false) {
			$t = $path[$i];
			$path[$i] = $path[$doublePos];
			$path[$doublePos] = $t;
			$actionCount++;
		} else {
			$actionCount++;
			if ($path[$i] == 'r') {
				$path[$i] = 'b';
			} else {
				$path[$i] = 'r';
			}
		}
	}
	echo $actionCount;
	/* / end body */
}

if (empty($is_test))
	getAnswer();


<?php

###### IO ######
error_reporting(E_ALL);
#error_reporting(0);

function readString($f) {
	$r = array(
		"\r" => '',
		"\n" => '',
	);
	return strtr(fgets($f), $r);
}

function readNumString($f) {
	return trim(fgets($f));
}

function stringToArray($str) {
	return str_split($str);
}

function readNum($f, $is_int = false) {
	$v = readNumString($f);
	return $is_int ? intval($v) : floatval($v);
}

function readStringExplode($f, $delimiter = ' ') {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = 'trim';
	return array_map($callf, $return);
}

function readStringExplodeNum($f, $delimiter = ' ', $is_int = false) {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = $is_int ? 'intval' : 'floatval';
	return array_map($callf, $return);
}

###### /IO ######

function getAnswer($is_test = false, $f = false) {
	if ($is_test === false) {
		$f = STDIN;
	}
	/* begin body */
	readNum($f);
	$path = trim(readString($f));
	$n = strlen($path);

	$actionCount = 0;
	for ($i = 1; $i < $n; $i++) {
		if ($path[$i] != $path[$i - 1]) {
			continue;
		}
		$doublePos = false;
		for ($j = $i + 2; $j < $n; $j++) {
			if ($path[$i] != $path[$j] && $path[$j] == $path[$j - 1]) {
				$doublePos = $j - 1;
				break;
			}
			if ($path[$i] != $path[$j] && $j + 1 == $n) {
				$doublePos = $j;
				break;
			}
		}
		if ($doublePos !== false) {
			$t = $path[$i];
			$path[$i] = $path[$doublePos];
			$path[$doublePos] = $t;
			$actionCount++;
		} else {
			$actionCount++;
			if ($path[$i] == 'r') {
				$path[$i] = 'b';
			} else {
				$path[$i] = 'r';
			}
		}
	}

	echo $actionCount;
	/* / end body */
}

if (empty($is_test))
	getAnswer();


<?php

###### IO ######
error_reporting(E_ALL);
#error_reporting(0);

function readString($f) {
	$r = array(
		"\r" => '',
		"\n" => '',
	);
	return strtr(fgets($f), $r);
}

function readNumString($f) {
	return trim(fgets($f));
}

function stringToArray($str) {
	return str_split($str);
}

function readNum($f, $is_int = false) {
	$v = readNumString($f);
	return $is_int ? intval($v) : floatval($v);
}

function readStringExplode($f, $delimiter = ' ') {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = 'trim';
	return array_map($callf, $return);
}

function readStringExplodeNum($f, $delimiter = ' ', $is_int = false) {
	$v = readNumString($f);
	if ($delimiter == '') {
		$return = stringToArray($v);
	} else {
		$return = explode($delimiter, $v);
	}
	$callf = $is_int ? 'intval' : 'floatval';
	return array_map($callf, $return);
}

###### /IO ######

function getAnswer($is_test = false, $f = false) {
	if ($is_test === false) {
		$f = STDIN;
	}
	/* begin body */
	readNum($f);
	$path = trim(readString($f));
	$n = strlen($path);

	$actionCount = 0;
	for ($i = 1; $i < $n; $i++) {
		if ($path[$i] != $path[$i - 1]) {
			continue;
		}
		$doublePos = false;
		for ($j = $i + 2; $j < $n; $j++) {
			if ($path[$i] != $path[$j] && $path[$j] == $path[$j - 1]) {
				$doublePos = $j - 1;
				break;
			}
		}
		if ($i + 2 == $n && $path[$i] != $path[$i + 1]) {
			$doublePos = $i + 1;
		}
		if ($doublePos !== false) {
			$t = $path[$i];
			$path[$i] = $path[$doublePos];
			$path[$doublePos] = $t;
			$actionCount++;
		} else {
			$actionCount++;
			if ($path[$i] == 'r') {
				$path[$i] = 'b';
			} else {
				$path[$i] = 'r';
			}
		}
	}

	echo $actionCount;
	/* / end body */
}

if (empty($is_test))
	getAnswer();


import sys

n = int(raw_input())
s = raw_input().strip()

def solve(head):
    a = list(s)
    cost = 0
    for i in range(1, n - 1):
        if a[i] == head[i % 2]:
            continue
        if a[i + 1] != a[i]:
            a[i + 1] = a[i]
        cost += 1
    if a[n - 1] != head[(n - 1) % 2]:
        cost += 1
    return cost

result = min(solve('rb'), solve('br'))
print(result)


import sys

n = int(raw_input())
s = raw_input().strip()

def solve(head):
    counts = { 'r': 0, 'b': 0 }
    cost = 0
    for i, ch in enumerate(s):
        if s[i] != head[i % 2]:
            cost += 1
            counts[s[i]] += 1
    cost -= min(counts.values())
    return cost

result = min(solve('rb'), solve('br'))
print(result)


n=input()
S=raw_input()
c,p='b','r'
m=n
for c,p in [['b','r'],['r','b']]:
    C=0
    s=list(S)
    for i in range(n):
        if s[i] != c:
            C+=1
            s[i]=c
            if i != n-1:
                if s[i+1] != p:
                    s[i+1]=p
        c,p=p,c
    #print s
    m=min(C,m)
print m


n=input()
S=raw_input()
c,p='b','r'
m=n
for c,p in [['b','r'],['r','b']]:
    C=[0,0]
    s=list(S)

    for i in range(n):
        if s[i] != c:
            C[s[i]=='r']+=1

        c,p=p,c
    #print s
    m=min(max(C),m)
print m


n=input()
s=raw_input()
r=b=0
for i in range(n):
    if i%2==0 and s[i]=="b":
        r+=1
    elif i%2==1 and s[i]=="r":
        b+=1
c=max(r,b)
r=b=0
for i in range(n):
    if i%2==0 and s[i]=="r":
        b+=1
    elif i%2==1 and s[i]=="b":
        r+=1
print min(c,max(r,b))


/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C460
{

	public static int mod = 1000000007;
	static FasterScanner in = new FasterScanner();
	static PrintWriter out = new PrintWriter(System.out);
	static int n,m,w;
	static long[] arr;
	public static boolean func(long x)
	{
		long[] temp=new long[2*n+5];
		long[] temparr=new long[n];
		for(int i=0;i<n;i++)
			temparr[i]=arr[i];
		long answer=0;
		for(int i=0;i<n;i++)
		{
			if(i!=0)
			temp[i]+=temp[i-1];
			temparr[i]+=temp[i];
			if(temparr[i]>x)
				continue;
			temp[i]+=(x-temparr[i]);
			answer+=(x-temparr[i]);
			temp[i+w]-=(x-temparr[i]);
		}
		return (answer<=m);
	}
	public static void main(String[] args)
	{
		n=in.nextInt();
		m=in.nextInt();
		w=in.nextInt();
		arr=in.nextLongArray(n);
		long l=0;
		long r=(long) 1e16;
		long answer=0;
		while(l<=r)
		{
			long mid=l+(r-l)/2;
			if(func(mid))
			{
				answer=mid;
				l=mid+1;
			}
			else
			{
				r=mid-1;
			}
		}
		out.println(answer);
		out.close();

	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FasterScanner
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

		public int read()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = System.in.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
import java.util.stream.Stream;
import java.util.Map.*;
import java.util.stream.IntStream;

public class CodeForces implements Runnable {

    private static final Reader in = new Reader();
    private static final PrintWriter out = new PrintWriter(System.out);
    private StringBuilder answer = new StringBuilder();

    public static void main(String[] args) {
        new Thread(null, new CodeForces(), "persefone", 1 << 28).start();
    }

    @Override
    public void run() {
        solve();
        printf();
        close();
    }

    void solve() {
        int n = in.nextInt();
        int t = in.nextInt();
        int w = in.nextInt();
        int[] a = new int[n + 1];
        for (int i = 1; i <= n; i++) a[i] = in.nextInt();

        int l = Arrays.stream(a).min().getAsInt(), r = (int) 1e9 + (int) 1e5 + 9, m = 0, ans = 0;
        while (l < r) {
            m = l + r >> 1;
            boolean check = true;
            int[] f = new int[n + 2];
            int x = t;
            for (int i = 1; i <= n; i++) {
                if (x < 0) { check = false; break; }
                f[i] += f[i - 1];
                if (a[i] + f[i] < m) {
                    int k = m - a[i] - f[i];
                    x -= k;
                    f[i] += k;
                    f[Math.min(i + w, n + 1)] -= k;
                }
            }
            if (x < 0) check = false;
            if (check) l = (ans = m) + 1; else r = m;
        }
        printf(ans);

    }

    static class Reader {
        private BufferedReader br;
        private StringTokenizer st;

        public Reader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        int[] nextIntArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) a[i] = nextInt();
            return a;
        }

        String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
    }

    void printf() {
        out.print(answer);
    }

    void close() {
        out.close();
    }

    void printf(Stream<?> str) {
        str.forEach(o -> add(o, " "));
        add("\n");
    }

    void printf(Object... obj) {
        printf(false, obj);
    }

    void printfWithDescription(Object... obj) {
        printf(true, obj);
    }

    private void printf(boolean b, Object... obj) {

        if (obj.length > 1) {
            for (int i = 0; i < obj.length; i++) {
                if (b) add(obj[i].getClass().getSimpleName(), " - ");
                if (obj[i] instanceof Collection<?>) {
                    printf((Collection<?>) obj[i]);
                } else if (obj[i] instanceof int[][]) {
                    printf((int[][]) obj[i]);
                } else if (obj[i] instanceof long[][]) {
                    printf((long[][]) obj[i]);
                } else if (obj[i] instanceof double[][]) {
                    printf((double[][]) obj[i]);
                } else printf(obj[i]);
            }
            return;
        }

        if (b) add(obj[0].getClass().getSimpleName(), " - ");
        printf(obj[0]);
    }

    void printf(Object o) {
        if (o instanceof int[])
            printf(Arrays.stream((int[]) o).boxed());
        else if (o instanceof char[])
            printf(new String((char[]) o));
        else if (o instanceof long[])
            printf(Arrays.stream((long[]) o).boxed());
        else if (o instanceof double[])
            printf(Arrays.stream((double[]) o).boxed());
        else if (o instanceof boolean[]) {
            for (boolean b : (boolean[]) o) add(b, " ");
            add("\n");
        } else
            add(o, "\n");
    }

    void printf(int[]... obj) {
        for (int i = 0; i < obj.length; i++) printf(obj[i]);
    }

    void printf(long[]... obj) {
        for (int i = 0; i < obj.length; i++) printf(obj[i]);
    }

    void printf(double[]... obj) {
        for (int i = 0; i < obj.length; i++) printf(obj[i]);
    }

    void printf(boolean[]... obj) {
        for (int i = 0; i < obj.length; i++) printf(obj[i]);
    }

    void printf(Collection<?> col) {
        printf(col.stream());
    }

    <T, K> void add(T t, K k) {
        if (t instanceof Collection<?>) {
            ((Collection<?>) t).forEach(i -> add(i, " "));
        } else if (t instanceof Object[]) {
            Arrays.stream((Object[]) t).forEach(i -> add(i, " "));
        } else
            add(t);
        add(k);
    }

    <T> void add(T t) {
        answer.append(t);
    }

}


import java.io.*;
import java.util.*;
import java.math.*;

public class Task implements Runnable {

    static int count(int n, int w, int[] a, int mn) {
        int[] t = new int[n];
        int sum = 0;
        long ret = 0;
        for (int i = 0; i < n; ++i) {
            if (i >= w) {
                sum -= t[i - w];
            }
            int c = mn - a[i] - sum;
            if (c > 0) {
                ret += c;
                t[i] = c;
            }
            sum += t[i];
        }
        return (int) Math.min(ret, Integer.MAX_VALUE);
    }

    public void solve() throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        int w = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = in.nextInt();
        }
        int l = 0;
        int r = Integer.MAX_VALUE / 2;
        while (r - l > 1) {
            int mn = (l + r) / 2;
            if (count(n, w, a, mn) <= m) {
                l = mn;
            } else {
                r = mn;
            }
        }
        out.println(l);
    }

    public void run() {
        try {
            in = new FastReader();
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    static FastReader in;
    static PrintWriter out;

    public static void main(String[] args) throws IOException {
        new Task().run();
    }

}

class FastReader {
    BufferedReader br;
    StringTokenizer in;

    FastReader() {
        this.br = new BufferedReader(new InputStreamReader(System.in));
    }

    FastReader(String filename) {
        try {
            this.br = new BufferedReader(new FileReader(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public String nextToken() throws IOException {
        while (in == null || !in.hasMoreTokens()) {
            in = new StringTokenizer(br.readLine());
        }

        return in.nextToken();
    }

    public int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    public double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    public long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }
}


import java.io.*;
import java.util.*;
import java.math.*;

public class Task implements Runnable {

    static int count(int n, int w, int[] a, int mn) {
        int[] t = new int[n];
        int sum = 0;
        int ret = 0;
        for (int i = 0; i < n; ++i) {
            if (i >= w) {
                sum -= t[i - w];
            }
            int c = mn - a[i] - sum;
            if (c > 0) {
                ret += c;
                t[i] = c;
            }
            sum += t[i];
        }
        return ret;
    }

    public void solve() throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        int w = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = in.nextInt();
        }
        int l = 0;
        int r = Integer.MAX_VALUE / 2;
        while (r - l > 1) {
            int mn = (l + r) / 2;
            if (count(n, w, a, mn) <= m) {
                l = mn;
            } else {
                r = mn;
            }
        }
        out.println(l);
    }

    public void run() {
        try {
            in = new FastReader();
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    static FastReader in;
    static PrintWriter out;

    public static void main(String[] args) throws IOException {
        new Task().run();
    }

}

class FastReader {
    BufferedReader br;
    StringTokenizer in;

    FastReader() {
        this.br = new BufferedReader(new InputStreamReader(System.in));
    }

    FastReader(String filename) {
        try {
            this.br = new BufferedReader(new FileReader(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public String nextToken() throws IOException {
        while (in == null || !in.hasMoreTokens()) {
            in = new StringTokenizer(br.readLine());
        }

        return in.nextToken();
    }

    public int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    public double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    public long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }
}


import java.io.*;
import java.util.*;

public class C {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt() , m = sc.nextInt() , w = sc.nextInt();

		int N = 1 ;

		while(N < n)
			N <<= 1 ;

		int [] a = new int [N + 1];
		Arrays.fill(a, Integer.MAX_VALUE);

		for(int i = 1 ; i <= n ; i++) a[i] = sc.nextInt();
		SegmentTree st = new SegmentTree(a);

		while(m-->0)
		{
			int start =  st.query(1, N).idx , end = Math.min(N, start + w - 1);

			st.update_range(start, end, 1);

		}

		out.println(st.query(1, N).val);
		out.flush();
		out.close();
	}
	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String path) throws Exception {
			br = new BufferedReader(new FileReader(path));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

	}
	 static class SegmentTree {

			int N;
			Node[] array, sTree, lazy;

			SegmentTree(int[] in)
			{
				N = in.length - 1;
				array = new Node[N + 1];
				for(int i = 0 ; i <= N ; i++)
				{
					array[i] = new Node(i , in[i]);

				}
				sTree = new Node[N<<1];
				lazy = new Node[N<<1];
				for(int i = 0 ; i < N <<1 ; i++)
					lazy[i] = new Node(0  , 0 );

				build(1,1,N);
			}

			void build(int node, int b, int e)
			{
				if(b == e)
					sTree[node] = array[b];
				else
				{
					int mid = b + e >> 1;
					build(node<<1,b,mid);
					build(node<<1|1,mid+1,e);

					combine(node);

				}
			}

			void combine(int node)
			{
				int idx = 0 ;
				long val = 0 ;
				if(sTree[node << 1].val <= sTree[node << 1 | 1].val)
					idx = sTree[node << 1].idx ;
				else
					idx = sTree[node << 1 | 1].idx;

				val = Math.min(sTree[node << 1].val, sTree[node << 1 | 1].val);

				sTree[node] = new Node(idx , val) ;

			}

			void update_range(int i, int j, int val)
			{
				update_range(1,1,N,i,j,val);
			}

			void update_range(int node, int b, int e, int i, int j, int val)
			{
				if(i > e || j < b)
					return;
				if(b >= i && e <= j)
				{
					sTree[node].val += (e-b+1)*val;
					lazy[node].val += val;
				}
				else
				{
					int mid = b + e >> 1;
					propagate(node, b, mid, e);
					update_range(node<<1,b,mid,i,j,val);
					update_range(node<<1|1,mid+1,e,i,j,val);
					combine(node);

				}

			}
			void propagate(int node, int b, int mid, int e)
			{
				lazy[node<<1].val += lazy[node].val;
				lazy[node<<1|1].val += lazy[node].val;

				sTree[node<<1].val += (mid-b+1)*lazy[node].val;
				sTree[node<<1|1].val += (e-mid)*lazy[node].val;
				lazy[node].val = 0;
			}

			Node query(int i, int j)
			{
				return query(1,1,N,i,j);
			}

			Node query(int node, int b, int e, int i, int j)
			{
				if(i>e || j <b)
					return new Node(-1 , -1);
				if(b>= i && e <= j)
					return sTree[node];

				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				Node q1 = query(node<<1,b,mid,i,j);
				Node q2 = query(node<<1|1,mid+1,e,i,j);
				if(q1.val <= q2.val)
					return q1 ;

				return q2 ;
			}
	 }

	 static class Node
	 {
		 int idx ;
		 long val ;

		 Node (int a , long b)
		 {
			 idx = a ; val = b ;
		 }
	 }

	private static  boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private static  void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }

}


import java.io.*;
import java.util.*;

public class C {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt() , m = sc.nextInt() , w = sc.nextInt();

		int N = 1 ;

		while(N < n)
			N <<= 1 ;

		int [] a = new int [N + 1];
		Arrays.fill(a, Integer.MAX_VALUE);

		for(int i = 1 ; i <= n ; i++) a[i] = sc.nextInt();
		SegmentTree st = new SegmentTree(a);

		while(m-->0)
		{
			int start =  st.query(1, N).idx , end = Math.min(N, start + w - 1);

			st.update_range(start, end, 1);

		}

		out.println(st.query(1, N).val);
		out.flush();
		out.close();
	}
	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String path) throws Exception {
			br = new BufferedReader(new FileReader(path));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

	}
	 static class SegmentTree {

			int N;
			Node[] array, sTree, lazy;

			SegmentTree(int[] in)
			{
				N = in.length - 1;
				array = new Node[N + 1];
				for(int i = 0 ; i <= N ; i++)
				{
					array[i] = new Node(i , in[i]);

				}
				sTree = new Node[N<<1];
				lazy = new Node[N<<1];
				for(int i = 0 ; i < N <<1 ; i++)
					lazy[i] = new Node(0  , 0 );

				build(1,1,N);
			}

			void build(int node, int b, int e)
			{
				if(b == e)
					sTree[node] = array[b];
				else
				{
					int mid = b + e >> 1;
					build(node<<1,b,mid);
					build(node<<1|1,mid+1,e);

					combine(node);

				}
			}

			void combine(int node)
			{
				int idx = 0 ;
				long val = 0 ;
				if(sTree[node << 1].val < sTree[node << 1 | 1].val)
					idx = sTree[node << 1].idx ;
				else
					idx = sTree[node << 1 | 1].idx;

				val = Math.min(sTree[node << 1].val, sTree[node << 1 | 1].val);

				sTree[node] = new Node(idx , val) ;

			}

			void update_range(int i, int j, int val)
			{
				update_range(1,1,N,i,j,val);
			}

			void update_range(int node, int b, int e, int i, int j, int val)
			{
				if(i > e || j < b)
					return;
				if(b >= i && e <= j)
				{
					sTree[node].val += (e-b+1)*val;
					lazy[node].val += val;
				}
				else
				{
					int mid = b + e >> 1;
					propagate(node, b, mid, e);
					update_range(node<<1,b,mid,i,j,val);
					update_range(node<<1|1,mid+1,e,i,j,val);
					combine(node);

				}

			}
			void propagate(int node, int b, int mid, int e)
			{
				lazy[node<<1].val += lazy[node].val;
				lazy[node<<1|1].val += lazy[node].val;

				sTree[node<<1].val += (mid-b+1)*lazy[node].val;
				sTree[node<<1|1].val += (e-mid)*lazy[node].val;
				lazy[node].val = 0;
			}

			Node query(int i, int j)
			{
				return query(1,1,N,i,j);
			}

			Node query(int node, int b, int e, int i, int j)
			{
				if(i>e || j <b)
					return new Node(-1 , -1);
				if(b>= i && e <= j)
					return sTree[node];

				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				Node q1 = query(node<<1,b,mid,i,j);
				Node q2 = query(node<<1|1,mid+1,e,i,j);
				if(q1.val < q2.val)
					return q1 ;

				return q2 ;
			}
	 }

	 static class Node
	 {
		 int idx ;
		 long val ;

		 Node (int a , long b)
		 {
			 idx = a ; val = b ;
		 }
	 }

	private static  boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private static  void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }

}


import java.io.*;
import java.util.*;

public class C {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt() , m = sc.nextInt() , w = sc.nextInt();

		int N = 1 ;

		while(N < n)
			N <<= 1 ;

		int [] a = new int [N + 1];
		Arrays.fill(a, Integer.MAX_VALUE);

		for(int i = 1 ; i <= n ; i++) a[i] = sc.nextInt();
		SegmentTree st = new SegmentTree(a);

		while(m-->0)
		{
			int start =  st.query(1, N).idx , end = Math.min(N, start + w - 1);
			if(start + w - 1 <= N)
				st.update_range(start, end, 1);
			else
				st.update_range(N - w + 1, N, 1);

		}

		out.println(st.query(1, N).val);
		out.flush();
		out.close();
	}
	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String path) throws Exception {
			br = new BufferedReader(new FileReader(path));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

	}
	 static class SegmentTree {

			int N;
			Node[] array, sTree, lazy;

			SegmentTree(int[] in)
			{
				N = in.length - 1;
				array = new Node[N + 1];
				for(int i = 0 ; i <= N ; i++)
				{
					array[i] = new Node(i , in[i]);

				}
				sTree = new Node[N<<1];
				lazy = new Node[N<<1];
				for(int i = 0 ; i < N <<1 ; i++)
					lazy[i] = new Node(0  , 0 );

				build(1,1,N);
			}

			void build(int node, int b, int e)
			{
				if(b == e)
					sTree[node] = array[b];
				else
				{
					int mid = b + e >> 1;
					build(node<<1,b,mid);
					build(node<<1|1,mid+1,e);

					combine(node);

				}
			}

			void combine(int node)
			{
				int idx = 0 ;
				long val = 0 ;
				if(sTree[node << 1].val <= sTree[node << 1 | 1].val)
					idx = sTree[node << 1].idx ;
				else
					idx = sTree[node << 1 | 1].idx;

				val = Math.min(sTree[node << 1].val, sTree[node << 1 | 1].val);

				sTree[node] = new Node(idx , val) ;

			}

			void update_range(int i, int j, int val)
			{
				update_range(1,1,N,i,j,val);
			}

			void update_range(int node, int b, int e, int i, int j, int val)
			{
				if(i > e || j < b)
					return;
				if(b >= i && e <= j)
				{
					sTree[node].val += val;
					lazy[node].val += val;
				}
				else
				{
					int mid = b + e >> 1;
					propagate(node, b, mid, e);
					update_range(node<<1,b,mid,i,j,val);
					update_range(node<<1|1,mid+1,e,i,j,val);
					combine(node);

				}

			}
			void propagate(int node, int b, int mid, int e)
			{
				lazy[node<<1].val += lazy[node].val;
				lazy[node<<1|1].val += lazy[node].val;

				sTree[node<<1].val += lazy[node].val;
				sTree[node<<1|1].val += lazy[node].val;
				lazy[node].val = 0;
			}

			Node query(int i, int j)
			{
				return query(1,1,N,i,j);
			}

			Node query(int node, int b, int e, int i, int j)
			{
				if(i>e || j <b)
					return new Node(-1 , -1);
				if(b>= i && e <= j)
					return sTree[node];

				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				Node q1 = query(node<<1,b,mid,i,j);
				Node q2 = query(node<<1|1,mid+1,e,i,j);
				if(q1.val <= q2.val)
					return q1 ;

				return q2 ;
			}
	 }

	 static class Node
	 {
		 int idx ;
		 long val ;

		 Node (int a , long b)
		 {
			 idx = a ; val = b ;
		 }
	 }

	private static  boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private static  void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }

}


import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int d = Integer.parseInt(tokenizer.nextToken());
        int w = Integer.parseInt(tokenizer.nextToken());

        tokenizer = new StringTokenizer(reader.readLine());
        long [] heights = new long[n];
        for(int i = 0 ; i < n ; i++)
            heights[i] = Integer.parseInt(tokenizer.nextToken());

        long lb = 0;
        long ub = 1000000000 + 1000000;

        while(ub - lb > 1)
        {
            long mid = lb + ub >> 1;
            long need = 0;

            long [] change = new long[n+1];
            long add = 0;

            for(int i = 0 ; i < n ; i++)
            {
                add += change[i];
                if(heights[i] + add < mid)
                {
                    long diff = mid - heights[i] - add;
                    need += diff;
                    add += diff;
                    change[Math.min(n, i+w)] -= diff;
                }
            }

            if(need <= d)
                lb = mid;
            else
                ub = mid;
        }

        System.out.println(lb);
    }
}


import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int d = Integer.parseInt(tokenizer.nextToken());
        int w = Integer.parseInt(tokenizer.nextToken());

        tokenizer = new StringTokenizer(reader.readLine());
        int [] heights = new int[n];
        for(int i = 0 ; i < n ; i++)
            heights[i] = Integer.parseInt(tokenizer.nextToken());

        int lb = 0;
        int ub = 1000000000 + 1000000;

        while(ub - lb > 1)
        {
            int mid = lb + ub >> 1;
            int need = 0;

            int [] change = new int[n+1];
            int add = 0;

            for(int i = 0 ; i < n ; i++)
            {
                add += change[i];
                if(heights[i] + add < mid)
                {
                    int diff = mid - heights[i] - add;
                    need += diff;
                    add += diff;
                    change[Math.min(n, i+w)] -= diff;
                }
            }

            if(need <= d)
                lb = mid;
            else
                ub = mid;
        }

        System.out.println(lb);
    }
}


import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int d = Integer.parseInt(tokenizer.nextToken());
        int w = Integer.parseInt(tokenizer.nextToken());

        tokenizer = new StringTokenizer(reader.readLine());
        int [] heights = new int[n];
        for(int i = 0 ; i < n ; i++)
            heights[i] = Integer.parseInt(tokenizer.nextToken());

        int lb = 0;
        int ub = 1000000000 + 100000000;

        while(ub - lb > 1)
        {
            int mid = lb + ub >> 1;
            int need = 0;

            int [] change = new int[n+1];
            int add = 0;

            for(int i = 0 ; i < n ; i++)
            {
                add += change[i];
                if(heights[i] + add < mid)
                {
                    int diff = mid - heights[i] - add;
                    need += diff;
                    add += diff;
                    change[Math.min(n, i+w)] -= diff;
                }
            }

            if(need <= d)
                lb = mid;
            else
                ub = mid;
        }

        System.out.println(lb);
    }
}


import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int d = Integer.parseInt(tokenizer.nextToken());
        int w = Integer.parseInt(tokenizer.nextToken());

        tokenizer = new StringTokenizer(reader.readLine());
        int [] heights = new int[n];
        for(int i = 0 ; i < n ; i++)
            heights[i] = Integer.parseInt(tokenizer.nextToken());

        int lb = 0;
        int ub = 1000000000 + 100000000;

        while(ub - lb > 1)
        {
            int mid = lb + ub >> 1;
            int need = 0;

            int [] tmp = heights.clone();

            for(int i = 0 ; i < n ; i++)
                if(heights[i] < mid)
                {
                    int change = mid - heights[i];
                    need += change;
                    if(need > d)
                        break;
                    for(int j = i ; j < Math.min(n, i+w) ; j++)
                        heights[j] += change;
                }

            heights = tmp.clone();

            if(need <= d)
                lb = mid;
            else
                ub = mid;
        }

        System.out.println(lb);
    }
}


import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int d = Integer.parseInt(tokenizer.nextToken());
        int w = Integer.parseInt(tokenizer.nextToken());

        tokenizer = new StringTokenizer(reader.readLine());
        int [] heights = new int[n];
        for(int i = 0 ; i < n ; i++)
            heights[i] = Integer.parseInt(tokenizer.nextToken());

        int lb = 0;
        int ub = 1000000000 + 1000000;

        while(ub - lb > 1)
        {
            int mid = lb + ub >> 1;
            int need = 0;

            int [] change = new int[n+1];
            long add = 0;

            for(int i = 0 ; i < n ; i++)
            {
                add += change[i];
                if(heights[i] + add < mid)
                {
                    long diff = mid - heights[i] - add;
                    need += diff;
                    add += diff;
                    change[Math.min(n, i+w)] -= diff;
                }
            }

            if(need <= d)
                lb = mid;
            else
                ub = mid;
        }

        System.out.println(lb);
    }
}


import java.io.*;
import java.math.*;
import java.util.*;

public class Main {

	public static class pair implements Comparable<pair>
	{
		int a;
		int b;
		public pair(int pa, int pb)
		{
			a = pa; b= pb;
		}
		@Override
		public int compareTo(pair o) {
			if(this.a < o.a)
				return -1;
			if(this.a > o.a)
				return 1;
			return Integer.compare(o.b, this.b);
		}
	}

	//int n = Integer.parseInt(in.readLine());
	//int n = Integer.parseInt(spl[0]);
	//String[] spl = in.readLine().split(" ");

	public static int n,m,w;
	public static int[] a;

	public static void main (String[] args) throws Exception
	{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] spl = in.readLine().split(" ");
		n = Integer.parseInt(spl[0]);
		m = Integer.parseInt(spl[1]);
		w = Integer.parseInt(spl[2]);
		a = new int[n];
		spl = in.readLine().split(" ");
		for(int i=0; i<n; i++) a[i] = Integer.parseInt(spl[i]);
		long lo = 1, hi = Long.parseLong("100000000000050");
		while(lo+1 < hi)
		{
			long med = (lo+hi)/2;
			if(pos(med))
				lo = med;
			else
				hi = med;
		}
		System.out.println(lo);

	}

	private static boolean pos(long med) {
		long[] need = new long[n];
		long[] act = new long[n];
		for(int i=0; i<n; i++) need[i] = Math.max(0, med-a[i]);
		long curS = 0;
		long tot = 0;
		for(int i=0; i<n; i++)
		{
			act[i] = Math.max(0, need[i] - curS);
			if(i>=w-1)
				curS-=act[i-(w-1)];
			curS+=act[i];
			tot+=act[i];
		}
		if(tot <= m)
			return true;
		else return false;
	}

}


import java.util.*;
import java.io.*;
import java.math.*;

public class Prg1 {

    PrintWriter pw = new PrintWriter(System.out);
    Random rnd = new Random();
    int a;

    void run() {
        a = ni();
        long dn = ni(), l = 0, r = 2000000000;
        int k = ni();
        long[] m = new long[a];
        for(int q=0; q<a; q++) m[q] = ni();
        for(; l+1!=r;){
            long mid = (r+l)/2, o=0, now=0;
            long[] d = new long[a], pl = new long[a];
            for(int q=0; q<a; q++) d[q] = Math.max(0, mid-m[q]);
            for(int q=0; q<a; q++){
                if(q-k>=0) now-=pl[q-k];
                if(now>=d[q]) continue;
                pl[q] = d[q]-now;
                o+=d[q]-now;
                now=d[q];
            }
            if(o<=dn) l=mid;
            else r = mid;
        }
        pw.print(l);
        pw.flush();
    }

    public static void main(String[] args) {
        new Prg1().run();
    }

    InputStream is = System.in;
    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private String nline(){
        int b = readByte();
        StringBuilder sb = new StringBuilder();
        while (b!=10) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }
        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }
        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Present
{
	static int n, m, w, arr[];
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		w = sc.nextInt();
		arr = new int[n];
		for (int i = 0; i < arr.length; i++)
			arr[i] = sc.nextInt();
		System.out.println(search(0, (int)2e9 + 5));
	}

	private static int search(int st, int en)
	{
		if(st == en)
			return st;
		int mid = st + (en-st+1)/2;
		if(check(mid))
			return search(mid, en);
		else
			return search(st, mid-1);
	}

	public static boolean check(int num)
	{
		int cnt = 0;
		int[] a = new int[n];
		for (int i = 0; i < arr.length; i++)
			a[i] = arr[i];
		int[] minus = new int[n];
		int add = 0;
		for (int i = 0; i < arr.length; i++)
		{
			add -= minus[i];
			a[i] += add;
			if(a[i] < num)
			{
				add += num - a[i];
				if(i+w < arr.length)
					minus[i+w] = num-a[i];
				cnt+=(num - a[i]);
			}
		}
		return cnt <= m;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Present
{
	static int n, m, w, arr[];
	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		w = sc.nextInt();
		arr = new int[n];
		for (int i = 0; i < arr.length; i++)
			arr[i] = sc.nextInt();
		System.out.println(search(0, (int)2e9 + 5));
	}

	private static int search(int st, int en)
	{
		if(st == en)
			return st;
		int mid = st + (en-st+1)/2;
		if(check(mid))
			return search(mid, en);
		else
			return search(st, mid-1);
	}

	public static boolean check(int num)
	{
		long cnt = 0;
		long[] a = new long[n];
		for (int i = 0; i < arr.length; i++)
			a[i] = arr[i];
		long[] minus = new long[n];
		long add = 0;
		for (int i = 0; i < arr.length; i++)
		{
			add -= minus[i];
			a[i] += add;
			if(a[i] < num)
			{
				add += num - a[i];
				if(i+w < arr.length)
					minus[i+w] = num-a[i];
				cnt+=(num - a[i]);
			}
		}
		return cnt <= m;
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}
	}
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {
    MyScanner sc    = new MyScanner();
    Scanner   sc2   = new Scanner(System.in);
    long      start = System.currentTimeMillis();
    long      fin   = System.currentTimeMillis();
    final int MOD   = 1000000007;
    int[]     dx    = { 1, 0, 0, -1 };
    int[]     dy    = { 0, 1, -1, 0 };

    int       n, m, w;
    int[]     a;

    void run() {
        n = sc.nextInt();
        m = sc.nextInt();
        w = sc.nextInt();
        a = sc.nextIntArray(n);
        int l = 0;
        int r = Integer.MAX_VALUE / 2;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (check(mid)) l = mid;
            else r = mid;
        }
        System.out.println(l);
    }

    boolean check(int d) {
        int cnt = 0;
        int[] sub = new int[n];
        int add = 0;
        for (int i = 0; i < n; i++) {
            if(i - w >= 0) add -= sub[i - w];
            if (a[i] + add < d) {
                sub[i] = d - (a[i] + add);
                cnt += sub[i];
                add += sub[i];
            }
        }
        return cnt <= m;
    }

    public static void main(String[] args) {
        new Main().run();
    }

    void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }

    void debug2(char[][] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]);
            }
            System.out.println();
        }
    }

    boolean inner(int h, int w, int limH, int limW) {
        return 0 <= h && h < limH && 0 <= w && w < limW;
    }

    void swap(int[] x, int a, int b) {
        int tmp = x[a];
        x[a] = x[b];
        x[b] = tmp;
    }

    // find minimum i (k <= a[i])
    int lower_bound(int a[], int k) {
        int l = -1;
        int r = a.length;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (k <= a[mid])
                r = mid;
            else
                l = mid;
        }
        // r = l + 1
        return r;
    }

    // find minimum i (k < a[i])
    int upper_bound(int a[], int k) {
        int l = -1;
        int r = a.length;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (k < a[mid])
                r = mid;
            else
                l = mid;
        }
        // r = l + 1
        return r;
    }

    int gcd(int a, int b) {
        return a % b == 0 ? b : gcd(b, a % b);
    }

    int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }

    boolean palindrome(String s) {
        for (int i = 0; i < s.length() / 2; i++) {
            if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
                return false;
            }
        }
        return true;
    }

    class MyScanner {
        int nextInt() {
            try {
                int c = System.in.read();
                while (c != '-' && (c < '0' || '9' < c))
                    c = System.in.read();
                if (c == '-')
                    return -nextInt();
                int res = 0;
                do {
                    res *= 10;
                    res += c - '0';
                    c = System.in.read();
                } while ('0' <= c && c <= '9');
                return res;
            } catch (Exception e) {
                return -1;
            }
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String next() {
            try {
                StringBuilder res = new StringBuilder("");
                int c = System.in.read();
                while (Character.isWhitespace(c))
                    c = System.in.read();
                do {
                    res.append((char) c);
                } while (!Character.isWhitespace(c = System.in.read()));
                return res.toString();
            } catch (Exception e) {
                return null;
            }
        }

        int[] nextIntArray(int n) {
            int[] in = new int[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextInt();
            }
            return in;
        }

        int[][] nextInt2dArray(int n, int m) {
            int[][] in = new int[n][m];
            for (int i = 0; i < n; i++) {
                in[i] = nextIntArray(m);
            }
            return in;
        }

        double[] nextDoubleArray(int n) {
            double[] in = new double[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextDouble();
            }
            return in;
        }

        long[] nextLongArray(int n) {
            long[] in = new long[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextLong();
            }
            return in;
        }

        char[][] nextCharField(int n, int m) {
            char[][] in = new char[n][m];
            for (int i = 0; i < n; i++) {
                String s = sc.next();
                for (int j = 0; j < m; j++) {
                    in[i][j] = s.charAt(j);
                }
            }
            return in;
        }
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {
    MyScanner sc    = new MyScanner();
    Scanner   sc2   = new Scanner(System.in);
    long      start = System.currentTimeMillis();
    long      fin   = System.currentTimeMillis();
    final int MOD   = 1000000007;
    int[]     dx    = { 1, 0, 0, -1 };
    int[]     dy    = { 0, 1, -1, 0 };

    int       n, m, w;
    int[]     a;

    void run() {
        n = sc.nextInt();
        m = sc.nextInt();
        w = sc.nextInt();
        a = sc.nextIntArray(n);
        int l = 0;
        int r = Integer.MAX_VALUE / 2;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (check(mid)) l = mid;
            else r = mid;
        }
        System.out.println(l);
    }

    boolean check(int d) {
        long cnt = 0;
        long[] sub = new long[n];
        long add = 0;
        for (int i = 0; i < n; i++) {
            if(i - w >= 0) add -= sub[i - w];
            if (a[i] + add < d) {
                sub[i] = d - (a[i] + add);
                cnt += sub[i];
                add += sub[i];
            }
        }
        return cnt <= m;
    }

    public static void main(String[] args) {
        new Main().run();
    }

    void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }

    void debug2(char[][] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]);
            }
            System.out.println();
        }
    }

    boolean inner(int h, int w, int limH, int limW) {
        return 0 <= h && h < limH && 0 <= w && w < limW;
    }

    void swap(int[] x, int a, int b) {
        int tmp = x[a];
        x[a] = x[b];
        x[b] = tmp;
    }

    // find minimum i (k <= a[i])
    int lower_bound(int a[], int k) {
        int l = -1;
        int r = a.length;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (k <= a[mid])
                r = mid;
            else
                l = mid;
        }
        // r = l + 1
        return r;
    }

    // find minimum i (k < a[i])
    int upper_bound(int a[], int k) {
        int l = -1;
        int r = a.length;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (k < a[mid])
                r = mid;
            else
                l = mid;
        }
        // r = l + 1
        return r;
    }

    int gcd(int a, int b) {
        return a % b == 0 ? b : gcd(b, a % b);
    }

    int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }

    boolean palindrome(String s) {
        for (int i = 0; i < s.length() / 2; i++) {
            if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
                return false;
            }
        }
        return true;
    }

    class MyScanner {
        int nextInt() {
            try {
                int c = System.in.read();
                while (c != '-' && (c < '0' || '9' < c))
                    c = System.in.read();
                if (c == '-')
                    return -nextInt();
                int res = 0;
                do {
                    res *= 10;
                    res += c - '0';
                    c = System.in.read();
                } while ('0' <= c && c <= '9');
                return res;
            } catch (Exception e) {
                return -1;
            }
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String next() {
            try {
                StringBuilder res = new StringBuilder("");
                int c = System.in.read();
                while (Character.isWhitespace(c))
                    c = System.in.read();
                do {
                    res.append((char) c);
                } while (!Character.isWhitespace(c = System.in.read()));
                return res.toString();
            } catch (Exception e) {
                return null;
            }
        }

        int[] nextIntArray(int n) {
            int[] in = new int[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextInt();
            }
            return in;
        }

        int[][] nextInt2dArray(int n, int m) {
            int[][] in = new int[n][m];
            for (int i = 0; i < n; i++) {
                in[i] = nextIntArray(m);
            }
            return in;
        }

        double[] nextDoubleArray(int n) {
            double[] in = new double[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextDouble();
            }
            return in;
        }

        long[] nextLongArray(int n) {
            long[] in = new long[n];
            for (int i = 0; i < n; i++) {
                in[i] = nextLong();
            }
            return in;
        }

        char[][] nextCharField(int n, int m) {
            char[][] in = new char[n][m];
            for (int i = 0; i < n; i++) {
                String s = sc.next();
                for (int j = 0; j < m; j++) {
                    in[i][j] = s.charAt(j);
                }
            }
            return in;
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.PrintWriter;
public class C460
{
    static class Scanner
    {
        BufferedReader br;
        StringTokenizer tk=new StringTokenizer("");
        public Scanner(InputStream is)
        {
            br=new BufferedReader(new InputStreamReader(is));
        }
        public int nextInt() throws IOException
        {
            if(tk.hasMoreTokens())
                return Integer.parseInt(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextInt();
        }
        public long nextLong() throws IOException
        {
            if(tk.hasMoreTokens())
                return Long.parseLong(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextLong();
        }
        public String next() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return next();
        }
        public String nextLine() throws IOException
        {
            tk=new StringTokenizer("");
            return br.readLine();
        }
        public double nextDouble() throws IOException
        {
            if(tk.hasMoreTokens())
                return Double.parseDouble(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextDouble();
        }
        public char nextChar() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken().charAt(0));
            tk=new StringTokenizer(br.readLine());
            return nextChar();
        }
        public int[] nextIntArray(int n) throws IOException
        {
            int a[]=new int[n];
            for(int i=0;i<n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArray(int n) throws IOException
        {
            long a[]=new long[n];
            for(int i=0;i<n;i++)
                a[i]=nextLong();
            return a;
        }
        public int[] nextIntArrayOneBased(int n) throws IOException
        {
            int a[]=new int[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArrayOneBased(int n) throws IOException
        {
            long a[]=new long[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextLong();
            return a;
        }

    }
    static boolean check(int n,int m,int w,int k,int a[])
    {
        int sum[]=new int[n+w+100];
        int x=0;
        for(int i=1;i<=n;i++)
        {
            x+=sum[i];
            if(a[i]+x<k)
            {
                int d=k-a[i]-x;
                if(m<d)
                    return false;
                m-=d;
                x+=d;
                sum[i+w]-=d;
            }
        }
        return true;
    }
    static int ans(int n,int m,int w,int a[])
    {
        int ans=0;
        int start=1;
        int end=1000100001;
        while(start<=end)
        {
            int mid=(start+end)/2;
            if(check(n,m,w,mid,a))
            {
                ans=Math.max(mid, ans);
                start=mid+1;
            }
            else
                end=mid-1;
        }
        return ans;
    }
    public static void main(String args[]) throws IOException
    {
        Scanner in=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);
        int n=in.nextInt();
        int m=in.nextInt();
        int w=in.nextInt();
        int a[]=in.nextIntArrayOneBased(n);
        System.out.println(ans(n,m,w,a));
        out.close();
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.PrintWriter;
public class C460
{
    static class Scanner
    {
        BufferedReader br;
        StringTokenizer tk=new StringTokenizer("");
        public Scanner(InputStream is)
        {
            br=new BufferedReader(new InputStreamReader(is));
        }
        public int nextInt() throws IOException
        {
            if(tk.hasMoreTokens())
                return Integer.parseInt(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextInt();
        }
        public long nextLong() throws IOException
        {
            if(tk.hasMoreTokens())
                return Long.parseLong(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextLong();
        }
        public String next() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return next();
        }
        public String nextLine() throws IOException
        {
            tk=new StringTokenizer("");
            return br.readLine();
        }
        public double nextDouble() throws IOException
        {
            if(tk.hasMoreTokens())
                return Double.parseDouble(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextDouble();
        }
        public char nextChar() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken().charAt(0));
            tk=new StringTokenizer(br.readLine());
            return nextChar();
        }
        public int[] nextIntArray(int n) throws IOException
        {
            int a[]=new int[n];
            for(int i=0;i<n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArray(int n) throws IOException
        {
            long a[]=new long[n];
            for(int i=0;i<n;i++)
                a[i]=nextLong();
            return a;
        }
        public int[] nextIntArrayOneBased(int n) throws IOException
        {
            int a[]=new int[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArrayOneBased(int n) throws IOException
        {
            long a[]=new long[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextLong();
            return a;
        }

    }
    static boolean check(int n,int m,int w,int k,int a[])
    {
        int sum[]=new int[n+w+100];
        int x=0;
        for(int i=1;i<=n;i++)
        {
            x+=sum[i];
            if(a[i]+x<k)
            {
                int d=k-a[i]-x;
                if(m<d)
                    return false;
                m-=d;
                x+=d;
                sum[i+w]-=d;
            }
        }
        return true;
    }
    static int ans(int n,int m,int w,int a[])
    {
        int ans=0;
        int start=1;
        int end=2000000001;
        while(start<=end)
        {
            int mid=(start+end)/2;
            if(check(n,m,w,mid,a))
            {
                ans=Math.max(mid, ans);
                start=mid+1;
            }
            else
                end=mid-1;
        }
        return ans;
    }
    public static void main(String args[]) throws IOException
    {
        Scanner in=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);
        int n=in.nextInt();
        int m=in.nextInt();
        int w=in.nextInt();
        int a[]=in.nextIntArrayOneBased(n);
        System.out.println(ans(n,m,w,a));
        out.close();
    }

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int w = in.nextInt();
            int[] ar = new int[n];
            for (int i = 0; i < n; i++) {
                ar[i] = in.nextInt();
            }
            int low = 1;
            int high = 2000000000;
            while ((high - low) > 1) {
                int mid = (high + low) / 2;
                //Does mid as a shortest flower works?
                int need = 0;
                int cur = 0;
                SegmentTreeRangeUpdate seg = new SegmentTreeRangeUpdate(ar);
                for (int i = 0; i <= (n - w); i++) {
                    long a = seg.query(i, i);
                    if (a < mid) {
                        seg.update(i, i + w - 1, (int) (mid - a));
                        need += (mid - a);
                    }
                }

                int maxNeed = 0;
                for (int i = (n - w + 1); i < n; i++) {
                    maxNeed = Math.max(maxNeed, (int) (mid - seg.query(i, i)));
                }
                need += maxNeed;

                if (need > m) {
                    high = mid;
                } else {
                    low = mid;
                }
            }
            out.println(low);
        }

    }

    static class SegmentTreeRangeUpdate {
        public long[] leaf;
        public long[] update;
        public int origSize;

        public SegmentTreeRangeUpdate(int[] list) {
            origSize = list.length;
            leaf = new long[4 * list.length];
            update = new long[4 * list.length];
            build(1, 0, list.length - 1, list);
        }

        public void build(int curr, int begin, int end, int[] list) {
            if (begin == end)
                leaf[curr] = list[begin];
            else {
                int mid = (begin + end) / 2;
                build(2 * curr, begin, mid, list);
                build(2 * curr + 1, mid + 1, end, list);
                leaf[curr] = leaf[2 * curr] + leaf[2 * curr + 1];
            }
        }

        public void update(int begin, int end, int val) {
            update(1, 0, origSize - 1, begin, end, val);
        }

        public void update(int curr, int tBegin, int tEnd, int begin, int end, int val) {
            if (tBegin >= begin && tEnd <= end)
                update[curr] += val;
            else {
                leaf[curr] += (Math.min(end, tEnd) - Math.max(begin, tBegin) + 1) * val;
                int mid = (tBegin + tEnd) / 2;
                if (mid >= begin && tBegin <= end)
                    update(2 * curr, tBegin, mid, begin, end, val);
                if (tEnd >= begin && mid + 1 <= end)
                    update(2 * curr + 1, mid + 1, tEnd, begin, end, val);
            }
        }

        public long query(int begin, int end) {
            return query(1, 0, origSize - 1, begin, end);
        }

        public long query(int curr, int tBegin, int tEnd, int begin, int end) {
            if (tBegin >= begin && tEnd <= end) {
                if (update[curr] != 0) {
                    leaf[curr] += (tEnd - tBegin + 1) * update[curr];
                    if (2 * curr < update.length) {
                        update[2 * curr] += update[curr];
                        update[2 * curr + 1] += update[curr];
                    }
                    update[curr] = 0;
                }
                return leaf[curr];
            } else {
                leaf[curr] += (tEnd - tBegin + 1) * update[curr];
                if (2 * curr < update.length) {
                    update[2 * curr] += update[curr];
                    update[2 * curr + 1] += update[curr];
                }
                update[curr] = 0;
                int mid = (tBegin + tEnd) / 2;
                long ret = 0;
                if (mid >= begin && tBegin <= end)
                    ret += query(2 * curr, tBegin, mid, begin, end);
                if (tEnd >= begin && mid + 1 <= end)
                    ret += query(2 * curr + 1, mid + 1, tEnd, begin, end);
                return ret;
            }
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}