#include <bits/stdc++.h>
using namespace std;
long long const INF = INT64_MAX;
struct edge {
  long long w;
  int u;
  int v;
  bool operator<(const edge& a) const { return w < a.w; }
};
struct SegmentTree {
 private:
  int n;
  vector<pair<long long, int> > node;

 public:
  SegmentTree(vector<pair<long long, int> > v) {
    int sz = v.size();
    n = 1;
    while (n < sz) n *= 2;
    node.resize(2 * n - 1, pair<long long, int>(INF, -1));
    for (int i = 0; i < sz; ++i) node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; --i)
      node[i] = min(node[2 * i + 1], node[2 * i + 2]);
  }
  void update(int x, pair<long long, int> val) {
    x += (n - 1);
    node[x] = val;
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = min(node[2 * x + 1], node[2 * x + 2]);
    }
  }
  pair<long long, int> getmin(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    if (r <= a || b <= l) return pair<long long, int>(INF, -1);
    if (a <= l && r <= b) return node[k];
    pair<long long, int> vl = getmin(a, b, 2 * k + 1, l, (l + r) / 2);
    pair<long long, int> vr = getmin(a, b, 2 * k + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
};
struct UnionFind {
 private:
  vector<int> par, depth;

 public:
  UnionFind(int n) {
    par.resize(n);
    depth = vector<int>(n, 0);
    for (int i = 0; i < n; ++i) par[i] = i;
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (depth[x] < depth[y])
      par[x] = y;
    else {
      par[y] = x;
      if (depth[x] == depth[y]) depth[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
int main() {
  int n;
  long long d, ans = 0;
  cin >> n >> d;
  vector<long long> a(n);
  vector<pair<long long, int> > b;
  vector<edge> edgelist;
  SegmentTree segL(
      vector<pair<long long, int> >(n, pair<long long, int>(INF, -1))),
      segR(vector<pair<long long, int> >(n, pair<long long, int>(INF, -1)));
  UnionFind kruskal(n);
  for (int i = 0; i < n; ++i) cin >> a[i];
  for (int i = 0; i < n; ++i) b.push_back(pair<long long, int>(a[i], i));
  sort(b.begin(), b.end());
  for (pair<long long, int> p : b) {
    int i = p.second;
    pair<long long, int> mnL = segL.getmin(0, i), mnR = segR.getmin(i, n);
    if (mnL.first < INF) {
      int j = mnL.second;
      edgelist.push_back(edge{a[i] + a[j] + (long long)(i - j) * d, i, j});
    }
    if (mnR.first < INF) {
      int j = mnR.second;
      edgelist.push_back(edge{a[i] + a[j] + (long long)(j - i) * d, i, j});
    }
    segL.update(i, pair<long long, int>(a[i] + (long long)(n - i) * d, i));
    segR.update(i, pair<long long, int>(a[i] + (long long)i * d, i));
  }
  sort(edgelist.begin(), edgelist.end());
  for (edge e : edgelist) {
    cout << e.u << " " << e.v << " " << e.w << endl;
    if (kruskal.same(e.u, e.v)) continue;
    ans += e.w;
    kruskal.unite(e.u, e.v);
  }
  cout << ans << endl;
  return 0;
}
