#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
inline void Max(A &x, B y) {
  x = x > y ? x : y;
}
template <typename A, typename B>
inline void Min(A &x, B y) {
  x = x < y ? x : y;
}
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void putc(char x) {
  *oS++ = x;
  if (oS == oT) flush();
}
template <typename A>
inline bool read(A &x) {
  for (f = 1, c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                              (iS == iT ? EOF : *iS++))
                            : *iS++);
       c < '0' || c > '9';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    if (c == '-')
      f = -1;
    else if (c == EOF)
      return 0;
  for (x = 0; c <= '9' && c >= '0';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    x = x * 10 + (c & 15);
  x *= f;
  return 1;
}
inline bool read(char &x) {
  while ((x = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                           (iS == iT ? EOF : *iS++))
                        : *iS++)) == ' ' ||
         x == '\n' || x == '\r')
    ;
  return x != EOF;
}
inline bool read(char *x) {
  while ((*x = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                            (iS == iT ? EOF : *iS++))
                         : *iS++)) == '\n' ||
         *x == ' ' || *x == '\r')
    ;
  if (*x == EOF) return 0;
  while (!(*x == '\n' || *x == ' ' || *x == '\r' || *x == EOF))
    *(++x) = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                          (iS == iT ? EOF : *iS++))
                       : *iS++);
  *x = 0;
  return 1;
}
template <typename A, typename... B>
inline bool read(A &x, B &...y) {
  return read(x) && read(y...);
}
template <typename A>
inline bool write(A x) {
  if (!x) putc('0');
  if (x < 0) putc('-'), x = -x;
  while (x) qu[++qr] = x % 10 + '0', x /= 10;
  while (qr) putc(qu[qr--]);
  return 0;
}
inline bool write(char x) {
  putc(x);
  return 0;
}
inline bool write(const char *x) {
  while (*x) {
    putc(*x);
    ++x;
  }
  return 0;
}
inline bool write(char *x) {
  while (*x) {
    putc(*x);
    ++x;
  }
  return 0;
}
template <typename A, typename... B>
inline bool write(A x, B... y) {
  return write(x) || write(y...);
}
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
}  // namespace io
using io ::putc;
using io ::read;
using io ::write;
namespace IO2 {
char sstack[40];
template <class T>
inline bool read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  for (; c < '0' || c > '9'; c = getchar())
    if (c == '-')
      f = -1;
    else if (c == EOF)
      return 0;
  for (; '0' <= c && c <= '9'; c = getchar()) x = x * 10 + (c ^ 48);
  x *= f;
  return c != EOF;
}
inline bool read(char &x) {
  while ((x = getchar()) == ' ' || x == '\n' || x == '\r')
    ;
  return x != EOF;
}
inline bool read(char *x) {
  while ((*x = getchar()) == '\n' || *x == ' ' || *x == '\r')
    ;
  if (*x == EOF) return 0;
  while (!(*x == '\n' || *x == ' ' || *x == '\r' || *x == EOF))
    *(++x) = getchar();
  *x = 0;
  return 1;
}
template <typename A, typename... B>
inline bool read(A &x, B &...y) {
  return read(x) && read(y...);
}
inline void putc(char c) { putchar(c); }
template <typename A>
inline bool write(A x) {
  if (x < 0) putc('-'), x = -x;
  int top = 0;
  if (!x) sstack[++top] = x + '0';
  for (; x; x /= 10) sstack[++top] = x % 10 + '0';
  while (top) putc(sstack[top--]);
  return 0;
}
inline bool write(char x) {
  putchar(x);
  return 0;
}
inline bool write(const char *x) {
  while (*x) {
    putchar(*x);
    ++x;
  }
  return 0;
}
inline bool write(char *x) {
  while (*x) {
    putchar(*x);
    ++x;
  }
  return 0;
}
template <typename A, typename... B>
inline bool write(A x, B... y) {
  return write(x) || write(y...);
}
};  // namespace IO2
const int mod = 1e9 + 7;
const int Wid = 1e3 + 5;
const int maxn = 1e3 + 20;
inline void add(int &x, int y) {
  x += y;
  x = x < mod ? x : x - mod;
}
inline void mul(int &x, int y, int z = 1) { x = 1ll * x * y % mod * z % mod; }
int n, m, R;
struct node {
  int x, y, b;
} p[maxn << 1];
int sum[maxn][maxn], c[maxn << 1][maxn << 1];
int C(int n, int m) {
  if (n < m || n < 0 || m < 0) return 0;
  return c[n][m];
}
int max(int a, int b, int c) {
  return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
int min(int a, int b, int c) {
  return a < b ? (a < c ? a : c) : (b < c ? b : c);
}
int area(int lx, int ly, int rx, int ry) {
  if (lx > rx || ly > ry) return 0;
  return sum[rx][ry] - sum[lx - 1][ry] - sum[rx][ly - 1] + sum[lx - 1][ly - 1];
}
int range(int i) {
  int x = p[i].x, y = p[i].y;
  int lx = max(1, x - R), ly = max(1, y - R), rx = min(Wid, x + R),
      ry = min(Wid, y + R);
  return area(lx, ly, rx, ry);
}
int range(int i, int j) {
  int lx = max(1, p[i].x - R, p[j].x - R), ly = max(1, p[i].y - R, p[j].y - R);
  int rx = min(Wid, p[i].x + R, p[j].x + R),
      ry = min(Wid, p[i].y + R, p[j].y + R);
  return area(lx, ly, rx, ry);
}
int main() {
  read(n, m, R);
  for (int i = 0; i <= n; i++) {
    c[i][0] = 1;
    for (int j = 1; j <= i; j++)
      c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
  }
  for (int i = 1; i <= n; i++) {
    read(p[i].x, p[i].y, p[i].b);
    sum[p[i].x][p[i].y]++;
  }
  for (int i = 1; i <= Wid; i++)
    for (int j = 1; j <= Wid; j++)
      sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
  int ans = 0;
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++) {
      int W, U, V;
      W = range(i, j);
      U = range(i);
      V = range(j);
      int Y = C(n, m) - C(n - V, m) - C(n - U, m) + C(n - U - V + W, m);
      Y %= mod;
      if (Y < 0) Y += mod;
      add(Y, Y);
      mul(Y, p[i].b, p[j].b);
      add(ans, Y);
    }
  int res = ans;
  for (int i = 1; i <= n; i++) {
    int X = range(i);
    int Y = C(n, m) - C(n - X, m);
    Y = Y < 0 ? Y + mod : Y;
    mul(Y, p[i].b, p[i].b);
    add(ans, Y);
  }
  ans %= mod;
  if (ans < 0) ans += mod;
  write(ans, '\n');
  return 0;
}
