#include <bits/stdc++.h>
using namespace std;
class SegmentTree {
 private:
  int n;
  vector<int> st;
  int left(int p) { return (p << 1); }
  int right(int p) { return (p << 1) + 1; }
  int parent(int p) { return (p >> 1); }
  void build(int p, int L, int R) {
    if (L == R)
      st[p] = A[L];
    else {
      build(left(p), L, (L + R) / 2);
      build(right(p), (L + R) / 2 + 1, R);
      int p1 = st[left(p)], p2 = st[right(p)];
      st[p] = p1 + p2;
    }
  }
  int rsq(int p, int L, int R, int i, int j) {
    if (i > R || j < L) return 0;
    if (i <= L && R <= j) return st[p];
    int p1 = rsq(left(p), L, (L + R) / 2, i, j);
    int p2 = rsq(right(p), (L + R) / 2 + 1, R, i, j);
    return p1 + p2;
  }

 public:
  vector<int> A;
  SegmentTree() {}
  SegmentTree(const vector<int> &v) {
    A = v;
    n = (int)A.size();
    st.assign(4 * n, 0);
    build(1, 0, n - 1);
  }
  int query(int i, int j) { return rsq(1, 0, n - 1, i, j); }
  void update(int i, int j, int a) {
    A[i] = a;
    int L = 0, R = n - 1, p = 1;
    while (L < R) {
      int mid = (L + R) / 2;
      if (i <= mid) {
        R = mid;
        p = left(p);
      } else {
        L = mid + 1;
        p = right(p);
      }
    }
    st[p] = a;
    while (p = parent(p)) {
      int p1 = st[left(p)], p2 = st[right(p)];
      st[p] = p1 + p2;
    }
  }
};
int a[123456];
int L[123456];
int R[123456];
vector<int> isOn(123456, 1);
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) cin >> a[i];
  SegmentTree st(isOn);
  vector<int> v;
  for (int i = 1; i < n; i++) {
    L[i] = i - 1;
    R[i] = i + 1;
    if (a[i] < a[i - 1]) v.push_back(i);
  }
  int cnt = 0;
  while (v.size() > 0) {
    for (int ID : v) {
      st.update(ID, ID, 0);
    }
    vector<int> _new;
    for (int ID : v) {
      int isOk1 = st.query(R[ID], R[ID]);
      int isOk2 = st.query(L[ID], L[ID]);
      if (isOk1 && isOk2) {
        R[L[ID]] = R[ID];
        L[R[ID]] = L[ID];
        if (R[ID] < n && a[R[ID]] < a[L[ID]]) {
          _new.push_back(R[ID]);
        }
        continue;
      }
      if (R[ID] < n) {
        int I = R[ID];
        if (isOk1) {
          int lo = 0, hi = I - 1, mid;
          while (hi - lo > 5) {
            mid = (lo + hi) / 2;
            int foo = st.query(mid, I - 1);
            if (foo > 1) {
              lo = mid + 1;
            } else if (foo == 0) {
              hi = mid - 1;
            } else {
              assert(foo == 1);
              lo = mid;
            }
          }
          int idx = 0;
          for (int i = hi; i >= lo; i--) {
            if (st.query(i, I - 1) == 1) {
              idx = i;
              break;
            }
          }
          L[I] = idx;
          if (a[idx] > a[I]) _new.push_back(I);
        }
      }
      int I = L[ID];
      if (isOk2) {
        int lo = I + 1, hi = n, mid;
        while (hi - lo > 5) {
          mid = (lo + hi) / 2;
          int foo = st.query(I + 1, mid);
          if (foo > 1) {
            hi = mid - 1;
          } else if (foo == 0) {
            lo = mid + 1;
          } else {
            assert(foo == 1);
            hi = mid;
          }
        }
        int idx = n;
        for (int i = lo; i <= hi; i++) {
          if (st.query(I + 1, i) == 1) {
            idx = i;
            break;
          }
        }
        R[I] = idx;
        if (idx < n && a[idx] < a[I]) _new.push_back(idx);
      }
    }
    v.clear();
    v = _new;
    assert(is_sorted(v.begin(), v.end()));
    auto it = unique(v.begin(), v.end());
    v.resize(distance(v.begin(), it));
    cnt++;
  }
  cout << cnt << '\n';
  return 0;
}
