Problem:
Problem
$N$ 枚のカードからなる山札がある。
  カードは上下に並べられており、上から $i$ 番目のカードには整数 $p_i$ が書かれている。
カードが上下に $1$ 枚以上重ねられた様子を
場
と呼ぶ。
  ただし、山札は場には含まないものとする。
  場の一番上のカードに書かれた数を、場に書かれた数と呼ぶ。
以下の操作を終了するまで繰り返し行う。
山札が空なら、場をそれらに書かれた数の昇順に上から重ね、それを新しい山札とする
山札が上から $1$ から $N$ の順に並んでいれば終了する
山札の一番上のカードを取る(取ったカードをAとする)
Aより大きい数の書かれた場が存在しない場合、Aからなる新しい場を作り、1. に戻る
Aより大きい数の書かれた場のうち、書かれている数が最小の場の上にAを置き、1. に戻る
終了までに3. が行われる回数を求めよ。
Input
入力は以下の形式で与えられる。
$N$
$p_1$ $p_2$ $\ldots$ $p_N$
Constraints
入力は以下の条件を満たす。
$2 \leq N \leq 10^4$
$1 \leq p_i \leq N$
$p_i \neq p_j \ (i\neq j)$
入力は全て整数である
Output
3. が行われる回数を一行に出力する。
Sample Input 1
5
2 4 1 3 5
Sample Output 1
5
Sample Input 2
5
5 2 3 4 1
Sample Output 2
15

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

using pii = pair<int, int>;

signed main() {

#ifdef DEBUG
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int n;
    cin >> n;
    vector<int> p(n), q(n);
    for (auto& x : p) cin >> x, --x;
    
    vector<vector<int>> st(n);

    int res = 0;
    while (1) {
        int sz = 0;
        for (auto x : p) {
            if (sz == 0 || st[sz - 1].back() < x) {
                st[sz].push_back(x);
                ++sz;
                ++res;
            } else {
                int bl = -1, br = sz - 1, bm;
                while (br - bl > 1) {
                    bm = bl + (br - bl) / 2;
                    if (st[bm].back() > x) {
                        br = bm;
                    } else {
                        bl = bm;
                    }
                }
                st[br].push_back(x);
                ++res;
            }
        }
        if (sz == n) {
            res -= n;
            break;
        }
        int ptr = 0;
        for (int i = 0; i < sz; ++i) {
            for (int j = (int) st[i].size() - 1; j >= 0; --j) {
                p[ptr++] = st[i][j];
            }
            st[i].clear();
        }
    }

    cout << res << "\n";

    return 0;
}
accuracy: 1
time_ms: 450
memory_kb: 3968
final_rank: 9

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

int n;
void to_simple(vector<int> &v){
	while (v.size() && n - v.size() == v[0])v.erase(v.begin());
	
}

vector<int> nex;
vector<bool> used;

int vals[1 << 14];
void trans(vector<int>& v) {
	fill(all(used), true);
	fill(all(nex), -1);
	for (int id : v)used[id] = false;
	int sz = 0;
	rep(i, v.size()) {
		if (sz == 0) {
			vals[sz] = v[i];
			sz++;
		}
		else {
			if (vals[sz - 1] < v[i]) {
				vals[sz] = v[i]; sz++;
			}
			else {
				int id = lower_bound(vals, vals + sz, v[i]) - vals;
				nex[v[i]] = vals[id];
				vals[id] = v[i];
			}
		}
	}
	vector<int> res;
	rep(i, n) {
		if (used[i])continue;
		int cur = i;
		while (cur >= 0) {
			res.push_back(cur);
			used[cur] = true;
			cur = nex[cur];
		}
	}
	swap(v, res);
}

