/* {{{ */ #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;

namespace utils{
  constexpr bool use_stdio = false;
  ostream* out = &cout;
  FILE* stdio_out = stdout;
  const bool __ = [](){ if constexpr(!use_stdio){ ios_base::sync_with_stdio(false); cin.tie(nullptr);
    cout << fixed; cout << setprecision(12); cerr << fixed; cerr << setprecision(12); } return true; }();
  template<typename ...> using to_void = void;
  template<typename T, typename = void> struct is_container : false_type {};
  template<typename T> struct is_container<T, to_void<decltype(declval<T>().begin()), decltype(declval<T>().end())>> : true_type {};
  template<typename V, typename N> struct resize { V& v; N& n; resize(V& vv, N& nn) : v(vv), n(nn) {} ~resize() { v.resize(n); } };

  inline void rd(int& x) { if constexpr(use_stdio) scanf("%d", &x); else cin >> x; }
  inline void rd(long long& x) { if constexpr(use_stdio) scanf("%lld", &x); else cin >> x; }
  inline void rd(double& x) { if constexpr(use_stdio) scanf("%lf", &x); else cin >> x; }
  inline void rd(long double& x) { if constexpr(use_stdio){ double y; scanf("%lf", &y); x=y; } else cin >> x; }
  inline void rd(char& x) { if constexpr(use_stdio) scanf(" %c", &x); else cin >> x; }
  inline void rd(char* x) { if constexpr(use_stdio) scanf("%s", x); else cin >> x; }
  inline void rd(string& x) { if constexpr(use_stdio) assert(false); else cin >> x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void rd(T& x) { cin >> x; }
  template<typename T> inline void rd(T* x);
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x);
  template<typename... Ts> inline void rd(tuple<Ts...>& x);
  template<typename V, typename N> inline void rd(const resize<V, N>& x);
  template<typename T, typename U> inline void rd(pair<T, U>& x) { rd(x.first); rd(x.second); }
  template<typename V, typename N> inline void rd(const resize<V, N>& x) { const_cast<V&>(x.v).resize(x.n); rd(x.v); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x) { for(auto& v : x) rd(v); }
  template<typename T, typename U, typename... Ts> inline void rd(T&& t, U&& u, Ts&&... ts) {
    rd(forward<T>(t)); rd(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void rd(tuple<Ts...>& x) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_rd = [](auto&&... xs) { rd(xs...); }; apply(apply_rd, x); }
  template<typename T> inline void rd(T* x) { rd(*x); }

  inline void prt(const int& x) { if constexpr(use_stdio) fprintf(stdio_out, "%d", x); else *out << x; }
  inline void prt(const long long& x) { if constexpr(use_stdio) fprintf(stdio_out, "%lld", x); else *out << x; }
  inline void prt(const double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", x); else *out << x; }
  inline void prt(const long double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", (double)x); else *out << x; }
  inline void prt(const char& x) { if constexpr(use_stdio) fprintf(stdio_out, "%c", x); else *out << x; }
  inline void prt(const char* x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x); else *out << x; }
  inline void prt(const string &x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x.c_str()); else *out << x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void prt(const T& x) { *out << x; }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x);
  template<typename... Ts> inline void prt(const tuple<Ts...>& x);
  template<typename T, typename U> inline void prt(const pair<T, U>& x) { prt(x.first); prt(' '); prt(x.second); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x) {
    if (x.begin() != x.end()) { prt(*x.begin()); for(auto it = x.begin(); ++it != x.end(); ) { prt(' '); prt(*it); } } }
  template<typename T, typename U, typename... Ts> inline void prt(T&& t, U&& u, Ts&&... ts) {
    prt(forward<T>(t)); prt(' '); prt(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void prt(const tuple<Ts...>& x ) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_prt = [](auto&&... xs) { prt(xs...); }; apply(apply_prt, x); }
  inline void wt() { prt('\n'); }
  template<typename... Ts> inline void wt(Ts&&... ts) { prt(forward<Ts>(ts)...); wt(); }

#ifdef MY_DEBUG_FLAG
  inline void enter_db() { if constexpr(use_stdio) stdio_out = stderr; else out = &cerr; }
  inline void leave_db() { if constexpr(use_stdio) stdio_out = stdout; else out = &cout; }
  inline void db() { enter_db(); prt('\n'); leave_db(); }
  template<typename... Ts> inline void db(Ts&&... ts) { enter_db(); prt(forward<Ts>(ts)...); wt(); leave_db(); }
#define db(...) utils::db("Debug(", #__VA_ARGS__, ") == (", __VA_ARGS__, ")")
#else
#define db(...)
#endif // define(MY_DEBUG_FLAG)
  constexpr int slen(char*s){ return (int) strlen(s); }
  void flush() { if constexpr(use_stdio) fflush(stdout); else cout << std::flush; }
} using utils::rd, utils::prt, utils::wt, utils::slen, utils::resize, utils::flush;

#define pb emplace_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end() /* }}} */

constexpr int inf = 0x3f3f3f3f;
constexpr ld EPS = 1e-9;
constexpr int MAXN = 1e5 + 10;
constexpr int LOGN = 20;
constexpr int mod = 1000000007;

/* {{{ */ template<typename Node> struct segtree {
  int n;
  vector<Node> tree;
  vector<int> lc, rc;

  segtree(int N = 0, Node Zero = Node())
    : tree{Zero}, lc{0}, rc{0} { build(N); }

  int add_node(const Node& node, int resl = 0, int resr = 0) {
    tree.push_back(node);
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  int add_node(Node&& node, int resl = 0, int resr = 0) {
    tree.push_back(move(node));
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  template<typename E>
    int build(int l, int r, E* leafs) {
      if (l == r) return add_node(Node(leafs[l]));
      int mid = (l + r) >> 1;
      int resl = build(l, mid, leafs);
      int resr = build(mid + 1, r, leafs);
    }

  void build(int N) {
    n = N;
    tree.resize(1);
    lc.resize(1);
    rc.resize(1);
    tree.reserve(n << 1);
    lc.reserve(n << 1);
    rc.reserve(n << 1);
  }

  template<typename E> int build(const vector<E>& leafs) {
    build((int) leafs.size());
    return build(0, n - 1, leafs.data());
  }

  template<typename E> int build(const E* leafs, int N) {
    build(N);
    return build(0, n - 1, leafs);
  }

  template<typename... Ts> int upd(int b, int l, int r, int p, Ts&&... vals) {
    if (l == r) {
      Node node = tree[b];
      node(forward<Ts>(vals)...);
      return add_node(move(node));
    }
    int mid = (l + r) >> 1, resl = lc[b], resr = rc[b];
    if (p <= mid) resl = upd(resl, l, mid, p, forward<Ts>(vals)...);
    else resr = upd(resr, mid + 1, r, p, forward<Ts>(vals)...);
    return add_node(tree[resl] + tree[resr], resl, resr);
  }

  template<typename... Ts> int upd(int root, int p, Ts&&... vals) {
    assert(0 <= p && p < n);
    return upd(root, 0, n - 1, p, forward<Ts>(vals)...);
  }

  Node query(int b, int l, int r, int x, int y) {
    if (r < x || y < l) return tree[0];
    if (x <= l && r <= y) return tree[b];
    int mid = (l + r) >> 1;
    return query(lc[b], l, mid, x, y) + query(rc[b], mid + 1, r, x, y);
  }

  Node query(int root, int x, int y) {
    return query(root, 0, n, x, y);
  }
}; /* }}} */

struct Node {
  int val;
  Node (int x = 0) : val(x) {}
  Node operator+(Node a) { return Node(max(val, a.val)); }
  void operator()(int x) { val = max(val, x); }
  explicit operator int() { return val; }
};

segtree<Node> st;
int n;
vi vet, roots;

int main() {
  rd(n, resize(vet, n));
  rep(i,0,n) vet[i] -= i;
  vi ord = vet;
  rep(i,0,n) ord.pb(vet[i] + 1);
  sort(all(ord));
  roots.assign(n + 1, 0);
  int m = 2 * n;
  st.build(m + 1);
  dec(i,n-1,0) {
    int v = (int) (lower_bound(all(ord), vet[i] + 1) - ord.begin());
    int q = (int) st.query(roots[i + 1], v, m) + 1;
    roots[i] = st.upd(roots[i + 1], v, q);
  }
  int ans = n - 1 - (int) st.query(roots[1], 0, m);
  int rootp = 0;
  rep(i,1,n) {
    int v = (int) (lower_bound(all(ord), vet[i - 1]) - ord.begin());
    int q = (int) st.query(rootp, 0, v) + 1;
    rootp = st.upd(rootp, v, q);
    ans = min(ans, n - 1 - q - (int) st.query(roots[i + 1], v, m));
  }
  wt(ans);
}


/* {{{ */ #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;

namespace utils{
  constexpr bool use_stdio = false;
  ostream* out = &cout;
  FILE* stdio_out = stdout;
  const bool __ = [](){ if constexpr(!use_stdio){ ios_base::sync_with_stdio(false); cin.tie(nullptr);
    cout << fixed; cout << setprecision(12); cerr << fixed; cerr << setprecision(12); } return true; }();
  template<typename ...> using to_void = void;
  template<typename T, typename = void> struct is_container : false_type {};
  template<typename T> struct is_container<T, to_void<decltype(declval<T>().begin()), decltype(declval<T>().end())>> : true_type {};
  template<typename V, typename N> struct resize { V& v; N& n; resize(V& vv, N& nn) : v(vv), n(nn) {} ~resize() { v.resize(n); } };

  inline void rd(int& x) { if constexpr(use_stdio) scanf("%d", &x); else cin >> x; }
  inline void rd(long long& x) { if constexpr(use_stdio) scanf("%lld", &x); else cin >> x; }
  inline void rd(double& x) { if constexpr(use_stdio) scanf("%lf", &x); else cin >> x; }
  inline void rd(long double& x) { if constexpr(use_stdio){ double y; scanf("%lf", &y); x=y; } else cin >> x; }
  inline void rd(char& x) { if constexpr(use_stdio) scanf(" %c", &x); else cin >> x; }
  inline void rd(char* x) { if constexpr(use_stdio) scanf("%s", x); else cin >> x; }
  inline void rd(string& x) { if constexpr(use_stdio) assert(false); else cin >> x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void rd(T& x) { cin >> x; }
  template<typename T> inline void rd(T* x);
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x);
  template<typename... Ts> inline void rd(tuple<Ts...>& x);
  template<typename V, typename N> inline void rd(const resize<V, N>& x);
  template<typename T, typename U> inline void rd(pair<T, U>& x) { rd(x.first); rd(x.second); }
  template<typename V, typename N> inline void rd(const resize<V, N>& x) { const_cast<V&>(x.v).resize(x.n); rd(x.v); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x) { for(auto& v : x) rd(v); }
  template<typename T, typename U, typename... Ts> inline void rd(T&& t, U&& u, Ts&&... ts) {
    rd(forward<T>(t)); rd(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void rd(tuple<Ts...>& x) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_rd = [](auto&&... xs) { rd(xs...); }; apply(apply_rd, x); }
  template<typename T> inline void rd(T* x) { rd(*x); }

  inline void prt(const int& x) { if constexpr(use_stdio) fprintf(stdio_out, "%d", x); else *out << x; }
  inline void prt(const long long& x) { if constexpr(use_stdio) fprintf(stdio_out, "%lld", x); else *out << x; }
  inline void prt(const double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", x); else *out << x; }
  inline void prt(const long double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", (double)x); else *out << x; }
  inline void prt(const char& x) { if constexpr(use_stdio) fprintf(stdio_out, "%c", x); else *out << x; }
  inline void prt(const char* x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x); else *out << x; }
  inline void prt(const string &x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x.c_str()); else *out << x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void prt(const T& x) { *out << x; }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x);
  template<typename... Ts> inline void prt(const tuple<Ts...>& x);
  template<typename T, typename U> inline void prt(const pair<T, U>& x) { prt(x.first); prt(' '); prt(x.second); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x) {
    if (x.begin() != x.end()) { prt(*x.begin()); for(auto it = x.begin(); ++it != x.end(); ) { prt(' '); prt(*it); } } }
  template<typename T, typename U, typename... Ts> inline void prt(T&& t, U&& u, Ts&&... ts) {
    prt(forward<T>(t)); prt(' '); prt(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void prt(const tuple<Ts...>& x ) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_prt = [](auto&&... xs) { prt(xs...); }; apply(apply_prt, x); }
  inline void wt() { prt('\n'); }
  template<typename... Ts> inline void wt(Ts&&... ts) { prt(forward<Ts>(ts)...); wt(); }

#ifdef MY_DEBUG_FLAG
  inline void enter_db() { if constexpr(use_stdio) stdio_out = stderr; else out = &cerr; }
  inline void leave_db() { if constexpr(use_stdio) stdio_out = stdout; else out = &cout; }
  inline void db() { enter_db(); prt('\n'); leave_db(); }
  template<typename... Ts> inline void db(Ts&&... ts) { enter_db(); prt(forward<Ts>(ts)...); wt(); leave_db(); }
#define db(...) utils::db("Debug(", #__VA_ARGS__, ") == (", __VA_ARGS__, ")")
#else
#define db(...)
#endif // define(MY_DEBUG_FLAG)
  constexpr int slen(char*s){ return (int) strlen(s); }
  void flush() { if constexpr(use_stdio) fflush(stdout); else cout << std::flush; }
} using utils::rd, utils::prt, utils::wt, utils::slen, utils::resize, utils::flush;

#define pb emplace_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end() /* }}} */

constexpr int inf = 0x3f3f3f3f;
constexpr ld EPS = 1e-9;
constexpr int MAXN = 1e5 + 10;
constexpr int LOGN = 20;
constexpr int mod = 1000000007;

/* {{{ */ template<typename Node> struct segtree {
  int n;
  vector<Node> tree;
  vector<int> lc, rc;

  segtree(int N = 0, Node Zero = Node())
    : tree{Zero}, lc{0}, rc{0} { build(N); }

  int add_node(const Node& node, int resl = 0, int resr = 0) {
    tree.push_back(node);
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  int add_node(Node&& node, int resl = 0, int resr = 0) {
    tree.push_back(move(node));
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  template<typename E>
    int build(int l, int r, E* leafs) {
      if (l == r) return add_node(Node(leafs[l]));
      int mid = (l + r) >> 1;
      int resl = build(l, mid, leafs);
      int resr = build(mid + 1, r, leafs);
    }

  void build(int N) {
    n = N;
    tree.resize(1);
    lc.resize(1);
    rc.resize(1);
    tree.reserve(n << 1);
    lc.reserve(n << 1);
    rc.reserve(n << 1);
  }

  template<typename E> int build(const vector<E>& leafs) {
    build((int) leafs.size());
    return build(0, n - 1, leafs.data());
  }

  template<typename E> int build(const E* leafs, int N) {
    build(N);
    return build(0, n - 1, leafs);
  }

  template<typename... Ts> int upd(int b, int l, int r, int p, Ts&&... vals) {
    if (l == r) {
      Node node = tree[b];
      node(forward<Ts>(vals)...);
      return add_node(move(node));
    }
    int mid = (l + r) >> 1, resl = lc[b], resr = rc[b];
    if (p <= mid) resl = upd(resl, l, mid, p, forward<Ts>(vals)...);
    else resr = upd(resr, mid + 1, r, p, forward<Ts>(vals)...);
    return add_node(tree[resl] + tree[resr], resl, resr);
  }

  template<typename... Ts> int upd(int root, int p, Ts&&... vals) {
    assert(0 <= p && p < n);
    return upd(root, 0, n - 1, p, forward<Ts>(vals)...);
  }

  Node query(int b, int l, int r, int x, int y) {
    if (r < x || y < l) return tree[0];
    if (x <= l && r <= y) return tree[b];
    int mid = (l + r) >> 1;
    return query(lc[b], l, mid, x, y) + query(rc[b], mid + 1, r, x, y);
  }

  Node query(int root, int x, int y) {
    assert(0 <= x && x <= y && y < n);
    return query(root, 0, n - 1, x, y);
  }
}; /* }}} */

struct Node {
  int val;
  Node (int x = 0) : val(x) {}
  Node operator+(Node a) { return Node(max(val, a.val)); }
  void operator()(int x) { val = max(val, x); }
  explicit operator int() { return val; }
};

segtree<Node> st;
int n;
vi vet, roots;

int main() {
  rd(n, resize(vet, n));
  rep(i,0,n) vet[i] -= i;
  vi ord = vet;
  rep(i,0,n) ord.pb(vet[i] + 1);
  sort(all(ord));
  roots.assign(n + 1, 0);
  int m = 2 * n;
  st.build(m + 1);
  dec(i,n-1,0) {
    int v = (int) (lower_bound(all(ord), vet[i] + 1) - ord.begin());
    int q = (int) st.query(roots[i + 1], v, m) + 1;
    roots[i] = st.upd(roots[i + 1], v, q);
  }
  int ans = n - 1 - (int) st.query(roots[1], 0, m);
  int rootp = 0;
  rep(i,1,n) {
    int v = (int) (lower_bound(all(ord), vet[i - 1]) - ord.begin());
    int q = (int) st.query(rootp, 0, v) + 1;
    rootp = st.upd(rootp, v, q);
    ans = min(ans, n - 1 - q - (int) st.query(roots[i + 1], v, m));
  }
  wt(ans);
}


/* {{{ */ #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;

namespace utils{
  constexpr bool use_stdio = false;
  ostream* out = &cout;
  FILE* stdio_out = stdout;
  const bool __ = [](){ if constexpr(!use_stdio){ ios_base::sync_with_stdio(false); cin.tie(nullptr);
    cout << fixed; cout << setprecision(12); cerr << fixed; cerr << setprecision(12); } return true; }();
  template<typename ...> using to_void = void;
  template<typename T, typename = void> struct is_container : false_type {};
  template<typename T> struct is_container<T, to_void<decltype(declval<T>().begin()), decltype(declval<T>().end())>> : true_type {};
  template<typename V, typename N> struct resize { V& v; N& n; resize(V& vv, N& nn) : v(vv), n(nn) {} ~resize() { v.resize(n); } };

  inline void rd(int& x) { if constexpr(use_stdio) scanf("%d", &x); else cin >> x; }
  inline void rd(long long& x) { if constexpr(use_stdio) scanf("%lld", &x); else cin >> x; }
  inline void rd(double& x) { if constexpr(use_stdio) scanf("%lf", &x); else cin >> x; }
  inline void rd(long double& x) { if constexpr(use_stdio){ double y; scanf("%lf", &y); x=y; } else cin >> x; }
  inline void rd(char& x) { if constexpr(use_stdio) scanf(" %c", &x); else cin >> x; }
  inline void rd(char* x) { if constexpr(use_stdio) scanf("%s", x); else cin >> x; }
  inline void rd(string& x) { if constexpr(use_stdio) assert(false); else cin >> x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void rd(T& x) { cin >> x; }
  template<typename T> inline void rd(T* x);
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x);
  template<typename... Ts> inline void rd(tuple<Ts...>& x);
  template<typename V, typename N> inline void rd(const resize<V, N>& x);
  template<typename T, typename U> inline void rd(pair<T, U>& x) { rd(x.first); rd(x.second); }
  template<typename V, typename N> inline void rd(const resize<V, N>& x) { const_cast<V&>(x.v).resize(x.n); rd(x.v); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x) { for(auto& v : x) rd(v); }
  template<typename T, typename U, typename... Ts> inline void rd(T&& t, U&& u, Ts&&... ts) {
    rd(forward<T>(t)); rd(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void rd(tuple<Ts...>& x) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_rd = [](auto&&... xs) { rd(xs...); }; apply(apply_rd, x); }
  template<typename T> inline void rd(T* x) { rd(*x); }

  inline void prt(const int& x) { if constexpr(use_stdio) fprintf(stdio_out, "%d", x); else *out << x; }
  inline void prt(const long long& x) { if constexpr(use_stdio) fprintf(stdio_out, "%lld", x); else *out << x; }
  inline void prt(const double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", x); else *out << x; }
  inline void prt(const long double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", (double)x); else *out << x; }
  inline void prt(const char& x) { if constexpr(use_stdio) fprintf(stdio_out, "%c", x); else *out << x; }
  inline void prt(const char* x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x); else *out << x; }
  inline void prt(const string &x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x.c_str()); else *out << x; }
  template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void prt(const T& x) { *out << x; }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x);
  template<typename... Ts> inline void prt(const tuple<Ts...>& x);
  template<typename T, typename U> inline void prt(const pair<T, U>& x) { prt(x.first); prt(' '); prt(x.second); }
  template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x) {
    if (x.begin() != x.end()) { prt(*x.begin()); for(auto it = x.begin(); ++it != x.end(); ) { prt(' '); prt(*it); } } }
  template<typename T, typename U, typename... Ts> inline void prt(T&& t, U&& u, Ts&&... ts) {
    prt(forward<T>(t)); prt(' '); prt(forward<U>(u), forward<Ts>(ts)...); }
  template<typename... Ts> inline void prt(const tuple<Ts...>& x ) { static_assert(sizeof...(Ts) > 0);
    constexpr auto apply_prt = [](auto&&... xs) { prt(xs...); }; apply(apply_prt, x); }
  inline void wt() { prt('\n'); }
  template<typename... Ts> inline void wt(Ts&&... ts) { prt(forward<Ts>(ts)...); wt(); }

#ifdef MY_DEBUG_FLAG
  inline void enter_db() { if constexpr(use_stdio) stdio_out = stderr; else out = &cerr; }
  inline void leave_db() { if constexpr(use_stdio) stdio_out = stdout; else out = &cout; }
  inline void db() { enter_db(); prt('\n'); leave_db(); }
  template<typename... Ts> inline void db(Ts&&... ts) { enter_db(); prt(forward<Ts>(ts)...); wt(); leave_db(); }
#define db(...) utils::db("Debug(", #__VA_ARGS__, ") == (", __VA_ARGS__, ")")
#else
#define db(...)
#endif // define(MY_DEBUG_FLAG)
  constexpr int slen(char*s){ return (int) strlen(s); }
  void flush() { if constexpr(use_stdio) fflush(stdout); else cout << std::flush; }
} using utils::rd, utils::prt, utils::wt, utils::slen, utils::resize, utils::flush;

#define pb emplace_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end() /* }}} */

constexpr int inf = 0x3f3f3f3f;
constexpr ld EPS = 1e-9;
constexpr int MAXN = 1e5 + 10;
constexpr int logn = 20;
constexpr int mod = 1000000007;

/* {{{ */ template<typename Node> struct segtree {
  int n;
  vector<Node> tree;
  vector<int> lc, rc;

  segtree(int N = 0, Node Zero = Node())
    : tree{Zero}, lc{0}, rc{0} { build(N); }

  int add_node(const Node& node, int resl = 0, int resr = 0) {
    tree.push_back(node);
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  int add_node(Node&& node, int resl = 0, int resr = 0) {
    tree.push_back(move(node));
    lc.push_back(resl);
    rc.push_back(resr);
    return (int) tree.size() - 1;
  }

  template<typename E>
    int build(int l, int r, E* leafs) {
      if (l == r) return add_node(Node(leafs[l]));
      int mid = (l + r) >> 1;
      int resl = build(l, mid, leafs);
      int resr = build(mid + 1, r, leafs);
    }

  void build(int N) {
    n = N;
    tree.resize(1);
    lc.resize(1);
    rc.resize(1);
    tree.reserve(n << 1);
    lc.reserve(n << 1);
    rc.reserve(n << 1);
  }

  template<typename E> int build(const vector<E>& leafs) {
    build((int) leafs.size());
    return build(0, n - 1, leafs.data());
  }

  template<typename E> int build(const E* leafs, int N) {
    build(N);
    return build(0, n - 1, leafs);
  }

  void reserve(int N) {
    tree.reserve(N);
    lc.reserve(N);
    rc.reserve(N);
  }

  template<typename... Ts> int upd(int b, int l, int r, int p, Ts&&... vals) {
    if (l == r) {
      Node node = tree[b];
      node(forward<Ts>(vals)...);
      return add_node(move(node));
    }
    int mid = (l + r) >> 1, resl = lc[b], resr = rc[b];
    if (p <= mid) resl = upd(resl, l, mid, p, forward<Ts>(vals)...);
    else resr = upd(resr, mid + 1, r, p, forward<Ts>(vals)...);
    return add_node(tree[resl] + tree[resr], resl, resr);
  }

  template<typename... Ts> int upd(int root, int p, Ts&&... vals) {
    assert(0 <= p && p < n);
    return upd(root, 0, n - 1, p, forward<Ts>(vals)...);
  }

  Node query(int b, int l, int r, int x, int y) {
    if (r < x || y < l) return tree[0];
    if (x <= l && r <= y) return tree[b];
    int mid = (l + r) >> 1;
    return query(lc[b], l, mid, x, y) + query(rc[b], mid + 1, r, x, y);
  }

  Node query(int root, int x, int y) {
    assert(0 <= x && x <= y && y < n);
    return query(root, 0, n - 1, x, y);
  }
}; /* }}} */

struct Node {
  int val;
  Node (int x = 0) : val(x) {}
  Node operator+(Node a) { return Node(max(val, a.val)); }
  void operator()(int x) { val = max(val, x); }
  explicit operator int() { return val; }
};

segtree<Node> st;
int n;
vi vet, roots;

int main() {
  rd(n, resize(vet, n));
  rep(i,0,n) vet[i] -= i;
  vi ord = vet;
  rep(i,0,n) ord.pb(vet[i] + 1);
  sort(all(ord));
  roots.assign(n + 1, 0);
  int m = 2 * n;
  st.build(m + 1);
  st.reserve(4 * n * logn);
  dec(i,n-1,0) {
    int v = (int) (lower_bound(all(ord), vet[i] + 1) - ord.begin());
    int q = (int) st.query(roots[i + 1], v, m) + 1;
    roots[i] = st.upd(roots[i + 1], v, q);
  }
  int ans = n - 1 - (int) st.query(roots[1], 0, m);
  int rootp = 0;
  rep(i,1,n) {
    int v = (int) (lower_bound(all(ord), vet[i - 1]) - ord.begin());
    int q = (int) st.query(rootp, 0, v) + 1;
    rootp = st.upd(rootp, v, q);
    ans = min(ans, n - 1 - q - (int) st.query(roots[i + 1], v, m));
  }
  wt(ans);
}


//#define _GLIBCXX_DEBUG

#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T1, typename T2>
bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>
bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>
void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}
template<typename T>
void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)
{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};
void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)
{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};
template<typename T>
void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];
for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};
template<typename T>
vector<vector<T>>vec(ll x, ll y, T w){
  vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};
vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2>&p){
  return os << p.first << " " << p.second;
}
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
template< typename Monoid ,typename F>
struct SegmentTree {
  int sz, n;
  vector< Monoid > seg;
  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), n(n){
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }

  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
	  if(a>=b)return M1;
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }

  template< typename C >
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while(a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if(check(nxt)) a = 2 * a + type;
      else M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template< typename C >
  int find_first(int a, const C &check) {
    Monoid L = M1;
    if(a <= 0) {
      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) {
        Monoid nxt = f(L, seg[a]);
        if(check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template< typename C >
  int find_last(int b, const C &check) {
    Monoid R = M1;
    if(b >= sz) {
      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for(b += sz; a < b; a >>= 1, b >>= 1) {
      if(b & 1) {
        Monoid nxt = f(seg[--b], R);
        if(check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(){
    for(ll i=0;i<n;i++)if((*this)[i]==M1)cout<<"x ";else cout<<(*this)[i]<<" ";
    cout<<endl;
  }
};
template<typename T>
map<T,ll> compress(vector<T> &v){
  sort(ALL(v));
  v.erase(unique(ALL(v)),v.end());
  map<T, ll> ret;
  for(ll i=0;i<(ll)v.size();i++)
    ret[v[i]]=i;
  return ret;
}
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  ll res=0,buf=0;
  bool judge = true;
  ll n;cin>>n;
  vector<ll>a(n);
  rep(i,0,n)cin>>a[i];
  rep(i,0,n)a[i]-=i;
  vector<ll>val;
  rep(i,0,n)val.PB(a[i]),val.PB(a[i]-1);
  auto mp=compress(val);
  ll sz=mp.size();
  auto f=[&](ll x,ll y){return max(x,y);};
  SegmentTree<ll,decltype(f)>seg1(sz,f,-INF);
  SegmentTree<ll,decltype(f)>seg2(sz,f,-INF);
  rep(i,0,sz)seg1.set(i,0);
  rep(i,0,sz)seg2.set(i,0);
  seg1.build();seg2.build();
  P lazy(0,0);
  rep(i,0,n){
    ll idx=mp[a[i]];
    ll len=seg2.query(0,idx+1);
    seg2.update(idx,len+1);
    if(seg2[lazy.fi]<lazy.se)seg2.update(lazy.fi,lazy.se);
    len=seg1.query(0,idx+1);
    seg1.update(idx,len+1);
    lazy=MP(mp[a[i]-1],len+2);
  }
  res=INF;
  rep(i,0,sz){
    chmin(res,n-seg1[i]);
    chmin(res,n-seg2[i]);
  }
  cout<<res<<endl;
  return 0;
}


//#define _GLIBCXX_DEBUG

#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T1, typename T2>
bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>
bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>
void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}
template<typename T>
void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)
{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};
void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)
{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};
template<typename T>
void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];
for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};
template<typename T>
vector<vector<T>>vec(ll x, ll y, T w){
  vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};
vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2>&p){
  return os << p.first << " " << p.second;
}
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
template< typename Monoid ,typename F>
struct SegmentTree {
  int sz, n;
  vector< Monoid > seg;
  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1), n(n){
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }

  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
	  if(a>=b)return M1;
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }

  template< typename C >
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while(a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if(check(nxt)) a = 2 * a + type;
      else M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template< typename C >
  int find_first(int a, const C &check) {
    Monoid L = M1;
    if(a <= 0) {
      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) {
        Monoid nxt = f(L, seg[a]);
        if(check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template< typename C >
  int find_last(int b, const C &check) {
    Monoid R = M1;
    if(b >= sz) {
      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for(b += sz; a < b; a >>= 1, b >>= 1) {
      if(b & 1) {
        Monoid nxt = f(seg[--b], R);
        if(check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(){
    for(ll i=0;i<n;i++)if((*this)[i]==M1)cout<<"x ";else cout<<(*this)[i]<<" ";
    cout<<endl;
  }
};
template<typename T>
map<T,ll> compress(vector<T> &v){
  sort(ALL(v));
  v.erase(unique(ALL(v)),v.end());
  map<T, ll> ret;
  for(ll i=0;i<(ll)v.size();i++)
    ret[v[i]]=i;
  return ret;
}
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  ll res=0,buf=0;
  bool judge = true;
  ll n;cin>>n;
  vector<ll>a(n);
  rep(i,0,n)cin>>a[i];
  rep(i,0,n)a[i]-=i;
  vector<ll>val;
  rep(i,0,n)val.PB(a[i]),val.PB(a[i]-1);
  auto mp=compress(val);
  ll sz=mp.size();
  auto f=[&](ll x,ll y){return max(x,y);};
  SegmentTree<ll,decltype(f)>seg1(sz,f,-INF);
  SegmentTree<ll,decltype(f)>seg2(sz,f,-INF);
  rep(i,0,sz)seg1.set(i,0);
  rep(i,0,sz)seg2.set(i,1);
  seg1.build();seg2.build();
  P lazy(0,0);
  rep(i,0,n){
    ll idx=mp[a[i]];
    ll len=seg2.query(0,idx+1);
    if(i!=0)seg2.update(idx,len+1);
    if(seg2[lazy.fi]<lazy.se)seg2.update(lazy.fi,lazy.se);
    len=seg1.query(0,idx+1);
    seg1.update(idx,len+1);
    lazy=MP(mp[a[i]-1],len+2);
  }
  //seg1.print();
  //seg2.print();
  res=INF;
  rep(i,0,sz){
    chmin(res,n-seg1[i]);
    chmin(res,n-seg2[i]);
  }
  cout<<res<<endl;
  return 0;
}


#pragma GCC optimize ("O3")
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> par;
typedef pair<par, int> prr;
typedef long long int LL;
#define x first
#define y second
int main () {
    int n;
    scanf("%d", &n);
    vector<int> arr;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        arr.push_back(x - i);
    }
    vector<int> A, bi;
    int ans = n;
    for (int i = 0; i < n; i++) {
        int pos = upper_bound(bi.begin(), bi.end(), arr[i]) - bi.begin();
        A.push_back(pos + 1);
        if (pos == bi.size()) bi.push_back(arr[i]);
        else bi[pos] = arr[i];
        ans = min(ans, n - 1 - A[i]);
    }
    bi.clear();
    deque<par> sta;
    for (int i = n - 1; i >= 2; i--) {
        int pos = upper_bound(bi.begin(), bi.end(), -arr[i]) - bi.begin();
        if (pos == bi.size()) bi.push_back(-arr[i]);
        else bi[pos] = -arr[i];
        while (sta.size() && arr[i] >= sta.front().x) {
            if (pos + 1 >= sta.front().y) sta.pop_front();
            else break;
        }

        if (sta.empty() || arr[i] < sta.front().x && pos + 1 > sta.front().y)
            sta.push_front({arr[i], pos + 1});

        //printf("(%d) %d... (%d - %d, %d)\n", (int) sta.size(), pos + 1, arr[i - 2], sta.front().x, sta.front().y);
        auto it = lower_bound(sta.begin(), sta.end(), (par){arr[i - 2] - 1, -12341234});
        if (it != sta.end()) ans = min(ans, n - 1 - A[i - 2] - it->y);
    }
    printf("%d\n", ans);
}


#pragma GCC optimize ("O3")
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> par;
typedef pair<par, int> prr;
typedef long long int LL;
#define x first
#define y second
int main () {
    int n;
    scanf("%d", &n);
    vector<int> arr;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        arr.push_back(x - i);
    }
    vector<int> A, bi;
    int ans = n;
    for (int i = 0; i < n; i++) {
        int pos = upper_bound(bi.begin(), bi.end(), arr[i]) - bi.begin();
        A.push_back(pos + 1);
        if (pos == bi.size()) bi.push_back(arr[i]);
        else bi[pos] = arr[i];
        ans = min(ans, n - 1 - A[i]);
    }
    bi.clear();
    deque<par> sta;
    for (int i = n - 1; i >= 2; i--) {
        int pos = upper_bound(bi.begin(), bi.end(), -arr[i]) - bi.begin();
        if (pos == bi.size()) bi.push_back(-arr[i]);
        else bi[pos] = -arr[i];
        while (sta.size() && arr[i] >= sta.front().x) {
            if (pos + 1 >= sta.front().y) sta.pop_front();
            else break;
        }

        if (sta.empty() || arr[i] < sta.front().x && pos + 1 > sta.front().y)
            sta.push_front({arr[i], pos + 1});

        //printf("(%d) %d... (%d - %d, %d)\n", (int) sta.size(), pos + 1, arr[i - 2], sta.front().x, sta.front().y);
        auto it = lower_bound(sta.begin(), sta.end(), (par){arr[i - 2] - 1, -12341234});
        if (it != sta.end()) ans = min(ans, n - 1 - A[i - 2] - it->y);
    }
    printf("%d\n", max(ans, 0));
}


/*
a[i] -= i : lis -> lnds
iterate i from 1 to n
assume a[i - 1] is in the optimal list
if a[i - 1] > a[i] then we can remove a[i]
if a[i - 1] <= a[i]
	if a[i] is not in the optimal list then we can also remove a[i]
	if a[i] is in the optimal list it will be the answer of the next loop
*/
#include "bits/stdc++.h"
#define left tuna
#define right uno
using ll = long long;
using namespace std;

const int N = 2e5 + 2, mod = 1e9 + 7;

int n, ans = 0, a[N], lnds[N];
map <int, int> m;

struct BIT {
	int tree[N];

	void update(int k, int x) {
		if (k == 0) {
			return;
		}
		while (k < N) {
			tree[k] = max(tree[k], x);
			k += k & -k;
		}
	}

	int query(int k) {
		int ans = 0;
		while (k >= 1) {
			ans = max(ans, tree[k]);
			k -= k & -k;
		}
		return ans;
	}

	int query(int l, int r) {
		if (l == 1) {
			return query(r);
		}
		return query(r) - query(l - 1);
	}
} left, right, mid;

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		a[i] -= i;
		m[a[i]] = 0;
	}
	int id = 0;
	for (auto x : m) {
		m[x.first] = ++id;
	}
	for (int i = 1; i <= n; ++i) {
		a[i] = m[a[i]];
	}
	for (int i = n; i >= 1; --i) {
		int cur = N - a[i] - 1;
		right.update(cur, right.query(cur) + 1);
		mid.update(cur, right.query(a[i]));
		lnds[i] = mid.query(N - a[i - 1] - 1);
	}
	for (int i = 1; i <= n; ++i) {
		int res = left.query(a[i - 1]) + 1;
		ans = max(ans, res + lnds[i + 1]);
		left.update(a[i - 1], res);
	}
	cout << n - 1 - ans;
}


/*
if we remove a[i] then the problem is lnds of a[j < i] - j, a[j > i] - j - 1
f[0][k] = minimum last value of lnds with length k
f[1][k] = minimum last value of lnds with length k and already removed one element
*/
#include "bits/stdc++.h"
#define left tuna
#define right uno
using ll = long long;
using namespace std;

const int N = 2e5 + 2, mod = 1e9 + 7;

int n, ans = 0, a[N], f[2][N];

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		f[0][i] = f[1][i] = INT_MAX;
	}
	f[0][0] = f[1][0] = 0;
	for (int i = 1; i <= n; ++i) {
		auto k = lower_bound(f[0] + 1, f[0] + n + 1, a[i - 1] - (i - 1) + 1);
		*k = a[i - 1] - (i - 1);
		k = lower_bound(f[1] + 1, f[1] + n + 1, a[i] - (i - 1) + 1);
		*k = a[i] - (i - 1);
		int l = k - f[1];
		f[1][l] = min(f[1][l], f[0][l]);
		ans = max(ans, l);
	}
	cout << n - 1 - ans;
}


/*
if we remove a[i] then the problem is lnds of a[j < i] - j, a[j > i] - j - 1
f[0][k] = minimum last value of lnds with length k
f[1][k] = minimum last value of lnds with length k and already removed one element
*/
#include "bits/stdc++.h"
using ll = long long;
using namespace std;

const int N = 2e5 + 2, mod = 1e9 + 7;

int n, ans = 0, a[N], f[2][N];

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
	}
	memset(f, 0x3f, sizeof f);
	for (int i = 2; i <= n; ++i) {
		int k = upper_bound(f[1] + 1, f[1] + n + 1, a[i] - (i - 1)) - f[1];
		f[1][k] = a[i] - (i - 1);
		ans = max(ans, k);
		k = upper_bound(f[0] + 1, f[0] + n + 1, a[i - 1] - (i - 1)) - f[0];
		f[0][k] = a[i - 1] - (i - 1);
		f[1][k] = min(f[1][k], f[0][k]);
		ans = max(ans, k);
	}
	cout << n - 1 - ans;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <iomanip>
#include <set>
#include <map>
#include <queue>
typedef long long ll;
typedef long double ld;
using namespace std;

class intervalac
{
	vector<int> l, r, v;
public:
	vector<pair<int, int> > rollback;
	void init(int n)
	{
		int n2 = 1;
		while (n2 < n) n2 <<= 1;
		l.resize(n2 * 2);
		r.resize(n2 * 2);
		v.resize(n2 * 2, 0);
		for (int i = n2 - 1; i < n2 * 2; i++)
		{
			l[i] = r[i] = i - (n2 - 1);
		}
		for (int i = n2 - 2; i >= 0; i--)
		{
			l[i] = l[i * 2 + 1];
			r[i] = r[i * 2 + 2];
		}
	}
	void update(int i, int val, int vr = 0)
	{
		if (i < l[vr] || r[vr] < i) return;
		if (l[vr] == i && r[vr] == i)
		{
			rollback.push_back(make_pair(vr, v[vr]));
			v[vr] = val;
			return;
		}
		update(i, val, vr * 2 + 1);
		update(i, val, vr * 2 + 2);
		rollback.push_back(make_pair(vr, v[vr]));
		v[vr] = max(v[vr * 2 + 1], v[vr * 2 + 2]);
	}
	int query(int li, int ri, int vr = 0)
	{
		if (ri < l[vr] || r[vr] < li) return 0;
		if (li <= l[vr] && r[vr] <= ri) return v[vr];
		return max(query(li, ri, vr * 2 + 1), query(li, ri, vr * 2 + 2));
	}
	void undo(int size)
	{
		while (rollback.size() > size)
		{
			v[rollback.back().first] = rollback.back().second;
			rollback.pop_back();
		}
	}
};
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin >> n;
	vector<int> a(n);
	map<int, int > m;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		m[a[i] - i] = 1;
		m[a[i] - i + 1] = 1;
	}
	int cnt = 0;
	for (const pair<int, int>& i : m)
	{
		m[i.first] = cnt;
		cnt++;
	}
	intervalac in1, in2;
	in1.init(m.size() + 1);
	in2.init(m.size() + 1);
	vector<int> s;
	for (int i = n - 1; i > 0; i--)
	{
		int dpi = in1.query(m[a[i] - i + 1], m.size()) + 1;
		s.push_back(in1.rollback.size());
		in1.update(m[a[i] - i + 1], dpi);
	}
	int ans = in1.query(0, m.size());
	for (int i = 0; i < n - 1; i++)
	{
		in1.undo(s.back());
		s.pop_back();
		int in = m[a[i] - i];
		int updval = in2.query(0, in) + 1;
		in2.update(in, updval);
		ans = max(in1.query(in, m.size()) + updval, ans);
	}
	cout << n - 1 - ans << "\n";
	return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=300200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  int mn = 1<<30;
  for (int i = 0; i < n; ++i) {a[i]-=i; mn = min(mn,a[i]);}
  for (int i = 0; i < n; ++i) a[i]-=mn;
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
    if(a[i]>n) throw "oh no...";
  }
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);

  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i])+1);
    int v0 = tmax(V0,1,0,n, 0,a[i])+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);
  }
  int res = tmax(V1,1,0,n,0,n);
  return n-res;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);

  //view(V0,0,n, n+1);
  //view(V1,0,n, n+1);
  //printf("\n");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);

    //view(V0,0,n, n+1);
    //view(V1,0,n, n+1);
    //printf("\n");
  }
  int res = tmax(V1,1,0,n,1,n);
  return n-res;
}

