                                                                                /*
                  ooo        ooooo                  .o88o.     o8o
                  `88.       .888'                  888 `"     `"'
                   888b     d'888      .oooo.      o888oo     oooo      .oooo.
                   8 Y88. .P  888     `P  )88b      888       `888     `P  )88b
                   8  `888'   888      .oP"888      888        888      .oP"888
                   8    Y     888     d8(  888      888        888     d8(  888
                  o8o        o888o    `Y888""8o    o888o      o888o    `Y888""8o

                                                    __       __
                                        |  | _ _|    _) /|  /  \ _|_ _ |_  _ _
                                        |/\|(-(_|   /__  |  \__/(_|_(_)|_)(-|

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

#define int                                       long long
#define lop(i,s,e)                                for(int i=s;i<(int)e;i++)
#define rlop(i,e,s)                               for(int i=e;i>=s;i--)
#define pb                                        push_back
#define all(v)                                    v.begin(),v.end()

const int N = 2e5 + 7, M = (int)1e9 + 7, inf = INT_MAX; const long long INF = LLONG_MAX;
#define bug(...)                                  __f (#__VA_ARGS__, __VA_ARGS__)
#define rtn                                       if(0)return;
template <typename Arg1> void __f (const char* name, Arg1&& arg1) { rtn cout << name << " : " << arg1 << endl; } template <typename Arg1, typename... Args> void __f (const char* names, Arg1&& arg1, Args&&... args) { rtn const char* comma = strchr (names + 1, ','); cout.write (names, comma - names) << " : " << arg1 << " | "; __f (comma + 1, args...); }

int segt[4*N];
void update(int i, int l, int r, int id, int value){
      if( l > id and id > r ) return;
      if( l == r ){ segt[i] = value; return ; }
      int m = (l+r)/2;
      update(2*i, l, m, id, value);
      update(2*i+1, m+1, r, id, value);
      segt[i] = max(segt[2*i], segt[2*i+1]);
}
int query(int i, int l, int r, int q_l, int q_r){
      if( r < q_l or q_r < l ) return 0;
      if( q_l <= l and r <= q_r ) return segt[i];
      int m = (l+r)/2;
      int a = query(2*i, l, m, q_l, q_r);
      int b = query(2*i+1, m+1, r, q_l, q_r);
      return max(a, b);
}
void solve()
{
      int n;
      cin >> n;
      int arr[n], l[n];
      lop(i,0,n) cin >> arr[i];
      stack<int> st;
      lop(i, 0, n){
            while( st.size() and arr[ st.top() ] < arr[i] ) st.pop();
            l[i] = (st.size()?st.top():-1);
            st.push(i);
      }

      int ans = 0;
      lop(i, 0, n){
            if( l[i] == -1 ) update( 1, 0, n-1, i, n+1 );
            else{
                  int x = query(1, 0, n-1, l[i] + 1, i - 1 );
                  update(i, 0, n-1, i, x+1);
                  //bug(i, x);
                  ans = max(ans, x+1);
            }
      }

      cout << ans << endl;

}

int32_t main()
{
      ios_base::sync_with_stdio(0);   cin.tie(0);   cout.tie(0);

      int test = 1;
      // cin >> test;
      while(test--)solve();

}


#include <iostream>
#include <vector>
#include <stack>

using namespace std;
/*
 *   0 1 2 3 4 5 6 7 8 9
 * [10 9 7 8 6 5 3 4 2 1]
 *
 * left bigger:
 * [-1 0 1 1 3 4 5 5 7 8]
 * diff:
 * [-1 1 1 2 1 1 1 2 1 1]
 *
 *   0 1 2 3 4 5 6 7 8 9
 * [10 7 4 2 5 8 9 6 3 1]
  *
 * left bigger:
 * [-1 0 1 2 1 0 0 6 7 8]
 * diff:
 * [-1 1 1 1 3 5 6 1 1 1]
 */
class Psycos {
public:
    Psycos(const vector<int> &a) : a(a), nextPeak(a.size()), nextBot(a.size()), leftBigger(a.size()) {
        //buildLeftBigger();
        //buildNext();
    };
private:
    vector<int> leftBigger;
    vector<int> a;
    vector<int> nextPeak;
    vector<int> nextBot;
    void buildNext() {
        int n = a.size();
        int lastPeak = -1;
        int lastBot = -1;
        int dir = a[n-2] - a[n-1];
        nextPeak[n-1] = -1;
        nextBot[n-1] = -1;
        for (int i = a.size() - 2; i >= 0; i--) {
            nextPeak[i] = lastPeak;
            nextBot[i] = lastBot;
            int newDir = a[i] - a[i+1];
            if (dir * newDir < 0) {
                if (dir > 0) lastPeak = i+1;
                else lastBot = i+1;
            }
            dir = newDir;
        }
    }
    void buildLeftBigger() {
        int t = a.size() - 1, h = a.size() - 2;
        while (t >= 0) {
            if (h < 0 || a[h] > a[t]) {
                leftBigger[t--] = h;
                if (t == h) h--;
            } else {
                h--;
            }
        }
    }
};
int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    Psycos ps(a);
    vector<int> timeKilled(n);
    stack<int> killers;
    timeKilled[0] = 200000;
    killers.push(0);
    for (int i = 1; i < a.size(); i++) {
        int tk = 0;
        while (!killers.empty() && a[killers.top()] < a[i]) {
            tk = max(tk, timeKilled[killers.top()]);
            killers.pop();
        }
        timeKilled[i] = 1 + tk;
        killers.push(i);
    }
    int res = 0;
    for (auto t : timeKilled) {
        if (t >= 200000) continue;
        res = max(res, t);
    }
    std::cout << res << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

using namespace std;
/*
 *   0 1 2 3 4 5 6 7 8 9
 * [10 9 7 8 6 5 3 4 2 1]
 *
 * left bigger:
 * [-1 0 1 1 3 4 5 5 7 8]
 * diff:
 * [-1 1 1 2 1 1 1 2 1 1]
 *
 *   0 1 2 3 4 5 6 7 8 9
 * [10 7 4 2 5 8 9 6 3 1]
  *
 * left bigger:
 * [-1 0 1 2 1 0 0 6 7 8]
 * diff:
 * [-1 1 1 1 3 5 6 1 1 1]
 */
class Psycos {
public:
    Psycos(const vector<int> &a) : a(a), leftBigger(a.size()) {
        //buildLeftBigger();
    };
    int count() {
        int cnt = 0;
        for (int i = 0; i < leftBigger.size(); i++) {
            cnt = max(cnt, leftBigger[i] != -1 ? i - leftBigger[i] : 0);
        }
        return cnt;
    }
    int count2() {
        stack<int> s;
        s.push(a.back());
        int cnt = 0;
        int k = -1;
        for (int i = a.size() - 2; i >= 0; i--) {
            if (k == -1) {
                if (a[i] <= s.top()) {
                    s.push(a[i]);
                    continue;
                }
                k = a[i];
            } else {
                if (a[i] >= k) {
                    k = a[i];
                    continue;
                }
                while (!s.empty() && k > s.top()) {
                    cnt++;
                    s.pop();
                }
                s.push(a[i]);
                k = -1;
            }
        }
        while (!s.empty() && k > s.top()) {
            cnt++;
            s.pop();
        }
        return cnt;
    }
private:
    vector<int> leftBigger;
    vector<int> a;
    void buildLeftBigger() {
        int t = a.size() - 1, h = a.size() - 2;
        while (t >= 0) {
            if (h < 0 || a[h] > a[t]) {
                leftBigger[t--] = h;
                if (t == h) h--;
            } else {
                h--;
            }
        }
    }
};
int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    Psycos ps(a);
    std::cout << ps.count2() << std::endl;
    return 0;
}


#include <iostream>
#include <vector>

using namespace std;
/*
 *   0 1 2 3 4 5 6 7 8 9
 * [10 9 7 8 6 5 3 4 2 1]
 *
 * left bigger:
 * [-1 0 1 1 3 4 5 5 7 8]
 * diff:
 * [-1 1 1 2 1 1 1 2 1 1]
 */
class Psycos {
public:
    Psycos(const vector<int> &a) : a(a), leftBigger(a.size()) {
        buildLeftBigger();
    };
    int count() {
        int cnt = 0;
        for (int i = 0; i < leftBigger.size(); i++) {
            cnt = max(cnt, leftBigger[i] != -1 ? i - leftBigger[i] : 0);
        }
        return cnt;
    }
private:
    vector<int> leftBigger;
    vector<int> a;
    void buildLeftBigger() {
        int t = a.size() - 1, h = a.size() - 2;
        while (t >= 0) {
            if (h < 0 || a[h] > a[t]) {
                leftBigger[t--] = h;
                if (t == h) h--;
            } else {
                h--;
            }
        }
    }
};
int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    Psycos ps(a);
    std::cout << ps.count() << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

using namespace std;
/*
 *   0 1 2 3 4 5 6 7 8 9
 * [10 9 7 8 6 5 3 4 2 1]
 *
 * left bigger:
 * [-1 0 1 1 3 4 5 5 7 8]
 * diff:
 * [-1 1 1 2 1 1 1 2 1 1]
 *
 *   0 1 2 3 4 5 6 7 8 9
 * [10 7 4 2 5 8 9 6 3 1]
  *
 * left bigger:
 * [-1 0 1 2 1 0 0 6 7 8]
 * diff:
 * [-1 1 1 1 3 5 6 1 1 1]
 */
class Psycos {
public:
    Psycos(const vector<int> &a) : a(2), leftBigger(a.size()), stepNr(0) {
        this->a[0] = a;
        //buildLeftBigger();
    };
    bool step() {
        a[(stepNr + 1)%2].clear();
        int prev = 0;
        for (auto e : a[stepNr % 2]) {
            if (e > prev) {
                a[(stepNr + 1)%2].push_back(e);
            }
            prev = e;
        }
        stepNr++;
        return a[0].size() == a[1].size();
    }
    int getStep() {
        return stepNr;
    }
private:
    vector<int> leftBigger;
    vector<vector<int>> a;
    int stepNr;
    void buildLeftBigger() {
        int t = a[0].size() - 1, h = a[0].size() - 2;
        while (t >= 0) {
            if (h < 0 || a[0][h] > a[0][t]) {
                leftBigger[t--] = h;
                if (t == h) h--;
            } else {
                h--;
            }
        }
    }
};
int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    Psycos ps(a);
    while (!ps.step());
    std::cout << ps.getStep() - 1 << std::endl;
    return 0;
}


10
10 7 4 2 5 8 9 6 3 1#include <bits/stdc++.h>

using namespace std;

template < typename T >
struct treap {

private:
    struct node {
        T sum = 0, x = 0;
        int y, cnt = 1, rev = 0;
        node * l, * r;

        node( T x ) {
            this -> sum = x;
            this -> x = x;
            this -> y = rand() | ( 1 << ( rand() % 31 ) );
            this -> l = this -> r = nullptr;
        }

