#include <bits/stdc++.h>
/*
#include <ext/rope>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_cxx;
using namespace __gnu_pbds;
*/

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,tune=native")

#define fast ios_base::sync_with_stdio(0); cin.tie(nullptr); cout.tie(nullptr);

#define CR const&

#define FORI(i, a, b) for(int i = a, max##i = b; i < max##i; ++i)
#define FOR(i, n) FORI(i, 0, n)
#define RFORI(i, a, b) for(int i = a, min##i = b; i >= min##i; --i)
#define RFOR(i, n) RFORI(i, n, 0)
#define FORA(i, a) for(auto i : a)
#define FORAR(i, a) for(auto& i : a)
#define FORACR(i, a) for(auto CR i : a)
#define ALL(obj) begin(obj), end(obj)
#define RALL(obj) rbegin(obj), rend(obj)
#define Count(q) while(q--)

#define OK cerr << "OK" << endl;

#define pb push_back


using namespace std;

template<class T>
using V = vector<T>;
template<class T>
using VV = V<V<T>>;

using ld = long double;
using ll = long long;
using PLL = pair<ll, ll>;
using PII = pair<int, int>;
using VI = V<int>;
using VLL = V<ll>;
using VVI = VV<int>;
using VVLL = VV<ll>;
using Gr = VVI;
using MLL = map<ll, ll>;

template<class T>
constexpr T sqr(T x)
{
    return x * x;
}

template<class T, class U = T>
void cmin(T& a, U const& b)
{
    if(b < a)
        a = b;
}

template<class T, class U = T>
void cmax(T& a, U const& b)
{
    if(a < b)
        a = b;
}

ll get_time()
{
    using namespace chrono;
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}
mt19937 rng(get_time());

bool choose(int x, int y)
{
    return x < rng() % (x + y);
}

constexpr int inf = 1e9;
struct Vertex
{
    Vertex *l = nullptr, *r = nullptr;
    int v, mn_, sz_;
    bool rev;

    Vertex(int x) : v(x), mn_(x), sz_(1), rev(0) {}
    friend int mn(Vertex* v) { return v ? v->mn_ : inf; }
    friend int sz(Vertex* v) { return v ? v->sz_ : 0; }

    friend void push_rev(Vertex* v) { if(v) v->rev ^= 1; }

    friend void push(Vertex* v)
    {
        if(!v)
            return;

        if(v->rev)
        {
            swap(v->l, v->r);
            push_rev(v->l);
            push_rev(v->r);
            v->rev = 0;
        }
    }

    friend void pull(Vertex* v)
    {
        if(!v)
            return;

        v->sz_ = 1 + sz(v->l) + sz(v->r);
        v->mn_ = min({v->v, mn(v->l), mn(v->r)});
    }

    friend int get_pos(Vertex* v)
    {
        push(v);
        //cerr << v << " -> " << v->l << " " << v->r << "   " << v->v << " " << v->mn_ << "\n";

        if(mn(v->l) == v->mn_)
            return get_pos(v->l);
        else if(v->v == v->mn_)
            return sz(v->l);
        else
            return sz(v->l) + 1 + get_pos(v->r);
    }

    friend void split(Vertex* v, Vertex*& a, Vertex*& b, int cnt)
    {
        push(v);

        if(!v)
        {
            a = b = nullptr;
            return;
        }

        int s = sz(v->l);
        if(s >= cnt)
        {
            split(v->l, a, v->l, cnt);
            b = v;
            pull(b);
        } else
        {
            split(v->r, v->r, b, cnt - s - 1);
            a = v;
            pull(a);
        }
    }

    friend void merge(Vertex* a, Vertex* b, Vertex*& v)
    {
        push(a);
        push(b);

        if(!a || !b)
        {
            v = a ? a : b;
            return;
        }

        if(choose(sz(a), sz(b)))
        {
            merge(a->r, b, a->r);
            v = a;
        } else
        {
            merge(a, b->l, b->l);
            v = b;
        }

        pull(v);
    }

    friend void debug(Vertex* v)
    {
        push(v);
        if(!v)
            return;

        debug(v->l);
        cerr << v->v << " ";
        debug(v->r);
    }
};

void print(string name, Vertex* v)
{
    cerr << name << ": ";
    debug(v);
    cerr << "\n";
}

int main()
{
    fast

    int n;
    cin >> n;

    VI a(n);
    FORAR(i, a)
        cin >> i;

    Vertex* tree = nullptr;
    FOR(i, n)
        merge(tree, new Vertex{a[i]}, tree);

    V<PII> ans;
    FOR(i, n)
    {
        //print("tree", tree);

        int p = get_pos(tree);
        //cerr << i << " -> " << p << "\n";
        if(p)
            ans.pb({i, p + i});

        Vertex *x;
        split(tree, x, tree, p + 1);

        push_rev(x);

        Vertex *y;
        split(x, y, x, 1);

        merge(x, tree, tree);
    }

    cout << ans.size() << "\n";
    for(auto i : ans)
        cout << i.first + 1 << " " << i.second + 1 << "\n";
}
