#include <bits/stdc++.h>
using namespace std;
pair<int, int> tree[4 * 100005];
int lazy[4 * 100005];
void mt(int u, int l, int r, int a[], int n) {
  if (l == r)
    tree[u] = {a[l], l};
  else {
    mt(2 * u + 1, l, (l + r) / 2, a, n);
    mt(2 * u + 2, (l + r) / 2 + 1, r, a, n);
    tree[u] = min(tree[2 * u + 1], tree[2 * u + 2]);
  }
}
void update(int u, int l, int r, int x, int y, int v) {
  if (x > r || y < l) return;
  if (x <= l && r <= y) {
    tree[u].first += v;
    lazy[u] += v;
    return;
  }
  int m = (l + r) / 2;
  lazy[2 * u + 1] += lazy[u];
  lazy[2 * u + 2] += lazy[u];
  tree[2 * u + 1].first += lazy[u];
  tree[2 * u + 2].first += lazy[u];
  lazy[u] = 0;
  update(2 * u + 1, l, m, x, y, v);
  update(2 * u + 2, m + 1, r, x, y, v);
  tree[u] = min(tree[2 * u + 1], tree[2 * u + 2]);
}
pair<int, int> query(int u, int l, int r, int x, int y) {
  if (x > r || y < l) return {1e9, 1e9};
  if (x <= l && r <= y) return tree[u];
  int m = (l + r) / 2;
  lazy[2 * u + 1] += lazy[u];
  lazy[2 * u + 2] += lazy[u];
  tree[2 * u + 1].first += lazy[u];
  tree[2 * u + 2].first += lazy[u];
  lazy[u] = 0;
  return min(query(2 * u + 1, l, m, x, y), query(2 * u + 2, m + 1, r, x, y));
}
vector<pair<int, int> > ans;
int ct = 2;
void solve(int l, int r, int n) {
  if (l > r) return;
  auto ret = query(0, 0, n - 1, l, r);
  if (ret.first) update(0, 0, n - 1, l, r, -ret.first);
  while (ret.first--) ans.push_back({l + 1, r + 1});
  solve(l, ret.second - 1, n);
  solve(ret.second + 1, r, n);
}
int a[100005];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
  mt(0, 0, n - 1, a, n);
  solve(0, n - 1, n);
  printf("%lu\n", ans.size());
  for (auto c : ans) printf("%d %d\n", c.first, c.second);
}