        ~node( ) {
            if ( l )
                delete l;
            if ( r )
                delete r;
        }
    };
public:
    node * root = nullptr;
    pair<node *, node *> split( node * Node, int k ) {
        if ( Node == nullptr )
            return { nullptr, nullptr };
        push( Node );
        if ( cnt ( Node ) <= k )
            return { Node, nullptr };
        if ( k == 0 )
            return { nullptr, Node };
        if ( cnt ( Node -> l ) < k ) {
            pair<node *, node *> res = split( Node -> r, k - cnt ( Node -> l ) - 1 );
            Node -> r = res.first;
            update( Node );
            return { Node, res.second };
        } else {
            pair<node *, node *> res = split( Node -> l, k );
            Node -> l = res.second;
            update( Node );
            return { res.first, Node };
        }
    }
    node * merge( node * First, node * Second ) {
        if ( First == nullptr )
            return Second;
        if ( Second == nullptr )
            return First;
        if ( First -> y <= Second -> y ) {
            push( First );
            First -> r = merge( First -> r, Second );
            update( First );
            return First;
        } else {
            push( Second );
            Second -> l = merge( First, Second -> l );
            update( Second );
            return Second;
        }
    }
    void insert( int pos, T x ){
        if ( pos > size() || pos < 0 ) return;
        pair< node *, node * > res = split( root, pos );
        node * new_node = new node( x );
        root = merge( merge( res.first, new_node ), res.second );
    }

    void erase( int pos ) {
        pair<node *, node *> res_1 = split( root, pos );
        pair<node *, node *> res_2 = split( res_1.second, 1 );
        root = merge( res_1.first, res_2.second );
    }

    node * erase( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        root = merge( res_1.first, res_2.second );
        return res_2.first;
    }

    void reverse( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        res_2.first -> rev ^= 1;
        merge( merge( res_1.first, res_2.first ), res_2.second );
    }

    T sum( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        T res = res_2.first -> sum;
        merge( merge( res_1.first, res_2.first ), res_2.second );
        return res;
    }

    T& operator []( int pos ){
        return order( root, pos + 1 );
    }

    T& order ( node *root, int pos ){
        push( root );
        T *res = nullptr;
        if( cnt( root ) - cnt( root -> r ) == pos )
            res = &root -> x;
        else if( pos > cnt( root ) - cnt( root -> r ) )
            res = &order( root -> r, pos - ( cnt( root ) - cnt( root -> r ) ) );
        else
            res = &order( root -> l, pos);
        update( root );
        return *res;
    }

    inline void push( node * Node ){
        if( Node == nullptr || Node -> rev == 0 ) return;
        swap( Node -> l, Node -> r );
        if( Node -> l != nullptr ) Node -> l -> rev ^= 1;
        if( Node -> r != nullptr ) Node -> r -> rev ^= 1;
        Node -> rev = 0;
    }

    inline void update( node * Node ) {
        if ( Node == nullptr )
            Node -> cnt = 0;
        else {
            Node -> sum = Node -> x;
            Node -> cnt = 1;
            if ( Node -> l != nullptr ){
                Node -> sum = Node -> sum + Node -> l -> sum;
                Node -> cnt += cnt( Node -> l );
            }
            if ( Node -> r != nullptr ){
                Node -> sum = Node -> sum + Node -> r -> sum;
                Node -> cnt += cnt( Node -> r );
            }
        }
    }

    node * find( node * Node, T x ) {
        if ( Node == nullptr )
            return nullptr;
        if ( Node -> x == x )
            return Node;
        if ( Node -> x < x )
            return find( Node -> r, x );
        return find( Node -> l, x );
    }

    void print( node * Node ) {
        if ( Node != nullptr ) {
            print( Node -> l );
            cout << Node -> x << " ";
            print( Node -> r );
        }
    }

    inline int size( ) { return root == nullptr ? 0 : root -> cnt; }
    inline bool empty( ) { return size(); }
    inline void clear( ) { root = nullptr; }
    inline int cnt( node * Node ) { return Node == nullptr ? 0 : Node -> cnt; }
    int count( T x ) { return find( root, x ) != nullptr; }
    void print( ) { print( root ); }
    node * find( T x ) { return find( root, x ); }

};

struct fenwick{

    vector<int> fw;

    fenwick( int n ){
        fw.resize( n + 1, 0 );
    }

    fenwick( const vector<int> & a ){
        fw.resize( a.size(), 0 );
        for( int i = 0; i < a.size(); i++ )
            update( i, a[i] );
    }

    void update( int i, int d ){
        while( i < fw.size() ){
            fw[i] += d;
            i = ( i | ( i + 1 ) );
        }
    }

    int get( int n ){
        int result = 0;
        while( n >= 0 ){
            result += fw[n];
            n = ( n & ( n + 1 ) ) - 1;
        }
        return result;
    }

    int get( int l, int r ){
        return get( r ) - get( l - 1 );
    }
};

void solution( istream &cin, ostream &cout, const int &test_case )
{
    treap<int> tr;
    int n;
    cin >> n;
    fenwick fw( n );
    for( int i = 1; i <= n; i++ ){
        int x;
        cin >> x;
        tr.insert( i - 1, x );
    }
    vector<int> ind;
    for( int i = tr.size() - 2; i >= 0; i-- ){
        if( tr[i] > tr[i + 1] ){
            ind.push_back( i );
        }
    }
    int ans = 0;
    while( true ){
        if( ind.empty() ) break;
        ans++;
        vector<int> new_ind;
        for( int i: ind ){
            tr.erase( i + 1 );
            fw.update( i + 1, 1 );
            if( i + 1 < tr.size() && tr[i] > tr[i + 1] && ( i == 0 || ( i > 0 && tr[i - 1] <= tr[i] ) ) ){
                new_ind.push_back( i );
            }
        }
        for( int &i: new_ind ){
            i -= fw.get( i );
        }
        for( int i: ind ){
            fw.update( i + 1, -1 );
        }
        ind = new_ind;
    }

    cout << ans << endl;
}

int32_t main()
{

    ios::sync_with_stdio( 0 );

    int t = 1;
    //cin >> t;

    for( int i = 1; i <= t; i++ ) solution( cin, cout, i );

}


#include <bits/stdc++.h>

using namespace std;

template < typename T >
struct treap {

private:
    struct node {
        T sum = 0, x = 0;
        int y, cnt = 1, rev = 0;
        node * l, * r;

        node( T x ) {
            this -> sum = x;
            this -> x = x;
            this -> y = rand() | ( 1 << ( rand() % 31 ) );
            this -> l = this -> r = nullptr;
        }

        ~node( ) {
            if ( l )
                delete l;
            if ( r )
                delete r;
        }
    };
public:
    node * root = nullptr;
    pair<node *, node *> split( node * Node, int k ) {
        if ( Node == nullptr )
            return { nullptr, nullptr };
        push( Node );
        if ( cnt ( Node ) <= k )
            return { Node, nullptr };
        if ( k == 0 )
            return { nullptr, Node };
        if ( cnt ( Node -> l ) < k ) {
            pair<node *, node *> res = split( Node -> r, k - cnt ( Node -> l ) - 1 );
            Node -> r = res.first;
            update( Node );
            return { Node, res.second };
        } else {
            pair<node *, node *> res = split( Node -> l, k );
            Node -> l = res.second;
            update( Node );
            return { res.first, Node };
        }
    }
    node * merge( node * First, node * Second ) {
        if ( First == nullptr )
            return Second;
        if ( Second == nullptr )
            return First;
        if ( First -> y <= Second -> y ) {
            push( First );
            First -> r = merge( First -> r, Second );
            update( First );
            return First;
        } else {
            push( Second );
            Second -> l = merge( First, Second -> l );
            update( Second );
            return Second;
        }
    }
    void insert( int pos, T x ){
        if ( pos > size() || pos < 0 ) return;
        pair< node *, node * > res = split( root, pos );
        node * new_node = new node( x );
        root = merge( merge( res.first, new_node ), res.second );
    }

    void erase( int pos ) {
        pair<node *, node *> res_1 = split( root, pos );
        pair<node *, node *> res_2 = split( res_1.second, 1 );
        root = merge( res_1.first, res_2.second );
    }

    node * erase( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        root = merge( res_1.first, res_2.second );
        return res_2.first;
    }

    void reverse( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        res_2.first -> rev ^= 1;
        merge( merge( res_1.first, res_2.first ), res_2.second );
    }

    T sum( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        T res = res_2.first -> sum;
        merge( merge( res_1.first, res_2.first ), res_2.second );
        return res;
    }

    T& operator []( int pos ){
        return order( root, pos + 1 );
    }

    T& order ( node *root, int pos ){
        push( root );
        T *res = nullptr;
        if( cnt( root ) - cnt( root -> r ) == pos )
            res = &root -> x;
        else if( pos > cnt( root ) - cnt( root -> r ) )
            res = &order( root -> r, pos - ( cnt( root ) - cnt( root -> r ) ) );
        else
            res = &order( root -> l, pos);
        update( root );
        return *res;
    }

    inline void push( node * Node ){
        if( Node == nullptr || Node -> rev == 0 ) return;
        swap( Node -> l, Node -> r );
        if( Node -> l != nullptr ) Node -> l -> rev ^= 1;
        if( Node -> r != nullptr ) Node -> r -> rev ^= 1;
        Node -> rev = 0;
    }

    inline void update( node * Node ) {
        if ( Node == nullptr )
            Node -> cnt = 0;
        else {
            Node -> sum = Node -> x;
            Node -> cnt = 1;
            if ( Node -> l != nullptr ){
                Node -> sum = Node -> sum + Node -> l -> sum;
                Node -> cnt += cnt( Node -> l );
            }
            if ( Node -> r != nullptr ){
                Node -> sum = Node -> sum + Node -> r -> sum;
                Node -> cnt += cnt( Node -> r );
            }
        }
    }

    node * find( node * Node, T x ) {
        if ( Node == nullptr )
            return nullptr;
        if ( Node -> x == x )
            return Node;
        if ( Node -> x < x )
            return find( Node -> r, x );
        return find( Node -> l, x );
    }

    void print( node * Node ) {
        if ( Node != nullptr ) {
            print( Node -> l );
            cout << Node -> x << " ";
            print( Node -> r );
        }
    }

    inline int size( ) { return root == nullptr ? 0 : root -> cnt; }
    inline bool empty( ) { return size(); }
    inline void clear( ) { root = nullptr; }
    inline int cnt( node * Node ) { return Node == nullptr ? 0 : Node -> cnt; }
    int count( T x ) { return find( root, x ) != nullptr; }
    void print( ) { print( root ); }
    node * find( T x ) { return find( root, x ); }

};

struct fenwick{

    vector<int> fw;

    fenwick( int n ){
        fw.resize( n + 1, 0 );
    }

    fenwick( const vector<int> & a ){
        fw.resize( a.size(), 0 );
        for( int i = 0; i < a.size(); i++ )
            update( i, a[i] );
    }

    void update( int i, int d ){
        while( i < fw.size() ){
            fw[i] += d;
            i = ( i | ( i + 1 ) );
        }
    }

    int get( int n ){
        int result = 0;
        while( n >= 0 ){
            result += fw[n];
            n = ( n & ( n + 1 ) ) - 1;
        }
        return result;
    }

    int get( int l, int r ){
        return get( r ) - get( l - 1 );
    }
};

void solution( istream &cin, ostream &cout, const int &test_case )
{
    treap<int> tr;
    int n;
    cin >> n;
    fenwick fw( n );
    for( int i = 1; i <= n; i++ ){
        int x;
        cin >> x;
        tr.insert( i - 1, x );
    }
    vector<int> ind;
    for( int i = tr.size() - 2; i >= 0; i-- ){
        if( tr[i] > tr[i + 1] ){
            ind.push_back( i );
        }
    }
    int ans = 0;
    while( true ){
        if( ind.empty() ) break;
        ans++;
        vector<int> new_ind;
        for( int i: ind ){
            tr.erase( i + 1 );
            fw.update( i + 1, 1 );
            if( i + 1 < tr.size() && tr[i] > tr[i + 1] && ( i == 0 || ( i > 0 && tr[i - 1] <= tr[i] ) ) ){
                new_ind.push_back( i );
            }
        }
        for( int &i: new_ind ){
            i -= fw.get( i );
        }
        for( int i: ind ){
            fw.update( i, -1 );
        }
        ind = new_ind;
    }

    cout << ans << endl;
}