void solve() {
	cin >> n;
	nex.resize(n);
	used.resize(n);
	vector<int> p(n);
	rep(i, n) {
		cin >> p[i]; p[i]--;
	}
	to_simple(p);
	ll ans = 0;
	//rep(i, p.size())cout << p[i] << " "; cout << "\n";
	while (p.size()) {
		trans(p);
		ans += n;
		//rep(i, p.size())cout << p[i] << " "; cout << "\n";
		to_simple(p);
	}
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 11896
final_rank: 8

code_snippet: #include<stdio.h>


#define INF (1<<30)
#define MAX  10001

short a[MAX][MAX];
int b[MAX];
int c[MAX];
int p[MAX];

signed main(){
	
	int N, i, minimum = 0, size, j, l, f, k;
	
	scanf("%d", &N);
	
	for(i = 0; i < N; i++){
		scanf("%d", &p[i]);
	}
	
	
	for(i = 0; ; i++){
		
		size = 0;
		
		for(j = minimum; j < N; j++){
			
			int l = -1, in = size, m;
			
			while(l + 1 < in){
				m = (l + in)>>1;
				
				if(b[m] < p[j]) {
					l = m;
				} else {
					in = m;
				}
			}
			
			if(in == size) {
				a[in][0] = p[j];
				
				b[in] = p[j];
				
				c[in] = 1;
				
				size++;
			} else {
				a[in][c[in]] = p[j];
			
				b[in] = p[j];
			
				c[in]++;
			}
		}
		
		if(size == N - minimum) break;
		
		for(j = 0, l = minimum, f = 1; j < size; j++){
			for(k = c[j]-1; k >= 0; k--){
				p[l++] = a[j][k];
				if(f && p[l-1] == l) minimum++;
				else f = 0;
			}
		}
	}
	
	printf("%d\n", i * N);
	
	return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 196096
final_rank: 15

code_snippet: #include <bits/stdc++.h>
//#include <chrono>
//#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
typedef pair<ll, ll> P;
const ll INF = (1LL<<60);

int solve(vec &p){
    vec ba(0), follows(N, -1);
    int res(-1);
    bool ok = false;
    while(!ok && res < N * 2){
        ++res;
        ok = true;
        //rep(i, N) cout<<p[i]<<" \n"[i == N - 1];
        reps(i, res, N){
            if(p[i] != i) ok = false;
            if(ba.empty() || *ba.rbegin() < p[i]){
                ba.push_back(p[i]);
            }else{
                Rrep(j, (int)ba.size()){
                    if(j - 1 == -1 || ba[j - 1] < p[i]){
                        follows[p[i]] = ba[j];
                        ba[j] = p[i];
                        break;
                    }
                }
            }
        }
        if(!ok){
            int id(res);
            for(int v : ba){
                while(v != -1){
                    p[id++] = v;
                    auto &f = follows[v];
                    v = f;
                    f = -1;
                }
            }
            ba.clear();
        }
    }
    return res;
}

int main() {
    cin>>N;
    vec p(N);
    rep(i, N) {cin>>p[i]; --p[i];}
    cout<<solve(p) * N<<endl;
}
accuracy: 1
time_ms: 150
memory_kb: 3424
final_rank: 3

code_snippet: #include <bits/stdc++.h>
//#include <chrono>
//#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
typedef pair<ll, ll> P;
const ll INF = (1LL<<60);

int solve(vec &p){
    mat ba_s(N, vec(0));
    vec follows(N, -1);
    int res(-1);
    bool ok = false;
    while(!ok && res < N * 2){
        ++res;
        ok = true;
        vec &ba = ba_s[res];
        reps(i, res, N){
            if(p[i] != i) ok = false;
            if(ba.empty() || *ba.rbegin() < p[i]){
                ba.push_back(p[i]);
            }else{
                Rrep(j, (int)ba.size()){
                    if(j - 1 == -1 || ba[j - 1] < p[i]){
                        follows[p[i]] = ba[j];
                        ba[j] = p[i];
                        break;
                    }
                }
            }
        }
        if(!ok){
            int id(res);
            for(int v : ba){
                while(v != -1){
                    p[id++] = v;
                    auto &f = follows[v];
                    v = f;
                    f = -1;
                }
            }
        }
    }
    return res;
}

int main() {
    cin>>N;
    vec p(N);
    rep(i, N) {cin>>p[i]; --p[i];}
    cout<<solve(p) * N<<endl;
}
accuracy: 1
time_ms: 300
memory_kb: 422528
final_rank: 19

code_snippet: #include <bits/stdc++.h>
//#include <chrono>
//#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
typedef pair<ll, ll> P;
const ll INF = (1LL<<60);

int solve(vec &p){
    vec ba(0), follows(N, -1);
    int res(-1);
    bool ok = false;
    while(!ok && res < N * 2){
        ++res;
        ok = true;
        //rep(i, N) cout<<p[i]<<" \n"[i == N - 1];
        rep(i, N){
            if(p[i] != i) ok = false;
            if(ba.empty() || *ba.rbegin() < p[i]){
                ba.push_back(p[i]);
            }else{
                Rrep(j, (int)ba.size()){
                    if(j - 1 == -1 || ba[j - 1] < p[i]){
                        follows[p[i]] = ba[j];
                        ba[j] = p[i];
                        break;
                    }
                }
            }
        }
        if(!ok){
            int id(0);
            for(int v : ba){
                while(v != -1){
                    p[id++] = v;
                    auto &f = follows[v];
                    v = f;
                    f = -1;
                }
            }
            ba.clear();
        }
    }
    return res;
}

int main() {
    cin>>N;
    vec p(N);
    rep(i, N) {cin>>p[i]; --p[i];}
    cout<<solve(p) * N<<endl;
}
accuracy: 1
time_ms: 240
memory_kb: 3444
final_rank: 5

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long long INF = 1e18;
//const ll mod = 1000000007;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
int popcnt(uint x) { return __builtin_popcount(x); }
int popcnt(ull x) { return __builtin_popcountll(x); }
int bsr(uint x) { return 31 - __builtin_clz(x); }
int bsr(ull x) { return 63 - __builtin_clzll(x); }
int bsf(uint x) { return __builtin_ctz(x); }
int bsf(ull x) { return __builtin_ctzll(x); }

struct FastSet {
    static constexpr uint B = 64;
    int n, lg;
    VV<ull> seg;
    FastSet(int _n) : n(_n) {
        do {
            seg.push_back(V<ull>((_n + B - 1) / B));
            _n = (_n + B - 1) / B;
        } while (_n > 1);
        lg = int(seg.size());
    }
    bool operator[](int i) const {
        return (seg[0][i / B] >> (i % B) & 1) != 0;
    }
    void set(int i) {
        for (int h = 0; h < lg; h++) {
            seg[h][i / B] |= 1ULL << (i % B);
            i /= B;
        }
    }
    void reset(int i) {
        for (int h = 0; h < lg; h++) {
            seg[h][i / B] &= ~(1ULL << (i % B));
            if (seg[h][i / B]) break;
            i /= B;
        }
    }
    // x以上最小の要素
    int next(int i) {
        for (int h = 0; h < lg; h++) {
            if (i / B == seg[h].size()) break;
            ull d = seg[h][i / B] >> (i % B);
            if (!d) {
                i = i / B + 1;
                continue;
            }
            // find
            i += bsf(d);
            for (int g = h - 1; g >= 0; g--) {
                i *= B;
                i += bsf(seg[g][i / B]);
            }
            return i;
        }
        return n;
    }
    // x未満最大の要素
    int prev(int i) {
        i--;
        for (int h = 0; h < lg; h++) {
            if (i == -1) break;
            ull d = seg[h][i / B] << (63 - i % 64);
            if (!d) {
                i = i / B - 1;
                continue;
            }
            // find
            i += bsr(d) - (B - 1);
            for (int g = h - 1; g >= 0; g--) {
                i *= B;
                i += bsr(seg[g][i / B]);
            }
            return i;
        }
        return -1;
    }
};

int N;
int a[10500];
int nxt[10500];
int prv[10500];

bool IsSorted() {
    for(int i = 1; i < N; i++) {
        if(a[i-1] > a[i]) return false;
    }
    return true;
}

void f() {
    for(int i = 0; i < N; i++) {
        //cerr << a[i] << " ";
        prv[i] = -1;
        nxt[i] = -1;
    }
    //cerr << endl;
    FastSet st(N);
    for(int i = 0; i < N; i++) {
        int p = st.next(a[i]);
        if(p != N) {
            nxt[a[i]] = p;
            prv[p] = a[i];
            st.reset(p);
        }
        st.set(a[i]);
    }
    int idx = 0;
    /*
    for(int i = 0; i < N; i++) {
        cerr << i << " " << prv[i] << " " << nxt[i] << endl;
    }
    */
    for(int i = 0; i < N; i++) {
        if(prv[i] != -1) continue;
        int now = i;
        while(now != -1) {
            //cerr << idx << " " << now << endl;
            a[idx] = now;
            idx++;
            now = nxt[now];
        }
    }
}

int main() {
    cin >> N;
    for(int i = 0; i < N; i++) {
        cin >> a[i];
        a[i]--;
    }
    for(int t = 0; ; t++) {
        if(IsSorted()) {
            cout << t * N << endl;
            return 0;
        }
        f();
    }
    return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 3552
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>

using lint = long long;

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> ps(n);
    for (auto& p : ps) {
        std::cin >> p;
        --p;
    }

    lint ans = 0;
    std::vector<int> stk, to(n, -1);

    while (true) {
        bool judge = true;
        for (int i = 0; i + 1 < n; ++i) {
            if (ps[i] > ps[i + 1]) judge = false;
        }
        if (judge) break;

        ans += n;

        stk.clear();
        std::fill(to.begin(), to.end(), -1);

        for (auto p : ps) {
            auto it = std::lower_bound(stk.begin(), stk.end(), p);
            if (it == stk.end()) {
                stk.push_back(p);
            } else {
                to[p] = *it;
                *it = p;
            }
        }

        int i = 0;
        for (auto x : stk) {
            while (x != -1) {
                ps[i++] = x;
                x = to[x];
            }
        }
    }

    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 940
memory_kb: 3560
final_rank: 16

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}
 
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}

class vanEmdeBoasTree
{
private:
    static const uint32_t LENGTH = 1073741824;
    uint32_t _size;
    #define msb(u) (63 - __builtin_clzll(u))
    #define lsb(u) (__builtin_ctzll(u))
    struct first_layer;
    struct middle_layer;
    struct last_layer;
    struct first_layer {
        uint64_t *data;
        middle_layer *summary;
        int32_t _max, _min;
        first_layer() : _max(-1), _min(1073741824){
            data = new uint64_t[16777216](), summary = new middle_layer();
        }
        first_layer(const first_layer& another) : _max(another._max), _min(another._min){
            data = new uint64_t[16777216];
            for(uint32_t i = 0; i < 16777216; ++i) data[i] = another.data[i];
            summary = new middle_layer(*another.summary);
        }
        first_layer(first_layer&& another)
            : _max(move(another._max)), _min(move(another._min)){
            data = another.data, summary = another.summary;
            data = nullptr, summary = nullptr;
        }
        first_layer& operator=(const first_layer& another){
            this->~first_layer();
            _max = another._max, _min = another._min;
            data = new uint64_t[16777216];
            for(uint32_t i = 0; i < 16777216; ++i) data[i] = another.data[i];
            summary = new middle_layer(*another.summary);
            return *this;
        }
        first_layer& operator=(first_layer&& another){
            this->~first_layer();
            _max = move(another._max), _min = move(another._min);
            data = another.data, summary = another.summary;
            data = nullptr, summary = nullptr;
            return *this;
        }
        // ~first_layer(){
        //     delete summary;
        //     delete[] data;
        // }
        inline bool empty() const noexcept { return (_max == -1); }
        inline bool isOne() const noexcept { return (_max == _min); }
        inline int32_t max() const noexcept { return _max; }
        inline int32_t min() const noexcept { return _min; }
        bool find(const int32_t value) const noexcept {
            return (value == _min) || ((data[value >> 6] >> (value & 63)) & 1ULL);
        }
        bool insert(int32_t value) noexcept {
            if(value == _min) return false;
            else if(_max == -1) return _max = _min = value, true;
            else if(value < _min) swap(value, _min);
            else if(value > _max) _max = value;
            const int32_t id = (value >> 6);
            if((data[id] >> (value & 63)) & 1ULL) return false;
            else{
                if(data[id] == 0) summary->insert(id);
                data[id] ^= (1ULL << (value & 63));
                return true;
            }
        }
        void erase(int32_t value) noexcept {
            if(_max == _min){
                _max = -1, _min = 1073741824;
                return;
            }else if(value == _min){
                const int32_t id = summary->min();
                 _min = value = (id << 6) + lsb(data[id]);
            }
            const int32_t id = (value >> 6);
            data[id] ^= (1ULL << (value & 63));
            if(data[id] == 0) summary->erase(id);
            if(value == _max){
                if(summary->empty()) _max = _min;
                else{
                    const int32_t id = summary->max();
                    _max = (id << 6) + msb(data[id]);
                }
            }
        }
        int32_t predecessor(const int32_t value) const noexcept {
            if(_min >= value) return -1;
            else if(value > _max) return _max;
            const int32_t id = (value >> 6), sm = (id << 6);
            if(data[id] && value > sm + lsb(data[id]))
                return sm + msb(data[id] & ((1ULL << (value & 63)) - 1ULL));
            else{
                const int32_t id2 = summary->predecessor(id);
                return (id2 >= 0) ? ((id2 << 6) + msb(data[id2])) : _min;
            }
        }
        int32_t successor(const int32_t value) const noexcept {
            if(value < _min) return _min;
            else if(value >= _max) return 1073741824;
            const int32_t id = (value >> 6), sm = (id << 6);
            if(data[id] && value < sm + msb(data[id]))
                return sm + lsb(data[id] & ~((1ULL << ((value & 63) + 1)) - 1ULL));
            else{
                const int32_t id2 = summary->successor(id);
                return (id2 << 6) + lsb(data[id2]);
            }
        }
    };
    struct middle_layer{
        last_layer *sublayers, *summary;
        int32_t _max, _min;
        middle_layer() : _max(-1), _min(16777216){
            sublayers = new last_layer[4096](), summary = new last_layer();
        }
        middle_layer(const middle_layer& another) : _max(another._max), _min(another._min){
            sublayers = new last_layer[4096];
            for(uint32_t i = 0; i < 4096; ++i)
                sublayers[i] = last_layer(another.sublayers[i]);
            summary = new last_layer(*another.summary);
        }
        middle_layer(middle_layer&& another)
            : _max(move(another._max)), _min(move(another._min)){
            sublayers = another.sublayers, summary = another.summary;
            another.sublayers = another.summary = nullptr;
        }
        middle_layer& operator=(const middle_layer& another){
            this->~middle_layer();
            _max = another._max, _min = another._min;
            sublayers = new last_layer[4096];
            for(uint32_t i = 0; i < 4096; ++i)
                sublayers[i] = last_layer(another.sublayers[i]);
            summary = new last_layer(*another.summary);
            return *this;
        }
        middle_layer& operator=(middle_layer&& another){
            this->~middle_layer();
            _max = move(another._max), _min = move(another._min);
            sublayers = another.sublayers, summary = another.summary;
            another.sublayers = another.summary = nullptr;
            return *this;
        }
        // ~middle_layer(){
        //     delete summary;
        //     delete[] sublayers;
        // }
        inline bool empty() const noexcept { return (_max == -1); }
        inline bool isOne() const noexcept { return (_max == _min); }
        inline int32_t max() const noexcept { return _max; }
        inline int32_t min() const noexcept { return _min; }
        bool insert(int32_t value) noexcept {
            if(value == _min) return false;
            else if(_max == -1) return _max = _min = value, true;
            else if(value < _min) swap(value, _min);
            else if(value > _max) _max = value;
            const int32_t id = (value >> 12);
            if(sublayers[id].insert(value & 4095)){
                if(sublayers[id].isOne()) summary->insert(id);
                return true;
            }else return false;
        }
        void erase(int32_t value) noexcept {
            if(_max == _min){
                _max = -1, _min = 16777216;
                return;
            }else if(value == _min){
                const int32_t id = summary->min();
                 _min = value = (id << 12) + sublayers[id].min();
            }
            const int32_t id = (value >> 12);
            sublayers[id].erase(value & 4095);
            if(sublayers[id].empty()) summary->erase(id);
            if(value == _max){
                if(summary->empty()) _max = _min;
                else{
                    const int32_t id = summary->max();
                    _max = (id << 12) + sublayers[id].max();
                }
            }
        }
        int32_t predecessor(const int32_t value) const noexcept {
            if(_min >= value) return -1;
            else if(value > _max) return _max;
            const int32_t id = (value >> 12), sm = (id << 12);
            if(value > sm + sublayers[id].min()){
                return sm + sublayers[id].predecessor(value & 4095);
            }else{
                const int32_t id2 = summary->predecessor(id);
                return (id2 >= 0) ? ((id2 << 12) + sublayers[id2].max()) : _min;
            }
        }
        int32_t successor(const int32_t value) const noexcept {
            if(value < _min) return _min;
            else if(value >= _max) return 16777216;
            const int32_t id = (value >> 12), sm = (id << 12);
            if(value < sm + sublayers[id].max()){
                return sm + sublayers[id].successor(value & 4095);
            }else{
                const int32_t id2 = summary->successor(id);
                return (id2 << 12) + sublayers[id2].min();
            }
        }
    };
    struct last_layer{
        uint64_t data[64], summary;
        int32_t _max, _min;
        last_layer() noexcept : summary(0ULL), _max(-1), _min(4096){
            memset(data, 0, sizeof(data));
        }
        inline bool empty() const noexcept { return (_max == -1); }
        inline bool isOne() const noexcept { return (_max == _min); }
        inline int32_t max() const noexcept { return _max; }
        inline int32_t min() const noexcept { return _min; }
        bool insert(int32_t value) noexcept {
            if(value == _min) return false;
            else if(_max == -1) return _max = _min = value, true;
            else if(value < _min) swap(value, _min);
            else if(value > _max) _max = value;
            const int32_t id = (value >> 6);
            if((data[id] >> (value & 63)) & 1ULL) return false;
            else{
                data[id] ^= (1ULL << (value & 63)), summary |= (1ULL << id);
                return true;
            }
        }
        void erase(int32_t value) noexcept {
            if(_max == _min){
                _max = -1, _min = 4096;
                return;
            }else if(value == _min){
                const int32_t id = lsb(summary);
                _min = value = (id << 6) + lsb(data[id]);
            }
            const int32_t id = (value >> 6);
            data[id] ^= (1ULL << (value & 63));
            if(data[id] == 0) summary ^= (1ULL << id);
            if(value == _max){
                if(summary == 0) _max = _min;
                else{
                    const int32_t id = msb(summary);
                    _max = (id << 6) + msb(data[id]);
                }
            }
        }
        int32_t predecessor(const int32_t value) const noexcept {
            if(_min >= value) return -1;
            else if(value > _max) return _max;
            const int32_t id = (value >> 6), sm = (id << 6);
            if(data[id] && value > sm + lsb(data[id]))
                return sm + msb(data[id] & ((1ULL << (value & 63)) - 1ULL));
            else{
                const uint64_t tmp = (summary & ((1ULL << id) - 1ULL));
                if(tmp == 0ULL) return _min;
                else{
                    const int32_t id2 = msb(tmp);
                    return (id2 << 6) + msb(data[id2]);
                }
            }
        }
        int32_t successor(const int32_t value) const noexcept {
            if(value < _min) return _min;
            else if(value >= _max) return 4096;
            const int32_t id = (value >> 6), sm = (id << 6);
            if(data[id] && value < sm + msb(data[id]))
                return sm + lsb(data[id] & ~((1ULL << ((value & 63) + 1)) - 1ULL));
            else{
                const int32_t id2 = lsb(summary & ~((1ULL << (id + 1)) - 1ULL));
                return (id2 << 6) + lsb(data[id2]);
            }
        }
    };
    first_layer base_layer;
public:
    vanEmdeBoasTree() : _size(0), base_layer(){}
    vanEmdeBoasTree(const vanEmdeBoasTree&) = default;
    vanEmdeBoasTree(vanEmdeBoasTree&&) = default;
    vanEmdeBoasTree& operator=(const vanEmdeBoasTree&) = default;
    vanEmdeBoasTree& operator=(vanEmdeBoasTree&&) = default;
    friend ostream& operator<< (ostream& os, vanEmdeBoasTree& veb) noexcept {
        for(uint32_t st = veb.successor(-1); st != veb.LENGTH; st = veb.successor(st))
            os << st << " ";
        return os;
    }
    bool empty() const noexcept { return (_size == 0); }
    uint32_t size() const noexcept { return _size; }
    uint32_t max_size() const noexcept { return LENGTH; }
    bool find(const uint32_t value) const noexcept {
        if(value >= LENGTH) return false;
        return base_layer.find(value);
    }
    uint32_t count(const uint32_t value) const noexcept {
        return find(value);
    }
    int32_t max() const noexcept { return base_layer.max(); }
    int32_t min() const noexcept { return base_layer.min(); }
    void insert(const uint32_t value){
        assert(value < LENGTH);
        _size += base_layer.insert(value);
    }
    void erase(const uint32_t value){
        assert(value < LENGTH);
        base_layer.erase(value), --_size;
    }
    int32_t predecessor(const int32_t value) const noexcept {
        return base_layer.predecessor(value);
    }
    int32_t successor(const int32_t value) const noexcept {
        return base_layer.successor(value);
    }
};

bitset<10001> flag;
bitset<10001> bs;
        
int p[10001];
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int> a(n);
    rep(i,n) {
        cin >> a[i];
        a[i]--;
    }
    int nn = n;
    int c = 0;
    while(1){
        bool fflag = 1;
        for(int i = n-2;i >= 0;i--){
            if(a[i] > a[i+1]){
                fflag = 0;
                break;
            }
        }
        if(fflag)break;
        vanEmdeBoasTree vB;
        rep(i,n)p[i] = i;
        int mx = n-1;
        int mi = 0;
        vB.insert(10000);
        rep(i,n){
            int k = vB.successor(a[i]);
            if(k!=10000){
                p[a[i]] = k;
                vB.erase(k);
                vB.insert(a[i]);
            }else{
                vB.insert(a[i]);
            }
        }
        vector<int> b;
        int s = 0;
        int cc = 1000000;
        rep(i,n){
            int id = i;
            while(!flag[id]){
                if(b.empty()&& mi + s== id){
                    s++;
                }else{
                    b.push_back(id);
                    chmin(cc,id);
                }
                flag.set(id);
                id = p[id];
            }
        }
        int m = b.size();
        for(int i=m-1;i>=0;i--){
            if(b[i]==mx){
                mx--;
                b.pop_back();
            }else{
                break;
            }
        }
        rep(i,b.size()){
            b[i] -= cc;   
            flag.reset(i);
        }
        n = b.size();
        swap(a,b);
        bs.reset();
        c++;
    }
    cout << c * nn << endl;
    return 0;
}
accuracy: 0.06666666666666667
time_ms: 30
memory_kb: 402932
final_rank: 20

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

