/*
尺取り法(with SWAG)
実際には結合則が適用できるなら使えるらしいが、
このコードでは更に単位元を必要としている

参考
https://motsu-xe.hatenablog.com/entry/2019/12/06/192424
verify:
DSL
*/

#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <limits>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <iomanip>
#include <functional>
#include <complex>
using namespace std;
using ll=long long int;

template<class Monoid>
struct SWAG{
    //情報
    const vector<Monoid> &v;
    //function
    const function<Monoid(Monoid,Monoid)> &op;
    //単位元
    Monoid unit;
    //SWAG
    Monoid front;
    stack<Monoid> back;
    //尺取りに使う
    int l,r;
    int sz;

    SWAG(vector<Monoid> &v,function<Monoid(Monoid,Monoid)> op,Monoid unit) 
            :v(v),op(op),unit(unit),front(unit),l(0),r(0),sz(v.size()){};

    //右に進んだ場合の値
    inline Monoid isR(){
        if(back.empty()){
            return op(front,v[r]);
        } 
        return op(op(front,v[r]),back.top());
    }
    //今の値
    inline Monoid value(){
        if(back.empty()){
            return front;
        } 
        return op(front,back.top());
    }
    //右に進めて値を返す
    inline Monoid Right(){
        front=op(front,v[r++]);
        if(back.empty()) return front;
        return op(back.top(),front);
    }
    //左を進めて値を返す
    inline Monoid Left(){
        if(back.empty()){
            Monoid tmp=unit;
            for(int u=r-1;u>l;u--){
                back.emplace(tmp=op(tmp,v[u]));
            }
            front=unit;
        }else back.pop();
        l++;
        if(back.empty()) return front;
        return op(back.top(),front);
    }
};
//DSL 3A
//S以上になる連続する部分列の長さの最小値
/*signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(20);
    int N,S;
    cin>>N>>S;
    vector<int> a(N);
    for(int i=0;i<N;i++) cin>>a[i];

    auto op=[](int a,int b){
        return a+b;
    };
    int l=0,r=0;
    SWAG<int> swag(a,op,0);
    int ret=N+10;
    while(l<N){
        //S以下なら右に進める
        while(r<N && swag.isR()<S){
            swag.Right();
            r++;
        }
        //r<Nなら右に一個進めた場合S以上になる
        if(r<N) ret=min(ret,r-l+1);
        if(r==l) swag.Right(),r++;
        swag.Left(),l++;
    }
    if(ret==N+10) cout<<0<<endl;
    else cout<<ret<<endl;
}*/


//DSL3C
//総和がx以下の連続する部分列の数え上げ
/*signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(20);
    int N,Q;
    cin>>N>>Q;
    vector<ll> a(N);
    for(int i=0;i<N;i++) cin>>a[i];

    auto op=[](ll a,ll b){
        return a+b;
    };
    while(Q--){
        ll x;
        cin>>x;
        int l=0,r=0;
        SWAG<ll> swag(a,op,0);
        ll ret=0;
        while(l<N){
            while(r<N && swag.isR()<=x){
                swag.Right();
                r++;
            }
            ret+=r-l;
            if(r==l) swag.Right(),r++;
            swag.Left(),l++;
        }
        cout<<ret<<endl;
    }    
}*/

//DSL 3D
//長さがLの部分列の最小値
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(20);
    int N,L;
    cin>>N>>L;
    vector<ll> a(N);
    for(int i=0;i<N;i++) cin>>a[i];

    auto op=[](ll a,ll b){
        return min(a,b);
    };
    int l=0,r=0;
    SWAG<ll> swag(a,op,1LL<<35);
    vector<ll> ret(N-L+1);
    while(l<N){
        while(r<N && r-l<L){
            swag.Right();
            r++;
        }
        ll x=swag.value();
        if(r-l==L){
            ret[l]=x;
        } 
        if(r==l) swag.Right(),r++;
        swag.Left(),l++;
    }
    for(int i=0;i<ret.size();i++){
        if(i!=0) cout<<" ";
        cout<<ret[i];
    }
    cout<<endl;
}




Measured memory_bytes: 18576