int32_t main()
{

    ios::sync_with_stdio( 0 );

    int t = 1;
    //cin >> t;

    for( int i = 1; i <= t; i++ ) solution( cin, cout, i );

}


#include <bits/stdc++.h>

using namespace std;

template < typename T >
struct treap {

private:
    struct node {
        T sum = 0, x = 0;
        int y, cnt = 1, rev = 0;
        node * l, * r;

        node( T x ) {
            this -> sum = x;
            this -> x = x;
            this -> y = rand() | ( 1 << ( rand() % 31 ) );
            this -> l = this -> r = nullptr;
        }

        ~node( ) {
            if ( l )
                delete l;
            if ( r )
                delete r;
        }
    };
public:
    node * root = nullptr;
    pair<node *, node *> split( node * Node, int k ) {
        if ( Node == nullptr )
            return { nullptr, nullptr };
        push( Node );
        if ( cnt ( Node ) <= k )
            return { Node, nullptr };
        if ( k == 0 )
            return { nullptr, Node };
        if ( cnt ( Node -> l ) < k ) {
            pair<node *, node *> res = split( Node -> r, k - cnt ( Node -> l ) - 1 );
            Node -> r = res.first;
            update( Node );
            return { Node, res.second };
        } else {
            pair<node *, node *> res = split( Node -> l, k );
            Node -> l = res.second;
            update( Node );
            return { res.first, Node };
        }
    }
    node * merge( node * First, node * Second ) {
        if ( First == nullptr )
            return Second;
        if ( Second == nullptr )
            return First;
        if ( First -> y <= Second -> y ) {
            push( First );
            First -> r = merge( First -> r, Second );
            update( First );
            return First;
        } else {
            push( Second );
            Second -> l = merge( First, Second -> l );
            update( Second );
            return Second;
        }
    }
    void insert( int pos, T x ){
        if ( pos > size() || pos < 0 ) return;
        pair< node *, node * > res = split( root, pos );
        node * new_node = new node( x );
        root = merge( merge( res.first, new_node ), res.second );
    }

    void erase( int pos ) {
        pair<node *, node *> res_1 = split( root, pos );
        pair<node *, node *> res_2 = split( res_1.second, 1 );
        root = merge( res_1.first, res_2.second );
    }

    node * erase( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        root = merge( res_1.first, res_2.second );
        return res_2.first;
    }

    void reverse( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        res_2.first -> rev ^= 1;
        merge( merge( res_1.first, res_2.first ), res_2.second );
    }

    T sum( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        T res = res_2.first -> sum;
        merge( merge( res_1.first, res_2.first ), res_2.second );
        return res;
    }

    T& operator []( int pos ){
        return order( root, pos + 1 );
    }

    T& order ( node *root, int pos ){
        push( root );
        T *res = nullptr;
        if( cnt( root ) - cnt( root -> r ) == pos )
            res = &root -> x;
        else if( pos > cnt( root ) - cnt( root -> r ) )
            res = &order( root -> r, pos - ( cnt( root ) - cnt( root -> r ) ) );
        else
            res = &order( root -> l, pos);
        update( root );
        return *res;
    }

    inline void push( node * Node ){
        if( Node == nullptr || Node -> rev == 0 ) return;
        swap( Node -> l, Node -> r );
        if( Node -> l != nullptr ) Node -> l -> rev ^= 1;
        if( Node -> r != nullptr ) Node -> r -> rev ^= 1;
        Node -> rev = 0;
    }

    inline void update( node * Node ) {
        if ( Node == nullptr )
            Node -> cnt = 0;
        else {
            Node -> sum = Node -> x;
            Node -> cnt = 1;
            if ( Node -> l != nullptr ){
                Node -> sum = Node -> sum + Node -> l -> sum;
                Node -> cnt += cnt( Node -> l );
            }
            if ( Node -> r != nullptr ){
                Node -> sum = Node -> sum + Node -> r -> sum;
                Node -> cnt += cnt( Node -> r );
            }
        }
    }

    node * find( node * Node, T x ) {
        if ( Node == nullptr )
            return nullptr;
        if ( Node -> x == x )
            return Node;
        if ( Node -> x < x )
            return find( Node -> r, x );
        return find( Node -> l, x );
    }

    void print( node * Node ) {
        if ( Node != nullptr ) {
            print( Node -> l );
            cout << Node -> x << " ";
            print( Node -> r );
        }
    }

    inline int size( ) { return root == nullptr ? 0 : root -> cnt; }
    inline bool empty( ) { return size(); }
    inline void clear( ) { root = nullptr; }
    inline int cnt( node * Node ) { return Node == nullptr ? 0 : Node -> cnt; }
    int count( T x ) { return find( root, x ) != nullptr; }
    void print( ) { print( root ); }
    node * find( T x ) { return find( root, x ); }

};

struct fenwick{

    vector<int> fw;

    fenwick( int n ){
        fw.resize( n + 1, 0 );
    }

    fenwick( const vector<int> & a ){
        fw.resize( a.size(), 0 );
        for( int i = 0; i < a.size(); i++ )
            update( i, a[i] );
    }

    void update( int i, int d ){
        while( i < fw.size() ){
            fw[i] += d;
            i = ( i | ( i + 1 ) );
        }
    }

    int get( int n ){
        int result = 0;
        while( n >= 0 ){
            result += fw[n];
            n = ( n & ( n + 1 ) ) - 1;
        }
        return result;
    }

    int get( int l, int r ){
        return get( r ) - get( l - 1 );
    }
};

void solution( istream &cin, ostream &cout, const int &test_case )
{
    treap<int> tr;
    int n;
    cin >> n;
    fenwick fw( n );
    for( int i = 1; i <= n; i++ ){
        int x;
        cin >> x;
        tr.insert( i - 1, x );
    }
    vector<int> ind;
    for( int i = tr.size() - 2; i >= 0; i-- ){
        if( tr[i] > tr[i + 1] ){
            ind.push_back( i );
        }
    }
    int ans = 0;
    while( true ){
        if( ind.empty() ) break;
        ans++;
        vector<int> new_ind;
        for( int i: ind ){
            tr.erase( i + 1 );
            fw.update( i + 1, 1 );
            if( i + 1 < tr.size() && tr[i] > tr[i + 1] && ( i == 0 || ( i > 0 && tr[i - 1] <= tr[i] ) ) ){
                new_ind.push_back( i );
            }
        }
        for( int &i: new_ind ){
            i -= fw.get( i );
        }
        for( int i: ind ){
            fw.update( i + 1, -1 );
        }
        ind = new_ind;
    }

    cout << ans << endl;
}

int32_t main()
{

    ios::sync_with_stdio( 0 );

    int t = 1;
    //cin >> t;

    for( int i = 1; i <= t; i++ ) solution( cin, cout, i );

}


#include <bits/stdc++.h>

using namespace std;

template < typename T >
struct treap {

private:
    struct node {
        T sum = 0, x = 0;
        int y, cnt = 1, rev = 0;
        node * l, * r;

        node( T x ) {
            this -> sum = x;
            this -> x = x;
            this -> y = rand() | ( 1 << ( rand() % 31 ) );
            this -> l = this -> r = nullptr;
        }

        ~node( ) {
            if ( l )
                delete l;
            if ( r )
                delete r;
        }
    };
public:
    node * root = nullptr;
    pair<node *, node *> split( node * Node, int k ) {
        if ( Node == nullptr )
            return { nullptr, nullptr };
        push( Node );
        if ( cnt ( Node ) <= k )
            return { Node, nullptr };
        if ( k == 0 )
            return { nullptr, Node };
        if ( cnt ( Node -> l ) < k ) {
            pair<node *, node *> res = split( Node -> r, k - cnt ( Node -> l ) - 1 );
            Node -> r = res.first;
            update( Node );
            return { Node, res.second };
        } else {
            pair<node *, node *> res = split( Node -> l, k );
            Node -> l = res.second;
            update( Node );
            return { res.first, Node };
        }
    }
    node * merge( node * First, node * Second ) {
        if ( First == nullptr )
            return Second;
        if ( Second == nullptr )
            return First;
        if ( First -> y <= Second -> y ) {
            push( First );
            First -> r = merge( First -> r, Second );
            update( First );
            return First;
        } else {
            push( Second );
            Second -> l = merge( First, Second -> l );
            update( Second );
            return Second;
        }
    }
    void insert( int pos, T x ){
        if ( pos > size() || pos < 0 ) return;
        pair< node *, node * > res = split( root, pos );
        node * new_node = new node( x );
        root = merge( merge( res.first, new_node ), res.second );
    }

    void erase( int pos ) {
        pair<node *, node *> res_1 = split( root, pos );
        pair<node *, node *> res_2 = split( res_1.second, 1 );
        root = merge( res_1.first, res_2.second );
    }

    node * erase( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        root = merge( res_1.first, res_2.second );
        return res_2.first;
    }

    void reverse( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        res_2.first -> rev ^= 1;
        merge( merge( res_1.first, res_2.first ), res_2.second );
    }

    T sum( int l, int r ){
        pair < node *, node * > res_1 = split( root, l );
        pair < node *, node * > res_2 = split( res_1.second, r - l + 1 );
        T res = res_2.first -> sum;
        merge( merge( res_1.first, res_2.first ), res_2.second );
        return res;
    }

    T& operator []( int pos ){
        return order( root, pos + 1 );
    }

    T& order ( node *root, int pos ){
        push( root );
        T *res = nullptr;
        if( cnt( root ) - cnt( root -> r ) == pos )
            res = &root -> x;
        else if( pos > cnt( root ) - cnt( root -> r ) )
            res = &order( root -> r, pos - ( cnt( root ) - cnt( root -> r ) ) );
        else
            res = &order( root -> l, pos);
        update( root );
        return *res;
    }

    inline void push( node * Node ){
        if( Node == nullptr || Node -> rev == 0 ) return;
        swap( Node -> l, Node -> r );
        if( Node -> l != nullptr ) Node -> l -> rev ^= 1;
        if( Node -> r != nullptr ) Node -> r -> rev ^= 1;
        Node -> rev = 0;
    }

    inline void update( node * Node ) {
        if ( Node == nullptr )
            Node -> cnt = 0;
        else {
            Node -> sum = Node -> x;
            Node -> cnt = 1;
            if ( Node -> l != nullptr ){
                Node -> sum = Node -> sum + Node -> l -> sum;
                Node -> cnt += cnt( Node -> l );
            }
            if ( Node -> r != nullptr ){
                Node -> sum = Node -> sum + Node -> r -> sum;
                Node -> cnt += cnt( Node -> r );
            }
        }
    }

    node * find( node * Node, T x ) {
        if ( Node == nullptr )
            return nullptr;
        if ( Node -> x == x )
            return Node;
        if ( Node -> x < x )
            return find( Node -> r, x );
        return find( Node -> l, x );
    }

    void print( node * Node ) {
        if ( Node != nullptr ) {
            print( Node -> l );
            cout << Node -> x << " ";
            print( Node -> r );
        }
    }