int n;
void to_simple(vector<int> &v){
	while (v.size() && n - v.size() == v[0])v.erase(v.begin());
	
}

vector<int> nex;
vector<bool> used;

int vals[1 << 14];
void trans(vector<int>& v) {
	fill(all(used), true);
	fill(all(nex), -1);
	for (int id : v)used[id] = false;
	int sz = 0;
	rep(i, v.size()) {
		if (sz == 0) {
			vals[sz] = v[i];
			sz++;
		}
		else {
			if (vals[sz - 1] < v[i]) {
				vals[sz] = v[i]; sz++;
			}
			else {
				int id = lower_bound(vals, vals + sz, v[i]) - vals;
				nex[v[i]] = vals[id];
				vals[id] = v[i];
			}
		}
	}
	vector<int> res;
	rep(i, n) {
		if (used[i])continue;
		int cur = i;
		while (cur >= 0) {
			res.push_back(cur);
			used[cur] = true;
			cur = nex[cur];
		}
	}
	swap(v, res);
}

void solve() {
	cin >> n;
	nex.resize(n);
	used.resize(n);
	vector<int> p(n);
	rep(i, n) {
		cin >> p[i]; p[i]--;
	}
	to_simple(p);
	ll ans = 0;
	//rep(i, p.size())cout << p[i] << " "; cout << "\n";
	while (p.size()) {
		trans(p);
		ans += n;
		//rep(i, p.size())cout << p[i] << " "; cout << "\n";
		to_simple(p);
	}
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 11892
final_rank: 7

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>

using lint = long long;

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> ps(n);
    for (auto& p : ps) {
        std::cin >> p;
        --p;
    }

    lint ans = 0;
    std::vector<int> stk, to(n, -1);

    while (true) {
        bool judge = true;
        for (int i = 0; i + 1 < n; ++i) {
            if (ps[i] > ps[i + 1]) judge = false;
        }
        if (judge) break;

        ans += n;

        stk.clear();
        std::fill(to.begin(), to.end(), -1);

        for (auto p : ps) {
            auto it = std::lower_bound(stk.begin(), stk.end(), p);
            if (it == stk.end()) {
                stk.push_back(p);
            } else {
                to[p] = *it;
                *it = p;
            }
        }

        int i = 0;
        for (auto x : stk) {
            while (x != -1) {
                ps[i++] = x;
                x = to[x];
            }
        }
    }

    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 940
memory_kb: 3628
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

//INSERT ABOVE HERE

const int MAX = 10010;
int ps[MAX],xs[MAX],dp[MAX];

signed main(){
  int n;
  cin>>n;
  for(int i=0;i<n;i++) cin>>ps[i];

  int cnt=0,len=0;
  while(!is_sorted(ps,ps+n)){
    cnt++;
    fill(dp,dp+n+1,n+1);

    int x=1;
    for(int i=len;i<n;i++){
      int p=ps[i];
      int k=lower_bound(dp,dp+x,p)-dp;
      if(k==x) x++;
      xs[p]=dp[k];
      dp[k]=p;
    }

    for(int i=0,j=len;i<n;i++){
      if(dp[i]==n+1) break;
      int cur=dp[i];
      while(cur!=n+1){
        ps[j++]=cur;
        cur=xs[cur];
      }
    }

    while(len<n && ps[len]==len+1) len++;
  }

  cout<<cnt*n<<endl;
  return 0;
}
accuracy: 1
time_ms: 830
memory_kb: 3348
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

//INSERT ABOVE HERE

const int MAX = 10010;
int ps[MAX],xs[MAX],dp[MAX];

signed main(){
  int n;
  cin>>n;
  for(int i=0;i<n;i++) cin>>ps[i];

  int cnt=0,len=0;
  while(!is_sorted(ps,ps+n)){
    cnt++;
    fill(dp,dp+n+1,n+1);

    int x=1;
    for(int i=len;i<n;i++){
      int p=ps[i];
      int k=lower_bound(dp,dp+x,p)-dp;
      if(k==x) x++;
      xs[p]=dp[k];
      dp[k]=p;
    }

    for(int i=0,j=len;i<n;i++){
      if(dp[i]==n+1) break;
      int cur=dp[i];
      while(cur!=n+1){
        ps[j++]=cur;
        cur=xs[cur];
      }
    }

    while(len<n && ps[len]==len+1) len++;
  }

  cout<<cnt*n<<endl;
  return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 3552
final_rank: 10

code_snippet: #pragma GCC optimize("O3")
#pragma GCC target("avx2")

#include <iostream>
#include <algorithm>
#include <vector>

using lint = long long;

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> ps(n);
    for (auto& p : ps) {
        std::cin >> p;
        --p;
    }

    lint ans = 0;
    std::vector<int> stk, to(n, -1);

    while (true) {
        bool judge = true;
        for (int i = 0; i + 1 < n; ++i) {
            if (ps[i] > ps[i + 1]) judge = false;
        }
        if (judge) break;

        ans += n;

        stk.clear();
        std::fill(to.begin(), to.end(), -1);

        for (auto p : ps) {
            auto it = std::lower_bound(stk.begin(), stk.end(), p);
            if (it == stk.end()) {
                stk.push_back(p);
            } else {
                to[p] = *it;
                *it = p;
            }
        }

        int i = 0;
        for (auto x : stk) {
            while (x != -1) {
                ps[i++] = x;
                x = to[x];
            }
        }
    }

    std::cout << ans << "\n";
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 980
memory_kb: 3628
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define short int

#define rep(i, n) for(long long i = 0; i < n; ++i)
#define rep2(i, a, b) for(long long i = a; i <= b; ++i)
#define ll long long
#define eb emplace_back
#define all(c) (c).begin(), (c).end()
#define vi vector<int>
#define N 200010
#define MOD 998244353
#define IMP 5000000000000000000

int main() {
	int n;
	short p[N];
	vector<short>a[N];
	short b[N];
	int l, r, m, cur, sz, x;
	bool v;
	cin >> n;
	rep(i, n)cin >> p[i];
	rep(i, n) {
		b[0] = p[i];
		cur = 0;
		rep(j, n - i - 1) {
                  //cout<<i<<" "<<j<<" "<<cur<<" "<<b[cur]<<endl;
			if (b[cur] < p[i + j + 1]) {
				b[cur + 1] = p[i + j + 1];
				cur++;
			}
			else {
				l = -1;
				r = cur;
				while ((l + 1) < r) {
					m = (l + r) / 2;
					if (b[m] < p[i + j + 1]) {
						l = m;
					}
					else r = m;
				}
				a[r].eb(b[r]);
				b[r] = p[i + j + 1];
			}
		}
		if (cur == n - i - 1) {
			cout << i*n << endl;
			return 0;
		}
		if (i == n - 2) {
			cout << (n - 1)*n << endl;
			return 0;
		}
		x = i;
		rep(j, cur+1) {
			p[x] = b[j];
			x++;
			sz = a[j].size();
			rep(ii, sz) {
				p[x] = a[j][sz-ii-1];
				x++;
			}
			a[j].clear();
		}
	}

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 8500
final_rank: 4

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

#define rep(i, n) for(long long i = 0; i < n; ++i)
#define rep2(i, a, b) for(long long i = a; i <= b; ++i)
#define ll long long
#define eb emplace_back
#define all(c) (c).begin(), (c).end()
#define vi vector<int>
#define N 200010
#define MOD 998244353
#define IMP 5000000000000000000

int main() {
	int n;
	short p[N];
	vector<short>a[N];
	short b[N];
	int l, r, m, cur, sz, x;
	bool v;
	cin >> n;
	rep(i, n)cin >> p[i];
	rep(i, n) {
		b[0] = p[i];
		cur = 0;
		rep(j, n - i - 1) {
                  //cout<<i<<" "<<j<<" "<<cur<<" "<<b[cur]<<endl;
			if (b[cur] < p[i + j + 1]) {
				b[cur + 1] = p[i + j + 1];
				cur++;
			}
			else {
				l = -1;
				r = cur;
				while ((l + 1) < r) {
					m = (l + r) / 2;
					if (b[m] < p[i + j + 1]) {
						l = m;
					}
					else r = m;
				}
				a[r].eb(b[r]);
				b[r] = p[i + j + 1];
			}
		}
		if (cur == n - i - 1) {
			cout << i*n << endl;
			return 0;
		}
		if (i == n - 2) {
			cout << (n - 1)*n << endl;
			return 0;
		}
		x = i;
		rep(j, cur+1) {
			p[x] = b[j];
			x++;
			sz = a[j].size();
			rep(ii, sz) {
				p[x] = a[j][sz-ii-1];
				x++;
			}
			a[j].clear();
		}
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 8488
final_rank: 2

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

#define rep(i, n) for(long long i = 0; i < n; ++i)
#define rep2(i, a, b) for(long long i = a; i <= b; ++i)
#define ll long long
#define eb emplace_back
#define all(c) (c).begin(), (c).end()
#define vi vector<int>
#define N 200010
#define MOD 998244353
#define IMP 5000000000000000000

int main() {
	int n;
	short p[N];
	vector<short>a[N];
	short b[N];
	int l, r, m, cur, sz, x;
	bool v;
	cin >> n;
	rep(i, n)cin >> p[i];
	rep(i, n) {
		b[0] = p[i];
		cur = 0;
		rep(j, n - i - 1) {
                  //cout<<i<<" "<<j<<" "<<cur<<" "<<b[cur]<<endl;
			if (b[cur] < p[i + j + 1]) {
				b[cur + 1] = p[i + j + 1];
				cur++;
			}
			else {
				l = -1;
				r = cur;
				while ((l + 1) < r) {
					m = (l + r) / 2;
					if (b[m] < p[i + j + 1]) {
						l = m;
					}
					else r = m;
				}
				a[r].eb(b[r]);
				b[r] = p[i + j + 1];
			}
		}
		if (cur == n - i - 1) {
			cout << i*n << endl;
			return 0;
		}
		if (i == n - 2) {
			cout << (n - 1)*n << endl;
			return 0;
		}
		x = i;
		rep(j, cur+1) {
			p[x] = b[j];
			x++;
			sz = a[j].size();
			rep(ii, sz) {
				p[x] = a[j][sz-ii-1];
				x++;
			}
			a[j].clear();
		}
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 8480
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC target("avx2,bmi,bmi2,lzcnt")

#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

const long long INF = 1e18;
// const ll mod = 1000000007;
using uint = unsigned;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
int popcnt(uint x) { return __builtin_popcount(x); }
int popcnt(ull x) { return __builtin_popcountll(x); }
int bsr(uint x) { return 31 - __builtin_clz(x); }
int bsr(ull x) { return 63 - __builtin_clzll(x); }
int bsf(uint x) { return __builtin_ctz(x); }
int bsf(ull x) { return __builtin_ctzll(x); }

struct FastSet {
  static constexpr uint B = 64;
  int n, lg;
  VV<ull> seg;
  FastSet(int _n) : n(_n) {
    do {
      seg.push_back(V<ull>((_n + B - 1) / B));
      _n = (_n + B - 1) / B;
    } while (_n > 1);
    lg = int(seg.size());
  }
  bool operator[](int i) const { return (seg[0][i / B] >> (i % B) & 1) != 0; }
  void set(int i) {
    for (int h = 0; h < lg; h++) {
      seg[h][i / B] |= 1ULL << (i % B);
      i /= B;
    }
  }
  void reset(int i) {
    for (int h = 0; h < lg; h++) {
      seg[h][i / B] &= ~(1ULL << (i % B));
      if (seg[h][i / B]) break;
      i /= B;
    }
  }
  // x以上最小の要素
  int next(int i) {
    for (int h = 0; h < lg; h++) {
      if (i / B == seg[h].size()) break;
      ull d = seg[h][i / B] >> (i % B);
      if (!d) {
        i = i / B + 1;
        continue;
      }
      // find
      i += bsf(d);
      for (int g = h - 1; g >= 0; g--) {
        i *= B;
        i += bsf(seg[g][i / B]);
      }
      return i;
    }
    return n;
  }
  // x未満最大の要素
  int prev(int i) {
    i--;
    for (int h = 0; h < lg; h++) {
      if (i == -1) break;
      ull d = seg[h][i / B] << (63 - i % 64);
      if (!d) {
        i = i / B - 1;
        continue;
      }
      // find
      i += bsr(d) - (B - 1);
      for (int g = h - 1; g >= 0; g--) {
        i *= B;
        i += bsr(seg[g][i / B]);
      }
      return i;
    }
    return -1;
  }
};

int N;
int a[10500];
int nxt[10500];
int prv[10500];

bool IsSorted() {
  for (int i = 1; i < N; i++) {
    if (a[i - 1] > a[i]) return false;
  }
  return true;
}

void f() {
  for (int i = 0; i < N; i++) {
    // cerr << a[i] << " ";
    prv[i] = -1;
    nxt[i] = -1;
  }
  // cerr << endl;
  FastSet st(N);
  for (int i = 0; i < N; i++) {
    int p = st.next(a[i]);
    if (p != N) {
      nxt[a[i]] = p;
      prv[p] = a[i];
      st.reset(p);
    }
    st.set(a[i]);
  }
  int idx = 0;
  /*
  for(int i = 0; i < N; i++) {
      cerr << i << " " << prv[i] << " " << nxt[i] << endl;
  }
  */
  for (int i = 0; i < N; i++) {
    if (prv[i] != -1) continue;
    int now = i;
    while (now != -1) {
      // cerr << idx << " " << now << endl;
      a[idx] = now;
      idx++;
      now = nxt[now];
    }
  }
}

struct stopwatch {
  std::string name = "Time";
  clock_t t = clock();
  void restart() { t = clock(); }
  int elapsed() const { return (clock() - t) * 1000 / CLOCKS_PER_SEC; }
  // ~stopwatch() { std::cerr << name << ": " << elapsed() << " ms\n"; }
} sw;

int main() {
  cin >> N;
  for (int i = 0; i < N; i++) {
    cin >> a[i];
    a[i]--;
  }
  for (int t = 0;; t++) {
    if (IsSorted()) {
      cout << t * N << endl;
      return 0;
    }
    f();
  }
  return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 3356
final_rank: 14

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC target("avx2,bmi,bmi2,lzcnt")

#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

const long long INF = 1e18;
// const ll mod = 1000000007;
using uint = unsigned;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
int popcnt(uint x) { return __builtin_popcount(x); }
int popcnt(ull x) { return __builtin_popcountll(x); }
int bsr(uint x) { return 31 - __builtin_clz(x); }
int bsr(ull x) { return 63 - __builtin_clzll(x); }
int bsf(uint x) { return __builtin_ctz(x); }
int bsf(ull x) { return __builtin_ctzll(x); }

struct FastSet {
  static constexpr uint B = 64;
  int n, lg;
  VV<ull> seg;
  FastSet(int _n) : n(_n) {
    do {
      seg.push_back(V<ull>((_n + B - 1) / B));
      _n = (_n + B - 1) / B;
    } while (_n > 1);
    lg = int(seg.size());
  }
  bool operator[](int i) const { return (seg[0][i / B] >> (i % B) & 1) != 0; }
  void set(int i) {
    for (int h = 0; h < lg; h++) {
      seg[h][i / B] |= 1ULL << (i % B);
      i /= B;
    }
  }
  void reset(int i) {
    for (int h = 0; h < lg; h++) {
      seg[h][i / B] &= ~(1ULL << (i % B));
      if (seg[h][i / B]) break;
      i /= B;
    }
  }
  // x以上最小の要素
  int next(int i) {
    for (int h = 0; h < lg; h++) {
      if (i / B == seg[h].size()) break;
      ull d = seg[h][i / B] >> (i % B);
      if (!d) {
        i = i / B + 1;
        continue;
      }
      // find
      i += bsf(d);
      for (int g = h - 1; g >= 0; g--) {
        i *= B;
        i += bsf(seg[g][i / B]);
      }
      return i;
    }
    return n;
  }
  // x未満最大の要素
  int prev(int i) {
    i--;
    for (int h = 0; h < lg; h++) {
      if (i == -1) break;
      ull d = seg[h][i / B] << (63 - i % 64);
      if (!d) {
        i = i / B - 1;
        continue;
      }
      // find
      i += bsr(d) - (B - 1);
      for (int g = h - 1; g >= 0; g--) {
        i *= B;
        i += bsr(seg[g][i / B]);
      }
      return i;
    }
    return -1;
  }
};

int N;
int a[10500];
int nxt[10500];
int prv[10500];

bool IsSorted() {
  for (int i = 1; i < N; i++) {
    if (a[i - 1] > a[i]) return false;
  }
  return true;
}

void f() {
  for (int i = 0; i < N; i++) {
    // cerr << a[i] << " ";
    prv[i] = -1;
    nxt[i] = -1;
  }
  // cerr << endl;
  FastSet st(N);
  for (int i = 0; i < N; i++) {
    int p = st.next(a[i]);
    if (p != N) {
      nxt[a[i]] = p;
      prv[p] = a[i];
      st.reset(p);
    }
    st.set(a[i]);
  }
  int idx = 0;
  /*
  for(int i = 0; i < N; i++) {
      cerr << i << " " << prv[i] << " " << nxt[i] << endl;
  }
  */
  for (int i = 0; i < N; i++) {
    if (prv[i] != -1) continue;
    int now = i;
    while (now != -1) {
      // cerr << idx << " " << now << endl;
      a[idx] = now;
      idx++;
      now = nxt[now];
    }
  }
}

struct stopwatch {
  std::string name = "Time";
  clock_t t = clock();
  void restart() { t = clock(); }
  int elapsed() const { return (clock() - t) * 1000 / CLOCKS_PER_SEC; }
  // ~stopwatch() { std::cerr << name << ": " << elapsed() << " ms\n"; }
} sw;

int main() {
  cin >> N;
  for (int i = 0; i < N; i++) {
    cin >> a[i];
    a[i]--;
  }
  for (int t = 0;; t++) {
    if (IsSorted()) {
      cout << t * N << endl;
      return 0;
    }
    f();
  }
  return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 3544
final_rank: 11

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

using ll = long long;
using Pi = pair<int, int>;
using Pl = pair<ll, ll>;
using vint = vector<int>;
using vvint = vector<vint>;
using vvvint = vector<vvint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using uint = unsigned int;
using ull = unsigned long long;

template<typename T> using uset = unordered_set<T>;
template<typename T1, typename T2> using umap = unordered_map<T1, T2>;

constexpr int INF = (1 << 30) - 1;
constexpr ll LLINF = 1LL << 60;
constexpr int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
constexpr char el = '\n';
constexpr int mod = 1000000007;

template<typename T> T gcd(T a, T b) { return (b ? gcd(b, a % b) : a); }
template<typename T> T lcm(T a, T b) { return (a / gcd(a, b) * b); }
template<typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) { return (a > b && (a = b, true)); }
template<typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) { return (a < b && (a = b, true)); }

template<typename T>
ostream& operator <<(ostream &os, vector<T> &v) {
	for (auto &u : v) os << u << el;
	return (os);
}

template<typename T>
istream& operator >>(istream &is, vector<T> &v) {
	for (auto &u : v) is >> u;
	return (is);
}

template<typename T1, typename T2>
istream& operator >>(istream &is, pair<T1, T2> &p) {
	return (is >> p.first >> p.second);
}


void Main() {
	int N; cin >> N;
	ll ans = 0; 
	vint A(N); cin >> A;

	while (A.size() > 0) {
		int n = A.size();
		int k = 0;
		vint li(n+1, N+1);
		vint field(n+1);
		for (auto &v : A) {
			while (k > 0 && li[k-1] > v) k--;
			while (li[k] < v) k++;
			field[v] = li[k];
			li[k] = v;
		}
		A = vint();
		int prev = 0;
		bool f = true;

		k = -1;
		for (int i = 0; i < n; i++) {
			if (li[i] != N+1) {
				int cur = li[i];
				while (cur <= N) {
					f &= (cur == prev + 1);
					if (!f && k == -1) k = prev;
					if (!f) A.push_back(cur-k);
					prev = cur;
					cur = field[cur];
				}
			}
		}
		ans++;
	}
	cout << ans * N << endl;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout << fixed << setprecision(20);
	Main();
	return (0);
}
accuracy: 1
time_ms: 270
memory_kb: 3364
final_rank: 6