#include <bits/stdc++.h>
using namespace std;
const int INF = ~(1 << 31);
const int N = 100000;
int n;
int a[N + 1];
pair<int, int> val[N];
int ind[N];
int indsorted[N];
long long ans[N];
struct SegmentTreeInd {
  vector<int> t;
  SegmentTreeInd() {
    t.resize((1 << (33 - __builtin_clz(n - 1))) - 1);
    build(0, 0, n - 1);
  }
  void build(int v, int tl, int tr);
  void remove(int v, int tl, int tr, int x);
  int query(int v, int tl, int tr, int l, int r);
};
void SegmentTreeInd::build(int v, int tl, int tr) {
  if (tl == tr)
    t[v] = tl;
  else {
    build(v * 2 + 1, tl, (tl + tr) / 2);
    build(v * 2 + 2, (tl + tr) / 2 + 1, tr);
    t[v] = a[t[v * 2 + 1]] <= a[t[v * 2 + 2]] ? t[v * 2 + 1] : t[v * 2 + 2];
  }
}
void SegmentTreeInd::remove(int v, int tl, int tr, int x) {
  if (tl == tr)
    t[v] = n;
  else {
    if (x <= (tl + tr) / 2)
      remove(v * 2 + 1, tl, (tl + tr) / 2, x);
    else
      remove(v * 2 + 2, (tl + tr) / 2 + 1, tr, x);
    t[v] = a[t[v * 2 + 1]] <= a[t[v * 2 + 2]] ? t[v * 2 + 1] : t[v * 2 + 2];
  }
}
int SegmentTreeInd::query(int v, int tl, int tr, int l, int r) {
  if (tr < l || tl > r)
    return n;
  else if (tl >= l && tr <= r)
    return t[v];
  int a1 = query(v * 2 + 1, tl, (tl + tr) / 2, l, r);
  int a2 = query(v * 2 + 2, (tl + tr) / 2 + 1, tr, l, r);
  return a[a1] <= a[a2] ? a1 : a2;
}
struct SegmentTreeVal {
  vector<int> t;
  SegmentTreeVal() {
    t.resize((1 << (33 - __builtin_clz(n - 1))) - 1);
    build(0, 0, n - 1);
  }
  void build(int v, int tl, int tr);
  void remove(int v, int tl, int tr, int x);
  int query(int v, int tl, int tr, int l, int r);
};
void SegmentTreeVal::build(int v, int tl, int tr) {
  if (tl == tr)
    t[v] = ind[tl];
  else {
    build(v * 2 + 1, tl, (tl + tr) / 2);
    build(v * 2 + 2, (tl + tr) / 2 + 1, tr);
    t[v] = min(t[v * 2 + 1], t[v * 2 + 2]);
  }
}
void SegmentTreeVal::remove(int v, int tl, int tr, int x) {
  if (tl == tr)
    t[v] = INF;
  else {
    if (x <= (tl + tr) / 2)
      remove(v * 2 + 1, tl, (tl + tr) / 2, x);
    else
      remove(v * 2 + 2, (tl + tr) / 2 + 1, tr, x);
    t[v] = min(t[v * 2 + 1], t[v * 2 + 2]);
  }
}
int SegmentTreeVal::query(int v, int tl, int tr, int l, int r) {
  if (tr < l || tl > r)
    return INF;
  else if (tl >= l && tr <= r)
    return t[v];
  return min(query(v * 2 + 1, tl, (tl + tr) / 2, l, r),
             query(v * 2 + 2, (tl + tr) / 2 + 1, tr, l, r));
}
int main() {
  int p;
  scanf("%d%d", &n, &p);
  for (int i = 0; i < n; ++i) {
    scanf("%d", a + i);
    val[i] = make_pair(a[i], i);
  }
  sort(val, val + n);
  for (int i = 0; i < n; ++i) {
    ind[i] = val[i].second;
    indsorted[val[i].second] = i;
  }
  a[n] = INF;
  SegmentTreeInd trInd;
  SegmentTreeVal trVal;
  long long t = 0;
  int cur = trInd.query(0, 0, n - 1, 0, n - 1);
  while (cur != n) {
    if (cur == n) break;
    t = max((long long)a[cur], t) + p;
    ans[cur] = t;
    trInd.remove(0, 0, n - 1, cur);
    trVal.remove(0, 0, n - 1, indsorted[cur]);
    while (cur > 0 && a[cur = trInd.query(0, 0, n - 1, 0, cur - 1)] < t &&
           cur != n) {
      t += p;
      ans[cur] = t;
      trInd.remove(0, 0, n - 1, cur);
      trVal.remove(0, 0, n - 1, indsorted[cur]);
    }
    int i;
    if (t >= INF)
      i = n - 1;
    else {
      pair<int, int> aux((int)t, INF);
      i = upper_bound(val, val + n, aux) - val - 1;
    }
    cur = trVal.query(0, 0, n - 1, 0, i);
    if (cur == INF) cur = trInd.query(0, 0, n - 1, 0, n - 1);
  }
  for (int i = 0; i < n; ++i) printf("%lld ", ans[i]);
  printf("\n");
  return 0;
}
