#include <bits/stdc++.h>
using namespace std;
using llong = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using pii = pair<int, int>;
constexpr int INF = 1e9;
constexpr double EPS = 1e-9;
constexpr int MOD = 1e9 + 7;
template <class Type>
void line(const Type &a) {
  int cnt = 0;
  for (const auto &elem : a) {
    cerr << (cnt++ ? ' ' : '>');
    cerr << elem;
  }
  cerr << endl;
}
template <typename T>
class SegmentTree {
  using F = function<T(T, T)>;
  int n, offset;
  T e;
  vector<T> node;
  F f_query;
  F f_update;
  int bufsize(int n_) {
    n = 1;
    while (n < n_) n <<= 1;
    offset = n - 1;
    return 2 * n - 1;
  }
  void build(int l = 0, int r = -1) {
    if (r < 0) r = n;
    l += offset, r += offset;
    do {
      l = (l - 1) / 2, r = (r - 1) / 2;
      for (int i = l; i < r; ++i)
        node[i] = f_query(node[2 * i + 1], node[2 * i + 2]);
    } while (l > 0);
  }

 public:
  SegmentTree(int n_, T e_, const F &f_query_, const F &f_update_)
      : node(bufsize(n_), e_), e(e_), f_query(f_query_), f_update(f_update_) {}
  SegmentTree(const vector<T> &v_, T e_, const F &f_query_, const F &f_update_)
      : node(bufsize(v_.size()), e_),
        e(e_),
        f_query(f_query_),
        f_update(f_update_) {
    copy((v_).begin(), (v_).end(), node.begin() + offset);
    build();
  }
  void init() { fill((node).begin(), (node).end(), e); }
  void update(int k, T a) {
    k += offset;
    node[k] = f_update(node[k], a);
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = f_query(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    if (b <= l or r <= a) return e;
    if (a <= l and r <= b) return node[k];
    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return f_query(vl, vr);
  }
  typename vector<T>::reference operator[](int i) { return node[i + offset]; }
};
int main() {
  int n, k;
  cin >> n >> k;
  vi a(n);
  for (int i = 0; i < (n); ++i) cin >> a[i];
  using type = int;
  auto f_query = [](type a, type b) -> type { return max(a, b); };
  auto f_update = [](type a, type b) -> type { return max(a, b); };
  SegmentTree<type> tree(3e5 + 1, 0, f_query, f_update);
  for (int i = 0; i < (n); ++i) {
    int l = max(0, a[i] - 3), r = min(a[i] + 3, (int)3e5 + 1) + 1;
    tree.update(a[i], tree.query(l, r) + 1);
  }
  cout << tree.query(a[n - 1], a[n - 1] + 1) << endl;
}
