#include<bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define endl "\n"
using namespace std;
const int N = 1e5 + 10, T = 100;
int a[N], deg[N], rev_idx[N], cost[N];
int n;
int st[N / T], ed[N / T];
vector<int> rrh[N / T];
struct IT {
int lazy[T * 4];
pair<int, int> T[T * 4];
void build(int s, int l, int r) {
if (l == r) {
T[s] = make_pair(0, l);
return;
}
int mid = l + r >> 1;
build(s << 1, l, mid);
build(s << 1 | 1, mid + 1, r);
T[s] = min(T[s << 1], T[s << 1 | 1]);
}
void push(int s, int l, int r) {
if (!lazy[s]) return;
T[s].first += lazy[s];
if (l != r) {
lazy[s << 1] += lazy[s];
lazy[s << 1 | 1] += lazy[s];
}
lazy[s] = 0;
}
void up(int s, int l, int r, int from, int to, int val) {
push(s, l, r);
if (l > to || r < from) return;
if (from <= l && r <= to) {
lazy[s] = val;
push(s, l, r);
return;
}
int mid = l + r >> 1;
up(s << 1, l, mid, from, to, val);
up(s << 1 | 1, mid + 1, r, from, to, val);
T[s] = min(T[s << 1], T[s << 1 | 1]);
}
} it[N / T];
int bit[N];
void add (int pos, int val) {
while (pos) {
bit[pos] += val;
pos -= pos & -pos;
}
}
int get(int pos) {
int ret = 0;
while (pos <= n) {
ret += bit[pos];
pos += pos & -pos;
}
return ret;
}
vector<int> q[2];
int32_t main() {
#define task ""
cin.tie(0) -> sync_with_stdio(0);
if (fopen("task.inp", "r")) {
freopen("task.inp", "r", stdin);
freopen("task.out", "w", stdout);
}
if (fopen(task".inp", "r")) {
freopen (task".inp", "r", stdin);
freopen (task".out", "w", stdout);
}
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) rev_idx[a[i]] = i;
for(int i = 1; i <= n; i++) {
cost[i] = get(a[i]);
add(a[i], 1);
}
for(int i = n, mn = 1e9; i >= 1; i--) {
deg[i] = a[i] > mn;
mn = min(mn, a[i]);
}
auto idx = [&] (int block, int val) {
return upper_bound(all(rrh[block]), val) - rrh[block].begin();
};
auto handle = [&] (int block) {
while (it[block].T[1].first == 0) {
int x = it[block].T[1].second;
it[block].up(1, 1, ed[block] - st[block] + 1, x, x, 1e9);
int y = rev_idx[x];
q[deg[y]].push_back(y);
}
};
for(int block = 0; block <= n / T; block++) {
st[block] = max(1, block * T);
ed[block] = min(n, block * T + T - 1);
for(int i = st[block]; i <= ed[block]; i++) rrh[block].push_back(a[i]);
sort(all(rrh[block]));
rrh[block].resize(unique(all(rrh[block])) - rrh[block].begin());
it[block].build(1, 1, ed[block] - st[block] + 1);
for(int i = st[block]; i <= ed[block]; i++) {
int pos = idx(block, a[i]);
it[block].up(1, 1, ed[block] - st[block] + 1, pos, pos, cost[i]);
}
handle(block);
}
auto del = [&] (int i) {
int group = i / T;
for(int j = i + 1; j <= ed[group]; j++) if (a[i] > a[j]) {
int pos = idx(group, a[j]);
it[group].up(1, 1, ed[group] - st[group] + 1, pos, pos, -1);
}
// exit(0);
handle(group);
for(int block = group + 1; block <= n / T; block++) {
int pos = idx(block, a[i]);
if (!pos) continue;
it[block].up(1, 1, ed[block] - st[block] + 1, 1, pos, -1);
handle(group);
}
};
vector<pair<int, int> > ans;
// del(1);
// cout << q[0].size() << endl;
// for(int &j : q[1]) cout << j << " "; cout << endl;
// exit(0);
while (1) {
if (q[1].size() >= 2) {
int x = q[1].back(); q[1].pop_back();
int y = q[1].back(); q[1].pop_back();
ans.emplace_back(a[x], a[y]);
del(x);
del(y);
}
else if (q[1].size() == 1) {
int x = q[1].back(); q[1].pop_back();
if (q[0].empty()) ans.emplace_back(a[x], a[x]);
else {
int y = q[0].back(); q[0].pop_back();
ans.emplace_back(a[x], a[y]);
}
del(x);
}
else {
if (q[0].empty()) break;
int x = q[0].back(); q[0].pop_back();
if (q[0].empty()) {
ans.emplace_back(a[x], a[x]);
break;
}
int y = q[0].back(); q[0].pop_back();
ans.emplace_back(a[x], a[y]);
}
}
cout << ans.size() << endl;
for(auto &[x, y] : ans) cout << x << " " << y << endl;
}