Link to this code: https://cses.fi/paste/65801a2536ed3306c534dc/
#include<bits/stdc++.h>
 
using namespace std;
 
#pragma GCC optimize("Ofast,unroll-loops")
 
typedef long long ll;
typedef unsigned long long ull;
typedef string str;
 
void dbg_out() { cerr << '\n'; }
template<typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifndef ONLINE_JUDGE
#define fastio 
#define debug(...) cerr << "(" << #__VA_ARGS__ << ") : ", dbg_out(__VA_ARGS__)
#define vdebug(x) cerr<<#x<<'\n'; for(auto &i:(x))cerr<<i<<' ';cerr<<'\n'
#else
#define fastio ios_base::sync_with_stdio(0);cin.tie(nullptr)
#define debug(...)
#define vdebug(x)
#endif
 
#define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define rng_seed(x) mt19937(), (x).end()
#define endl '\n'
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define all(x) x.begin(), x.end()
#define all1(x) x.begin()+1, x.end()
#define vi vector<int>
#define vvi vector<vector<int>>
#define vd vector<double>
#define vii vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vlll vector<vector<ll>>
#define vs vector<string>
#define vc vector<char>
#define vvc vector<vector<char>>
#define vcc vector<vector<char>>
#define vpii vector<pair<int, int>>
#define vpll vector<pair<ll, ll>>
#define vvpii vector<vector<pair<int, int>>>
#define vb vector<bool>
#define vbb vector<vector<bool>>
#define fi first
#define se second
 
const int mxN = 2 * 1e5 + 2;
const int mod = 1e9 + 7;
const int md = 998244353;
const int iinf = INT_MAX;
const ll inf = 1e18 + 1;
 
 
//Check for edge case, dont FST again , use inf
void solve(){
    int n;
    cin>>n;
    priority_queue<array<int, 2>, vector<array<int, 2>>, greater<array<int, 2>>> pq;
    int ans = 1;
    vi arr(n);
    for(int i = 0; i<n; i++){
        cin>>arr[i];
        int cnt = 1;
        // If there's smaller mountains,
        // we can add up it's count with current mountain
        while(!pq.empty() && pq.top()[0] < arr[i]){
            cnt = max(cnt + 1, pq.top()[1] + 1);
            pq.pop();
        }
        ans = max(ans, cnt);
        // If previously there has been the same element,
        // we only need to know the one that can visit maximum mountains
        if(!pq.empty() && pq.top()[0] == arr[i]){
            auto [val, num] = pq.top();
            pq.pop();
            cnt = max(num, cnt);
        }
        pq.push({arr[i], cnt});
    }
    int cnt = 0;
    // Use the same formula as in the for loop to empty pq
    while(!pq.empty()){
        cnt = max(cnt + 1, pq.top()[1] + 1);
        pq.pop();
    }
    ans = max(ans, cnt-1);
    cout<<ans<<endl;
}
 
int main(){
    fastio;
    // Remember to comment ifndef when stress test
 
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
        freopen("error.txt", "w", stderr);
    #endif
    int t = 1;
    //cin>>t;
    for(int TEST_CASE = 1; TEST_CASE <= t; TEST_CASE++){
        debug(TEST_CASE);
        solve();
    }
    return 0;
}
 
/*
For Interactive Problems , Remember :
After Finish first cout, do cout.flush(), then cin the next input!
Remember to do cout.flush() even after outputting the answer!
*/
 
/*To set Randoms do Below (For random / adaptating problems)
    mt19937 mt;
    shuffle(begin(arr), end(arr), mt);
*/