#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-9;
const long double pi = 4 * atan(1.0);
const int inf = 100500;
bool lt(long double a, long double b) { return b - a > eps; }
bool eq(long double a, long double b) { return abs(a - b) <= eps; }
bool leq(long double a, long double b) { return lt(a, b) || eq(a, b); }
bool gt(long double a, long double b) { return a - b > eps; }
bool geq(long double a, long double b) { return gt(a, b) || eq(a, b); }
struct pt {
  long double x, y;
  pt() : x(0), y(0) {}
  pt(long double x, long double y) : x(x), y(y) {}
  pt operator-(const pt& other) const { return {x - other.x, y - other.y}; }
  pt operator+(const pt& other) const { return {x + other.x, y + other.y}; }
  pt operator*(long double k) const { return {x * k, y * k}; }
};
const pt origin = {0, 0};
struct line {
  long double a, b, c;
  line() {}
  line(long double aa, long double bb, long double cc) {
    long double tmp = sqrt(aa * aa + bb * bb);
    a = aa / tmp;
    b = bb / tmp;
    c = cc / tmp;
  }
};
long double dist(const pt& p, const line& l) {
  return abs(p.x * l.a + p.y * l.b + l.c);
}
long double dist(const pt& p, const pt& q) {
  return sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y));
}
pt ortho(const pt& p, const line& l) {
  long double alpha = (-p.x * l.a - p.y * l.b - l.c);
  pt n = {l.a, l.b};
  return p + n * alpha;
}
struct circle {
  pt c;
  long double r;
};
vector<pt> intersect(const line& l, const circle& c) {
  long double d = dist(c.c, l);
  if (gt(d, c.r)) {
    return {};
  }
  pt h = ortho(c.c, l);
  if (eq(d, c.r)) {
    return {h};
  }
  long double t = sqrt(c.r * c.r - d * d);
  pt a = {l.b, -l.a};
  return {h + a * t, h - a * t};
}
long double polar(const pt& p) {
  long double ans = atan2(p.y, p.x);
  while (lt(ans, 0)) {
    ans += 2 * pi;
  }
  return ans;
}
vector<int> t;
int N;
void update(int l, int r, int val) {
  for (l += N, r += N; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
    if (l & 1) {
      t[l] += val;
    }
    if (!(r & 1)) {
      t[r] += val;
    }
  }
}
int get(int pos) {
  int ans = 0;
  for (pos += N; pos; pos >>= 1) {
    ans += t[pos];
  }
  return ans;
}
int count(long double angle, long double d, const circle& c) {
  line l(sin(angle), -cos(angle), 0);
  vector<pt> v = intersect(l, c);
  if (v.empty()) {
    return 0;
  }
  long double x = dist(origin, v[0]);
  long double y = dist(origin, v.back());
  if (lt(y, x)) {
    swap(x, y);
  }
  int lf = 0, rg = inf;
  while (lf < rg - 1) {
    int md = (lf + rg) >> 1;
    if (geq(d * md, x)) {
      rg = md;
    } else {
      lf = md;
    }
  }
  int t = rg;
  int ans = 0;
  for (long double R = d * t; leq(R, y); R += d) {
    ++ans;
  }
  return ans;
}
int main() {
  int n;
  cin >> n;
  long double d;
  cin >> d;
  vector<circle> circles(n);
  for (int i = 0; i < n; ++i) {
    cin >> circles[i].c.x >> circles[i].c.y >> circles[i].r;
  }
  vector<vector<long double> > v(n);
  vector<long double> angles;
  for (int i = 0; i < n; ++i) {
    long double x = dist(origin, circles[i].c) - circles[i].r;
    long double x0 = circles[i].c.x;
    long double y0 = circles[i].c.y;
    long double y = dist(origin, circles[i].c) + circles[i].r;
    int lf = 0, rg = inf;
    while (lf < rg - 1) {
      int md = (lf + rg) >> 1;
      if (geq(d * md, x)) {
        rg = md;
      } else {
        lf = md;
      }
    }
    int c = rg;
    for (long double R = d * c; leq(R, y); R += d) {
      line l(-2.0 * x0, -2.0 * y0,
             x0 * x0 + y0 * y0 + R * R - circles[i].r * circles[i].r);
      vector<pt> p = intersect(l, {origin, R});
      for (pt& point : p) {
        v[i].push_back(polar(point));
        angles.push_back(polar(point));
      }
    }
    sort((v[i]).begin(), (v[i]).end());
    v[i].resize(unique((v[i]).begin(), (v[i]).end()) - v[i].begin());
    if (!v[i].empty()) {
      if (lt(v[i][0], pi / 2) && geq(v[i].back(), 3 * pi / 2)) {
        for (int j = 0; j < (int)(v[i]).size(); ++j) {
          if (gt(v[i][j], pi)) {
            v[i][j] -= 2 * pi;
          }
        }
        sort((v[i]).begin(), (v[i]).end());
        for (int j = 0; j < (int)(v[i]).size(); ++j) {
          if (lt(v[i][j], 0)) {
            v[i][j] += 2 * pi;
          }
        }
      }
    }
  }
  sort((angles).begin(), (angles).end());
  angles.resize(unique((angles).begin(), (angles).end()) - angles.begin());
  N = (int)(angles).size();
  t.resize(2 * N);
  for (int i = 0; i < n; ++i) {
    for (long double angle : v[i]) {
      int c = count(angle, d, circles[i]);
      int pos =
          lower_bound((angles).begin(), (angles).end(), angle) - angles.begin();
      update(pos, pos, c);
    }
    for (int j = 0; j < (int)(v[i]).size() - 1; ++j) {
      long double angle = (v[i][j] + v[i][j + 1]) / 2.0;
      int c = count(angle, d, circles[i]);
      int l = lower_bound((angles).begin(), (angles).end(), v[i][j]) -
              angles.begin();
      int r = lower_bound((angles).begin(), (angles).end(), v[i][j + 1]) -
              angles.begin();
      if (l <= r) {
        update(l + 1, r - 1, c);
      } else {
        update(l + 1, N - 1, c);
        update(0, r - 1, c);
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < N; ++i) {
    ans = max(ans, get(i));
  }
  cout << ans << "\n";
}
