#include <cstdio>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

unsigned long xor128() {
        static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123;
        unsigned long t = (x ^ (x << 11));
        x = y; y = z; z = w;
        return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

static const int INF = 0x3f3f3f3f;

struct node_t {
        node_t *l = NULL, *r = NULL;
        int val, first, ma;
        int pri;
        bool monotone;
        node_t(int val) : val(val), pri(xor128() % INF) {
                first = ma = val;
                monotone = true;
        }
        void reset() {
                first = ma = val;
                monotone = true;
        }
        void update() {
                first = (l ? l->first : val);
                int tmpma = val;
                bool tmpmonotone = true;
                if (l) {
                        tmpma = max(tmpma, l->ma);
                        if (!l->monotone || l->ma > val) tmpmonotone = false;
                }
                if (r) {
                        tmpma = max(tmpma, r->ma);
                        if (tmpmonotone && (!r->monotone || val > r->first)) tmpmonotone = false;
                }
                ma = tmpma;
                monotone = tmpmonotone;
        }
        void update2() {
                first = (l ? l->first : val);
                ma = (r ? r->ma : val);
                monotone = true; 
        }
};

inline node_t* merge(node_t *l, node_t *r) {
        if (!l) return r;
        if (!r) return l;
        if (l->pri > r->pri) {
                l->r = l->r ? merge(l->r, r) : r;
                l->update();
                return l;
        } else {
                r->l = r->l ? merge(l, r->l) : l;
                r->update();
                return r;
        }
}

inline node_t* merge2(node_t *l, node_t *r) {
        if (!l) return r;
        if (!r) return l;
        if (l->pri > r->pri) {
                l->r = l->r ? merge2(l->r, r) : r;
                l->update2();
                return l; 
        } else {
                r->l = r->l ? merge2(l, r->l) : l;
                r->update2();
                return r;
        }
}

pair<node_t*, node_t*> split(node_t *tree, int lb) {
        if (!tree) return { NULL, NULL };
        if (tree->ma < lb) return { NULL, tree };
        if (tree->monotone) {
                if (lb < tree->first) return { tree, NULL };
                else if (!tree->l) {
                        if (!tree->r) return { NULL, tree };
                        auto sub = split(tree->r, lb);
                        tree->r = NULL;
                        tree->reset();
                        sub.second = merge(tree, sub.second);
                        return sub;
                } else if (lb < tree->val) {
                        auto sub = split(tree->l, lb);
                        tree->l = NULL;
                        tree->update();
                        sub.first = merge2(sub.first, tree);
                        return sub;
                } else {
                        auto sub = split(tree->r, lb);
                        tree->r = NULL;
                        tree->update();
                        sub.second = merge(tree, sub.second);
                        return sub;
                }
        } else {
                node_t *left = tree->l, *right = tree->r;
                tree->l = tree->r = NULL;
                tree->update();
                auto sub = split(left, lb);
                if (sub.first) {
                        lb = sub.first->ma;
                }
                if (tree->val > lb) {
                        sub.first = merge2(sub.first, tree);
                        lb = tree->val;
                } else {
                        sub.second = merge(sub.second, tree);
                }
                auto sub2 = split(right, lb);
                return { merge2(sub.first, sub2.first), merge(sub.second, sub2.second) };
        }
}

/*
void dfs(node_t* u) {
        if (u->l) dfs(u->l);
        cerr << u->val << ' ';
        if (u->r) dfs(u->r);
}
*/

int main() {
        int n;
        scanf("%d", &n);
        vector<node_t> nodes;
        for (int i = 0; i < n; i ++) {
                int p;
                scanf("%d", &p);
                nodes.emplace_back(p);
        }
        node_t* tree = NULL;
        for (int i = 0; i < n; i ++) {
                tree = merge(tree, &nodes[i]);
        }
        int ans = 0;
        /*
        dfs(tree);
        cerr << endl;
        */
        while (!tree->monotone) {
                ans ++;
                auto sub = split(tree, 0);
                tree = merge(sub.second, sub.first);
                /*
                dfs(tree);
                cerr << endl;
                */
        }
        printf("%d\n", ans);
        return 0;
}



Measured memory_bytes: 12524