int brut(VI a) {
  int best = a.size();
  for (int m = a.size(); m < 1<<a.size(); ++m) {
    VI b; for (int i = 0; i < a.size(); ++i) if (m&(1<<i)) b.pb(a[i]);
    int fnd = 0;
    for (int k = 0; k < b.size(); ++k) {
      VI c = b;
      c.erase(c.begin()+k);
      int ok = 1;
      for (int i = 1; i < c.size(); ++i) {
        if (c[i]<=c[i-1]) ok=0;
      }
      if (ok) {fnd=1; break;}
    }
    if (fnd) best = min((int)a.size()-(int)b.size(), best);
  }
  return best;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  /*for (int t = 0; t < 100; ++t) {
    int n = 1+rand()%16;
    VI a; for (int i = 0; i <n; ++i) a.pb(1+rand()%100);
    int r1 = brut(a);
    int r2 = solve(a);
    if (r1!=r2) {
      print(a, "%d");
      printf("r1=%d\nr2=%d\n", r1,r2);
      return 0;
    }
  }
  printf("OK\n");//*/
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

int R0[222222];
int R1[222222];

int solve(VI &a) {
  int n = a.size();
  for (int i = 0; i < n+1; ++i) R0[i]=R1[i]=INF;
  R0[0]=-INF;

  int toAdd=0;
  int r0=1;
  int r1=0;

  for (int i = 0; i < a.size(); ++i) {

    int v1 = upper_bound(R1,R1+r1+1,a[i]-i+1)-R1;
    if (v1>r1) ++r1;
    R1[v1]=a[i]-i+1;

    R1[toAdd]=min(R0[toAdd], R1[toAdd]);
    if (toAdd>r1) ++r1;
    int v0 = upper_bound(R0,R0+r0+1,a[i]-i)-R0;
    if (v0>=r0) ++r0;
    R0[v0]=a[i]-i;

    toAdd = v0;
  }
  return max(0, (int)a.size() - min(n,r1+1));
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=300200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
    if(a[i]>n) throw "oh no...";
  }
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);

  //view(V0,0,n, n+1);
  //view(V1,0,n, n+1);
  //printf("\n");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);

    //view(V0,0,n, n+1);
    //view(V1,0,n, n+1);
    //printf("\n");
  }
  int res = tmax(V1,1,0,n,0,n);
  return n-res;
}