    inline int size( ) { return root == nullptr ? 0 : root -> cnt; }
    inline bool empty( ) { return size(); }
    inline void clear( ) { root = nullptr; }
    inline int cnt( node * Node ) { return Node == nullptr ? 0 : Node -> cnt; }
    int count( T x ) { return find( root, x ) != nullptr; }
    void print( ) { print( root ); }
    node * find( T x ) { return find( root, x ); }

};

void solution( istream &cin, ostream &cout, const int &test_case )
{
    treap<int> tr;
    int n;
    cin >> n;
    for( int i = 1; i <= n; i++ ){
        int x;
        cin >> x;
        tr.insert( i - 1, x );
    }
    vector<int> ind;
    for( int i = tr.size() - 2; i >= 0; i-- ){
        if( tr[i] > tr[i + 1] ){
            ind.push_back( i );
        }
    }
    int ans = 0;
    while( true ){
        if( ind.empty() ) break;
        ans++;
        vector<int> new_ind;
        vector<int> sub( tr.size() + 1, 0 );
        for( int i: ind ){
            tr.erase( i + 1 );
            sub[i + 1]++;
            if( i + 1 < tr.size() && tr[i] > tr[i + 1] && ( i == 0 || ( i > 0 && tr[i - 1] <= tr[i] ) ) ){
                new_ind.push_back( i );
            }
        }

        for( int i = 1; i < sub.size(); i++ ){
            sub[i] += sub[i - 1];
        }

        for( int &i: new_ind ){
            i -= sub[i];
        }

        ind = new_ind;
    }

    cout << ans << endl;
}

int32_t main()
{

    ios::sync_with_stdio( 0 );

    int t = 1;
    //cin >> t;

    for( int i = 1; i <= t; i++ ) solution( cin, cout, i );

}


#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define pb push_back
#define ms(v,x) memset(v,x,sizeof(v))
#define ff first
#define ss second
#define td(v) v.begin(),v.end()
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define re(v) {for(auto &_re : v) cin >> _re;}
#define rre(v){for(auto &_re : v) for(auto &_rre : _re) cin >> _rre;}
#define pr(v) {for(auto _pr : v) cout << _pr << " "; cout << endl;}
#define prr(v) {for(auto _prr : v) cout << _prr.ff << " " << _prr.ss << endl;}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define eb emplace_back
using namespace std;
const ll M = 1e9 + 7;
const ll mod = 998244353;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

ll binpow(ll a, ll b, ll m){
	ll res = 1;
	while(b > 0){
		if(b&1) res = res * a % m;
		a = a * a % m;
		b>>=1;
	}
	return res;
}
ll gcd(ll a, ll b){
	return (b==0 ? a : gcd(b,a%b));
}
//#define int long long
//#define double long double
void solve(){
	int n;
	cin >> n;
	vector<int> a(n);
	re(a);
	stack<pii> s;
	s.push({a[0], 0});
	vector<int> dp(n);
	for(int i=1;i<n;i++){
		int last = -1;
		while(!s.empty() && s.top().ff < a[i]){
			last = max(last, dp[s.top().ss]);
			s.pop();
		}
		if(!s.empty()){
			if(last == -1) dp[i] = 1;
			else dp[i] = last + 1;
		}
		s.push({a[i], i});
	}
	cout << *max_element(td(dp)) << endl;
}
int32_t main(){
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int t=1;
 	//cin >> t;
  while(t--){
  	solve();
  }
}


#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define pb push_back
#define ms(v,x) memset(v,x,sizeof(v))
#define ff first
#define ss second
#define td(v) v.begin(),v.end()
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define re(v) {for(auto &_re : v) cin >> _re;}
#define pr(v) {for(auto _pr : v) cout << _pr << " "; cout << endl;}
#define prr(v) {for(auto _prr : v) cout << _prr.ff << " " << _prr.ss << endl;}
using namespace std;
const ll M = 1e9 + 7;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
   	int n;
   	cin >> n;
   	vector<int> p(n); re(p);
   	stack<int> last;
   	vector<int> t(n), k(n);
   	t[0] = 0;
   	last.push(0);
   	for(int i=1;i<n;i++){
   		while(!last.empty() && p[i] > p[last.top()]){
   			last.pop();
   		}
   		if(last.empty()){
   			last.push(i);
   			continue;
   		}
   		else{
   			k[last.top()]++;
   			t[i] = k[last.top()];
   			last.push(i);
   		}
   	}
   	cout << *max_element(td(t)) << endl;
}

/*

	se pi < pi+1
	pi mata pi+1

*/


#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define pb push_back
#define ms(v,x) memset(v,x,sizeof(v))
#define ff first
#define ss second
#define td(v) v.begin(),v.end()
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define re(v) {for(auto &_re : v) cin >> _re;}
#define pr(v) {for(auto _pr : v) cout << _pr << " "; cout << endl;}
#define prr(v) {for(auto _prr : v) cout << _prr.ff << " " << _prr.ss << endl;}
using namespace std;
const ll M = 1e9 + 7;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
   	int n;
   	cin >> n;
   	vector<int> p(n); re(p);
   	stack<int> last;
   	vector<int> t(n), k(n), unk(n);
   	t[0] = 0;
   	unk[0] = 1;
   	last.push(0);
   	for(int i=1;i<n;i++){
   		int tt = 0;
   		while(!last.empty() && (p[i] > p[last.top()] or (tt > t[last.top()] && !unk[last.top()]))){
   			tt++;
   			last.pop();
   		}
   		if(last.empty()){
   			//cout << "act : " << i << " survived" << endl;
   			unk[i] = 1;
   			last.push(i);
   			continue;
   		}
   		else{
   			//cout << "act : " << last.top() << " killed " << i << endl;
   			k[last.top()]++;
   			t[i] = k[last.top()];
   			last.push(i);
   		}
   	}
  // 	pr(t);
   	cout << *max_element(td(t)) << endl;
}

/*

	se pi < pi+1
	pi mata pi+1

*/


#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define pb push_back
#define ms(v,x) memset(v,x,sizeof(v))
#define ff first
#define ss second
#define td(v) v.begin(),v.end()
#define rep(i,a,n) for (int i=(a);i<(n);i++)
#define re(v) {for(auto &_re : v) cin >> _re;}
#define rre(v){for(auto &_re : v) for(auto &_rre : _re) cin >> _rre;}
#define pr(v) {for(auto _pr : v) cout << _pr << " "; cout << endl;}
#define prr(v) {for(auto _prr : v) cout << _prr.ff << " " << _prr.ss << endl;}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define eb emplace_back
using namespace std;
const ll M = 1e9 + 7;
const ll mod = 998244353;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

