// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



constexpr int N = 5e5 + 10;

constexpr int MOD = 1e9 + 7;



int n, k, a[N], fen[N], p[N], d[N], lazy[4 * N];

pair <int, int> tree[4 * N];



void upd (int x, int val) {

    for (; x < N; x += x & (-x))

        fen[x] += val;

}



int get (int x) {

    int ret = 0;

    for (; x; x -= x & (-x))

        ret += fen[x];

    return ret;

}



void build (int b, int e, int idx) {

    if (b + 1 == e) {

        tree[idx] = {d[b], b};

        return;

    }

    int mid = (b + e) >> 1,

                lidx = idx << 1, ridx = lidx | 1;

    build (b, mid, lidx);

    build (mid, e, ridx);

    if (tree[ridx].first <= tree[lidx].first)

        tree[idx] = tree[ridx];

    else

        tree[idx] = tree[lidx];

}



void shift (int b, int e, int idx) {

    int lidx = idx << 1, ridx = lidx | 1;

    tree[lidx].first -= lazy[idx];

    tree[ridx].first -= lazy[idx];

    lazy[ridx] += lazy[idx];

    lazy[lidx] += lazy[idx];

    lazy[idx] = 0;

}



void dec (int b, int e, int l, int r, int idx) {

    if (b >= r || e <= l)

        return;

    if (b >= l && e <= r) {

        tree[idx].first--;

        lazy[idx]++;

        return;

    }

    int mid = (b + e) >> 1,

                lidx = idx << 1, ridx = lidx | 1;

    shift (b, e, idx);

    dec (b, mid, l, r, lidx);

    dec (mid, e, l, r, ridx);

    if (tree[ridx].first <= tree[lidx].first)

        tree[idx] = tree[ridx];

    else

        tree[idx] = tree[lidx];

}



void change (int b, int e, int pos, int idx) {

    if (b + 1 == e) {

        tree[idx] = {1e9, b};

        return;

    }

    int mid = (b + e) >> 1,

                lidx = idx << 1, ridx = lidx | 1;

    shift (b, e, idx);

    if (pos >= mid)

        change (mid, e, pos, ridx);

    else

        change (b, mid, pos, lidx);

    if (tree[ridx].first <= tree[lidx].first)

        tree[idx] = tree[ridx];

    else

        tree[idx] = tree[lidx];

}



int main() {

    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

    cin >> n >> k;

    for (int i = 1; i <= n; i++)

        cin >> a[i];

    for (int i = 1; i <= n; i++) {

        upd (a[i], 1);

        if (i > k)

            upd (a[i - k], -1);

        d[i] = get (N - 1) - get (a[i]);

    }

    memset (fen, 0, sizeof (fen));

    for (int i = n; i; i--) {

        upd (a[i], 1);

        if (i <= n - k)

            upd (a[i + k], -1);

        d[i] += get (N - 1) - get (a[i]);

    }

    build (1, n + 1, 1);

    int now = n;

    while (now) {

        int pos = tree[1].second;

        p[pos] = now;

        now--;

        dec (1, n + 1, max (1, pos - k + 1), min (n + 1, pos + k), 1);

        change (1, n + 1, pos, 1);

    }

    for (int i = 1; i <= n; i++)

        cout << p[i] << '\n';

    return 0;

}


// Optimized solution to the same problem (faster):
#include<queue>

#include<cstdio>

#include<algorithm>

using namespace std;

const int maxn=500005;

int n,K,P[maxn],ans[maxn];priority_queue<int> H;bool vis[maxn];

inline int read()

{

	int ret=0,f=1;char ch=getchar();

	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}

	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}

	return ret*f;

}

struct SegmentTree

{

	int Tree[maxn*4];

	inline void PushUp(int rt){Tree[rt]=(P[Tree[rt*2]]<P[Tree[rt*2+1]]?Tree[rt*2+1]:Tree[rt*2]);}

	inline void Build(int L=1,int R=n,int rt=1)

	{

		if(L==R){Tree[rt]=L;return;}

		int M=(L+R)>>1;

		Build(L,M,rt*2);

		Build(M+1,R,rt*2+1);

		PushUp(rt);

	}

	inline void Update(int P,int L=1,int R=n,int rt=1)

	{

		if(L==R) return;

		int M=(L+R)>>1;

		if(P<=M) Update(P,L,M,rt*2);

		if(M<P) Update(P,M+1,R,rt*2+1);

		PushUp(rt);

	}

	inline int Query(int LL,int RR,int L=1,int R=n,int rt=1)

	{

		if(LL<=L&&R<=RR) return Tree[rt];

		int ret=0,M=(L+R)>>1;

		if(LL<=M)

		{

			int tep=Query(LL,RR,L,M,rt*2);

			if(P[tep]>P[ret]) ret=tep;

		}

		if(M<RR)

		{

			int tep=Query(LL,RR,M+1,R,rt*2+1);

			if(P[tep]>P[ret]) ret=tep;

		}

		return ret;

	}

}ST;

inline void Solve()

{

	for(int i=1;i<=n;i+=K)

	{

		int t=ST.Query(i,min(n,i+K-1));

		if(t==ST.Query(max(1,t-K+1),min(n,t+K-1)))

		{H.push(t);vis[t]=true;}

	}

	for(int i=n;i;i--)

	{

		int qh=H.top();H.pop();ans[qh]=i;

		P[qh]=0;ST.Update(qh);

		for(int j=(qh-1)/K;j<=(qh-1)/K+2;j++)

		{

			int L=(j-1)*K+1,R=j*K;

			if(L>n||R<1) continue;

			L=max(1,L);R=min(n,R);

			int t=ST.Query(L,R);

			if(t&&t==ST.Query(max(1,t-K+1),min(n,t+K-1))&&!vis[t])

			{H.push(t);vis[t]=true;}

		}

	}

}

int main()

{

	n=read();K=read();

	for(int i=1;i<=n;i++) P[i]=read();

	ST.Build();

	Solve();

	for(int i=1;i<=n;i++)

		printf("%d\n",ans[i]);

	return 0;

}

// Fastest known solution for this problem: