#include <bits/stdc++.h>
using namespace std;
const int nmax = 2000005;
int n, T, K;
vector<int> v;
int a[nmax];
set<pair<int, int> > mySet[nmax];
set<int> gf[nmax];
int viz[nmax], a2[nmax];
vector<int> comp[nmax];
int getId() {
  if (v.size() == 0) {
    cout << -1 << "\n";
    exit(0);
  }
  int x = v.back();
  v.pop_back();
  return x;
}
void addSon(int tata, int node) { gf[tata].insert(node); }
void updateNodeOnLevel(int nivel, int node, int beforeSize) {
  set<pair<int, int> > &currSet = mySet[nivel];
  int currSize = gf[node].size();
  auto it = currSet.find(make_pair(beforeSize, node));
  if (it == currSet.end()) {
    currSet.insert(make_pair(currSize, node));
    return;
  }
  currSet.erase(it);
  currSet.insert(make_pair(currSize, node));
}
int getNode(int nivel) {
  set<pair<int, int> > &currSet = mySet[nivel];
  if (currSet.size() == 0) {
    cout << -1 << "\n";
    exit(0);
  }
  auto it = currSet.end();
  --it;
  return it->second;
}
void doIt(int nivel) {
  if (nivel == 0) {
    return;
  }
  if (a[nivel] == 0) {
    doIt(nivel - 1);
    return;
  }
  int brother = getNode(nivel);
  if (gf[brother].size() == 1) {
    if (K > 0) {
      int tata = getNode(nivel - 1);
      int currId = getId();
      int beforeSize = gf[tata].size();
      addSon(tata, currId);
      --K;
      updateNodeOnLevel(nivel - 1, tata, beforeSize);
      --a[nivel];
      if (a[nivel] == 0) {
        doIt(nivel - 1);
        return;
      } else {
        doIt(nivel);
        return;
      }
    } else {
      cout << -1 << "\n";
      exit(0);
    }
  }
  int sonOfBrother = *gf[brother].begin();
  gf[brother].erase(gf[brother].begin());
  updateNodeOnLevel(nivel, brother, gf[brother].size() + 1);
  int tata = getNode(nivel - 1);
  int currId = getId();
  addSon(tata, currId);
  updateNodeOnLevel(nivel - 1, tata, gf[tata].size() - 1);
  addSon(currId, sonOfBrother);
  updateNodeOnLevel(nivel, currId, gf[currId].size() - 1);
  --a[nivel];
  if (a[nivel] == 0) {
    doIt(nivel - 1);
  } else {
    doIt(nivel);
  }
}
void mutaFii(int destinatie, int sursa) {
  for (auto it = gf[sursa].begin(); it != gf[sursa].end(); ++it) {
    int currFiu = *it;
    gf[destinatie].insert(currFiu);
  }
}
void stabilizeaza(int nivel) {
  if (K == 0) {
    return;
  }
  if (nivel == T) {
    return;
  }
  int cntNodes = comp[nivel].size();
  int primu = -1;
  for (int i = 0; i < cntNodes; ++i) {
    int currNode = comp[nivel][i];
    if (gf[currNode].size() > 0) {
      primu = currNode;
    }
  }
  for (int i = 0; i < cntNodes; ++i) {
    int currNode = comp[nivel][i];
    if (currNode == primu) {
      continue;
    }
    if (K == 0) {
      return;
    }
    if (gf[currNode].size() == 0) {
      continue;
    }
    --K;
    mutaFii(primu, currNode);
    gf[currNode].clear();
  }
  if (K > 0) {
    stabilizeaza(nivel + 1);
    return;
  } else {
    return;
  }
}
void dfs2(int node, int nivel) {
  comp[nivel].push_back(node);
  ++a2[nivel];
  viz[node] = 1;
  for (auto vc = gf[node].begin(); vc != gf[node].end(); ++vc) {
    if (viz[*vc] == 0) {
      dfs2(*vc, nivel + 1);
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> T >> K;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
  }
  for (int i = n; i >= 1; --i) {
    v.push_back(i);
  }
  v.pop_back();
  if (a[T] > K) {
    cout << -1 << "\n";
    return 0;
  }
  int tata = 1;
  for (int i = 1; i < T; ++i) {
    --a[i];
    int currId = getId();
    int beforeSize = gf[tata].size();
    addSon(tata, currId);
    updateNodeOnLevel(i - 1, tata, beforeSize);
    tata = currId;
  }
  for (int i = 1; i <= a[T]; ++i) {
    int currId = getId();
    --K;
    int beforeSize = gf[tata].size();
    addSon(tata, currId);
    updateNodeOnLevel(T - 1, tata, beforeSize);
  }
  doIt(T - 1);
  dfs2(1, 0);
  if (K > 0) {
    stabilizeaza(1);
  }
  if (K > 0) {
    cout << -1 << "\n";
    return 0;
  }
  cout << n << "\n";
  for (int i = 1; i <= n; ++i) {
    for (auto it = gf[i].begin(); it != gf[i].end(); ++it) {
      cout << i << " " << *it << "\n";
    }
  }
  return 0;
}