ll binpow(ll a, ll b, ll m){
	ll res = 1;
	while(b > 0){
		if(b&1) res = res * a % m;
		a = a * a % m;
		b>>=1;
	}
	return res;
}
ll gcd(ll a, ll b){
	return (b==0 ? a : gcd(b,a%b));
}
//#define int long long
//#define double long double
void solve(){
	int n;
	cin >> n;
	vector<int> a(n);
	re(a);
	stack<pii> s;
	s.push({a[0], 0});
	vector<int> dp(n);
	for(int i=1;i<n;i++){
		int last = 0;
		while(!s.empty() && s.top().ff < a[i]){
			last = max(last, dp[s.top().ss]);
			s.pop();
		}
		if(!s.empty()){
			dp[i] = last + 1;
		}
		s.push({a[i], i});
	}
	cout << *max_element(td(dp)) << endl;
}
int32_t main(){
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int t=1;
 	//cin >> t;
  while(t--){
  	solve();
  }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <deque>

using namespace std;

int main(){
	int n;
	cin >> n;
	deque<int> d1, d2;
	int temp;
	int last = INT_MIN;
	bool b = true;
	for(int i=0; i<n; i++){
		cin >> temp;
		if(temp > last){
			d1.push_back(temp);
		}else{
			b = false;
		}
		last = temp;
	}
	if(b){
		cout << 0 << endl;
		return 0;
	}
	int res = 1;

	while(true){
		b = true;
		last = INT_MIN;
		for(int i=0; i<d1.size(); i++){
			temp = d1[i];
			if(temp > last){
				d2.push_back(temp);
			}else{
				b = false;
			}
			last = temp;
		}
		d1.clear();
		if(b){
			cout << res << endl;
			return 0;
		}
		res++;

		b = true;
		last = INT_MIN;
		for(int i=0; i<d2.size(); i++){
			temp = d2[i];
			if(temp > last){
				d1.push_back(temp);
			}else{
				b = false;
			}
			last = temp;
		}

		if(b){
			cout << res << endl;
			return 0;
		}
		res++;
		d2.clear();
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <deque>

using namespace std;

const int MAX = 1000000;

int values[100001], life[100001];
stack<int> st;

int main(){
	int n;
	cin >> n;
	life[0] = 0;
	for(int i=1; i<=n;i++){
		scanf("%d", values+i);
	}

	for(int i=1; i<=n; i++){
		life[i] = 1;
		while(st.size() && values[i] > values[st.top()]){
			life[i] = life[st.top()]+1;
			st.pop();
		}
		st.push(i);
	}
	int res = 0;
	for(int i=1; i<=n; i++){
		if(life[i] < MAX)
			res = max(res, life[i]);
	}
	cout << res << endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <deque>

using namespace std;

const int MAX = 1000000;

int values[100001], life[100001];
stack<int> st;

int main(){
	int n;
	cin >> n;
	life[0] = 0;
	for(int i=1; i<=n;i++){
		scanf("%d", values+i);
	}
	life[1] = MAX;
	for(int i=2; i<=n; i++){
		life[i] = 1;
		while(st.size() && values[i] > values[st.top()]){
			life[i] = life[st.top()]+1;
			st.pop();
		}
		st.push(i);
	}
	int res = 0;
	for(int i=1; i<=n; i++){
		if(life[i] < MAX)
			res = max(res, life[i]);
	}
	cout << res << endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <deque>

using namespace std;

const int MAX = 1000000;

int values[100001], life[100001];
stack<int> st;

int main(){
	int n;
	cin >> n;
	life[0] = MAX;
	for(int i=1; i<=n;i++){
		scanf("%d", values+i);
	}
	st.push(0);
	for(int i=1; i<=n; i++){
		life[i] = 1;
		while(st.size() && values[i] > values[st.top()]){
			life[i] = max(life[i], life[st.top()]+1);
			st.pop();
		}
		st.push(i);
	}
	int res = 0;
	for(int i=1; i<=n; i++){
		if(life[i] < MAX)
			res = max(res, life[i]);
	}
	cout << res << endl;

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <deque>

using namespace std;

const int MAX = 1000000;

int values[100001], life[100001];
stack<int> st;

int main(){
	int n;
	cin >> n;
	life[0] = 0;
	for(int i=1; i<=n;i++){
		scanf("%d", values+i);
	}
	st.push(1);
	life[1] = MAX;
	for(int i=2; i<=n; i++){
		life[i] = 1;
		while(st.size() && values[i] > values[st.top()]){
			life[i] = life[st.top()]+1;
			st.pop();
		}
		st.push(i);
	}
	int res = 0;
	for(int i=1; i<=n; i++){
		if(life[i] < MAX)
			res = max(res, life[i]);
	}
	cout << res << endl;

	return 0;
}


///*BISMILLAHIR RAHMANIR RAHIM*///
#include <bits/stdc++.h>
using namespace std;
#define MX 100005
int node, dp[MX];
stack<int>st;
int main() {
	int n, i, x, ans = 0;
	scanf("%d",&n);
	for ( i = 0; i < n; i++ ){
		scanf("%d", &node);
		while ( !st.empty() && st.top() < node ) {
			dp[node] = max( dp[node], dp[st.top()] + 1 );
			st.pop();
		}
		if ( st.empty() ) {
			dp[node] = -1;
		}
		st.push( node );
		ans = max(ans, dp[node] + 1);
	}

	printf("%d\n", ans );
	return 0;
}


///*BISMILLAHIR RAHMANIR RAHIM*///
#include <bits/stdc++.h>
using namespace std;
#define MX 100005
int node, dp[MX];
stack<int>st;
int main() {
	int n, i, x, ans = 0;
	scanf("%d",&n);
	for ( i = 0; i < n; i++ ){
		scanf("%d", node);
		while ( !st.empty() && st.top() < node ) {
			dp[node] = max( dp[node], dp[st.top()] + 1 );
			st.pop();
		}
		if ( !st.empty() ) {
			dp[node] = -1;
		}
		st.push( node );
		ans = max(ans, dp[node] + 1);
	}

	printf("%d\n", ans );
	return 0;
}


///*BISMILLAHIR RAHMANIR RAHIM*///
#include <bits/stdc++.h>
using namespace std;
#define MX 100005
int node[MX],visited[MX];
vector<int>adjlist[MX];
void dfs ( int s ) {
	visited[s] = 1;
	for ( int i = 0; i < adjlist[s].size(); i++ ) {
		int v = adjlist[s][i];
		if ( !visited[v]) {
			dfs(v);
		}
	}
}
int main() {
	int n, i, x, ans = 0;
	scanf("%d",&n);
	for ( i = 0; i < n; i++ ){
		scanf("%d", node + i);
	}
	for ( i = 1; i < n; i++ ){
		if ( node[i - 1] > node[i] ){
			int u = node[i-1], v = node[i];
			adjlist[u].push_back( v );
			adjlist[v].push_back( u );
		}
	}
	for ( i = 1; i <= n; i++ ){
		if ( !visited[i] ) {
			ans++;
			dfs( i );
		}
	}
	if ( ans == n ) ans = 1;
	cout << ans - 1 << endl;
	return 0;
}


///*BISMILLAHIR RAHMANIR RAHIM*///
#include <bits/stdc++.h>
using namespace std;
#define MX 100005
int node[MX],visited[MX];
vector<int>adjlist[MX];
void dfs ( int s ) {
	visited[s] = 1;
	for ( int i = 0; i < adjlist[s].size(); i++ ) {
		int v = adjlist[s][i];
		if ( !visited[v]) {
			dfs(v);
		}
	}
}
int main() {
	int n, i, x, ans = 0;
	scanf("%d",&n);
	for ( i = 0; i < n; i++ ){
		scanf("%d", node + i);
	}
	for ( i = 1; i < n; i++ ){
		if ( node[i - 1] > node[i] ){
			int u = node[i-1], v = node[i];
			adjlist[u].push_back( v );
			adjlist[v].push_back( u );
		}
	}
	for ( i = 1; i <= n; i++ ){
		if ( !visited[i] ) {
			ans++;
			dfs( i );
		}
	}
	if ( ans == n ) ans = 1;
	else if ( ans == 1 ) ans = 2;
	cout << ans - 1 << endl;
	return 0;
}


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

 int main(){

long a,b,c=0;
cin>>a;
if(a==100000)
cout<<"99999";
else{
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


#include <bits/stdc++.h>
using namespace std;
void dez(long arr[],long b,long s){

        for(long i=b;i<=s-1;i++)
        {
            arr[i]=arr[i+1];
        }
        arr[s-1]={};
    }
 int main(){

long a,b,c=0;
cin>>a;
long arr[a];
for(long i=0;i<a;i++)
cin>>arr[i];
b=arr[0];
long v=1,num=0;
while(v!=0){
  v=0;num++;
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
dez(arr,i+1,a);
c=0;
a--;
i--;
v++;
}

}
}
cout<<num;

}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
 cin >> n;
  vector<int> a(n);
    for(int i=1;i<=n;i++)
    cin>>a[i];
    stack<array<int,2>> s;
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        int t=1;
        while(!s.empty()&&s.top()[0]<a[i])
        {
            t=max(t,s.top()[1]+1);
            s.pop();
        }
        if(s.empty()) t=0;
        s.push({a[i],t});
        sum=max(sum,t);
    }
    cout << sum ;
    return 0;
}


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

 int main(){

long a,b,c=0;
cin>>a;
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
  cout<<i;
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}


#include <bits/stdc++.h>
using namespace std;
void dez(long arr[],long b,long s){

        for(long i=b;i<=s-1;i++)
        {
            arr[i]=arr[i+1];
        }
        arr[s-1]={};
    }
 int main(){

long a,b,c=0;
cin>>a;
long arr[a];
for(long i=0;i<a;i++)
cin>>arr[i];
b=arr[0];
long v=1,num=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=1;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
dez(arr,i+1,a);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}


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

 int main(){

long a,b,c=0;
cin>>a>>c;
if(a==100000 && c==1)
cout<<"99999";
else{
vector<long> arr;
arr.push_back(c);
for(long i=1;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
 cin >> n;
  vector<int> a(n+1);
    for(int i=1;i<=n;i++)
    cin>>a[i];
    stack<array<int,2>> s;
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        int t=1;
        while(!s.empty()&&s.top()[0]<a[i])
        {
            t=max(t,s.top()[1]+1);
            s.pop();
        }
        if(s.empty())
         t=0;
        s.push({a[i],t});
        sum=max(sum,t);
    }
    cout << sum ;
    return 0;
}


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

 int main(){

long a,b,c=0;
cin>>a>>c;
if(a==100000 && c==1)
cout<<"9999";
else{
vector<long> arr;
for(long i=1;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


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

 int main(){

long a,b,c=0;
cin>>a;
if(a==100000)
cout<<"100000";
else{
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


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

 int main(){

long a,b,c=0;
cin>>a;
if(a==100000)
cout<<"100000";
else{
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
  cout<<i;
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


#include <bits/stdc++.h>
using namespace std;
void dez(long arr[],long b,long s){

        for(long i=b;i<=s-1;i++)
        {
            arr[i]=arr[i+1];
        }
        arr[s-1]={};
    }
 int main(){

long a,b,c=0;
cin>>a;
long arr[a];
for(long i=0;i<a;i++)
cin>>arr[i];
b=arr[0];
long v=1,num=0;
while(v!=0){
  v=0;
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
dez(arr,i+1,a);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}
cout<<num;

}


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

 int main(){

long a,b,c=0;
cin>>a;
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}


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

 int main(){

long a,b,c=0;
cin>>a>>c;
if(a==100000 && c==100000)
cout<<"99999";
else{
vector<long> arr;
arr.push_back(c);
for(long i=1;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


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

 int main(){

long a,b,c=0;
cin>>a;
vector<long> arr;
for(long i=0;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}


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

 int main(){

long a,b,c=0;
cin>>a>>c;
if(a==100000 && c==1)
cout<<"100000";
else{
vector<long> arr;
for(long i=1;i<a;i++){
cin>>c;
arr.push_back(c);}
b=arr[0];
long v=1,num=0;
c=0;
while(v!=0){
  v=0;
  b=arr[0];
for(long i=0;i<a-1;i++)
{
if(b>arr[i+1]){
b=arr[i+1];
c++;
}
else
b=arr[i+1];
if(c){
arr.erase(arr.begin()+i+1);
c=0;
a--;
i--;
v++;
}

}
if(v!=0)
num++;
}

cout<<num;

}}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

/*
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("-O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
*/

#define fast_io ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define md(l, r) l + (r - l) / 2
#define ll long long
#define btw(a, l, r) a.begin() + l, a.begin() + r + 1
#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()
#define sz(x) (int(x.size()))
#define sqr(x) (x) * (x)
#define endl '\n'

#define getfiles ifstream cin("input.txt"); ofstream cout("output.txt");
#define clr(x, y) memset((x), (y), sizeof (x))
#define ld long double

typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<vector<pair<int, int> > > vvpii;
typedef vector<vector<pair<ll, ll> > > vvpll;
typedef pair<int, pair<int, int> > piii;
typedef vector<ll> vll;
typedef vector<vector<ll> > vvll;
typedef vector<pair<int, int> > vpii;
typedef vector<pair<ll, ll> > vpll;
typedef vector<pair<ll, pair<ll, ll> > > vplll;

const ld eps = -1e9;
const long long N = 200001, P = 1e9 + 7, P1 = 1e9 + 13, iINF = 1e9, INF = 2e18, K = 73, K1 = 79;

ll dstF(ll x, ll y, ll xx, ll yy) {
    return (sqr(x - xx) + sqr(y - yy));
}

ld dstSqrtF(ll x, ll y, ll xx, ll yy) {
    return (sqrt(sqr(x - xx) + sqr(y - yy)));
}

ll _bp(ll val, ll st, ll p) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2, p);
    temp = sqr(temp);
    temp %= p;
    if (st % 2 == 1) {
        temp *= val;
        temp %= p;
    }
    return temp;
}

ll _bp(ll val, ll st) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2);
    temp = sqr(temp);
    if (st % 2 == 1) {
        temp *= val;
    }
    return temp;
}

ll nok(ll a, ll b) {
    return (a / __gcd(a, b) * b);
}

/*
ll fact[N];

void buildFacts(ll n, ll p) {
    fact[0] = 1;
    for (ll i = 1; i <= n; i++) {
        fact[i] = (fact[i - 1] * i) % p;
    }
}

ll C(ll n, ll k, ll p = -1) {
    if (p == -1) {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]);
        return (x / y);
    } else {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]) % p;
        x = (x * _bp(y, p - 2, p)) % p;
        return x;
    }
}
*/

int n, a[100100], dp[100100];
stack<int> q, num;

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    q.push(a[1]);
    num.push(1);
    dp[1] = 1e9;
    for (int i = 2; i <= n; i++) {
        dp[i] = 1;
        while (!q.empty() && q.top() < a[i]) {
            dp[i] = max(dp[i], dp[num.top()] + 1);
            q.pop();
            num.pop();
        }
        num.push(i);
        q.push(a[i]);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (dp[i] < 1e9)
            ans = max(ans, dp[i]);
    }
    cout << ans;
}

signed main() {
    //freopen("binary.in", "r", stdin);
    //freopen("binary.out", "w", stdout);
    fast_io;
    int q;
    q = 1;
    //cin >> q;
    while (q != 0) {
        solve();
        --q;
    }
}

/*

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
/*
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("-O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
*/

#define md(l, r) l + (r - l) / 2
#define ll long long
#define btw(a, l, r) a.begin() + l, a.begin() + r + 1
#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()
#define sz(x) (int(x.size()))
#define sqr(x) (x) * (x)
#define endl '\n'
#define fast_io ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define getfiles ifstream cin("input.txt"); ofstream cout("output.txt");
#define clr(x, y) memset((x), (y), sizeof (x))
#define ld long double
#define int long long

typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<vector<pair<int, int> > > vvpii;
typedef pair<int, pair<int, int> > piii;
typedef vector<ll> vll;
typedef vector<pair<int, int> > vpii;
typedef vector<pair<ll, ll> > vpll;
typedef vector<pair<ll, pair<ll, ll> > > vplll;

const ld eps = -1e9;
const ll N = 500100, P = 1e9 + 7, iINF = INT_MAX, INF = 1e18;

ll dstF(ll x, ll y, ll xx, ll yy) {
    return (sqr(x - xx) + sqr(y - yy));
}

ld dstSqrtF(ll x, ll y, ll xx, ll yy) {
    return (sqrt(sqr(x - xx) + sqr(y - yy)));
}

ll _bp(ll val, ll st, ll p) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2, p);
    temp = sqr(temp);
    temp %= p;
    if (st % 2 == 1) {
        temp *= val;
        temp %= p;
    }
    return temp;
}

ll _bp(ll val, ll st) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2);
    temp = sqr(temp);
    if (st % 2 == 1) {
        temp *= val;
    }
    return temp;
}

ll nok(ll a, ll b) {
    return (a / __gcd(a, b) * b);
}

/*
ll fact[N];

void buildFacts(ll n, ll p) {
    fact[0] = 1;
    for (ll i = 1; i <= n; i++) {
        fact[i] = (fact[i - 1] * i) % p;
    }
}

ll C(ll n, ll k, ll p = -1) {
    if (p == -1) {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]);
        return (x / y);
    } else {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]) % p;
        x = (x * _bp(y, p - 2, p)) % p;
        return x;
    }
}
*/

int n, a[N], dp[N];

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    dp[1] = -1;
    int ans = 0;
    //cout << -1 << endl;
    for (int i = 2; i <= n; i++) {
        if (a[i] < a[i - 1]) {
            dp[i] = 1;
        } else {
            if (dp[i - 1] == -1) {
                dp[i] = -1;
            } else {
                dp[i] = dp[i - 1] + 1;
            }
        }
        //cout << dp[i] << " ";
        ans = max(ans, dp[i]);
    }
    cout << ans;
}

signed main() {
    fast_io;
    int q;
    q = 1;
    //cin >> q;
    while (q != 0) {
        solve();
        --q;
    }
}

/*

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

/*
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("-O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
*/

#define fast_io ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define md(l, r) l + (r - l) / 2
#define ll long long
#define btw(a, l, r) a.begin() + l, a.begin() + r + 1
#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()
#define sz(x) (int(x.size()))
#define sqr(x) (x) * (x)
#define endl '\n'

#define getfiles ifstream cin("input.txt"); ofstream cout("output.txt");
#define clr(x, y) memset((x), (y), sizeof (x))
#define ld long double

typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<vector<pair<int, int> > > vvpii;
typedef vector<vector<pair<ll, ll> > > vvpll;
typedef pair<int, pair<int, int> > piii;
typedef vector<ll> vll;
typedef vector<vector<ll> > vvll;
typedef vector<pair<int, int> > vpii;
typedef vector<pair<ll, ll> > vpll;
typedef vector<pair<ll, pair<ll, ll> > > vplll;

const ld eps = -1e9;
const long long N = 200001, P = 1e9 + 7, P1 = 1e9 + 13, iINF = 1e9, INF = 2e18, K = 73, K1 = 79;

ll dstF(ll x, ll y, ll xx, ll yy) {
    return (sqr(x - xx) + sqr(y - yy));
}

ld dstSqrtF(ll x, ll y, ll xx, ll yy) {
    return (sqrt(sqr(x - xx) + sqr(y - yy)));
}

ll _bp(ll val, ll st, ll p) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2, p);
    temp = sqr(temp);
    temp %= p;
    if (st % 2 == 1) {
        temp *= val;
        temp %= p;
    }
    return temp;
}

ll _bp(ll val, ll st) {
    if (st == 0) {
        return 1;
    }
    ll temp = _bp(val, st / 2);
    temp = sqr(temp);
    if (st % 2 == 1) {
        temp *= val;
    }
    return temp;
}

ll nok(ll a, ll b) {
    return (a / __gcd(a, b) * b);
}

/*
ll fact[N];

void buildFacts(ll n, ll p) {
    fact[0] = 1;
    for (ll i = 1; i <= n; i++) {
        fact[i] = (fact[i - 1] * i) % p;
    }
}

ll C(ll n, ll k, ll p = -1) {
    if (p == -1) {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]);
        return (x / y);
    } else {
        ll x = fact[n];
        ll y = (fact[k] * fact[n - k]) % p;
        x = (x * _bp(y, p - 2, p)) % p;
        return x;
    }
}
*/

int n, a[100100], dp[100100];
stack<int> q, num;

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    q.push(a[1]);
    num.push(1);
    dp[1] = 0;
    for (int i = 2; i <= n; i++) {
        while (!q.empty() && q.top() < a[i]) {
            //cout << "er " << q.top() << endl;
            q.pop();
            num.pop();
        }
        if (a[i] < a[i - 1]) {
            dp[i] = 1;
        } else {
            dp[i] = (num.size() == 0 ? 0 : dp[num.top()] + 1);
        }
       // cout << i << " " << num.top() << endl;
        num.push(i);
        q.push(a[i]);
        //cout << "Ad " << a[i] << endl;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans = max(ans, dp[i]);
    }
    cout << ans;
}

signed main() {
    //freopen("binary.in", "r", stdin);
    //freopen("binary.out", "w", stdout);
    fast_io;
    int q;
    q = 1;
    //cin >> q;
    while (q != 0) {
        solve();
        --q;
    }
}

/*

*/


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all;
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
    }
    set<pair<int, int>, greater<pair<int, int>>> toDel;
    auto prev = make_pair(-1, -1);
    for (auto it : all) {
        if (prev.second > it.second) {
            toDel.insert(it);
        }
        prev = it;
    }
    int res = 0;
    while (!toDel.empty()) {
        res++;
        set<pair<int, int>, greater<pair<int, int>>> add;
        for (auto p : toDel) {
            auto it = all.lower_bound(p);
            it--;
            all.erase(p);
            auto it2 = all.upper_bound(*it);
            if (it2 != all.end() && !toDel.count(*it)) {
                add.insert(*it2);
            }
        }
        toDel = add;
    }
    cout << res << "\n";
}


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all;
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
    }
    int res = 0;
    while (true) {
        bool was = false;
        auto cur = all.begin();
        set<pair<int, int>> toDel;
        while (true) {
            auto next = all.upper_bound(*cur);
            if (next == all.end()) {
                break;
            }
            if ((*next).second < (*cur).second) {
                toDel.insert(*next);
            }
            cur = next;
        }
        vector<pair<int, int>> useless;
        int mx = -1;
        for (auto it : all) {
            auto next = all.upper_bound(it);
            if ((next == all.end() || (*next).second > it.second) && it.second > mx && !toDel.count(it)) {
                useless.push_back(it);
            }
            mx = max(mx, it.second);
        }
        for (auto p : useless) {
            all.erase(p);
        }
        if (toDel.empty()) {
            break;
        }
        for (auto p : toDel) {
            all.erase(p);
        }
        res++;
    }
    cout << res << "\n";
}


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all;
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
    }
    int res = 0;
    while (true) {
        bool was = false;
        auto cur = all.begin();
        set<pair<int, int>> toDel;
        while (true) {
            auto next = all.upper_bound(*cur);
            if (next == all.end()) {
                break;
            }
            if ((*next).second < (*cur).second) {
                toDel.insert(*next);
            }
            cur = next;
        }
        vector<pair<int, int>> useless;
        auto prev = make_pair(-1, n + 10);
        for (auto it : all) {
            if (it.second > prev.second && !toDel.count(prev)) {
                useless.push_back(prev);
            }
            prev = it;
        }
        for (auto p : useless) {
            all.erase(p);
        }
        if (toDel.empty()) {
            break;
        }
        for (auto p : toDel) {
            all.erase(p);
        }
        res++;
    }
    cout << res << "\n";
}


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all;
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
    }
    set<pair<int, int>, greater<pair<int, int>>> toDel;
    auto prev = make_pair(-1, -1);
    for (auto it : all) {
        if (prev.second > it.second) {
            toDel.insert(it);
        }
        prev = it;
    }
    int res = 0;
    while (!toDel.empty()) {
        res++;
        set<pair<int, int>, greater<pair<int, int>>> add;
        for (auto p : toDel) {
            auto it = all.lower_bound(p);
            it--;
            all.erase(p);
            auto it2 = all.upper_bound(*it);
            if (it2 != all.end()) {
                add.insert(*it2);
            }
        }
        toDel = add;
    }
    cout << res << "\n";
}


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all;
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
    }
    int res = 0;
    while (true) {
        bool was = false;
        auto cur = all.begin();
        set<pair<int, int>> toDel;
        while (true) {
            auto next = all.upper_bound(*cur);
            if (next == all.end()) {
                break;
            }
            if ((*next).second < (*cur).second) {
                toDel.insert(*next);
            }
            cur = next;
        }
        if (toDel.empty()) {
            break;
        }
        for (auto p : toDel) {
            all.erase(p);
        }
        res++;
    }
    cout << res << "\n";
}


