#include <bits/stdc++.h>
using namespace std;
const long long Maxn = 3e5 + 100;
const long long Maxm = 305;
template <typename Temp>
inline void read(Temp& res) {
  Temp fh = 1;
  res = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') fh = -1;
  for (; isdigit(ch); ch = getchar())
    res = (res << 3) + (res << 1) + (ch ^ '0');
  res = res * fh;
}
template <typename Temp>
inline void Checkmax(Temp& num, Temp comp) {
  num = (num > comp ? num : comp);
}
template <typename Temp>
inline void Checkmin(Temp& num, Temp comp) {
  num = (num < comp ? num : comp);
}
long long Abs(long long A) { return A < 0 ? 0 - A : A; }
struct Monoque {
  long long array[Maxn];
  long long Head, Tail;
  Monoque() {
    Head = 1;
    Tail = 0;
  }
  inline void pushback(long long num) {
    Tail++;
    array[Tail] = num;
  }
  inline void popback() {
    if (Head > Tail) return;
    Tail--;
  }
  inline void popfront() {
    if (Head > Tail) return;
    Head++;
  }
  inline long long Front() { return array[Head]; }
  inline long long Back() { return array[Tail]; }
  inline bool emp() { return Head > Tail; }
  inline void Clear() {
    Head = 1;
    Tail = 0;
  }
  long long Maxset;
  inline void setmax(long long num) { Maxset = num; }
  inline void push(long long num) {
    if (Tail - Head + 1 == Maxset) popfront();
    while ((!emp()) && (Back() < num)) popback();
    pushback(num);
  }
  inline long long getmax() { return Front(); }
};
struct monoque {
  deque<long long> deq;
  long long Maxset;
  inline void setmax(long long num) { Maxset = num; }
  inline void push(long long num) {
    if (deq.size() == Maxset) deq.pop_front();
    while ((!deq.empty()) && (deq.back() < num)) deq.pop_back();
    deq.push_back(num);
  }
  inline long long getmax() { return deq.empty() ? -0x7fffffff : deq.front(); }
  inline void Clear() { deq.clear(); }
} q;
long long n, m, d;
long long t[Maxm], a[Maxm];
long long b[Maxm];
long long f[2][Maxn], ans;
signed main() {
  read(n);
  read(m);
  read(d);
  for (register long long i = 1; i <= m; ++i) {
    read(a[i]);
    read(b[i]);
    read(t[i]);
  }
  t[0] = 1;
  for (register long long i = 1; i <= n; ++i) {
    f[1][i] = b[1] - (long long)(Abs(a[1] - i));
  }
  for (register long long i = 2; i <= m; ++i) {
    q.Clear();
    q.setmax((t[i] - t[i - 1]) * d * 2 + 1);
    for (register long long j = 1; j <= min(n, (t[i] - t[i - 1]) * d); ++j) {
      q.push(f[i - 1 & 1][j]);
    }
    for (register long long j = 1; j <= n; ++j) {
      long long pos = (j + ((t[i] - t[i - 1]) * d)), N = n;
      if (pos <= N)
        q.push(f[i - 1 & 1][j + ((t[i] - t[i - 1]) * d)]);
      else
        q.push(-0x7fffffff);
      f[i & 1][j] = q.getmax() + b[i] - (long long)(Abs(a[i] - j));
    }
  }
  ans = -0x7fffffff;
  for (register long long i = 1; i <= n; ++i) {
    Checkmax(ans, f[m & 1][i]);
  }
  printf("%lld", ans);
  return 0;
}
