#include <bits/stdc++.h>
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
using namespace std;
const int N = 1e6 + 9;
const int M = 2e3 + 9;
const int INFINT = 1e9 + 9;
const long long INFLL = 1e18 + 9;
const long long MOD = (long long)(1000000007);
vector<int> dx = {-1, 0, 1, 0};
vector<int> dy = {0, -1, 0, 1};
void solve() {
  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < (int)n; ++i) cin >> a[i];
  vector<pair<int, int> > ans;
  int last_row = n - 1;
  vector<bool> used_row(n, 0), used_col(n, 0);
  set<pair<int, int> > one, two;
  for (int i = (int)n - 1; i >= 0; --i) {
    if (a[i] == 0) {
      used_col[i] = true;
    }
    if (a[i] == 1) {
      ans.emplace_back(last_row, i);
      one.insert({i, last_row});
      --last_row;
    }
    if (a[i] == 2) {
      if (one.empty()) {
        cout << -1 << endl;
        return;
      }
      int row = one.begin()->second;
      one.erase(one.begin());
      used_row[row] = true;
      ans.emplace_back(row, i);
      two.insert({i, row});
    }
    if (a[i] == 3) {
      ans.emplace_back(last_row, i);
      int col;
      if (!two.empty()) {
        col = two.begin()->first;
        two.erase(two.begin());
      } else if (!one.empty()) {
        col = one.begin()->first;
        one.erase(one.begin());
      } else {
        cout << -1 << endl;
        return;
      }
      ans.emplace_back(last_row, col);
      two.insert({i, last_row});
      --last_row;
    }
  }
  cout << (int)(ans.size()) << endl;
  for (int i = 0; i < (int)(int)(ans.size()); ++i)
    cout << ans[i].first + 1 << ' ' << ans[i].second + 1 << '\n';
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int tt = 1;
  while (tt--) {
    solve();
  }
  return 0;
}
