You are given a permutation P_1 ... P_N of the set {1, 2, ..., N}.

You can apply the following operation to this permutation, any number of times (possibly zero):

* Choose two indices i,j (1 ≦ i < j ≦ N), such that j - i ≧ K and |P_i - P_j| = 1. Then, swap the values of P_i and P_j.



Among all permutations that can be obtained by applying this operation to the given permutation, find the lexicographically smallest one.

Constraints

* 2≦N≦500,000
* 1≦K≦N-1
* P is a permutation of the set {1, 2, ..., N}.

Input

The input is given from Standard Input in the following format:


N K
P_1 P_2 ... P_N


Output

Print the lexicographically smallest permutation that can be obtained.

Examples

Input

4 2
4 2 3 1


Output

2
1
4
3


Input

5 1
5 4 3 2 1


Output

1
2
3
4
5


Input

8 3
4 5 7 8 3 1 2 6


Output

1
2
6
7
5
3
4
8
#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;
}