There are n psychos standing in a line. Each psycho is assigned a unique integer from 1 to n. At each step every psycho who has an id greater than the psycho to his right (if exists) kills his right neighbor in the line. Note that a psycho might kill and get killed at the same step. 

You're given the initial arrangement of the psychos in the line. Calculate how many steps are needed to the moment of time such, that nobody kills his neighbor after that moment. Look notes to understand the statement more precise.

Input

The first line of input contains integer n denoting the number of psychos, (1 ≤ n ≤ 105). In the second line there will be a list of n space separated distinct integers each in range 1 to n, inclusive — ids of the psychos in the line from left to right.

Output

Print the number of steps, so that the line remains the same afterward.

Examples

Input

10
10 9 7 8 6 5 3 4 2 1


Output

2


Input

6
1 2 3 4 5 6


Output

0

Note

In the first sample line of the psychos transforms as follows: [10 9 7 8 6 5 3 4 2 1]  →  [10 8 4] →  [10]. So, there are two steps.
#include <bits/stdc++.h>
template <typename T>
class ListOverArray {
 public:
  struct Handle {
    Handle(size_t id_, const ListOverArray<T>& container_)
        : id(id_), container(&container_) {}
    bool IsValid() const { return container->IsValidId(id); }
    T GetValue() const {
      ;
      return container->GetValueById(id);
    }
    Handle GetNext() const {
      if (!IsValid()) return *this;
      const size_t nextId = container->m_next[id];
      return Handle(container->GetHandleById(nextId));
    }
    Handle GetPrev() const {
      if (!IsValid()) return *this;
      const size_t prevId = container->m_prev[id];
      return Handle(container->GetHandleById(prevId));
    }
    const Handle& operator++() {
      if (!IsValid()) return *this;
      id = container->m_next[id];
      return *this;
    }
    Handle operator++(int) {
      if (!IsValid()) return *this;
      Handle hCopy = *this;
      id = container->m_next[id];
      return hCopy;
    }
    size_t id;
    const ListOverArray<T>* container;
  };
  ListOverArray() { Init(); }
  bool IsEmpty() const {
    CheckConsistency();
    return !IsValidId(m_firstId);
  }
  bool IsValidId(size_t id) const { return id < m_values.size(); }
  Handle GetFirst() const { return Handle(m_firstId, *this); }
  Handle GetLast() const { return Handle(m_lastId, *this); }
  Handle GetHandleById(const size_t id) const { return Handle(id, *this); }
  T GetValueById(const size_t id) const { return m_values[id]; }
  void PushBack(const T x) {
    CheckConsistency();
    const size_t newId = m_values.size();
    m_values.push_back(x);
    m_next.push_back(AfterLastId);
    m_prev.push_back(BeforeFirstId);
    m_isDeleted.push_back(0);
    if (!IsValidId(m_lastId)) {
      m_lastId = m_firstId = newId;
      return;
    }
    m_next[m_lastId] = newId;
    m_prev[newId] = m_lastId;
    m_lastId = newId;
  }
  void PushFront(const T x) {
    CheckConsistency();
    const size_t newId = m_values.size();
    m_values.push_back(x);
    m_next.push_back(AfterLastId);
    m_prev.push_back(BeforeFirstId);
    m_isDeleted.push_back(0);
    if (!IsValidId(m_lastId)) {
      m_lastId = m_firstId = newId;
      return;
    }
    m_prev[m_firstId] = newId;
    m_next[newId] = m_firstId;
    m_firstId = newId;
  }
  void PopBack() {
    CheckConsistency();
    const size_t lastId = m_lastId;
    ;
    ;
    m_isDeleted[lastId] = 1;
    const size_t prevId = m_prev[lastId];
    if (IsValidId(prevId)) {
      m_next[prevId] = AfterLastId;
      m_lastId = prevId;
    } else {
      m_lastId = AfterLastId;
      m_firstId = BeforeFirstId;
    }
  }
  void PopFront() {
    CheckConsistency();
    const size_t firstId = m_firstId;
    ;
    ;
    m_isDeleted[firstId] = 1;
    const size_t nextId = m_next[firstId];
    if (IsValidId(nextId)) {
      m_prev[nextId] = BeforeFirstId;
      m_firstId = nextId;
    } else {
      m_lastId = AfterLastId;
      m_firstId = BeforeFirstId;
    }
  }
  void EraseById(const size_t id) {
    CheckConsistency();
    ;
    if (m_isDeleted[id]) return;
    m_isDeleted[id] = 1;
    const size_t nextId = m_next[id];
    const size_t prevId = m_prev[id];
    if (IsValidId(nextId))
      m_prev[nextId] = prevId;
    else
      m_lastId = prevId;
    if (IsValidId(prevId))
      m_next[prevId] = nextId;
    else
      m_firstId = nextId;
  }
  void Erase(const Handle& h) {
    ;
    EraseById(h.id);
  }