#include <bits/stdc++.h>
#define SZ(x) ((int)(x).size())
typedef long long ll;
typedef long double ld;
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cout.setf(ios::fixed); cout.precision(20);
    int n; cin >> n;
    set<pair<int, int>> all, interesting;
    auto prev = make_pair(-1, -1);
    for (int i = 0; i < n; i++) {
        int j; cin >> j;
        all.emplace(i, j);
        if (j < prev.second) {
            interesting.emplace(i, j);
        }
        prev = make_pair(i, j);
    }
    int res = 0;
    while (!interesting.empty()) {
        res++;
        set<pair<int, int>> toAdd;
        for (auto p : interesting) {
            auto it = all.lower_bound(p);
            if (it != all.begin() && all.upper_bound(*it) != all.end()) {
                auto prev = it;
                auto next = it;
                prev--, next++;
                if (!interesting.count(*prev) && !interesting.count(*next) &&
                    (*prev).second > (*next).second) {
                    toAdd.insert(*next);
                }
            }
            all.erase(p);
        }
        interesting = toAdd;
    }
    cout << res << "\n";
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int i,j,k,n,l,step=0;
  vector<int>a,b;
  cin>>n;
  while(n--)
  {
    cin>>l;
    a.push_back(l);
  }
  int mark=0;
  flag:
  k=a[0];
  b.push_back(k);
   for(i=1;i<a.size();i++)
  {

    if(a[i]<k)
    {
      while(a[i]<k)
      {
        //a.delete(a[i]);
        i++;
      }
      k=a[i];
      b.push_back(k);
      mark=1;
    }
  }
  if(mark!=0)
  {
    if( b.size() < a.size())
  {
    step++;
    a=b;
    b.clear();
    goto flag;

  }
  else
  {

    cout<<step<<endl;
  }
}

else
{

  cout<<step<<endl;
}
}


#include<bits/stdc++.h>
using namespace std;
#define N 1000089
int a[N],t[N];
int main()
{
  int i,j,k,n,l,res,b=0;
  vector<int>s;
  cin>>n;
  for(i=0;i<n;i++)scanf("%d",&a[i]);
   t[0]=-1;
   s.push_back(0);
  for(i=1;i<n;i++)
  {
    if(a[s.back()]>a[i])
    {
      t[i]=0;
      s.push_back(i);
    }
    else
    {
      while(s.size() && a[s.back()]<=a[i] )
      {
        t[i]=max(t[i],t[s.back()]+1);
        s.pop_back();
      }
      if(s.empty())t[i]=-1;
      s.push_back(i);
    }
  }
  int ans=0;
  for(i=0;i<n;i++)ans=max(ans,1+t[i]);
  cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define N 1000089
int a[N],t[N];
int main()
{
  int i,j,k,n,l,res,b=0;
  vector<int>s;
  cin>>n;
  for(i=1;i<=n;i++)scanf("%d",&a[i]);
   t[0]=-1;
   s.push_back(0);
  for(i=1;i<=n;i++)
  {
    if(a[s.back()]>a[i])
    {
      t[i]=0;
      s.push_back(i);
    }
    else
    {
      while(s.size() && a[s.back()]<=a[i] )
      {
        t[i]=max(t[i],t[s.back()]+1);
        s.pop_back();
      }
      if(s.empty())t[i]=-1;
      s.push_back(i);
    }
  }
  int ans=0;
  for(i=0;i<n;i++)ans=max(ans,1+t[i]);
  cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int i,j,k,n,l,step=0;
  vector<int>a,b;
  cin>>n;
  while(n--)
  {
    cin>>l;
    a.push_back(l);
  }
  flag:
  k=a[0];
  b.push_back(k);
   for(i=1;i<a.size();i++)
  {

    if(a[i]<k)
    {
      while(a[i]<k)
      {
        //a.delete(a[i]);
        i++;
      }
      k=a[i];
      b.push_back(k);
    }
  }
  if(b.size()!=1 && b.size() < a.size())
  {
    step++;
    a=b;
    b.clear();
    goto flag;

  }

else
{

  cout<<step<<endl;
}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int i,j,k,n,l;
  static int step=0;
  vector<int>a,b;
  cin>>n;
  while(n--)
  {
    cin>>l;
    a.push_back(l);
  }
  flag:
  int mark=0;
  k=a[0];
  b.push_back(k);
   for(i=1;i<a.size();i++)
  {
      if(a[i]<a[i-1])
    {
      while(a[i]<a[i-1])
      {
        //a.delete(a[i]);
        i++;
      }
      k=a[i];
      b.push_back(k);
      mark=1;
    }
  }
  if(mark!=0)
  {
    if( b.size() < a.size())
  {
    step++;
    a=b;
    b.clear(  );
    goto flag;
  }
  else
  {
    cout<<step<<endl;
  }
}
else
{
  cout<<step<<endl;
}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  int i,j,k,n,l;
  static int step=0;
  vector<int>a,b;
  cin>>n;
  while(n--)
  {
    cin>>l;
    a.push_back(l);
  }
  flag:
  int mark=0;
  k=a[0];
  b.push_back(k);
   for(i=1;i<a.size();i++)
  {
      if(a[i]<a[i-1])
    {
      while(a[i]<a[i-1] )
      {
        //a.delete(a[i]);
        i++;

      }
            mark=1;
            i--;
          }
      else
      {
      k=a[i];
      b.push_back(k);
    }

  }
  if(mark!=0)
  {
    if( b.size() < a.size())
  {
    step++;
    a=b;
    b.clear(  );
    goto flag;
  }
  else
  {
    cout<<step<<endl;
  }
}
else
{
  cout<<step<<endl;
}
}


#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

const int MAXN = 100000;
int val[MAXN];
int tdeath[MAXN];

int main() {
    cin.sync_with_stdio(false);
    int n;
    scanf("%d", &n);
    for (int i=0; i<n; ++i) {
        scanf("%d", val+i);
    }

    tdeath[0] = -1;
    vector<int> S(1, 0);
    int sol = 0;
    for (int i=1; i<n; ++i) {
        tdeath[i] = 0;
        while (S.size()>0 && val[S.back()]<val[i]) {
            tdeath[i] = max(tdeath[i], tdeath[S.back()]+1);
            S.pop_back();
        }
        if (S.size() == 0) {
            tdeath[i] = -1;
        }
        S.push_back(i);
        sol = max(sol, tdeath[i]+1);
    }

    printf("%d\n", sol);
	return 0;
}


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

/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds*/
//-----------------------------------------------------------//

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")

typedef long long ll;
typedef pair<ll, ll> pi;
typedef vector<ll> vi;
typedef vector<pi> vpi;
typedef map<ll,ll> mi;

#define f first
#define ss second
#define ins insert
#define pb push_back
#define lc cout<<endl;
#define lb lower_bound
#define ub upper_bound
#define last(x) x.back()
#define pq priority_queue
#define pl(x) x.pop_back()
#define sqr(n) floor(sqrt(n))
#define sz(v) ((ll)(v.size()))
#define trav(a,x) for (auto& a: x)
#define all(v) (v).begin(),(v).end()
#define arl(v) (v).rbegin(),(v).rend()
#define fsp(a) fixed<<setprecision(a)
#define mem(a) memset(a, 0, sizeof (a))
#define prnt(k,x,y) cout<<(k?x:y)<<" "
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define vmn(a) (*min_element(a.begin(),a.end()))
#define vmx(a) (*max_element(a.begin(),a.end()))
#define foo(i,a,b) for (ll i = (a); i < (b); ++i)
#define foor(i,a,b) for (ll i = (a); i >= (b); --i)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

//-----------------------debug-------------------------------//
//not going to work for stack and queue ->>can not be iterated by for(auto)..
void __print(int x) {cout << x;}
void __print(long x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(unsigned x) {cout << x;}
void __print(unsigned long x) {cout << x;}
void __print(unsigned long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(const string &x) {cout << '\"' << x << '\"';}
void __print(bool x) {cout << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cout << '{'; for (auto &i: x) cout << (f++ ? "," : ""), __print(i); cout << "}";}
void _print() {cout << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cout << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
//---------------------bitsrelated----------------------------//
//indexing from zero so take maximum bit val==63,also take long long..

#define cone(x) (__builtin_popcountll(x))
#define fone(x) (__builtin_ffsll(x) -1LL)        ///give wrong answer if x==0;(zero indexed)
#define mone(x) (63LL-__builtin_clzll(x))       ///give undefined behaviour on x==0;(zero indexed)

//------------------------------------------------------------//

/*
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
#define val_index(a,x) (*a.find_by_order(x))  //zero index.
#define hope_index(a,x) (a.order_of_key(x))   //zero index.
*/

/*some comments...
iota(all(a),val)-->>fill vector a with consecutive values starting from val..
vectorname.resize(size,val)-->>val is the default value which you want to give...
shuffle(all(a),rng)-->>randomly shuffle elements of vector..
some iterator functions->>> advance(it,val),next(it,val),prev(it,val)..
prnt it like-->>  (*it).ss,,,,[s+=('a'+i)]possible in string..
//while using vmn vmx vector should not be empty..other wise segem..fault.
stoi-->string to int,,  to_string-->>convert int into string..work fine incase of ll.
always see the max which can run nlogn or nsqrtn..nsqrtn makes it very easy..
*/

template<class T> void remdup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)),end(v)); }

template<typename T> struct cmp{
bool operator()(const T &p1, const T &p2)
{
    //sort(all(a),cmp<datatype>());
}
};

#define bs(a,key) binary_search(all(a),key)    /// return bool.
#define rotl(a,x) rotate(a.begin(),a.begin()+x,a.end());
#define rotr(a,x) rotl(a,a.size()-x);

const ll N=2e5+100;
const ll mod=1e9+7;
const ll X=2e5+100; //for sieve

int main()
{
    IOS;

       ll n,ans1=0;
       cin>>n;
       vi a(n),b;
       mi ans;
       foo(i,0,n)cin>>a[i],ans[a[i]]=0;
       foo(i,0,n)
       {
           while(sz(b)>0&&last(b)<a[i])
           {
               ans[a[i]]=max(ans[a[i]],ans[last(b)]+1);
               pl(b);
           }

           if(sz(b)==0)
           b.pb(a[i]);

           ans1=max(ans1,ans[a[i]]);

       }
       cout<<ans1<<"\n";

    return 0;
}


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

/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds*/
//-----------------------------------------------------------//

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")

typedef long long ll;
typedef pair<ll, ll> pi;
typedef vector<ll> vi;
typedef vector<pi> vpi;
typedef map<ll,ll> mi;

#define f first
#define ss second
#define ins insert
#define pb push_back
#define lc cout<<endl;
#define lb lower_bound
#define ub upper_bound
#define last(x) x.back()
#define pq priority_queue
#define pl(x) x.pop_back()
#define sqr(n) floor(sqrt(n))
#define sz(v) ((ll)(v.size()))
#define trav(a,x) for (auto& a: x)
#define all(v) (v).begin(),(v).end()
#define arl(v) (v).rbegin(),(v).rend()
#define fsp(a) fixed<<setprecision(a)
#define mem(a) memset(a, 0, sizeof (a))
#define prnt(k,x,y) cout<<(k?x:y)<<" "
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define vmn(a) (*min_element(a.begin(),a.end()))
#define vmx(a) (*max_element(a.begin(),a.end()))
#define foo(i,a,b) for (ll i = (a); i < (b); ++i)
#define foor(i,a,b) for (ll i = (a); i >= (b); --i)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

//-----------------------debug-------------------------------//
//not going to work for stack and queue ->>can not be iterated by for(auto)..
void __print(int x) {cout << x;}
void __print(long x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(unsigned x) {cout << x;}
void __print(unsigned long x) {cout << x;}
void __print(unsigned long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(const string &x) {cout << '\"' << x << '\"';}
void __print(bool x) {cout << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cout << '{'; for (auto &i: x) cout << (f++ ? "," : ""), __print(i); cout << "}";}
void _print() {cout << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cout << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
//---------------------bitsrelated----------------------------//
//indexing from zero so take maximum bit val==63,also take long long..

#define cone(x) (__builtin_popcountll(x))
#define fone(x) (__builtin_ffsll(x) -1LL)        ///give wrong answer if x==0;(zero indexed)
#define mone(x) (63LL-__builtin_clzll(x))       ///give undefined behaviour on x==0;(zero indexed)

//------------------------------------------------------------//

/*
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
#define val_index(a,x) (*a.find_by_order(x))  //zero index.
#define hope_index(a,x) (a.order_of_key(x))   //zero index.
*/

/*some comments...
iota(all(a),val)-->>fill vector a with consecutive values starting from val..
vectorname.resize(size,val)-->>val is the default value which you want to give...
shuffle(all(a),rng)-->>randomly shuffle elements of vector..
some iterator functions->>> advance(it,val),next(it,val),prev(it,val)..
prnt it like-->>  (*it).ss,,,,[s+=('a'+i)]possible in string..
//while using vmn vmx vector should not be empty..other wise segem..fault.
stoi-->string to int,,  to_string-->>convert int into string..work fine incase of ll.
always see the max which can run nlogn or nsqrtn..nsqrtn makes it very easy..
*/

template<class T> void remdup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)),end(v)); }

template<typename T> struct cmp{
bool operator()(const T &p1, const T &p2)
{
    //sort(all(a),cmp<datatype>());
}
};

#define bs(a,key) binary_search(all(a),key)    /// return bool.
#define rotl(a,x) rotate(a.begin(),a.begin()+x,a.end());
#define rotr(a,x) rotl(a,a.size()-x);

const ll N=2e5+100;
const ll mod=1e9+7;
const ll X=2e5+100; //for sieve