int brut(VI a) {
  int best = a.size();
  for (int m = a.size(); m < 1<<a.size(); ++m) {
    VI b; for (int i = 0; i < a.size(); ++i) if (m&(1<<i)) b.pb(a[i]);
    int fnd = 0;
    for (int k = 0; k < b.size(); ++k) {
      VI c = b;
      c.erase(c.begin()+k);
      int ok = 1;
      for (int i = 1; i < c.size(); ++i) {
        if (c[i]<=c[i-1]) ok=0;
      }
      if (ok) {fnd=1; break;}
    }
    if (fnd) best = min((int)a.size()-(int)b.size(), best);
  }
  return best;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  /*for (int t = 0; t < 100; ++t) {
    int n = 1+rand()%16;
    VI a; for (int i = 0; i <n; ++i) a.pb(1+rand()%100);
    int r1 = brut(a);
    int r2 = solve(a);
    if (r1!=r2) {
      print(a, "%d");
      printf("r1=%d\nr2=%d\n", r1,r2);
      return 0;
    }
  }
  printf("OK\n");//*/
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n, int time) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i)+time-1);
  }
  printf("\n");
}

int solve() {
  int n = gi();
  VI a = gvi(n);
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  for(int i = 0; i < SIZE*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);

  for (int i = 0; i < a.size(); ++i) {
    // try drop:
    if (i>0) {
      int v1 = tmax(V0,1,0,n, 0,a[i-1]-1)+2;
      tput(V1,1,0,n,a[i-1],v1);
    }
    int v2 = tmax(V1,1,0,n,0,a[i]-1)+1;
    tput(V1,1,0,n,a[i],v2);

    // try 0:
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
  }
  //view(V0,0,n,n+1,time);
  //view(V1,0,n,n+1,time);
  int res = tmax(V1,1,0,n,0,n);
  printf("%d\n", n-res);
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  solve();
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=300200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
    if(a[i]>n || a[i]<=0) throw "oh no...";
  }
  for(int i = 0; i <= (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(1,1);

  //view(V0,0,n, n+1);
  //view(V1,0,n, n+1);
  //printf("\n");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i]+1, v0+1);

    //view(V0,0,n, n+1);
    //view(V1,0,n, n+1);
    //printf("\n");
  }
  int res = tmax(V1,1,0,n,0,n);
  return n-res;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=400200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  int mn = 1<<30;
  for (int i = 0; i < n; ++i) {a[i]-=i; mn = min(mn,a[i]);}
  for (int i = 0; i < n; ++i) a[i]-=mn;
  VI b;
  for (int i = 0; i < a.size(); ++i) {
    b.pb(a[i]);
    b.pb(a[i]+1);
  }
  sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  n=n*2+2;
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);
  //print(a,"%d");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i]+1, tmax(V1,1,0,n,0,a[i]+1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i])+1;
    tput(V0,1,0,n, a[i], v0);
    if (i) tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0);

    //view(V0,0,n,n);
    //view(V1,0,n,n);
  }
  int res = tmax(V1,1,0,n,0,n);
  return a.size() - min(n,res+1);
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmin(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return min(
      l<=m ? tmin(V,v<<1,tl,m,l,min(m,r)) : INF,
      r>m ? tmin(V,v<<1|1,m+1,tr,max(l,m+1),r) : INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = min(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = min(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n, int time) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmin(V,1,tl,tr,i,i)+time-1);
  }
  printf("\n");
}

int solve() {
  int n = gi();
  VI a = gvi(n);
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  for(int i = 0; i < SIZE*4; ++i) {
    V0[i]=INF;
    V1[i]=INF;
  }
  int time = 1;
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,-1);

  for (int i = 0; i < a.size(); ++i,++time) {
    //view(V0,0,n,n+1,time);
    //view(V1,0,n,n+1,time);

    // try 0:
    int v0 = tmin(V0,1,0,n, 0,a[i]-1)+time-1;
    tput(V0,1,0,n, a[i], v0-time);
    tput(V1,1,0,n, a[i], v0-time-1);

    // try 1:
    // using 1:
    int v11 = tmin(V1,1,0,n, 0,a[i]-1)+time-1;
    tput(V1,1,0,n, a[i], v11-time);
  }
  //view(V0,0,n,n+1,time);
  //view(V1,0,n,n+1,time);
  int res = tmin(V1,1,0,n,0,n)+time-1;
  printf("%d\n", max(0,res));
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  solve();
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
    if(a[i]>n) throw "oh no...";
  }
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);

  //view(V0,0,n, n+1);
  //view(V1,0,n, n+1);
  //printf("\n");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);

    //view(V0,0,n, n+1);
    //view(V1,0,n, n+1);
    //printf("\n");
  }
  int res = tmax(V1,1,0,n,0,n);
  return n-res;
}