 private:
  void Init() {
    m_firstId = BeforeFirstId;
    m_lastId = AfterLastId;
  }
  void CheckConsistency() const {
    ;
    ;
    ;
    ;
  }
  static const size_t BeforeFirstId = 0xFFFFFFFD;
  static const size_t AfterLastId = 0xFFFFFFFC;
  size_t m_firstId;
  size_t m_lastId;
  std::vector<T> m_values;
  std::vector<size_t> m_next;
  std::vector<size_t> m_prev;
  std::vector<unsigned short> m_isDeleted;
};
template <size_t id>
class StopWatch {};
size_t GetAns(const std::vector<size_t>& a) {
  const size_t n = a.size();
  ListOverArray<size_t> killers;
  ListOverArray<size_t> list;
  for (size_t i = 0; i < n; i++) {
    killers.PushBack(i);
    list.PushBack(a[i]);
  }
  size_t ans = 0;
  bool wasChanged = true;
  while (wasChanged) {
    wasChanged = false;
    std::vector<size_t> victims;
    for (ListOverArray<size_t>::Handle pi = killers.GetFirst(); pi.IsValid();) {
      const size_t currIndex = pi.GetValue();
      ListOverArray<size_t>::Handle h = list.GetHandleById(currIndex);
      ListOverArray<size_t>::Handle hNext = h;
      ++hNext;
      if (!hNext.IsValid()) {
        killers.Erase(pi++);
        continue;
      }
      const size_t currValue = h.GetValue();
      const size_t nextValue = hNext.GetValue();
      if (currValue <= nextValue) {
        killers.Erase(pi++);
        continue;
      }
      victims.push_back(hNext.id);
      ++pi;
      wasChanged = true;
    }
    if (wasChanged) {
      ans++;
      for (size_t i = 0; i < victims.size(); i++) {
        const size_t victimIndex = victims[i];
        ;
        killers.EraseById(victimIndex);
        list.EraseById(victimIndex);
      }
    }
  }
  return ans;
}
bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode) {
  StopWatch<1> sw;
  sw;
  size_t n;
  ist >> n;
  if (multipleTestMode && !ist) return false;
  std::vector<size_t> a(n);
  for (size_t i = 0; i < n; i++) {
    ist >> a[i];
  }
  const size_t ans = GetAns(a);
  ost << ans << std::endl;
  return multipleTestMode;
}
size_t GetAnsRef(const std::vector<size_t>& a) {
  std::vector<size_t> b(a);
  bool wasChanged = true;
  size_t ans = 0;
  while (wasChanged) {
    wasChanged = false;
    std::set<size_t> toDelete;
    for (size_t i = 0; i + 1 < b.size(); i++) {
      if (b[i] > b[i + 1]) {
        wasChanged = true;
        toDelete.insert(i + 1);
      }
    }
    if (wasChanged) {
      ans++;
      for (std::set<size_t>::reverse_iterator pt = toDelete.rbegin();
           pt != toDelete.rend(); ++pt) {
        const size_t badIdx = *pt;
        b.erase(b.begin() + badIdx);
      }
    }
  }
  return ans;
}
void Test() {
  const size_t testCount = 10000;
  const size_t maxSize = 1000;
  for (size_t n = 1; n <= 9; n++) {
    std::vector<size_t> a(n);
    for (size_t i = 0; i < n; i++) {
      a[i] = i + 1;
    }
    do {
      const size_t ans = GetAns(a);
      const size_t ansRef = GetAnsRef(a);
      ;
    } while (std::next_permutation(a.begin(), a.end()));
  }
  for (size_t t = 0; t < testCount; t++) {
    const size_t n = rand() % maxSize + 1;
    std::vector<size_t> a(n);
    for (size_t i = 0; i < n; i++) {
      a[i] = i + 1;
    }
    std::random_shuffle(a.begin(), a.end());
    const size_t ans = GetAns(a);
    const size_t ansRef = GetAnsRef(a);
    ;
  }
  std::cout << "Test passed" << std::endl;
}
int main() {
  std::ios_base::sync_with_stdio(false);
  std::istream& ist = std::cin;
  std::ostream& ost = std::cout;
  Solve(ist, ost, false);
}