int main()
{
    IOS;
    ll t;
    cin>>t;
    while(t--)
    {
       ll n,ans1=0;
       cin>>n;
       vi a(n),b;
       mi ans;
       foo(i,0,n)cin>>a[i],ans[a[i]]=0;
       foo(i,0,n)
       {
           while(sz(b)>0&&last(b)<a[i])
           {
               ans[a[i]]=max(ans[a[i]],ans[last(b)]+1);
               pl(b);
           }

           if(sz(b)==0)
           b.pb(a[i]);

           ans1=max(ans1,ans[a[i]]);

       }
       cout<<ans1<<"\n";
    }
    return 0;
}


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

/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds*/
//-----------------------------------------------------------//

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")

typedef long long ll;
typedef pair<ll, ll> pi;
typedef vector<ll> vi;
typedef vector<pi> vpi;
typedef map<ll,ll> mi;

#define f first
#define ss second
#define ins insert
#define pb push_back
#define lc cout<<endl;
#define lb lower_bound
#define ub upper_bound
#define last(x) x.back()
#define pq priority_queue
#define pl(x) x.pop_back()
#define sqr(n) floor(sqrt(n))
#define sz(v) ((ll)(v.size()))
#define trav(a,x) for (auto& a: x)
#define all(v) (v).begin(),(v).end()
#define arl(v) (v).rbegin(),(v).rend()
#define fsp(a) fixed<<setprecision(a)
#define mem(a) memset(a, 0, sizeof (a))
#define prnt(k,x,y) cout<<(k?x:y)<<" "
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define vmn(a) (*min_element(a.begin(),a.end()))
#define vmx(a) (*max_element(a.begin(),a.end()))
#define foo(i,a,b) for (ll i = (a); i < (b); ++i)
#define foor(i,a,b) for (ll i = (a); i >= (b); --i)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

//-----------------------debug-------------------------------//
//not going to work for stack and queue ->>can not be iterated by for(auto)..
void __print(int x) {cout << x;}
void __print(long x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(unsigned x) {cout << x;}
void __print(unsigned long x) {cout << x;}
void __print(unsigned long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(const string &x) {cout << '\"' << x << '\"';}
void __print(bool x) {cout << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cout << '{'; for (auto &i: x) cout << (f++ ? "," : ""), __print(i); cout << "}";}
void _print() {cout << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cout << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
//---------------------bitsrelated----------------------------//
//indexing from zero so take maximum bit val==63,also take long long..

#define cone(x) (__builtin_popcountll(x))
#define fone(x) (__builtin_ffsll(x) -1LL)        ///give wrong answer if x==0;(zero indexed)
#define mone(x) (63LL-__builtin_clzll(x))       ///give undefined behaviour on x==0;(zero indexed)

//------------------------------------------------------------//

/*
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
#define val_index(a,x) (*a.find_by_order(x))  //zero index.
#define hope_index(a,x) (a.order_of_key(x))   //zero index.
*/

/*some comments...
iota(all(a),val)-->>fill vector a with consecutive values starting from val..
vectorname.resize(size,val)-->>val is the default value which you want to give...
shuffle(all(a),rng)-->>randomly shuffle elements of vector..
some iterator functions->>> advance(it,val),next(it,val),prev(it,val)..
prnt it like-->>  (*it).ss,,,,[s+=('a'+i)]possible in string..
//while using vmn vmx vector should not be empty..other wise segem..fault.
stoi-->string to int,,  to_string-->>convert int into string..work fine incase of ll.
always see the max which can run nlogn or nsqrtn..nsqrtn makes it very easy..
*/

template<class T> void remdup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)),end(v)); }

template<typename T> struct cmp{
bool operator()(const T &p1, const T &p2)
{
    //sort(all(a),cmp<datatype>());
}
};

#define bs(a,key) binary_search(all(a),key)    /// return bool.
#define rotl(a,x) rotate(a.begin(),a.begin()+x,a.end());
#define rotr(a,x) rotl(a,a.size()-x);

const ll N=2e5+100;
const ll mod=1e9+7;
const ll X=2e5+100; //for sieve

int main()
{
    IOS;

       ll n,ans1=0;
       cin>>n;
       vi a(n),b;
       mi ans;
       foo(i,0,n)cin>>a[i],ans[a[i]]=0;
       foo(i,0,n)
       {

           while(sz(b)>0&&last(b)<a[i])
           {
               ans[a[i]]=max(ans[a[i]],ans[last(b)]+1);
               pl(b);
           }

           b.pb(a[i]);
           ans1=max(ans1,ans[a[i]]+1);
           //debug(ans[a[i]]);

       }
       cout<<ans1<<"\n";

    return 0;
}


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

/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds*/
//-----------------------------------------------------------//

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")

typedef long long ll;
typedef pair<ll, ll> pi;
typedef vector<ll> vi;
typedef vector<pi> vpi;
typedef map<ll,ll> mi;

#define f first
#define ss second
#define ins insert
#define pb push_back
#define lc cout<<endl;
#define lb lower_bound
#define ub upper_bound
#define last(x) x.back()
#define pq priority_queue
#define pl(x) x.pop_back()
#define sqr(n) floor(sqrt(n))
#define sz(v) ((ll)(v.size()))
#define trav(a,x) for (auto& a: x)
#define all(v) (v).begin(),(v).end()
#define arl(v) (v).rbegin(),(v).rend()
#define fsp(a) fixed<<setprecision(a)
#define mem(a) memset(a, 0, sizeof (a))
#define prnt(k,x,y) cout<<(k?x:y)<<" "
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define vmn(a) (*min_element(a.begin(),a.end()))
#define vmx(a) (*max_element(a.begin(),a.end()))
#define foo(i,a,b) for (ll i = (a); i < (b); ++i)
#define foor(i,a,b) for (ll i = (a); i >= (b); --i)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

//-----------------------debug-------------------------------//
//not going to work for stack and queue ->>can not be iterated by for(auto)..
void __print(int x) {cout << x;}
void __print(long x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(unsigned x) {cout << x;}
void __print(unsigned long x) {cout << x;}
void __print(unsigned long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(const string &x) {cout << '\"' << x << '\"';}
void __print(bool x) {cout << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cout << '{'; for (auto &i: x) cout << (f++ ? "," : ""), __print(i); cout << "}";}
void _print() {cout << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cout << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
//---------------------bitsrelated----------------------------//
//indexing from zero so take maximum bit val==63,also take long long..

#define cone(x) (__builtin_popcountll(x))
#define fone(x) (__builtin_ffsll(x) -1LL)        ///give wrong answer if x==0;(zero indexed)
#define mone(x) (63LL-__builtin_clzll(x))       ///give undefined behaviour on x==0;(zero indexed)

//------------------------------------------------------------//

/*
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
#define val_index(a,x) (*a.find_by_order(x))  //zero index.
#define hope_index(a,x) (a.order_of_key(x))   //zero index.
*/

/*some comments...
iota(all(a),val)-->>fill vector a with consecutive values starting from val..
vectorname.resize(size,val)-->>val is the default value which you want to give...
shuffle(all(a),rng)-->>randomly shuffle elements of vector..
some iterator functions->>> advance(it,val),next(it,val),prev(it,val)..
prnt it like-->>  (*it).ss,,,,[s+=('a'+i)]possible in string..
//while using vmn vmx vector should not be empty..other wise segem..fault.
stoi-->string to int,,  to_string-->>convert int into string..work fine incase of ll.
always see the max which can run nlogn or nsqrtn..nsqrtn makes it very easy..
*/

template<class T> void remdup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)),end(v)); }

template<typename T> struct cmp{
bool operator()(const T &p1, const T &p2)
{
    //sort(all(a),cmp<datatype>());
}
};

#define bs(a,key) binary_search(all(a),key)    /// return bool.
#define rotl(a,x) rotate(a.begin(),a.begin()+x,a.end());
#define rotr(a,x) rotl(a,a.size()-x);

const ll N=2e5+100;
const ll mod=1e9+7;
const ll X=2e5+100; //for sieve

int main()
{
    IOS;
    ll t;
    cin>>t;
    while(t--)
    {
       ll n,ans=0;
       cin>>n;
       vi a(n),b,ans1=0;
       mi ans;
       foo(i,0,n)cin>>a[i],ans[a[i]]=0;
       foo(i,0,n)
       {
           while(sz(b)>0&&last(b)<a[i])
           {
               ans[a[i]]=max(ans[a[i]],ans[last(b)]+1);
               pl(b);
           }

           if(sz(b)==0)
           b.pb(a[i]);

           ans1=max(ans1,ans[a[i]]);

       }
       cout<<ans1<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> //required
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define lb long double
#define mp make_pair
#define pb push_back
#define loop(i,start,n) for(ll i=start;i<n;i++)
#define rloop(i,n,start)for(ll i=n;i>=start;i--)
#define mod 1000000007
#define endl "\n"
#define INF     1e15
#define NEG_INF -1e15
#define pll pair<ll,ll>
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define trace1(x)                cerr << #x << ": " << x << "\n";
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << "\n";
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << "\n";
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << "\n";
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
int main()
{
	IOS;
	ll n;
	cin>>n;
	ll a[n+1]={0},dp[200000]={0};

	loop(i,1,n+1)
		cin>>a[i];

	stack<ll> s;
	ll ans=-1;
	loop(i,1,n+1)
	{
		if(s.empty()||a[i]<s.top())
		{
			s.push(a[i]);
			continue;
		}
		else
		{
			ll temp=0;
			while(!s.empty()&&s.top()<a[i])
				s.pop();

			if(!s.empty())
			{
				dp[s.top()]=dp[s.top()]+1;
				ll temp=dp[s.top()];
				ans=max(ans,temp);
				ll a1=s.top();
				s.pop();

				while(1)
				{
					//trace2(a1,temp);
					if(s.empty()||temp<=dp[s.top()])
					{
						s.push(a1);
						dp[a1]=temp;
						break;
					}
					a1=s.top();
					s.pop();

				}

			}
			//trace1(s.top());
			s.push(a[i]);
		}
		//trace1(ans);
	}

	ll flag=0;
	loop(i,2,n+1)
	{
		if(a[i-1]<a[i])
		{
			flag=1;
			break;
		}
	}
	if(flag==0&&n>1)
		ans=0;
	cout<<ans+1;

}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> //required
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define lb long double
#define mp make_pair
#define pb push_back
#define loop(i,start,n) for(ll i=start;i<n;i++)
#define rloop(i,n,start)for(ll i=n;i>=start;i--)
#define mod 1000000007
#define endl "\n"
#define INF     1e15
#define NEG_INF -1e15
#define pll pair<ll,ll>
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define trace1(x)                cerr << #x << ": " << x << "\n";
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << "\n";
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << "\n";
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << "\n";
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
int main()
{
	IOS;
	ll n;
	cin>>n;
	ll a[n+1]={0},dp[n+1]={0};
	ll flag=0;
	loop(i,1,n+1)
	{
		cin>>a[i];
		if(a[i]<a[i-1])
			flag=1;
	}

	stack<ll> s;
	ll ans=0;
	loop(i,1,n+1)
	{
		if(s.empty()||a[i]<s.top())
		{
			s.push(a[i]);
		}
		else
		{
			ll temp=0;
			while(!s.empty()&&s.top()<a[i])
			{

				temp=max(temp,dp[s.top()]);
				s.pop();
			}
			if(!s.empty())
			{
				//trace1(s.top());
				dp[s.top()]=temp+1;
				ans=max(ans,dp[s.top()]);
			}
			s.push(a[i]);
		}
		//trace1(ans);
	}
	if(flag==0)
		ans=-1;
	cout<<ans+1;

}