using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("7 3");
WillReturn.Add("1 7 7 4 8 1 6");
//1 4 4 1 1
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(pX => int.Parse(pX)).ToArray();
int L = wkArr[1];
int[] AArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();
int UB = AArr.GetUpperBound(0);
var AnswerList = new List<int>();
var InsDeque = new Deque<int>();
for (int I = 0; I <= UB; I++) {
// 引退処理
while (InsDeque.Count > 0) {
int FrontInd = InsDeque[0];
if (I - FrontInd + 1 > L) {
InsDeque.PopFront();
continue;
}
break;
}
// 押し出し処理
while (InsDeque.Count > 0) {
int LastInd = InsDeque[InsDeque.Count - 1];
if (AArr[LastInd] > AArr[I]) {
InsDeque.PopBack();
continue;
}
break;
}
// 追加処理
InsDeque.PushBack(I);
if (I >= L - 1) {
AnswerList.Add(AArr[InsDeque[0]]);
}
}
Console.WriteLine(IntEnumJoin(" ", AnswerList));
}
// セパレータとInt型の列挙を引数として、結合したstringを返す
static string IntEnumJoin(string pSeparater, IEnumerable<int> pEnum)
{
string[] StrArr = Array.ConvertAll(pEnum.ToArray(), pX => pX.ToString());
return string.Join(pSeparater, StrArr);
}
}
#region Deque
internal class Deque<T>
{
T[] buf;
int offset, count, capacity;
internal int Count { get { return count; } }
internal Deque(int cap) { buf = new T[capacity = cap]; }
internal Deque() { buf = new T[capacity = 16]; }
internal T this[int index]
{
get { return buf[GetIndex(index)]; }
set { buf[GetIndex(index)] = value; }
}
private int GetIndex(int index)
{
if (index >= capacity)
throw new IndexOutOfRangeException("out of range");
int ret = index + offset;
if (ret >= capacity)
ret -= capacity;
return ret;
}
internal void PushFront(T item)
{
if (count == capacity) Extend();
if (--offset < 0) offset += buf.Length;
buf[offset] = item;
count++;
}
internal T PopFront()
{
if (count == 0)
throw new InvalidOperationException("collection is empty");
count--;
T ret = buf[offset++];
if (offset >= capacity) offset -= capacity;
return ret;
}
internal void PushBack(T item)
{
if (count == capacity) Extend();
int id = count + offset;
count++;
if (id >= capacity) id -= capacity;
buf[id] = item;
}
internal T PopBack()
{
if (count == 0)
throw new InvalidOperationException("collection is empty");
return buf[GetIndex(--count)];
}
internal void Insert(int index, T item)
{
if (index > count) throw new IndexOutOfRangeException();
this.PushFront(item);
for (int i = 0; i < index; i++)
this[i] = this[i + 1];
this[index] = item;
}
internal T RemoveAt(int index)
{
if (index < 0 || index >= count) throw new IndexOutOfRangeException();
T ret = this[index];
for (int i = index; i > 0; i--)
this[i] = this[i - 1];
this.PopFront();
return ret;
}
private void Extend()
{
T[] newBuffer = new T[capacity << 1];
if (offset > capacity - count) {
int len = buf.Length - offset;
Array.Copy(buf, offset, newBuffer, 0, len);
Array.Copy(buf, 0, newBuffer, len, count - len);
}
else Array.Copy(buf, offset, newBuffer, 0, count);
buf = newBuffer;
offset = 0;
capacity <<= 1;
}
internal T[] Items//デバッグ時に中身を調べるためのプロパティ
{
get
{
T[] a = new T[count];
for (int i = 0; i < count; i++)
a[i] = this[i];
return a;
}
}
}
#endregion