#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vi = vector<int>;
using vvi = vector<vi>;
using ll = long long;
using vll = vector<long long>;
template <class T>
using min_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
istream &operator>>(istream &, vector<T> &);
template <class T>
ostream &operator<<(ostream &, const vector<T> &);
template <class T, class U>
istream &operator>>(istream &, pair<T, U> &);
template <class T, class U>
ostream &operator<<(ostream &, const pair<T, U> &);
template <class T>
struct Inf {
  static constexpr T inf() {
    return std::numeric_limits<T>::has_infinity()
               ? std::numeric_limits<T>::infinty()
               : std::numeric_limits<T>::max();
  }
};
template <>
struct Inf<int> {
  static constexpr int inf() { return 0x3f3f3f3f; }
};
template <>
struct Inf<long long> {
  static constexpr long long inf() { return 0x3f3f3f3f3f3f3f3fLL; }
};
constexpr int INF = Inf<int>::inf();
constexpr ll BINF = Inf<ll>::inf();
template <class T>
class Dinic {
 private:
  struct edge {
    int from, to;
    T cap;
    edge *rev;
    edge(int u, int v, T c) : from(u), to(v), cap(c), rev(nullptr) {}
  };
  static constexpr T INF = Inf<T>::inf();
  static constexpr int DINF = Inf<int>::inf();
  int n, s, t;
  std::vector<std::vector<edge *>> g;

 public:
  Dinic(int n, int s, int t) : n(n), s(s), t(t), g(n) {}
  ~Dinic() {
    for (auto v : g)
      for (edge *e : v) delete e;
  }
  void addEdge(int u, int v, T c) {
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    g[u].push_back(in);
    g[v].push_back(out);
    in->rev = out;
    out->rev = in;
  }
  T maxFlow() {
    T mxf = 0;
    std::vector<int> dist(n, DINF), vis(n);
    std::function<T(int, T)> dfs = [&](int u, T fo) -> T {
      if (u == t) return fo;
      for (; vis[u] < int(g[u].size()); vis[u]++) {
        edge *e = g[u][vis[u]];
        int v = e->to;
        if (dist[v] != dist[u] + 1 || e->cap <= 0) continue;
        T foo = dfs(v, std::min(fo, e->cap));
        if (foo > 0) {
          e->cap -= foo;
          e->rev->cap += foo;
          return foo;
        }
      }
      return 0;
    };
    for (;;) {
      for (int i = 0; i < n; i++) dist[i] = DINF, vis[i] = 0;
      std::queue<int> q;
      q.push(s);
      dist[s] = 0;
      while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == t) break;
        for (edge *e : g[u]) {
          int v = e->to;
          if (e->cap > 0 && dist[v] == DINF) {
            dist[v] = dist[u] + 1;
            q.push(v);
          }
        }
      }
      if (dist[t] == DINF) break;
      while (T fo = dfs(s, INF)) mxf += fo;
    }
    return mxf;
  }
};
template <class T>
constexpr T Dinic<T>::INF;
template <class T>
constexpr int Dinic<T>::DINF;
int solve() {
  int n;
  cin >> n;
  vi a(n);
  cin >> a;
  const int M = 150002;
  Dinic<int> mxf(n + M + 2, n + M, n + M + 1);
  for (int i = 0; i < n; i++) mxf.addEdge(n + M, i, 1);
  for (int i = 1; i < M; i++) mxf.addEdge(n + i, n + M + 1, 1);
  for (int i = 0; i < n; i++) {
    mxf.addEdge(i, n + a[i], 1);
    if (a[i] - 1 >= 1) mxf.addEdge(i, n + a[i] - 1, 1);
    if (a[i] + 1 < M) mxf.addEdge(i, n + a[i] + 1, 1);
  }
  cout << mxf.maxFlow() << endl;
  return 0;
}
int main() {
  ios::sync_with_stdio(0);
  solve();
  return 0;
}
template <class T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto it = v.begin(); it != v.end(); ++it) is >> *it;
  return is;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (auto it = v.begin(); it != v.end();)
    os << *it, os << " \n"[++it == v.end()];
  return os;
}
template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ' ' << p.second;
}
