#include <bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
using namespace std;
const int maxn = 2e6 + 7;
const int INF = 0x3f3f3f3f;
const long long INFF = 1e18;
int n, a[maxn], maxx, col[maxn], row[maxn], h[maxn], a1[maxn], a2[maxn], t1 = 0,
                                                                         t2 = 0;
struct node {
  int x, y;
} p[maxn];
vector<node> ans;
stack<node> S1, S2;
int main() {
  scanf("%d", &n);
  maxx = n + 1;
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = n; i >= 1; i--) {
    if (a[i] == 1) {
      h[i] = --maxx;
      a1[++t1] = i;
      ans.push_back(node{h[i], i});
    } else if (a[i] == 2) {
      if (t1 == 0) {
        printf("%d\n", -1);
        return 0;
      }
      h[i] = h[a1[t1--]];
      a2[++t2] = i;
      ans.push_back(node{h[i], i});
    } else if (a[i] == 3) {
      if (t1 == 0 && t2 == 0) {
        printf("%d\n", -1);
        return 0;
      }
      h[i] = --maxx;
      ans.push_back(node{h[i], i});
      int j;
      if (t2)
        j = a2[t2--];
      else
        j = a1[t1--];
      ans.push_back(node{h[i], j});
      a2[++t2] = i;
    }
  }
  printf("%d\n", ans.size());
  for (int i = 0; i < ans.size(); i++) printf("%d %d\n", ans[i].x, ans[i].y);
  return 0;
}
