#include <bits/stdc++.h>
using namespace std;
const int S = 1010;
const int N = 2010;
const int oo = 1e9 + 7;
int f[S][S];
struct Snake {
  int x, y, snakes;
  long long d;
} s[N];
long long pow(long long x, int y) {
  if (x == 0) return 0;
  x %= oo;
  long long res = 1;
  for (; y; x = x * x % oo, y >>= 1)
    if (y & 1) res = res * x % oo;
  return res;
}
long long fac[N], fac_inv[N];
void init(int n) {
  fac[0] = fac_inv[0] = 1;
  fac[1] = fac_inv[1] = 1;
  for (int i = 2; i <= n; ++i) {
    fac[i] = fac[i - 1] * i % oo;
  }
  fac_inv[n] = pow(fac[n], oo - 2);
  for (int i = n - 1; i > 1; --i) {
    fac_inv[i] = fac_inv[i + 1] * (i + 1) % oo;
  }
}
long long C(int x, int y) {
  if (x < y || x <= 0 || y <= 0) return 0;
  return fac[x] * fac_inv[y] % oo * fac_inv[x - y] % oo;
}
int get_snakes(int x, int y, int p, int q) {
  x = min(max(x, 1), 1000);
  y = min(max(y, 1), 1000);
  p = min(max(p, 1), 1000);
  q = min(max(q, 1), 1000);
  return f[p][q] - f[x - 1][q] - f[p][y - 1] + f[x - 1][y - 1];
}
array<int, 4> intersection(int x, int y, int p, int q, int r) {
  if (abs(x - p) > r * 2 || abs(y - q) > r * 2) return {oo, oo, oo, oo};
  int a[4] = {x - r, p - r, x + r, p + r};
  sort(a, a + 4);
  int X = a[1], P = a[2];
  int b[4] = {y - r, q - r, y + r, q + r};
  sort(b, b + 4);
  int Y = b[1], Q = b[2];
  return {X, Y, P, Q};
}
int main() {
  int n, m, r;
  scanf("%d%d%d", &n, &m, &r);
  init(n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d%lld", &s[i].x, &s[i].y, &s[i].d);
    f[s[i].x][s[i].y]++;
  }
  for (int i = 1; i <= 1000; ++i)
    for (int j = 1; j <= 1000; ++j)
      f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
  long long all_plans = C(n, m);
  long long ans1 = 0;
  for (int i = 1; i <= n; ++i) {
    s[i].snakes = get_snakes(s[i].x - r, s[i].y - r, s[i].x + r, s[i].y + r);
    if (0)
      printf("snakes around #%d (%d, %d): %d\n", i, s[i].x, s[i].y,
             s[i].snakes);
    long long res = (all_plans - C(n - s[i].snakes, m) + oo) % oo * s[i].d %
                    oo * s[i].d % oo;
    if (0) printf("snake #%d square contributes: %lld\n", i, res);
    ans1 += res;
  }
  ans1 = (ans1 % oo + oo) % oo;
  if (m == 1) {
    printf("%lld\n", ans1);
    return 0;
  }
  long long ans2 = 0;
  for (int i = 1; i < n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      auto in = intersection(s[i].x, s[i].y, s[j].x, s[j].y, r);
      int X = s[i].snakes, Y = s[j].snakes, Z = 0;
      if (in[0] != oo) {
        Z = get_snakes(in[0], in[1], in[2], in[3]);
      }
      if (0) printf("snake (#%d, #%d) X=%d Y=%d Z=%d\n", i, j, X, Y, Z);
      long long tot =
          all_plans - C(n - X, m) - C(n - Y, m) + C(n - (X + Y - Z), m);
      tot = (tot % oo + oo) % oo;
      long long res = s[i].d * s[j].d * 2 % oo * tot % oo;
      if (0) printf("snake (#%d, #%d) contributes: %lld\n", i, j, res);
      ans2 += res;
    }
  ans2 = (ans2 % oo + oo) % oo;
  long long ans = (ans1 + ans2) % oo;
  printf("%lld\n", ans);
  return 0;
}
