#include <bits/stdc++.h>
using namespace std;
int arr[100005], lazy[4 * 100005], num, value;
bool flag;
struct Node {
  int maxi, mini, one, two;
} tree[4 * 100005];
Node merge(Node a, Node b) {
  Node temp;
  int num = max(a.maxi, b.maxi);
  temp.maxi = num, temp.one = num == a.maxi ? a.one : b.one;
  num = min(a.mini, b.mini);
  temp.mini = num, temp.two = num == a.mini ? a.two : b.two;
  return temp;
}
void build(int node, int a, int b) {
  if (a > b) return;
  if (a == b) {
    tree[node] = (Node){arr[a], arr[a], a, a};
    return;
  }
  int left, right;
  left = 2 * node + 1, right = 2 * node + 2;
  build(left, a, (a + b) / 2);
  build(right, (a + b) / 2 + 1, b);
  tree[node] = merge(tree[left], tree[right]);
}
void lazy_update(int node, int a, int b) {
  int left, right;
  left = 2 * node + 1, right = 2 * node + 2;
  tree[node].maxi -= lazy[node];
  tree[node].mini -= lazy[node];
  if (a != b) {
    lazy[left] += lazy[node];
    lazy[right] += lazy[node];
  }
  lazy[node] = 0;
}
void update(int node, int a, int b, int i, int j, int val) {
  if (lazy[node]) lazy_update(node, a, b);
  if (a > b || a > j || b < i) return;
  if (a >= i && b <= j) {
    lazy[node] = val;
    lazy_update(node, a, b);
    return;
  }
  int left, right;
  left = 2 * node + 1, right = 2 * node + 2;
  update(left, a, (a + b) / 2, i, j, val);
  update(right, (a + b) / 2 + 1, b, i, j, val);
  tree[node] = merge(tree[left], tree[right]);
}
void query(int node, int a, int b, int i, int j, int val) {
  if (lazy[node]) lazy_update(node, a, b);
  if (flag) return;
  if (a > b || a > j || b < i) return;
  if (val > tree[node].mini) {
    if (a == b) {
      flag = true;
      num = a;
      return;
    }
    int left, right;
    left = 2 * node + 1, right = 2 * node + 2;
    query(left, a, (a + b) / 2, i, j, val);
    query(right, (a + b) / 2 + 1, b, i, j, val);
  }
}
int main() {
  int n, a, b, one, two, k = 0, diff;
  scanf("%d", &n);
  set<int> zero;
  for (int i = 0; i < n; i++) {
    scanf("%d", &arr[i]);
    if (!arr[i]) zero.insert(i);
  }
  build(0, 0, n - 1);
  zero.insert(n);
  vector<pair<int, int> > vec;
  while (true) {
    if (lazy[0]) lazy_update(0, 0, n - 1);
    if (tree[0].maxi == 0) break;
    int index = tree[0].one, x, y;
    y = *zero.upper_bound(index);
    flag = false;
    query(0, 0, n - 1, index + 1, y - 1, tree[0].maxi);
    a = index;
    b = flag ? num - 1 : min(n - 1, y - 1);
    update(0, 0, n - 1, a, b, 1);
    vec.push_back(make_pair(a + 1, b + 1));
  }
  printf("%d\n", vec.size());
  for (int i = 0; i < vec.size(); i++)
    printf("%d %d\n", vec[i].first, vec[i].second);
  return 0;
}
