#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T SQR(T x) {
  return x * x;
}
template <class T>
inline string TOSTR(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
template <class T>
void UPDATE_MIN(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <class T>
void UPDATE_MAX(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
template <typename K, typename V>
V GetWithDef(const std::map<K, V> &m, const K &key, const V &defval) {
  typename std::map<K, V>::const_iterator it = m.find(key);
  if (it == m.end()) {
    return defval;
  } else {
    return it->second;
  }
}
int arr[30001] = {};
int maxes[30001][1000];
int NMAX, N, d0;
int main() {
  cin >> N >> d0;
  for (int(i) = 0; (i) < (int)(N); (i)++) {
    int j;
    cin >> j;
    arr[j]++;
    UPDATE_MAX(NMAX, j);
  }
  for (int(i) = 0; (i) < (int)(30001); (i)++)
    for (int(j) = 0; (j) < (int)(1000); (j)++) maxes[i][j] = -1;
  int offset = (((1) > (d0 - 250)) ? (1) : (d0 - 250));
  maxes[d0][d0 - offset] = arr[0] + arr[d0];
  int min_d = d0;
  int max_d = d0;
  int MAX_ALL = arr[0] + arr[d0];
  for (int(pos) = d0; (pos) < (int)(NMAX + 1); (pos)++) {
    for (int(j) = min_d; (j) < (int)(max_d + 1); (j)++) {
      int mx_prev = maxes[pos][j - offset];
      if (mx_prev == -1) continue;
      int min_jmp = (((1) > (j - 1)) ? (1) : (j - 1));
      int max_jmp = (((j + 1) < (NMAX - pos)) ? (j + 1) : (NMAX - pos));
      UPDATE_MIN(min_d, min_jmp);
      UPDATE_MAX(max_d, max_jmp);
      for (int(jmp) = min_jmp; (jmp) < (int)(max_jmp + 1); (jmp)++) {
        UPDATE_MAX(maxes[pos + jmp][jmp - offset], mx_prev + arr[pos + jmp]);
        UPDATE_MAX(MAX_ALL, maxes[pos + jmp][jmp - offset]);
      }
    }
  }
  cout << MAX_ALL;
  return 0;
}
