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 <bits/stdc++.h>
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;
}
