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;

#define sz(x) ((int) ((x).size()))
typedef long long ll;
typedef long double ld;

struct treap {
	struct node {
		int size,prio,val;
		node *l=0,*r=0,*p=0;
	} *root=0;
	int get(node *n) { return n?n->size:0; }
	void upd(node *n) {
		if (n) {
			n->size=1+get(n->l)+get(n->r);
      if (n->l)
        n->l->p = n;
      if (n->r)
        n->r->p = n;
      n->p = 0;
    }
	}
	void split(node *n, node *&l, node *&r, int key, int add=0) {
		if (!n)
			return void(l=r=0);
		int nkey=add+get(n->l)+1;
		if (nkey<key)
			split(n->r,n->r,r,key,nkey),l=n;
		else
			split(n->l,l,n->l,key,add),r=n;
		upd(n);
	}
	void merge(node *l, node *r, node *&n) {
		if (!l||!r)
			n=l?l:r;
		else if (l->prio>r->prio)
			merge(l->r,r,l->r),n=l;
		else
			merge(l,r->l,r->l),n=r;
		upd(n);
	}
	node * insert(int pos, int val) {
		node *n=new node();
		n->prio=rand(),n->val=val;
		node *l,*r;
		split(root,l,r,pos);
		merge(l,n,l);
		merge(l,r,root);
    return n;
	}
  int getPos(node * n) {
    if (n->p && n->p->l == n)
      return getPos(n->p) + get(n->l) - get(n);
    else if (n->p && n->p->r == n)
      return getPos(n->p) + get(n->l) + 1;
    else
      return get(n->l) + 1;
  }
	int get(int pos) {
		node *l,*n,*r;
		split(root,l,r,pos);
		split(r,n,r,2);
		int res=n?n->val:0;
		merge(l,n,l);
		merge(l,r,root);
		return res;
	}
} tr;

int n, k, p[600000], pos[600000];
treap::node * nodes[600000];

#define MAXN 600000
#define left(i) (2 * (i) + 1)
#define right(i) (2 * (i) + 2)
#define parent(i) (((i) - 1) / 2)

const int logmaxn = (int) log2(MAXN) + 1;
const int ts = 1 << (logmaxn + 1), to = (1 << logmaxn) - 1;

struct data {
  int v = -1;
};

struct operation {
  int a = -1;
};

data t[ts];
operation o[ts];

int getMax(int a, int b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return tr.getPos(nodes[a]) > tr.getPos(nodes[b]) ? a : b;
}

// combine the data from different branches
data combine(data l, data r) {
  return {getMax(l.v, r.v)};
}

// apply an operation on top of an other operation
operation combine(operation ot, operation ob) {
  return {getMax(ot.a, ob.a)};
}

// apply an operation on a range with data
data apply(operation ot, data d) {
  return {getMax(ot.a, d.v)};
}

data getValue(int x) {
  return apply(o[x], t[x]);
}

void calcValue(int x) {
  t[x] = combine(getValue(left(x)), getValue(right(x)));
}

void propagate(int x) {
  o[left(x)] = combine(o[x], o[left(x)]);
  o[right(x)] = combine(o[x], o[right(x)]);
  o[x] = operation();
}

// query the data on the range [a, b[
data query(int a, int b, int x = 0, int l = 0, int r = 1 << logmaxn) {
  if (a <= l && r <= b)
    return getValue(x);
  if (b <= l || r <= a)
    return data();
  int m = (l + r) / 2;
  propagate(x);
  data d = combine(query(a, b, left(x), l, m), query(a, b, right(x), m, r));
  calcValue(x);
  return d;
}

// apply an operation on the range [a, b[
void apply(int a, int b, operation v, int x = 0, int l = 0, int r = 1 << logmaxn) {
  if (a <= l && r <= b) {
    o[x] = combine(v, o[x]);
    return;
  }
  if (b <= l || r <= a)
    return;
  int m = (l + r) / 2;
  propagate(x);
  apply(a, b, v, left(x), l, m);
  apply(a, b, v, right(x), m, r);
  calcValue(x);
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(10);
  cin >> n >> k;
  for (int i = 0; i < n; i++)
    cin >> p[i], p[i]--, pos[p[i]] = i;
  // for (int i = 0; i < n; i++)
  //   cerr << pos[i] << (i < n - 1 ? " " : "\n");
  for (int i = 0; i < n; i++) {
    int inspos = 0;
    int j = query(0, pos[i] + k).v;
    // cerr << "j: " << j << "\n";
    if (j >= 0) {
      inspos = max(inspos, tr.getPos(nodes[j]));
      // cerr << "pos: " << tr.getPos(nodes[j]) - 1 << "\n";
    }
    nodes[pos[i]] = tr.insert(inspos + 1, pos[i]);
    apply(pos[i], pos[i] + 1, {pos[i]});
    // cerr << "cur:";
    // for (int j = 0; j <= i; j++)
    //   cerr << " " << tr.get(j + 1);
    // cerr << "\n";
  }
  for (int i = 0; i < n; i++)
    pos[i] = tr.get(i + 1), p[pos[i]] = i;
  for (int i = 0; i < n; i++)
    cout << p[i] + 1 << "\n";
}