int brut(VI a) {
  int best = a.size();
  for (int m = a.size(); m < 1<<a.size(); ++m) {
    VI b; for (int i = 0; i < a.size(); ++i) if (m&(1<<i)) b.pb(a[i]);
    int fnd = 0;
    for (int k = 0; k < b.size(); ++k) {
      VI c = b;
      c.erase(c.begin()+k);
      int ok = 1;
      for (int i = 1; i < c.size(); ++i) {
        if (c[i]<=c[i-1]) ok=0;
      }
      if (ok) {fnd=1; break;}
    }
    if (fnd) best = min((int)a.size()-(int)b.size(), best);
  }
  return best;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  /*for (int t = 0; t < 100; ++t) {
    int n = 1+rand()%16;
    VI a; for (int i = 0; i <n; ++i) a.pb(1+rand()%100);
    int r1 = brut(a);
    int r2 = solve(a);
    if (r1!=r2) {
      print(a, "%d");
      printf("r1=%d\nr2=%d\n", r1,r2);
      return 0;
    }
  }
  printf("OK\n");//*/
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=400200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  int mn = 1<<30;
  for (int i = 0; i < n; ++i) {a[i]-=i; mn = min(mn,a[i]);}
  for (int i = 0; i < n; ++i) a[i]-=mn;
  VI b;
  for (int i = 0; i < a.size(); ++i) {
    b.pb(a[i]);
    b.pb(a[i]+1);
  }
  sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  n=n*2+2;
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);
  //print(a,"%d");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i]+1, tmax(V1,1,0,n,0,a[i]+1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i])+1;
    tput(V0,1,0,n, a[i], v0);
    if (i) tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0);

    //view(V0,0,n,n);
    //view(V1,0,n,n);
  }
  int res = tmax(V1,1,0,n,0,n);
  return max(0, (int)a.size() - min(n,res+1));
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);

  //view(V0,0,n, n+1);
  //view(V1,0,n, n+1);
  //printf("\n");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i], tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);

    //view(V0,0,n, n+1);
    //view(V1,0,n, n+1);
    //printf("\n");
  }
  int res = tmax(V1,1,0,n,1,n);
  return n-res;
}

int brut(VI a) {
  int best = a.size();
  for (int m = a.size(); m < 1<<a.size(); ++m) {
    VI b; for (int i = 0; i < a.size(); ++i) if (m&(1<<i)) b.pb(a[i]);
    int fnd = 0;
    for (int k = 0; k < b.size(); ++k) {
      VI c = b;
      c.erase(c.begin()+k);
      int ok = 1;
      for (int i = 1; i < c.size(); ++i) {
        if (c[i]<=c[i-1]) ok=0;
      }
      if (ok) {fnd=1; break;}
    }
    if (fnd) best = min((int)a.size()-(int)b.size(), best);
  }
  return best;
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  /*for (int t = 0; t < 100; ++t) {
    int n = 1+rand()%16;
    VI a; for (int i = 0; i <n; ++i) a.pb(1+rand()%100);
    int r1 = brut(a);
    int r2 = solve(a);
    if (r1!=r2) {
      print(a, "%d");
      printf("r1=%d\nr2=%d\n", r1,r2);
      return 0;
    }
  }
  printf("OK\n");//*/
  int n = vi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void solve() {
  int n = gi();
  VI a = gvi(n);
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  for (int i = 0; i < a.size(); ++i) {
    a[i] = lower_bound(ALL(b), a[i]) - b.begin()+1;
  }
  for(int i = 0; i < n*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i],tmax(V1,1,0,n,0,a[i]-1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i]-1)+1;
    tput(V0,1,0,n, a[i], v0);
    tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0+1);
  }
  int res = tmax(V1,1,0,n,1,n);
  printf("%d\n", n-res);
}
int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  solve();
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmax(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return max(
      l<=m ? tmax(V,v<<1,tl,m,l,min(m,r)) : -INF,
      r>m ? tmax(V,v<<1|1,m+1,tr,max(l,m+1),r) : -INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = max(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = max(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmax(V,1,tl,tr,i,i));
  }
  printf("\n");
}

int solve(VI a) {
  int n = a.size();
  int mn = 1<<30;
  for (int i = 0; i < n; ++i) {a[i]-=i; mn = min(mn,a[i]);}
  for (int i = 0; i < n; ++i) a[i]-=mn;
  VI b;
  for (int i = 0; i < a.size(); ++i) {
    b.pb(a[i]);
    b.pb(a[i]+1);
  }
  sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  n=n*2+2;
  for(int i = 0; i < (n+1)*4; ++i) {
    V0[i]=-INF;
    V1[i]=-INF;
  }
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);
  PII toAdd(0,1);
  //print(a,"%d");
  for (int i = 0; i < a.size(); ++i) {
    tput(V1,1,0,n,a[i]+1, tmax(V1,1,0,n,0,a[i]+1)+1);
    int v0 = tmax(V0,1,0,n, 0,a[i])+1;
    tput(V0,1,0,n, a[i], v0);
    if (i) tput(V1,1,0,n, toAdd.first, toAdd.second);
    toAdd = mp(a[i], v0);

    //view(V0,0,n,n);
    //view(V1,0,n,n);
  }
  int res = tmax(V1,1,0,n,0,n);
  return a.size() - min(n,res+1);
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  int n = gi();
  VI a = gvi(n);
  printf("%d\n", solve(a));
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-12;
const int INF = 1<<30;
const LL LINF = 1LL<<62;

#define pb push_back
#define mp make_pair
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))
#define sqr(a) ((a)*(a))
const int BUFFER_SZ = 1 << 10;
const int MOD = 1000*1000*1000+7;

