// Slower C++ solution:
#include<cstdio>

#include<queue>

#include<cstring>

#include<algorithm>

using namespace std;

#define MAXN 500010

int a[MAXN],n,k,ans[MAXN];

int t[MAXN*4];

int Query(int i,int l,int r,int L,int R)

{

	if(L>R) return t[0];

	if(L<=l&&r<=R) return t[i];

	int mid=(l+r)/2;

	if(R<=mid) return Query(i<<1,l,mid,L,R);

	if(L>mid) return Query(i<<1|1,mid+1,r,L,R);

	return min(Query(i<<1,l,mid,L,R),Query(i<<1|1,mid+1,r,L,R));

}

void Change(int i,int l,int r,int p,int w)

{

	if(l==r)

	{

		t[i]=w;

		return;

	}

	int mid=(l+r)/2;

	if(p<=mid) Change(i<<1,l,mid,p,w);

	else Change(i<<1|1,mid+1,r,p,w);

	t[i]=min(t[i<<1|1],t[i<<1]);

}

int Adj[MAXN],V[MAXN*2],nxt[MAXN*2],c,d[MAXN];

void AddEdge(int u,int v)

{

	d[v]++;c++;V[c]=v,nxt[c]=Adj[u];Adj[u]=c;

}

priority_queue<int ,vector<int>,greater<int> >Q;

void TopSort()

{

	for(int i=1;i<=n;i++) if(!d[i]) Q.push(i);

	int tot=0;

	while(!Q.empty())

	{

		int u=Q.top();Q.pop();

		ans[u]=++tot;

		for(int i=Adj[u];i;i=nxt[i])

			if(!--d[V[i]])

				Q.push(V[i]);

	}

}

int main()

{

//	freopen("swap.in","r",stdin);

//	freopen("swap.out","w",stdout);

	scanf("%d%d",&n,&k);

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

	{

		int x;

		scanf("%d",&x);

		a[x]=i;

	}

	if(k<=1)

	{

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

			printf("%d\n",i);

		return 0;

	}

	memset(t,0x3f3f3f3f,sizeof t);

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

	{

		int x=Query(1,1,n,a[i]+1,min(a[i]+k-1,n));

		if(x<1e9) AddEdge(a[i],a[x]);

		x=Query(1,1,n,max(a[i]-k+1,1),a[i]-1);

		if(x<1e9) AddEdge(a[i],a[x]);

		Change(1,1,n,a[i],i);

	}

	TopSort();

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

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

}

// Faster C++ solution for the same problem (measured speedup: 1.7808524493969826x):
/*Lucky_Glass*/

#include<queue>

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;



inline int Read(){

	register int r=0,c=getchar();

	while(c<'0' || '9'<c) c=getchar();

	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();

	return r;

}



#define cs const int &

const int N=5e5+10;



int n,m,num[N],ans[N];

priority_queue< int,vector<int>,greater<int> > que;



struct SEGTREE{

	int mn[N<<1],inf;

	SEGTREE(){memset(mn,0x3f,sizeof mn),inf=mn[0];}

	#define idx(l,r) (((l)+(r))|((l)!=(r)))

	inline void PushUp(cs le,cs ri){

		int mi=(le+ri)>>1;

		mn[idx(le,ri)]=min(mn[idx(le,mi)],mn[idx(mi+1,ri)]);

	}

	inline void Modify(cs le,cs ri,cs po,cs key){

		if(le==ri){mn[idx(le,ri)]=key;return;}

		int mi=(le+ri)>>1;

		if(po<=mi) Modify(le,mi,po,key);

		else Modify(mi+1,ri,po,key);

		PushUp(le,ri);

	}

	inline int Query(cs le,cs ri,cs Le,cs Ri){

		if(Le>Ri || ri<Le || Ri<le) return inf;

		if(Le<=le && ri<=Ri) return mn[idx(le,ri)];

		int mi=(le+ri)>>1;

		return min(Query(le,mi,Le,Ri),Query(mi+1,ri,Le,Ri));

	}

}Se;



struct GRAPH{

	int head[N],nxt[N<<1],to[N<<1],du[N],ncnt;

	void AddEdge(int u,int v){

		ncnt++;

		nxt[ncnt]=head[u],to[ncnt]=v,head[u]=ncnt;

		du[v]++;

	}

	int operator [](const int &u){return head[u];}

}Gr;



int main(){

	n=Read(),m=Read();

	for(int i=1;i<=n;i++) num[Read()]=i;

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

		int j=Se.Query(1,n,num[i]+1,num[i]+m-1),k=Se.Query(1,n,num[i]-m+1,num[i]-1);

		if(j!=Se.inf) Gr.AddEdge(num[i],num[j]);

		if(k!=Se.inf) Gr.AddEdge(num[i],num[k]);

		Se.Modify(1,n,num[i],i);

	}

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

		if(!Gr.du[i])

			que.push(i);

	int nans=0;

	while(!que.empty()){

		int u=que.top();que.pop();

		ans[u]=++nans;

		for(int it=Gr[u];it;it=Gr.nxt[it]){

			Gr.du[Gr.to[it]]--;

			if(!Gr.du[Gr.to[it]])

				que.push(Gr.to[it]);

		}

	}

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

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

	return 0;

}