char BUFFER[BUFFER_SZ];
int gi() { int x; scanf("%d", &x); return x; }
LL gll() { LL x; scanf("%lld", &x); return x; }
VI gvi(int n) { VI a; while(n-->0) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }
template <class T> void print(vector<T> &x, string format) {
  format += "%c";
  for (int i = 0; i < x.size(); ++i) printf(format.c_str(), x[i], i+1==x.size() ? '\n' : ' ');
}
// ---------------------------------------------------------- //

const int SIZE=200200;
int V0[SIZE*4];
int V1[SIZE*4];

int tmin(int *V, int v, int tl, int tr, int l, int r) {
  if (tl==l && tr==r) {
    return V[v];
  }
  int m = (tl+tr)>>1;
  return min(
      l<=m ? tmin(V,v<<1,tl,m,l,min(m,r)) : INF,
      r>m ? tmin(V,v<<1|1,m+1,tr,max(l,m+1),r) : INF
  );
}

void tput(int *V, int v, int tl, int tr, int p, int x) {
  if (tl==tr) {
    V[v] = min(V[v],x);
    return;
  }
  int m = (tl+tr)>>1;
  if (p<=m) tput(V,v<<1,tl,m,p,x);
  if (p>m) tput(V,v<<1|1, m+1,tr,p,x);
  V[v] = min(V[v<<1],V[v<<1|1]);
}

void view(int *V, int tl, int tr, int n, int time) {
  for (int i = 0; i < n; ++i) {
    printf("%d ", tmin(V,1,tl,tr,i,i)+time-1);
  }
  printf("\n");
}

int solve() {
  int n = gi();
  VI a = gvi(n);
  VI b = a; sort(ALL(b)); b.erase(unique(ALL(b)), b.end());
  map<int,int> IDX; for (int i = 0; i < b.size(); ++i) IDX[b[i]]=i+1;
  for (int i = 0; i < a.size(); ++i) {
    a[i] = IDX[a[i]];
  }
  for(int i = 0; i < SIZE*4; ++i) {
    V0[i]=INF;
    V1[i]=INF;
  }
  int time = 1;
  tput(V0,1,0,n,0,0);
  tput(V1,1,0,n,0,0);

  for (int i = 0; i < a.size(); ++i,++time) {
    //view(V0,0,n,n+1,time);
    //view(V1,0,n,n+1,time);

    // try 0:
    int v0 = tmin(V0,1,0,n, 0,a[i]-1)+time-1;
    tput(V0,1,0,n, a[i], v0-time);
    tput(V1,1,0,n, a[i], v0-time-1);

    // try 1:
    // using 1:
    int v11 = tmin(V1,1,0,n, 0,a[i]-1)+time-1;
    tput(V1,1,0,n, a[i], v11-time);
  }
  //view(V0,0,n,n+1,time);
  //view(V1,0,n,n+1,time);
  int res = tmin(V1,1,0,n,0,n)+time-1;
  printf("%d\n", max(0,res));
}

int main() {
#ifdef DEAD_RABBIT
  freopen("in.txt","r",stdin);
  //freopen("out.txt","w",stdout);
  clock_t start = clock();
#endif
  solve();
#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
//#define int long long
#define MAXN 500005
#define ff first
#define ss second

using namespace std;

int n, i, a[MAXN], ca[MAXN], cb[MAXN];
pair <int, pair<int, int> > cmp[2 * MAXN];

struct ST{
    int t[MAXN * 4];
    vector <pair<int, int> > c[MAXN];

    ST(){
        fill(t, t + 4 * MAXN, 0);
    }

    void upd(int v, int tl, int tr, int pos, int x, int num = -1){
        int m = (tl + tr) / 2;

        //cout << v << " " << tl << " " << tr << endl;
        if(tl == tr){
            if(num != -1)
                c[num].push_back({v, t[v]});
            t[v] = x;
            return;
        }

        if(pos <= m)
            upd(v * 2, tl, m, pos, x, num);
        else
            upd(v * 2 + 1, m + 1, tr, pos, x, num);

        if(num != -1)
            c[num].push_back({v, t[v]});
        t[v] = max(t[v * 2], t[v * 2 + 1]);
    }

    int get(int v, int tl, int tr, int l, int r){
        int m = (tl + tr) / 2;

        if(l > r)
            return 0;

        if(tl == l && tr == r)
            return t[v];

        return max(get(v * 2, tl, m, l, min(r, m)),
                get(v * 2 + 1, m + 1, tr, max(l, m + 1), r));
    }

    void del(int num){
        for(int i = (int)c[num].size() - 1; i >= 0; i--)
            t[c[num][i].ff] = c[num][i].ss;
    }
} preff, suff;

int main(){
    //freopen("input.txt", "r", stdin);
    cin >> n;

    for(i = 0; i < n; i++){
        cin >> a[i];
        cmp[i] = {a[i] - i, {i, 0}};
        cmp[n + i] = {a[i] - i + 1, {i, 1}};
    }

    sort(cmp, cmp + 2 * n);

    int cnt = 0;
    for(i = 0; i < 2 * n; i++){
        if(i && cmp[i].ff != cmp[i - 1].ff)
            cnt++;

        if(cmp[i].ss.ss == 0)
            ca[cmp[i].ss.ff] = cnt;
        else
            cb[cmp[i].ss.ff] = cnt;
    }

    for(i = n - 1; i >= 0; i--)
        suff.upd(1, 0, cnt, cb[i], suff.get(1, 0, cnt, cb[i], cnt) + 1, i);

    int ans = 0;

    for(i = 0; i < n; i++){
        suff.del(i);

        int sum = (i)? preff.get(1, 0, cnt, ca[i - 1], ca[i - 1]) : 0;

        //cout << sum + 1 + suff.get(1, 0, cnt, ((i)? a[i - 1] : cnt) + 1, cnt) << endl;
        ans = max(ans, sum + 1 + suff.get(1, 0, cnt, (i)? ca[i - 1] : 0, cnt));

        preff.upd(1, 0, cnt, ca[i], preff.get(1, 0, cnt, 0, ca[i]) + 1);
    }

    cout << n - max(preff.get(1, 0, cnt, 0, cnt), ans);
    return 0;
}