To improve the boomerang throwing skills of the animals, Zookeeper has set up an $n \times n$ grid with some targets, where each row and each column has at most $2$ targets each. The rows are numbered from $1$ to $n$ from top to bottom, and the columns are numbered from $1$ to $n$ from left to right. 

 For each column, Zookeeper will throw a boomerang from the bottom of the column (below the grid) upwards. When the boomerang hits any target, it will bounce off, make a $90$ degree turn to the right and fly off in a straight line in its new direction. The boomerang can hit multiple targets and does not stop until it leaves the grid.

  [Image] 

In the above example, $n=6$ and the black crosses are the targets. The boomerang in column $1$ (blue arrows) bounces $2$ times while the boomerang in column $3$ (red arrows) bounces $3$ times.

 The boomerang in column $i$ hits exactly $a_i$ targets before flying out of the grid. It is known that $a_i \leq 3$.

However, Zookeeper has lost the original positions of the targets. Thus, he asks you to construct a valid configuration of targets that matches the number of hits for each column, or tell him that no such configuration exists. If multiple valid configurations exist, you may print any of them.


-----Input-----

The first line contains a single integer $n$ $(1 \leq n \leq 10^5)$.

 The next line contains $n$ integers $a_1,a_2,\ldots,a_n$ $(0 \leq a_i \leq 3)$.


-----Output-----

If no configuration of targets exist, print $-1$.

 Otherwise, on the first line print a single integer $t$ $(0 \leq t \leq 2n)$: the number of targets in your configuration. 

 Then print $t$ lines with two spaced integers each per line. Each line should contain two integers $r$ and $c$ $(1 \leq r,c \leq n)$, where $r$ is the target's row and $c$ is the target's column. All targets should be different. 

 Every row and every column in your configuration should have at most two targets each. 


-----Examples-----
Input
6
2 0 3 0 1 1

Output
5
2 1
2 5
3 3
3 6
5 6

Input
1
0

Output
0

Input
6
3 2 2 2 1 1

Output
-1



-----Note-----

For the first test, the answer configuration is the same as in the picture from the statement.

 For the second test, the boomerang is not supposed to hit anything, so we can place $0$ targets.

 For the third test, the following configuration of targets matches the number of hits, but is not allowed as row $3$ has $4$ targets.

  [Image] 

It can be shown for this test case that no valid configuration of targets will result in the given number of target hits.

Difficulty: HARD

Starter code:

Solutions:
from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from heapq import *
from math import gcd, factorial, floor, ceil
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func
mod = 10 ** 9 + 7

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def zerolist(n):
	return [0] * n

def nextline():
	out('\n')

def testcase(t):
	for pp in range(t):
		solve(pp)

def printlist(a):
	for p in range(0, len(a)):
		out(str(a[p]) + ' ')

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def count(g, n, col):
	ans = 0
	row = -1
	for i in range(n - 1, -1, -1):
		if g[i][col] == 1:
			ans += 1
			row = i
			break
	if ans == 0:
		return 0
	for i in range(col + 1, n):
		if g[row][i] == 1:
			ans += 1
			col = i
			break
	if ans == 1:
		return 1
	for i in range(row + 1, n):
		if g[i][col] == 1:
			ans += 1
			break
	return ans

def chck(ans, n):
	g = [[0] * n for i in range(n)]
	for i in range(len(ans)):
		g[ans[i][0]][ans[i][1]] = 1
	f = True
	for i in range(n):
		if g[i].count(1) > 2:
			f = False
			break
	for j in range(n):
		cnt = 0
		for j in range(n):
			cnt += g[i][j]
		if cnt > 2:
			f = False
			break
	col = [0] * n
	for i in range(n):
		col[i] = count(g, n, i)
	return (col, f)
from random import randint
f = True

def solve(case):
	n = int(inp())
	a = lis()
	ans = []
	one = []
	two = []
	three = []
	for i in range(n - 1, -1, -1):
		if a[i] == 1:
			ans.append((i, i))
			one.append(i)
		elif a[i] == 2:
			if len(one) == 0:
				print(-1)
				return
			curr = one.pop()
			ans.append((curr, i))
			two.append(i)
		elif a[i] == 3:
			if len(two) == 0 and len(one) == 0 and (len(three) == 0):
				print(-1)
				return
			if len(three) != 0:
				curr = three.pop()
				ans.append((i, i))
				ans.append((i, curr))
			elif len(two) != 0:
				curr = two.pop()
				ans.append((i, i))
				ans.append((i, curr))
			else:
				curr = one.pop()
				ans.append((i, i))
				ans.append((i, curr))
			three.append(i)
	print(len(ans))
	for i in range(len(ans)):
		print(ans[i][0] + 1, ans[i][1] + 1)
	sys.stdout.flush()
while f:
	f = False
	testcase(1)


def function(param):
	n = len(param)
	single_rows = []
	open_row = 0
	double = False
	targets = []
	for index in range(n):
		amnt = param[index]
		if amnt == 0:
			continue
		elif amnt == 1 and len(single_rows) != 0:
			targets.append((single_rows.pop(), index))
			continue
		else:
			if amnt == 1:
				if double:
					targets.append((open_row, index))
					open_row = open_row + 1
					targets.append((open_row, index))
					open_row = open_row + 1
				else:
					targets.append((open_row, index))
					open_row = open_row + 1
				double = False
			if amnt == 2:
				if double:
					targets.append((open_row, index))
					open_row = open_row + 1
					targets.append((open_row, index))
					single_rows.append(open_row)
					open_row = open_row + 1
				else:
					targets.append((open_row, index))
					single_rows.append(open_row)
					open_row = open_row + 1
				double = False
			if amnt == 3:
				if double:
					targets.append((open_row, index))
					open_row = open_row + 1
					targets.append((open_row, index))
				else:
					targets.append((open_row, index))
				double = True
	if len(single_rows) == 0 and double == False:
		return targets
	else:
		return None
total = int(input())
line = input()
result = function([int(x) for x in line.split()])
if result == None:
	print(-1)
else:
	print(len(result))
	for (x, y) in result:
		print(str(x + 1) + ' ' + str(y + 1))


import sys
readline = sys.stdin.readline
N = int(readline())
A = list(map(int, readline().split()))
Ans = []
one = []
tt = []
for i in range(N - 1, -1, -1):
	a = A[i]
	if a == 0:
		continue
	if a == 1:
		Ans.append((i, i))
		one.append((i, i))
		continue
	if a == 2:
		if not one:
			Ans = None
			break
		else:
			(oi, _) = one.pop()
			Ans.append((oi, i))
			tt.append((oi, i))
			continue
	else:
		if not tt:
			if not one:
				Ans = None
				break
			else:
				(oi, wi) = one.pop()
				Ans.append((i, wi))
				Ans.append((i, i))
				tt.append((i, i))
		else:
			(oi, wi) = tt.pop()
			Ans.append((i, wi))
			Ans.append((i, i))
			tt.append((i, i))
		continue
if Ans is None:
	print(-1)
else:
	print(len(Ans))
	if Ans:
		print('\n'.join((f'{a + 1} {b + 1}' for (a, b) in Ans)))


import sys
from collections import deque

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')
di = [[-1, 0], [1, 0], [0, 1], [0, -1]]

def string(s):
	return ''.join(s)

def fori(n):
	return [fi() for i in range(n)]

def inc(d, c, x=1):
	d[c] = d[c] + x if c in d else x

def bo(i):
	return ord(i) - ord('A')

def li():
	return [int(xx) for xx in input().split()]

def fli():
	return [float(x) for x in input().split()]

def comp(a, b):
	if a > b:
		return 2
	return 2 if a == b else 0

def gi():
	return [xx for xx in input().split()]

def cil(n, m):
	return n // m + int(n % m > 0)

def fi():
	return int(input())

def pro(a):
	return reduce(lambda a, b: a * b, a)

def swap(a, i, j):
	(a[i], a[j]) = (a[j], a[i])

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())

def gh():
	sys.stdout.flush()

def isvalid(i, j):
	return 0 <= i < n and 0 <= j < m and (a[i][j] != '.')

def bo(i):
	return ord(i) - ord('a')

def graph(n, m):
	for i in range(m):
		(x, y) = mi()
		a[x].append(y)
		a[y].append(x)
t = 1
while t > 0:
	t -= 1
	n = fi()
	a = li()
	twos = []
	threes = flag = 0
	ans = []
	l = 1
	r = n
	for i in range(n):
		if a[i] == 1:
			if twos:
				p = twos[-1]
				twos.pop()
				ans.append([p, i + 1])
			elif threes:
				threes -= 1
				ans.append([r, i + 1])
				r -= 1
				ans.append([r, i + 1])
				r -= 1
			else:
				ans.append([l, i + 1])
				l += 1
		elif a[i] == 2:
			if threes:
				threes -= 1
				ans.append([r, i + 1])
				r -= 1
				ans.append([r, i + 1])
				twos.append(r)
				r -= 1
			else:
				ans.append([l, i + 1])
				twos.append(l)
				l += 1
		elif a[i] == 3:
			if threes:
				threes -= 1
				ans.append([r, i + 1])
				r -= 1
				ans.append([r, i + 1])
			else:
				ans.append([r, i + 1])
			threes += 1
	r = [0] * (n + 1)
	c = [0] * (n + 1)
	for (i, j) in ans:
		r[i] += 1
		c[j] += 1
	flag = max(r) > 2 or max(c) > 2
	if len(twos) + threes or flag:
		print(-1)
	else:
		print(len(ans))
		for i in ans:
			print(n - i[0] + 1, i[1])


import sys, io, os
BUFSIZE = 8192

class FastIO(io.IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = io.BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(io.IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
N = int(input())
A = list(map(int, input().split()))
Ans = []
Q2 = []
Q1 = []
row = 1
for (col, a) in enumerate(A, 1):
	if a == 3:
		if Q2:
			q2 = Q2.pop()
			Ans.append((q2, col))
			Ans.append((row, col))
			Q2.append(row)
			row += 1
		else:
			Ans.append((row, col))
			Q2.append(row)
			row += 1
	elif a == 2:
		if Q2:
			q2 = Q2.pop()
			Ans.append((q2, col))
			Ans.append((row, col))
			Q1.append(row)
			row += 1
		else:
			Ans.append((row, col))
			Q1.append(row)
			row += 1
	elif a == 1:
		if Q1:
			q1 = Q1.pop()
			Ans.append((q1, col))
		elif Q2:
			q2 = Q2.pop()
			Ans.append((q2, col))
			Ans.append((row, col))
			row += 1
		else:
			Ans.append((row, col))
			row += 1
if Q1 or Q2:
	print(-1)
else:
	print(len(Ans))
	for (a, b) in Ans:
		print(f'{a} {b}')


import os
import sys
from io import BytesIO, IOBase

def main():
	n = int(input())
	a = list(map(int, input().split()))
	target = []
	curRow = 1
	pendingThree = []
	pendingTwo = []
	for i in range(1, n + 1):
		if a[i - 1] == 3:
			if pendingThree:
				prevRow = pendingThree.pop()
				target.append((prevRow, i))
				target.append((curRow, i))
				pendingThree.append(curRow)
				curRow += 1
			else:
				target.append((curRow, i))
				pendingThree.append(curRow)
				curRow += 1
		if a[i - 1] == 2:
			if pendingThree:
				prevRow = pendingThree.pop()
				target.append((prevRow, i))
				target.append((curRow, i))
				pendingTwo.append(curRow)
				curRow += 1
			else:
				target.append((curRow, i))
				pendingTwo.append(curRow)
				curRow += 1
		if a[i - 1] == 1:
			if pendingTwo:
				prevRow = pendingTwo.pop()
				target.append((prevRow, i))
			elif pendingThree:
				prevRow = pendingThree.pop()
				target.append((prevRow, i))
				target.append((curRow, i))
				curRow += 1
			else:
				target.append((curRow, i))
				curRow += 1
	if pendingThree or pendingTwo:
		print(-1)
	else:
		print(len(target))
		for elem in target:
			print(str(elem[0]) + ' ' + str(elem[1]))
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


n = int(input())
a = list(map(int, input().split()))
threes = []
twos = []
out = []
for i in range(n):
	if a[i] == 1:
		if twos:
			p = twos.pop()
			out.append((p, i))
		elif threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
	elif a[i] == 2:
		if threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
		twos.append(i)
	elif a[i] == 3:
		if threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
		threes.append(i)
if twos or threes:
	print(-1)
else:
	print(len(out))
	print('\n'.join([str(x[0] + 1) + ' ' + str(x[1] + 1) for x in out]))


ones = []
ans = []
h = 1
lastThree = (-1, -1)
n = int(input())
arr = list(map(int, input().split(' ')))
for i in range(n - 1, -1, -1):
	if arr[i] == 0:
		continue
	elif arr[i] == 1:
		ones.append((i, h))
		ans.append((i, h))
		h += 1
	elif arr[i] == 2:
		if len(ones) == 0:
			print(-1)
			exit(0)
		T = ones[-1]
		ones.pop()
		ans.append((i, T[1]))
		lastThree = (i, T[1])
	elif arr[i] == 3:
		if lastThree[0] == -1:
			if len(ones) == 0:
				print(-1)
				exit(0)
			else:
				lastThree = ones[-1]
				ones.pop()
		ans.append((i, h))
		ans.append((lastThree[0], h))
		lastThree = (i, h)
		h += 1
print(len(ans))
for x in ans:
	print(n - x[1] + 1, end=' ')
	print(x[0] + 1)


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from bisect import bisect_left, bisect_right
from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import time
start_time = time.time()
import collections as col
import math, string
from functools import reduce

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())
MOD = 10 ** 9 + 7

def solve():
	N = getInt()
	A = getInts()
	targs = []
	curr_row = N + 1
	curr_col = N + 1
	last_row = N
	available = col.deque([])
	available_set = set()

	def add_t(x, y):
		targs.append((x, y))
	for j in range(N - 1, -1, -1):
		if A[j] == 0:
			continue
		elif A[j] == 1:
			curr_row -= 1
			if curr_row < 1:
				print(-1)
				return
			curr_col = j + 1
			add_t(curr_row, curr_col)
			available.appendleft(curr_row)
			available_set.add(curr_row)
			last_row = curr_row
		elif A[j] == 2:
			if not available:
				print(-1)
				return
			row = available.pop()
			while row not in available_set:
				if not available:
					print(-1)
					return
				row = available.pop()
			available_set.remove(row)
			curr_col = j + 1
			add_t(row, curr_col)
			last_row = row
		else:
			curr_row -= 1
			if curr_row < 1 or curr_row == N:
				print(-1)
				return
			add_t(curr_row, curr_col)
			curr_col = j + 1
			add_t(curr_row, curr_col)
			if last_row in available_set:
				available_set.remove(last_row)
	targs.sort()
	print(len(targs))
	for (x, y) in targs:
		print(x, y)
solve()


import sys, os.path
from collections import *
from copy import *
import math
mod = 10 ** 9 + 7
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
n = int(input())
temp = []
ans = []
a = list(map(int, input().split()))
prev = -1
cur = n
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		temp.append(cur)
		ans.append((cur, i + 1))
		prev = i + 1
		cur -= 1
	elif a[i] == 2:
		if not temp:
			print(-1)
			exit()
		else:
			r = temp.pop()
			ans.append((r, i + 1))
			prev = i + 1
	elif a[i] == 3:
		if prev == -1:
			print(-1)
			exit()
		if temp and temp[-1] == cur + 1:
			temp.pop()
		ans.append((cur, prev))
		ans.append((cur, i + 1))
		prev = i + 1
		cur -= 1
print(len(ans))
for i in ans[::-1]:
	print(*i)


import sys
input = sys.stdin.readline

def NO():
	print(-1)
	exit(0)
N = int(input())
A = list(map(int, input().split()))
T = []
ones = []
others = []
for i in range(N - 1, -1, -1):
	if A[i] == 0:
		continue
	if A[i] == 1:
		T.append((i, i))
		ones.append(i)
	elif A[i] == 2:
		if not ones:
			NO()
		one = ones.pop()
		T.append((one, i))
		others.append(i)
	elif A[i] == 3:
		if not others and (not ones):
			NO()
		T.append((i, i))
		something = (others or ones).pop()
		T.append((i, something))
		others.append(i)
print(len(T))
for t in T:
	print(t[0] + 1, t[1] + 1)


import os
import math
import statistics
true = True
false = False
from functools import reduce
is_dev = 'vscode' in os.environ
if is_dev:
	inF = open('in.txt', 'r')
	outF = open('out.txt', 'w')

def ins():
	return list(map(int, input_().split(' ')))

def inss():
	return list(input_().split(' '))

def input_():
	if is_dev:
		return inF.readline()[:-1]
	else:
		return input()

def ranin():
	return range(int(input_()))

def print_(data):
	if is_dev:
		outF.write(str(data) + '\n')
	else:
		print(data)
epsilon = 1e-07
input_()
a = ins()
que2 = []
que3 = []
result = []
cur_row = 1
for (idx, i) in enumerate(a):
	if i == 0:
		continue
	elif i == 1:
		if not (que3 or que2):
			result.append((idx + 1, cur_row))
		else:
			if que3 and que2:
				if que3[0][1] > que2[0][1]:
					k = que2.pop(0)
				else:
					k = que3.pop(0)
			elif que3:
				k = que3.pop(0)
			else:
				k = que2.pop(0)
			if k[0] == 3:
				result.append((idx + 1, k[1]))
				result.append((idx + 1, cur_row))
			else:
				result.append((idx + 1, k[1]))
	elif i == 2:
		result.append((idx + 1, cur_row))
		if que3:
			k = que3.pop(0)
			result.append((idx + 1, k[1]))
		que2.append((2, cur_row))
	else:
		result.append((idx + 1, cur_row))
		if que3:
			k = que3.pop(0)
			result.append((idx + 1, k[1]))
		que3.append((3, cur_row))
	cur_row += 1
if que3 or que2:
	print_(-1)
else:
	print_(len(result))
	for (i, j) in result:
		print_(f'{j} {i}')
if is_dev:
	outF.close()

	def compare_file():
		print(open('out.txt', 'r').read() == open('outactual.txt', 'r').read())
	compare_file()


import sys
from collections import deque
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7

def resolve():
	n = int(input())
	A = list(map(int, input().split()))
	last = [None, None]
	que = deque([])
	H = 1
	res = []
	for i in reversed(range(n)):
		if A[i] == 0:
			continue
		elif A[i] == 1:
			que.append([i, H])
			res.append([i, H])
			H += 1
		elif A[i] == 2:
			if not que:
				print(-1)
				exit()
			(_, h) = que.pop()
			res.append([i, h])
			last = [i, h]
		else:
			if last == [None, None]:
				if not que:
					print(-1)
					exit()
				else:
					last = que.pop()
			res.append([i, H])
			res.append([last[0], H])
			last = [i, H]
			H += 1
	print(len(res))
	for j in res:
		print(n - j[1] + 1, j[0] + 1)
resolve()


from sys import stdin, gettrace
if gettrace():
	inputi = input
else:

	def input():
		return next(stdin)[:-1]

	def inputi():
		return stdin.buffer.readline()

def main():
	n = int(inputi())
	aa = [int(a) for a in inputi().split()]
	res = []
	ones = []
	twos = []
	for i in range(n - 1, -1, -1):
		a = aa[i]
		if a == 1:
			res.append((i + 1, i + 1))
			ones.append(res[-1])
		elif a == 2:
			if not ones:
				print(-1)
				return
			res.append((ones.pop()[0], i + 1))
			twos.append(res[-1])
		elif a == 3:
			if not ones and (not twos):
				print(-1)
				return
			if twos:
				(x, y) = twos.pop()
			else:
				(x, y) = ones.pop()
			res.append((i + 1, i + 1))
			res.append((i + 1, y))
			twos.append((i + 1, i + 1))
	print(len(res))
	for (x, y) in res:
		print(x, y)
main()


from sys import stdin
n = int(stdin.readline())
bo = list(map(int, stdin.readline().split()))
stack2 = []
stack3 = []
ans = []
height = 1
for i in range(1, 1 + n):
	if height > n:
		break
	if bo[i - 1] == 0:
		continue
	if bo[i - 1] == 1:
		if stack2:
			j = stack2.pop()
			ans.append((height, j))
			ans.append((height, i))
			height += 1
			continue
		if stack3:
			j = stack3.pop()
			ans.append((height, j))
			ans.append((height, i))
			ans.append((height + 1, i))
			height += 2
			continue
		ans.append((height, i))
		height += 1
		continue
	elif bo[i - 1] == 2:
		if stack3:
			j = stack3.pop()
			ans.append((height, j))
			ans.append((height, i))
			height += 1
		stack2.append(i)
		continue
	else:
		if stack3:
			j = stack3.pop()
			ans.append((height, j))
			ans.append((height, i))
			height += 1
		stack3.append(i)
		continue
if height > n + 1:
	print(-1)
elif stack2 or stack3:
	print(-1)
else:
	print(len(ans))
	for (x, y) in ans:
		print(x, y)


import sys
import random
import math
import copy
from heapq import heappush, heappop, heapify
from functools import cmp_to_key
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, Counter
input = sys.stdin.readline
getS = lambda : input().strip()
getN = lambda : int(input())
getList = lambda : list(map(int, input().split()))
getZList = lambda : [int(x) - 1 for x in input().split()]
INF = float('inf')
MOD = 10 ** 9 + 7
divide = lambda x: pow(x, MOD - 2, MOD)

def solve(n=0, li=0):
	if n == 0:
		n = getN()
		li = getList()
	ans = []
	lbound = n + 1
	cand2 = deque()
	cand3 = deque()
	oki = [0] * (n + 1)
	used = [0] * (n + 1)
	for i in range(n, 0, -1):
		t = li[i - 1]
		ok = False
		while not ok:
			if t == 0:
				ok = True
			if t == 1:
				lbound -= 1
				ans.append((lbound, i))
				cand2.append(i)
				cand3.append(i)
				oki[i] = lbound
				ok = True
			elif t == 2:
				if not cand2:
					print(-1)
					return
				c = cand2.popleft()
				if used[c]:
					continue
				takasa = oki[c]
				ans.append((takasa, i))
				oki[i] = takasa
				cand3.appendleft(i)
				ok = True
				used[c] = 1
			elif t == 3:
				if not cand3:
					print(-1)
					return
				c = cand3.popleft()
				if used[c]:
					continue
				lbound -= 1
				ans.append((lbound, i))
				ans.append((lbound, c))
				cand3.appendleft(i)
				oki[i] = lbound
				ok = True
				used[c] = 1
	print(len(ans))
	for an in ans:
		print(*an)

def main():
	n = getN()
	for _ in range(n):
		nn = 50
		li = [random.randint(0, 3) for i in range(nn - 1)] + [random.randint(1, 1)]
		print(li)
		solve(nn, li)
	return
solve()


n = int(input())
x = []
y = []
ans = []
A = list(map(int, input().split()))
for i in range(n):
	if A[i] == 1:
		if y:
			ans += [[y.pop(), i + 1]]
		elif x:
			ans += [[x.pop(), i + 1]]
			ans += [[i + 1, i + 1]]
		else:
			ans += [[i + 1, i + 1]]
	elif A[i] == 2:
		if x:
			ans += [[x.pop(), i + 1]]
			ans += [[i + 1, i + 1]]
		else:
			ans += [[i + 1, i + 1]]
		y += [i + 1]
	elif A[i] == 3:
		if x:
			ans += [[x.pop(), i + 1]]
			ans += [[i + 1, i + 1]]
		else:
			ans += [[i + 1, i + 1]]
		x += [i + 1]
if x or y:
	print(-1)
else:
	print(len(ans))
	for Ans in ans:
		print(*Ans)


from collections import Counter
import math
import sys
from bisect import bisect, bisect_left, bisect_right
from itertools import permutations

def input():
	return sys.stdin.readline().strip()

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def mod():
	return 10 ** 9 + 7
n = INT()
a = LIST()
two = []
three = []
ans = []
for i in range(len(a)):
	if a[i] == 0:
		continue
	elif a[i] == 1:
		if two:
			x = two.pop()
			ans.append([x + 1, i + 1])
		elif three:
			x = three.pop()
			ans.append([x + 1, i + 1])
			ans.append([i + 1, i + 1])
		else:
			ans.append([i + 1, i + 1])
	elif a[i] == 2:
		if three:
			x = three.pop()
			ans.append([x + 1, i + 1])
			ans.append([i + 1, i + 1])
		else:
			ans.append([i + 1, i + 1])
		two.append(i)
	else:
		if three:
			x = three.pop()
			ans.append([x + 1, i + 1])
			ans.append([i + 1, i + 1])
		else:
			ans.append([i + 1, i + 1])
		three.append(i)
if two or three:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()

def solve():
	ans = []
	if aa[-1] > 1:
		return -1
	c2 = list(range(n, 0, -1))
	c1 = []
	p2 = []
	p3 = []
	for (j, a) in enumerate(aa, 1):
		if a == 0:
			continue
		if not c2 and (not c1):
			return -1
		if a == 1:
			if p2:
				(pi, pj) = p2.pop()
				ans.append((pi, j))
			elif p3:
				if not c2:
					return -1
				(pi, pj) = p3.pop()
				ans.append((pi, j))
				i = c2.pop()
				ans.append((i, j))
			else:
				i = c2.pop()
				ans.append((i, j))
		if a == 2:
			if p3:
				(pi, pj) = p3.pop()
				ans.append((pi, j))
			i = c2.pop()
			ans.append((i, j))
			p2.append((i, j))
		if a == 3:
			if p3:
				(pi, pj) = p3.pop()
				ans.append((pi, j))
			i = c2.pop()
			ans.append((i, j))
			p3.append((i, j))
	if p3 or p2:
		return -1
	return ans
n = II()
aa = LI()
ans = solve()
if ans == -1:
	print(-1)
else:
	print(len(ans))
	for (i, j) in ans:
		print(i, j)


import sys
input = sys.stdin.readline
n = int(input())
a = list(map(int, input().split()))
poss = True
col = []
row = []
cl = None
t = 0
ts = []
i = n - 1
while i >= 0:
	if a[i] == 1:
		col.append(i)
		row.append(i)
		t += 1
		ts.append([i + 1, i + 1])
	if a[i] == 2:
		if len(col) == 0:
			poss = False
		else:
			t += 1
			r = row.pop()
			c = col.pop()
			ts.append([r + 1, i + 1])
			cl = i
	if a[i] == 3:
		if cl != None:
			t += 2
			ts.append([i + 1, i + 1])
			ts.append([i + 1, cl + 1])
			cl = i
		elif len(col) == 0:
			poss = False
		else:
			c = col.pop()
			r = row.pop()
			t += 2
			ts.append([i + 1, i + 1])
			ts.append([i + 1, c + 1])
			cl = i
	i -= 1
if poss:
	print(t)
	for x in ts:
		print(*x)
else:
	print(-1)


def solve():
	n = int(input())
	hits = [int(x) for x in input().split()]
	ans = []
	ones = []
	twos = []
	x = n
	for y in range(n, 0, -1):
		if hits[y - 1] == 0:
			continue
		elif hits[y - 1] == 1:
			dot = [x, y]
			ans.append(dot)
			ones.append(dot)
			x -= 1
		elif hits[y - 1] == 2:
			if len(ones) == 0:
				print(-1)
				return
			curr = ones.pop()
			dot = [curr[0], y]
			ans.append(dot)
			twos.append(dot)
		elif hits[y - 1] == 3:
			if len(twos) > 0:
				curr = twos.pop(0)
			elif len(ones) > 0:
				curr = ones.pop(0)
			else:
				print(-1)
				return
			dot = [x, y]
			ans.append(dot)
			twos.append(dot)
			dot = [x, curr[1]]
			ans.append(dot)
			x -= 1
		if x < 0:
			print(-1)
			return
	print(len(ans))
	for x in ans:
		print(*x)
solve()


import sys
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
if a[-1] > 1:
	print(-1)
	exit(0)
table = [-1] * N
s = []
for i in range(N - 1, -1, -1):
	if a[i] == 1:
		s.append(i)
	if a[i] == 2:
		if len(s) == 0:
			print(-1)
			exit(0)
		j = s.pop()
		table[j] = i
s = []
for i in range(N - 1, -1, -1):
	if a[i] == 3:
		if len(s) == 0:
			print(-1)
			exit(0)
		j = s.pop()
		table[j] = i
	if a[i] and table[i] == -1:
		s.append(i)
s = []
for i in range(N):
	if table[i] >= 0:
		s.append((table[i] + 1, i + 1))
s.reverse()
res = []
z = 1
call = [0] * N
while len(s):
	(x, y) = s.pop()
	if call[x - 1]:
		if a[x - 1] >= 2:
			res.append((call[x - 1], y))
		if a[x - 1] == 3:
			res.append((z, y))
			call[y - 1] = z
			z += 1
	elif a[x - 1] == 2:
		res.append((z, x))
		res.append((z, y))
		z += 1
	elif a[x - 1] == 3:
		res.append((z, x))
		res.append((z, y))
		res.append((z + 1, y))
		call[y - 1] = z + 1
		z += 2
if len(res) and res[-1][0] == z:
	z += 1
for i in range(N):
	if a[i] == 1 and table[i] == -1 and (call[i] == 0):
		res.append((z, i + 1))
		if z > N:
			print(-1)
			exit(0)
		z += 1
res = set(res)
print(len(res))
for r in sorted(res):
	print(*r)


n = int(input())
A = list(map(int, input().split()))
max_not_used = n
ones = []
twos = []
targets = []
failed = False
for (c, a) in zip(list(range(n, 0, -1)), reversed(A)):
	if a == 1:
		r = max_not_used
		max_not_used -= 1
		targets.append((r, c))
		ones.append((r, c))
	elif a == 2:
		if not ones:
			failed = True
			break
		else:
			(r, __) = ones.pop()
			targets.append((r, c))
			twos.append((r, c))
	elif a == 3:
		if not ones and (not twos):
			failed = True
			break
		else:
			if twos:
				(rr, cc) = twos.pop()
			else:
				(rr, cc) = ones.pop()
			r = max_not_used
			max_not_used -= 1
			targets.append((r, c))
			targets.append((r, cc))
			twos.append((r, c))
if failed:
	print(-1)
else:
	print(len(targets))
	for target in targets:
		print(*target)


(n, *a) = map(int, open(0).read().split())
now = 1
heights = [[] for _ in range(n)]
st0 = []
st1 = []
failed = False
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		heights[i].append(now)
		st0.append((now, i))
		now += 1
	elif a[i] == 2:
		if len(st0):
			(h, j) = st0.pop()
			heights[i].append(h)
			st1.append(i)
		else:
			failed = True
			break
	elif a[i] == 3:
		if len(st1):
			j = st1.pop()
			heights[i].append(now)
			heights[j].append(now)
			st1.append(i)
			now += 1
		elif len(st0):
			(_, j) = st0.pop()
			heights[i].append(now)
			heights[j].append(now)
			st1.append(i)
			now += 1
		else:
			failed = True
			break
if failed:
	print('-1')
else:
	ans = []
	for i in range(n):
		for j in heights[i]:
			ans.append(str(n - j + 1) + ' ' + str(i + 1))
	print(len(ans), *ans, sep='\n')


import math
from sys import stdin
from sys import setrecursionlimit
setrecursionlimit(100000)

def put():
	return map(int, stdin.readline().split())
for _ in range(1):
	n = int(input())
	l = list(put())
	ans = []
	rows = set()
	col = set()
	colrow = {}
	curr = n
	f = 0
	for i in range(len(l) - 1, -1, -1):
		if l[i] == 0:
			curr -= 1
		elif l[i] == 1:
			ans.append([curr, i + 1])
			rows.add(curr)
			col.add(i + 1)
			colrow[i + 1] = curr
			curr -= 1
		elif l[i] == 2:
			if len(rows) == 0:
				f = 1
				break
			else:
				r = rows.pop()
				col.add(i + 1)
				colrow[i + 1] = curr
				ans.append([r, i + 1])
		elif len(col) == 0:
			f = 1
			break
		else:
			c = col.pop()
			col.add(i + 1)
			colrow[i + 1] = curr
			if colrow[c] in rows:
				rows.remove(colrow[c])
			ans.append([curr, i + 1])
			ans.append([curr, c])
			curr -= 1
	if f:
		print(-1)
	else:
		print(len(ans))
		for i in range(len(ans)):
			print(ans[i][0], ans[i][1])


from sys import stdin
n = int(input())
array = list(map(int, stdin.readline().split()))
flag = True
queue2 = []
queue3 = []
only1 = []
ans = []
cur = 1
count = [0, 0, 0, 0]
for i in range(n):
	c = array[i]
	count[c] += 1
	if c == 0:
		continue
	elif c == 1:
		if queue2:
			ans.append([queue2.pop(), i + 1])
		elif queue3:
			ans.append([queue3.pop(), i + 1])
			ans.append([cur, i + 1])
			cur += 1
		else:
			ans.append([cur, i + 1])
			cur += 1
	elif c == 2:
		if queue3:
			ans.append([queue3.pop(), i + 1])
			ans.append([cur, i + 1])
			queue2.append(cur)
			cur += 1
		else:
			ans.append([cur, i + 1])
			queue2.append(cur)
			cur += 1
	elif queue3:
		ans.append([queue3.pop(), i + 1])
		ans.append([cur, i + 1])
		queue3.append(cur)
		cur += 1
	else:
		ans.append([cur, i + 1])
		queue3.append(cur)
		cur += 1
if len(queue2) > 0 or len(queue3) > 0:
	flag = False
if flag:
	print(len(ans))
	for j in ans:
		print(*j)
else:
	print(-1)


import sys
Z = sys.stdin.readline
o = []
n = int(Z())
a = [*map(int, Z().split())]
thr = 0
two = []
r = 1
for i in range(1, n + 1):
	if a[i - 1] == 1:
		if two:
			o.append(f'{two.pop()} {i}')
		elif thr:
			o.append(f'{thr} {i}')
			o.append(f'{thr + 1} {i}')
			thr = 0
			r += 1
		else:
			o.append(f'{r} {i}')
			r += 1
	elif a[i - 1] == 2:
		if thr:
			o.append(f'{thr} {i}')
			o.append(f'{thr + 1} {i}')
			two.append(thr + 1)
			thr = 0
			r += 1
		else:
			o.append(f'{r} {i}')
			two.append(r)
			r += 1
	elif a[i - 1] == 3:
		if thr:
			o.append(f'{thr} {i}')
			o.append(f'{thr + 1} {i}')
			thr += 1
			r += 1
		else:
			o.append(f'{r} {i}')
			thr = r
			r += 1
if thr or two:
	print(-1)
else:
	print(len(o))
	print('\n'.join(o))


n = int(input())
a = list(map(int, input().split()))
positive = [(col, val) for (col, val) in enumerate(a, 1) if val > 0][::-1]

def no():
	print(-1)
	exit(0)
ans = []
ones = []
twos = []
for (i, (col, val)) in enumerate(positive):
	if val == 1:
		ones.append(col)
		ans.append((col, col))
	elif val == 2:
		if len(ones) == 0:
			no()
		ans.append((ones.pop(), col))
		twos.append(col)
	elif val == 3:
		if len(twos) > 0:
			prv = twos.pop()
		elif len(ones) > 0:
			prv = ones.pop()
		else:
			no()
		ans.append((col, col))
		ans.append((col, prv))
		twos.append(col)
print(len(ans))
for (x, y) in ans:
	print(x, y)


def solve():
	N = int(input())
	A = [int(x) for x in input().split()]
	prev2 = None
	prev3 = None
	ans = []
	ones = []
	next_row = N - 1
	for col in range(N - 1, -1, -1):
		if A[col] == 0:
			continue
		if A[col] == 1:
			ans.append((next_row, col))
			ones.append((next_row, col))
			next_row -= 1
		if A[col] == 2:
			if len(ones) == 0:
				return -1
			(r, c) = ones.pop()
			ans.append((r, col))
			prev2 = (r, col)
		if A[col] == 3:
			if prev3 is not None:
				(r, c) = prev3
			elif prev2 is not None:
				(r, c) = prev2
				prev2 = None
			elif len(ones) == 0:
				return -1
			else:
				(r, c) = ones.pop()
			ans.append((next_row, c))
			ans.append((next_row, col))
			prev3 = (next_row, col)
			next_row -= 1
	return ans
ans = solve()
if ans == -1:
	print(-1)
else:
	print(len(ans))
	for (r, c) in ans:
		print(r + 1, c + 1)


from bisect import *
from collections import *
from math import *
from heapq import *
from typing import List
from itertools import *
from operator import *
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

@lru_cache(None)
def fact(x):
	if x < 2:
		return 1
	return fact(x - 1) * x

@lru_cache(None)
def per(i, j):
	return fact(i) // fact(i - j)

@lru_cache(None)
def com(i, j):
	return per(i, j) // fact(j)

def linc(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t > f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rinc(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t < f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def ldec(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t < f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rdec(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t > f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def binfun(x):
	c = 0
	for w in arr:
		c += ceil(w / x)
	return c

def lowbit(n):
	return n & -n

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class smt:

	def __init__(self, l, r, arr):
		self.l = l
		self.r = r
		self.value = (1 << 31) - 1 if l < r else arr[l]
		mid = (l + r) // 2
		if l < r:
			self.left = smt(l, mid, arr)
			self.right = smt(mid + 1, r, arr)
			self.value &= self.left.value & self.right.value

	def setvalue(self, x, val):
		if self.l == self.r:
			self.value = val
			return
		mid = (self.l + self.r) // 2
		if x <= mid:
			self.left.setvalue(x, val)
		else:
			self.right.setvalue(x, val)
		self.value = self.left.value & self.right.value

	def ask(self, l, r):
		if l <= self.l and r >= self.r:
			return self.value
		val = (1 << 31) - 1
		mid = (self.l + self.r) // 2
		if l <= mid:
			val &= self.left.ask(l, r)
		if r > mid:
			val &= self.right.ask(l, r)
		return val

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return prime

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d
n = N()
a = RLL()
ans = []
flag = True
one = set()
two = set()
thr = set()
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		ans.append([i + 1, i + 1])
		one.add(i + 1)
	elif a[i] == 2:
		if not one:
			flag = False
			break
		r = one.pop()
		ans.append([r, i + 1])
		two.add(i + 1)
	elif a[i] == 3:
		if thr:
			c = thr.pop()
			ans.append([i + 1, i + 1])
			ans.append([i + 1, c])
			thr.add(i + 1)
		elif two:
			c = two.pop()
			ans.append([i + 1, i + 1])
			ans.append([i + 1, c])
			thr.add(i + 1)
		elif one:
			c = one.pop()
			ans.append([i + 1, i + 1])
			ans.append([i + 1, c])
			thr.add(i + 1)
		else:
			flag = False
			break
if flag:
	print(len(ans))
	for a in ans:
		print(*a)
else:
	print(-1)


import sys
input = sys.stdin.readline
for _ in range(1):
	n = int(input())
	a = [0] + list(map(int, input().split()))
	d = {}
	twolist = []
	two = 0
	row = 1
	threelist = []
	three = 0
	for col in range(1, n + 1):
		if a[col] == 2:
			if three > 0:
				d[threelist.pop(), col] = 1
				d[row, col] = 1
				row += 1
				three -= 1
				two += 1
				twolist.append(row - 1)
			else:
				two += 1
				twolist.append(row)
				d[row, col] = 1
				row += 1
		elif a[col] == 1:
			if two > 0:
				d[twolist.pop(), col] = 1
				two -= 1
			elif three > 0:
				d[threelist.pop(), col] = 1
				d[row, col] = 1
				row += 1
				three -= 1
			else:
				d[row, col] = 1
				row += 1
		elif a[col] == 3:
			if three > 0:
				three -= 1
				d[threelist.pop(), col] = 1
			three += 1
			threelist.append(row)
			d[row, col] = 1
			row += 1
	row = [0] * (n + 1)
	col = [0] * (n + 1)
	if two > 0 or three > 0:
		print(-1)
		exit()
	for i in d:
		(x, y) = i
		row[x] += 1
		col[y] += 1
		if x > n or y > n or row[x] > 2 or (col[y] > 2):
			print('-1')
			break
	else:
		print(len(d))
		for i in d:
			print(*i)


import sys
n = int(input())
a = list(map(int, sys.stdin.readline().split()))
one = []
an = []
f = 0
p = n
for j in range(n - 1, -1, -1):
	if a[j] == 1:
		one.append((p, j + 1))
		p = p - 1
	elif a[j] == 2:
		if one == []:
			f = 1
			break
		else:
			v = one.pop()
			an.append(v)
			an.append((v[0], j + 1))
	elif a[j] == 3:
		if an != []:
			q = an[-1]
			an.append((p, q[1]))
			an.append((p, j + 1))
			p = p - 1
		elif one != []:
			q = one.pop()
			an.append(q)
			an.append((p, q[1]))
			an.append((p, j + 1))
			p = p - 1
		else:
			f = 1
			break
if f == 1:
	print(-1)
else:
	for v in one:
		an.append(v)
	print(len(an))
	for (u, v) in an:
		print(u, v)


n = int(input())
a = [0] + [int(x) for x in input().split()]
smallestEmptyRow = 1
twoStack = []
threeStack = []
ans = []
for col in range(1, n + 1):
	v = a[col]
	if v == 0:
		continue
	elif threeStack:
		r = threeStack.pop()
		ans.append([r, col])
		ans.append([smallestEmptyRow, col])
		if v == 2:
			twoStack.append(smallestEmptyRow)
		if v == 3:
			threeStack.append(smallestEmptyRow)
		smallestEmptyRow += 1
	elif v == 1:
		if twoStack:
			r = twoStack.pop()
			ans.append([r, col])
		else:
			ans.append([smallestEmptyRow, col])
			smallestEmptyRow += 1
	else:
		ans.append([smallestEmptyRow, col])
		if v == 2:
			twoStack.append(smallestEmptyRow)
		elif v == 3:
			threeStack.append(smallestEmptyRow)
		smallestEmptyRow += 1
if smallestEmptyRow > n + 1 or twoStack or threeStack:
	print(-1)
else:
	print(len(ans))
	ans2 = []
	for rc in ans:
		string = ' '.join([str(xx) for xx in rc])
		ans2.append(string)
	ans3 = '\n'.join(ans2)
	print(ans3)


def st(a, b):
	(a, b) = (n - a, b + 1)
	if not (1 <= a <= n and 1 <= b <= n):
		out()
	return str(a) + ' ' + str(b)

def out():
	print(-1)
	exit()
n = int(input())
u = list(map(int, input().split()))
on = []
on0 = 0
dn = 0
ans = []
ss = set()
for i in range(n - 1, -1, -1):
	if u[i] == 1:
		on.append(i)
	elif u[i] == 2:
		if len(on) == on0:
			out()
		ans.append(st(dn, i))
		ans.append(st(dn, on[-1]))
		ss.add(on[-1])
		on.pop()
		dn += 1
for i in range(on0, len(on)):
	ans.append(st(dn, on[i]))
	dn += 1
tr = -1
for i in range(n - 1, -1, -1):
	if u[i] != 3:
		if u[i] == 2 or (u[i] == 1 and i not in ss):
			tr = i
		continue
	if tr == -1:
		out()
	ans.append(st(dn, i))
	ans.append(st(dn, tr))
	dn += 1
	tr = i
if len(ans) > 2 * n:
	out()
print(len(ans))
print('\n'.join(ans))


from collections import defaultdict as dd
import sys
input = sys.stdin.readline
n = int(input())
arr = list(map(int, input().split()))
stac1 = []
stac2 = []
d = dd(list)
flag = 0
for i in range(n - 1, -1, -1):
	if arr[i] == 1:
		d[i] += [i]
		stac1 += [i]
	elif arr[i] == 2:
		if len(stac1) == 0:
			flag = 1
			break
		d[i] += [stac1[-1]]
		stac1.pop()
		stac2 += [i]
	elif arr[i] == 0:
		pass
	else:
		if len(stac2) == 0 and len(stac1) == 0:
			flag = 1
			break
		d[i] += [i]
		if len(stac2) != 0:
			d[stac2[-1]] += [i]
			stac2.pop()
		else:
			d[stac1[-1]] += [i]
			stac1.pop()
		stac2 += [i]
if flag == 1:
	print(-1)
else:
	co = 0
	for i in d:
		co += len(d[i])
	print(co)
	for i in d:
		for j in d[i]:
			print(j + 1, i + 1)


from math import *
from bisect import *
from collections import *
from random import *
from decimal import *
from itertools import *
import sys
input = sys.stdin.readline

def inp():
	return int(input())

def st():
	return input().rstrip('\n')

def lis():
	return list(map(int, input().split()))

def ma():
	return map(int, input().split())
n = inp()
a = lis()
ones = []
re = []
crow = 1
fl = 0
prev = [-1, -1]
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		continue
	if a[i] == 1:
		re.append([i, crow])
		ones.append([i, crow])
		crow += 1
	elif a[i] == 2:
		if len(ones) == 0:
			fl = 1
			break
		ex = ones.pop()
		re.append([i, ex[-1]])
		prev = [i, ex[-1]]
	else:
		if prev[0] == -1:
			if len(ones) == 0:
				fl = 1
				break
			prev = ones.pop()
		re.append([i, crow])
		re.append([prev[0], crow])
		crow += 1
		prev = [i, crow - 1]
if fl:
	print(-1)
else:
	print(len(re))
	for i in re:
		print(n - i[1] + 1, i[0] + 1)


import sys

def minp():
	return sys.stdin.readline().strip()

def mint():
	return int(minp())

def mints():
	return map(int, minp().split())

def solve():
	n = mint()
	a = list(mints())
	col = [0] * (n + 1)
	row_free = n
	col_prev = None
	ones = []
	twos = []
	ans = []
	ones_i = 0
	twos_i = 0
	for i in range(n - 1, -1, -1):
		v = a[i]
		if v == 1:
			if row_free < 1:
				print(-1)
				return
			ones.append((row_free, i + 1))
			ans.append((row_free, i + 1))
			row_free -= 1
		elif v == 2:
			if ones_i >= len(ones):
				print(-1)
				return
			ans.append((ones[ones_i][0], i + 1))
			twos.append((ones[ones_i][0], i + 1))
			ones_i += 1
		elif v == 3:
			ans.append((row_free, i + 1))
			if twos_i < len(twos):
				twos.append((row_free, i + 1))
				ans.append((row_free, twos[twos_i][1]))
				twos_i += 1
				row_free -= 1
			elif ones_i < len(ones):
				twos.append((row_free, i + 1))
				ans.append((row_free, ones[ones_i][1]))
				ones_i += 1
				row_free -= 1
			else:
				print(-1)
				return
	print(len(ans))
	for (x, y) in ans:
		print(x, y)
solve()


import math
import random
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
import threading
from collections import defaultdict
mod = 10 ** 9 + 7
mod1 = 998244353
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class TreeNode:

	def __init__(self, k, v):
		self.key = k
		self.value = v
		self.left = None
		self.right = None
		self.parent = None
		self.height = 1
		self.num_left = 1
		self.num_total = 1

class AvlTree:

	def __init__(self):
		self._tree = None

	def add(self, k, v):
		if not self._tree:
			self._tree = TreeNode(k, v)
			return
		node = self._add(k, v)
		if node:
			self._rebalance(node)

	def _add(self, k, v):
		node = self._tree
		while node:
			if k < node.key:
				if node.left:
					node = node.left
				else:
					node.left = TreeNode(k, v)
					node.left.parent = node
					return node.left
			elif node.key < k:
				if node.right:
					node = node.right
				else:
					node.right = TreeNode(k, v)
					node.right.parent = node
					return node.right
			else:
				node.value = v
				return

	@staticmethod
	def get_height(x):
		return x.height if x else 0

	@staticmethod
	def get_num_total(x):
		return x.num_total if x else 0

	def _rebalance(self, node):
		n = node
		while n:
			lh = self.get_height(n.left)
			rh = self.get_height(n.right)
			n.height = max(lh, rh) + 1
			balance_factor = lh - rh
			n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
			n.num_left = 1 + self.get_num_total(n.left)
			if balance_factor > 1:
				if self.get_height(n.left.left) < self.get_height(n.left.right):
					self._rotate_left(n.left)
				self._rotate_right(n)
			elif balance_factor < -1:
				if self.get_height(n.right.right) < self.get_height(n.right.left):
					self._rotate_right(n.right)
				self._rotate_left(n)
			else:
				n = n.parent

	def _remove_one(self, node):
		replacement = node.left or node.right
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = replacement
			else:
				node.parent.right = replacement
			replacement.parent = node.parent
			node.parent = None
		else:
			self._tree = replacement
			replacement.parent = None
		node.left = None
		node.right = None
		node.parent = None
		self._rebalance(replacement)

	def _remove_leaf(self, node):
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = None
			else:
				node.parent.right = None
			self._rebalance(node.parent)
		else:
			self._tree = None
		node.parent = None
		node.left = None
		node.right = None

	def remove(self, k):
		node = self._get_node(k)
		if not node:
			return
		if AvlTree._is_leaf(node):
			self._remove_leaf(node)
			return
		if node.left and node.right:
			nxt = AvlTree._get_next(node)
			node.key = nxt.key
			node.value = nxt.value
			if self._is_leaf(nxt):
				self._remove_leaf(nxt)
			else:
				self._remove_one(nxt)
			self._rebalance(node)
		else:
			self._remove_one(node)

	def get(self, k):
		node = self._get_node(k)
		return node.value if node else -1

	def _get_node(self, k):
		if not self._tree:
			return None
		node = self._tree
		while node:
			if k < node.key:
				node = node.left
			elif node.key < k:
				node = node.right
			else:
				return node
		return None

	def get_at(self, pos):
		x = pos + 1
		node = self._tree
		while node:
			if x < node.num_left:
				node = node.left
			elif node.num_left < x:
				x -= node.num_left
				node = node.right
			else:
				return (node.key, node.value)
		raise IndexError('Out of ranges')

	@staticmethod
	def _is_left(node):
		return node.parent.left and node.parent.left == node

	@staticmethod
	def _is_leaf(node):
		return node.left is None and node.right is None

	def _rotate_right(self, node):
		if not node.parent:
			self._tree = node.left
			node.left.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.left
			node.left.parent = node.parent
		else:
			node.parent.right = node.left
			node.left.parent = node.parent
		bk = node.left.right
		node.left.right = node
		node.parent = node.left
		node.left = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	def _rotate_left(self, node):
		if not node.parent:
			self._tree = node.right
			node.right.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.right
			node.right.parent = node.parent
		else:
			node.parent.right = node.right
			node.right.parent = node.parent
		bk = node.right.left
		node.right.left = node
		node.parent = node.right
		node.right = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	@staticmethod
	def _get_next(node):
		if not node.right:
			return node.parent
		n = node.right
		while n.left:
			n = n.left
		return n

class SegmentTree1:

	def __init__(self, data, default=300006, func=lambda a, b: min(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def powm(a, n, m):
	if a == 1 or n == 0:
		return 1
	if n % 2 == 0:
		s = powm(a, n // 2, m)
		return s * s % m
	else:
		return a * powm(a, n - 1, m) % m

def sort_list(list1, list2):
	zipped_pairs = zip(list2, list1)
	z = [x for (_, x) in sorted(zipped_pairs)]
	return z

def product(l):
	por = 1
	for i in range(len(l)):
		por *= l[i]
	return por

def binarySearchCount(arr, n, key):
	left = 0
	right = n - 1
	count = 0
	while left <= right:
		mid = int((right + left) / 2)
		if arr[mid] <= key:
			count = mid + 1
			left = mid + 1
		else:
			right = mid - 1
	return count

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def binary(x, length):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] > k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater

class TrieNode:

	def __init__(self):
		self.children = [None] * 26
		self.isEndOfWord = False

class Trie:

	def __init__(self):
		self.root = self.getNode()

	def getNode(self):
		return TrieNode()

	def _charToIndex(self, ch):
		return ord(ch) - ord('a')

	def insert(self, key):
		pCrawl = self.root
		length = len(key)
		for level in range(length):
			index = self._charToIndex(key[level])
			if not pCrawl.children[index]:
				pCrawl.children[index] = self.getNode()
			pCrawl = pCrawl.children[index]
		pCrawl.isEndOfWord = True

	def search(self, key):
		pCrawl = self.root
		length = len(key)
		for level in range(length):
			index = self._charToIndex(key[level])
			if not pCrawl.children[index]:
				return False
			pCrawl = pCrawl.children[index]
		return pCrawl != None and pCrawl.isEndOfWord

class Node:

	def __init__(self, data):
		self.data = data
		self.count = 0
		self.left = None
		self.right = None

class BinaryTrie:

	def __init__(self):
		self.root = Node(0)

	def insert(self, pre_xor):
		self.temp = self.root
		for i in range(31, -1, -1):
			val = pre_xor & 1 << i
			if val:
				if not self.temp.right:
					self.temp.right = Node(0)
				self.temp = self.temp.right
				self.temp.count += 1
			if not val:
				if not self.temp.left:
					self.temp.left = Node(0)
				self.temp = self.temp.left
				self.temp.count += 1
		self.temp.data = pre_xor

	def query(self, xor):
		self.temp = self.root
		for i in range(31, -1, -1):
			val = xor & 1 << i
			if not val:
				if self.temp.left and self.temp.left.count > 0:
					self.temp = self.temp.left
				elif self.temp.right:
					self.temp = self.temp.right
			elif self.temp.right and self.temp.right.count > 0:
				self.temp = self.temp.right
			elif self.temp.left:
				self.temp = self.temp.left
			self.temp.count -= 1
		return xor ^ self.temp.data
n = int(input())
l = list(map(int, input().split()))
ind = []
c = 0
rw = 0
rw1 = 0
ind1 = []
for i in range(n):
	if l[i] == 0:
		continue
	if l[i] == 1:
		c += 1
		ind.append(i)
	if l[i] == 3:
		rw += 1
	if l[i] == 2:
		rw1 += 1
	ind1.append(i)
ind1.sort()
ind.sort()
ans = []
r = 0
r1 = 0
t = 1
done = defaultdict(int)
for i in range(n):
	if l[i] == 1 or l[i] == 0:
		continue
	elif l[i] == 3:
		if r == len(ind1):
			print(-1)
			sys.exit(0)
		while ind1[r] <= i or done[ind1[r]] == 1:
			r += 1
			if r == len(ind1):
				print(-1)
				sys.exit(0)
		if l[ind1[r]] == 1:
			ans.append((i + 1, t))
			ans.append((ind1[r] + 1, t))
			ans.append((ind1[r] + 1, t + 1))
			done[ind1[r]] = 1
		else:
			ans.append((i + 1, t))
			ans.append((ind1[r] + 1, t))
			done[ind1[r]] = 1
			t -= 1
		r += 1
		t += 2
t1 = t
for i in range(n):
	if l[i] == 2:
		if r1 == len(ind):
			print(-1)
			sys.exit(0)
		while ind[r1] <= i or done[ind[r1]] == 1:
			r1 += 1
			if r1 == len(ind):
				print(-1)
				sys.exit(0)
		ans.append((i + 1, t1))
		ans.append((ind[r1] + 1, t1))
		done[ind[r1]] = 1
		t1 += 1
		r1 += 1
for i in range(len(ind)):
	if done[ind[i]] == 0:
		ans.append((ind[i] + 1, t1))
		t1 += 1
print(len(ans))
for i in range(len(ans)):
	print(ans[i][1], ans[i][0])


import sys
(n, *aaa) = map(int, sys.stdin.buffer.read().split())
ans = []
i = 1
required2 = set()
required3 = set()
for (j, a) in enumerate(aaa, start=1):
	if a == 0:
		continue
	elif a == 1:
		if required2:
			p = required2.pop()
			ans.append('{} {}'.format(p, j))
		elif required3:
			p = required3.pop()
			ans.append('{} {}'.format(p, j))
			ans.append('{} {}'.format(i, j))
			i += 1
		else:
			ans.append('{} {}'.format(i, j))
			i += 1
	elif a == 2:
		if required3:
			p = required3.pop()
			ans.append('{} {}'.format(p, j))
		ans.append('{} {}'.format(i, j))
		required2.add(i)
		i += 1
	elif a == 3:
		if required3:
			p = required3.pop()
			ans.append('{} {}'.format(p, j))
		ans.append('{} {}'.format(i, j))
		required3.add(i)
		i += 1
	else:
		raise AssertionError
if len(required2) > 0 or len(required3) > 0:
	print(-1)
else:
	print(len(ans))
	print('\n'.join(ans))


import sys
input = sys.stdin.readline
from collections import defaultdict as dc
from collections import Counter
from bisect import bisect_right, bisect_left, bisect
import math
from operator import itemgetter
from heapq import heapify, heappop, heappush
n = int(input())
l = list(map(int, input().split()))
s = []
p = [-1] * n
x = dc(int)
if l[-1] in [2, 3]:
	print(-1)
else:
	q = 0
	for i in range(n - 1, -1, -1):
		if l[i] == 1:
			p[i] = i
			s.append(i)
		elif l[i] == 2:
			if s:
				t = s.pop(-1)
				x[t] = 1
				p[i] = t
	t = -1
	for i in range(n - 1, -1, -1):
		if l[i] == 1 and x[i] == 0 or l[i] == 2:
			if t == -1:
				t = i
		elif l[i] == 3:
			p[i] = t
			t = i
	f = 1
	for i in range(n):
		if l[i] != 0 and p[i] == -1:
			f = 0
			break
	if f == 0:
		print(-1)
	else:
		r = 1
		c = 0
		x = dc(int)
		s = []
		for i in range(n):
			if l[i] == 3:
				if l[p[i]] == 3:
					if x[i] == 0:
						c += 3
						s.append([r, i + 1])
						s.append([r, p[i] + 1])
						s.append([r + 1, p[i] + 1])
						x[i] = 1
						x[p[i]] = 1
						r += 1
					else:
						c += 2
						s.append([r, p[i] + 1])
						s.append([r + 1, p[i] + 1])
						x[p[i]] = 1
						r += 1
				elif x[i] == 0:
					c += 3
					s.append([r, i + 1])
					s.append([r, p[i] + 1])
					s.append([r + 1, p[i] + 1])
					x[i] = 1
					x[p[i]] = 1
					if l[p[i]] == 2:
						c += 1
						s.append([r + 1, p[p[i]] + 1])
						x[p[p[i]]] = 1
					r += 1
				else:
					c += 2
					s.append([r, p[i] + 1])
					s.append([r + 1, p[i] + 1])
					x[p[i]] = 1
					if l[p[i]] == 2:
						c += 1
						s.append([r + 1, p[p[i]] + 1])
						x[p[p[i]]] = 1
					r += 1
		if c > 0:
			r += 1
		for i in range(n):
			if l[i] == 1:
				if x[i] == 0:
					c += 1
					s.append([r, i + 1])
					x[i] = 1
					r += 1
			elif l[i] == 2:
				if x[i] == 0:
					c += 2
					s.append([r, i + 1])
					s.append([r, p[i] + 1])
					x[i] = 1
					x[p[i]] = 1
					r += 1
		print(c)
		if c > 0:
			for i in s:
				print(*i)


import sys
n = int(input())
A = list(map(int, input().split()))
A2 = []
A3 = []
for (i, ai) in enumerate(A, 1):
	if ai != 0:
		A3 += [i]
	if ai == 1:
		A2 += [i]
p2 = 0
p3 = 0
lenA2 = len(A2)
lenA3 = len(A3)
ans = []
Y = [-1 for i in range(n + 1)]
y = 1
for (x, ai) in enumerate(A, 1):
	if ai == 0:
		continue
	if ai == 3:
		if p3 == lenA3:
			print(-1)
			sys.exit()
		i = A3[p3]
		while i <= x or Y[i] != -1:
			p3 += 1
			if p3 == lenA3:
				print(-1)
				sys.exit()
			i = A3[p3]
		if Y[x] == -1:
			ans += [str(y) + ' ' + str(x)]
			ans += [str(y) + ' ' + str(i)]
			ans += [str(y + 1) + ' ' + str(i)]
			Y[i] = y + 1
			y += 2
		else:
			ans += [str(Y[x]) + ' ' + str(i)]
			ans += [str(y) + ' ' + str(i)]
			Y[i] = y
			y += 1
	elif ai == 2:
		if p2 == lenA2:
			print(-1)
			sys.exit()
		i = A2[p2]
		while i <= x or Y[i] != -1:
			p2 += 1
			if p2 == lenA2:
				print(-1)
				sys.exit()
			i = A2[p2]
		if Y[x] == -1:
			ans += [str(y) + ' ' + str(x)]
			ans += [str(y) + ' ' + str(i)]
			Y[i] = y
			y += 1
		else:
			ans += [str(Y[x]) + ' ' + str(i)]
			Y[i] = y
	elif ai == 1 and Y[x] == -1:
		ans += [str(y) + ' ' + str(x)]
		Y[x] = y
		y += 1
print(len(ans))
for a in ans:
	print(a)


from sys import stdin

class Input:

	def __init__(self):
		self.it = iter(stdin.readlines())

	def line(self):
		return next(self.it).strip()

	def array(self, sep=' ', cast=int):
		return list(map(cast, self.line().split(sep=sep)))

def testcases(unknown=False):
	inpt = Input()

	def testcases_decorator(func):
		(cases,) = [float('Inf')] if unknown else inpt.array()
		while cases > 0:
			try:
				func(inpt)
				cases -= 1
			except StopIteration:
				break
	return testcases_decorator

@testcases(unknown=True)
def solve(inpt):
	(n,) = inpt.array()
	a = inpt.array()
	row = [None] * n
	s = [[], [], [], []]
	r = n
	tp = 0
	possible = True
	targets = []
	for c in range(n - 1, -1, -1):
		if a[c] == 0:
			continue
		elif a[c] == 1:
			if not r:
				possible = False
				break
			row[c] = r
			s[1].append(c)
			targets.append((r, c + 1))
			r -= 1
		elif a[c] == 2:
			if not s[1]:
				possible = False
				break
			d = s[1].pop()
			row[c] = row[d]
			targets.append((row[c], c + 1))
			s[2].append(c)
		else:
			ok = False
			for i in range(3, 0, -1):
				if not s[i]:
					continue
				if not r:
					continue
				ok = True
				d = s[i].pop()
				row[c] = r
				targets.append((r, c + 1))
				targets.append((r, d + 1))
				s[3].append(c)
				r -= 1
				break
			if not ok:
				possible = False
				break
	if possible:
		print(len(targets))
		for t in targets:
			print(*t)
	else:
		print(-1)


import sys
input = sys.stdin.readline
n = int(input())
A = list(map(int, input().split()))
ONE = []
TWO = []
THREE = []
for i in range(n):
	if A[i] == 1:
		ONE.append(i)
	elif A[i] == 2:
		TWO.append(i)
	elif A[i] == 3:
		THREE.append(i)
one = 0
two = 0
three = 0
twonouse = 0
threenouse = 0
LONE = len(ONE)
LTWO = len(TWO)
LTHREE = len(THREE)
ONE.append(1 << 30)
TWO.append(1 << 30)
THREE.append(1 << 30)
height = n
USE = [[] for i in range(n)]
while one < LONE or two < LTWO or three < LTHREE:
	if ONE[one] < TWO[two] and ONE[one] < THREE[three]:
		USE[ONE[one]].append(height)
		height -= 1
		one += 1
	elif TWO[two] < ONE[one] and TWO[two] < THREE[three]:
		USE[TWO[two]].append(height)
		if one == LONE:
			print(-1)
			sys.exit()
		USE[ONE[one]].append(height)
		height -= 1
		two += 1
		one += 1
	else:
		while TWO[twonouse] <= THREE[three]:
			twonouse += 1
		while THREE[threenouse] <= THREE[three]:
			threenouse += 1
		if TWO[twonouse] < THREE[threenouse] and twonouse < LTWO:
			USE[TWO[twonouse]].append(height)
			USE[THREE[three]].append(height)
			three += 1
			twonouse += 1
			height -= 1
		elif THREE[threenouse] < TWO[twonouse] and threenouse < LTHREE:
			USE[THREE[threenouse]].append(height)
			USE[THREE[three]].append(height)
			three += 1
			threenouse += 1
			height -= 1
		elif one < LONE:
			USE[ONE[one]].append(height)
			USE[ONE[one]].append(height - 1)
			USE[THREE[three]].append(height)
			three += 1
			one += 1
			height -= 2
		else:
			print(-1)
			sys.exit()
ANS = []
for i in range(n):
	for j in USE[i]:
		ANS.append((n + 1 - j, i + 1))
print(len(ANS))
for (x, y) in ANS:
	print(x, y)


from collections import defaultdict as dd
import sys
input = sys.stdin.readline
n = int(input())
l = list(map(int, input().split()))
ho = dd(int)
one = []
un = []
up = 1
ans = []
lol = 0
for i in range(n):
	if l[i] == 1:
		one.append(i)
	if l[i]:
		un.append(i)
un.reverse()
one.reverse()
for i in range(n):
	if l[i] == 0:
		continue
	if l[i] == 1 and ho[i] == 0:
		if up == n + 1:
			lol = 1
			break
		ans.append((up, i + 1))
		up += 1
		ho[i] = 1
	elif l[i] == 1 and ho[i] == 1:
		up += 1
	if l[i] == 2:
		if ho[i] == 0:
			if up == n + 1:
				lol = 1
				break
			ans.append((up, i + 1))
			ho[i] = 1
		if not one or up == n + 1:
			lol = 1
			break
		while one and ho[one[-1]] == 1:
			one.pop()
		if one:
			ind = one.pop()
			ho[ind] = 1
			ans.append((up, ind + 1))
			up += 1
		else:
			lol = 1
			break
	if l[i] == 3:
		if ho[i] == 0:
			if up == n + 1:
				lol = 1
				break
			ans.append((up, i + 1))
			ho[i] = 1
		if not un or up == n + 1:
			lol = 1
			break
		while un and ho[un[-1]] == 1:
			un.pop()
		if un:
			ind = un.pop()
			ho[ind] = 1
			ans.append((up, ind + 1))
			up += 1
			if up == n + 1:
				lol = 1
				break
			ans.append((up, ind + 1))
		else:
			lol = 1
			break
if lol:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


n = int(input())
a = list(map(int, input().split()))
st1 = 0
st2 = 0
st3 = 0
one = []
two = []
three = []
c = 0
k = 1
l = 0
g1 = []
g2 = []
for j in range(n):
	if a[j] == 1:
		one.append(j)
		st1 = st1 + 1
	if a[j] == 2:
		two.append(j)
		st2 = st2 + 1
	if a[j] == 3:
		three.append(j)
		st3 = st3 + 1
g = [0] * n
if st3 > 0:
	for j in range(st3 - 1):
		g1.append(k)
		g2.append(three[j] + 1)
		g1.append(k)
		g2.append(three[j + 1] + 1)
		k = k + 1
		l = l + 2
	if st2 > 0:
		if two[st2 - 1] > three[st3 - 1]:
			g1.append(k)
			g2.append(three[st3 - 1] + 1)
			g1.append(k)
			g2.append(two[st2 - 1] + 1)
			k = k + 1
			l = l + 2
		elif st1 > 0:
			if one[st1 - 1] > three[st3 - 1]:
				g1.append(k)
				g2.append(three[st3 - 1] + 1)
				g1.append(k)
				g2.append(one[st1 - 1] + 1)
				k = k + 1
				l = l + 2
				g1.append(k)
				g2.append(one[st1 - 1] + 1)
				k = k + 1
				l = l + 1
				g[one[st1 - 1]] = -1
				st1 = st1 - 1
			else:
				c = c + 1
		else:
			c = c + 1
	elif st1 > 0:
		if one[st1 - 1] > three[st3 - 1]:
			g1.append(k)
			g2.append(three[st3 - 1] + 1)
			g1.append(k)
			g2.append(one[st1 - 1] + 1)
			k = k + 1
			l = l + 2
			g1.append(k)
			g2.append(one[st1 - 1] + 1)
			k = k + 1
			l = l + 1
			g[one[st1 - 1]] = -1
			st1 = st1 - 1
		else:
			c = c + 1
	else:
		c = c + 1
on = 0
tw = 0
for j in range(n):
	if a[j] == 2:
		if on == st1:
			c = c + 1
		elif on < st1:
			if two[tw] < one[on]:
				g1.append(k)
				g2.append(j + 1)
				g1.append(k)
				g2.append(one[on] + 1)
				on = on + 1
				tw = tw + 1
				k = k + 1
				g[one[on - 1]] = -1
				l = l + 2
	elif a[j] == 1:
		if g[j] == 0:
			g1.append(k)
			g2.append(j + 1)
			k = k + 1
			on = on + 1
			l = l + 1
			g[j] = -1
if c > 0:
	print('-1')
else:
	print(l)
	for j in range(l):
		print(g1[j], g2[j])


n = int(input())
l = list(map(int, input().split()))
ones = []
ans = []
lastthree = (-1, -1)
h = 1
f = 0
for i in range(n - 1, -1, -1):
	if l[i] == 1:
		ones.append((i, h))
		ans.append((i, h))
		h += 1
	if l[i] == 2:
		if len(ones) == 0:
			print(-1)
			f = 1
			break
		else:
			t = ones[-1]
			ones.pop()
			ans.append((i, t[1]))
			lastthree = (i, t[1])
	if l[i] == 3:
		if lastthree[0] == -1:
			if len(ones) == 0:
				print(-1)
				f = 1
				break
			else:
				lastthree = ones[-1]
				ones.pop()
		ans.append((i, h))
		ans.append((lastthree[0], h))
		lastthree = (i, h)
		h += 1
if f == 0:
	print(len(ans))
	for i in ans:
		print(n - i[1] + 1, i[0] + 1)


n = int(input())
a = list(map(int, input().split()))
col = [[] for i in range(n)]
used = [0] * n
ind = []
val = []
cur = 0
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		continue
	if a[i] == 1 and len(val) == 0:
		val.append(1)
		ind.append(i)
		used[i] = 1
		col[i].append(cur)
		cur += 1
	elif a[i] == 3 and len(val) > 0:
		if 3 not in val:
			val.append(3)
		col[ind[-1]].append(cur)
		col[i].append(cur)
		ind.append(i)
		used[i] = 1
		cur += 1
	elif a[i] == 2 and len(val) == 1:
		val.append(2)
		col[i].append(cur - 1)
		ind.append(i)
		used[i] = 1
stack = []
for i in range(n):
	if a[i] == 0:
		used[i] = 1
	a[i] = a[i] * (1 - used[i])
for i in range(n):
	if a[i] == 1:
		col[i] += [cur]
		used[i] = 1
		if len(stack):
			col[stack[-1]].append(cur)
			used[stack[-1]] = 1
			stack.pop(-1)
		cur += 1
	elif a[i] == 2:
		stack.append(i)
if sum(used) < n:
	print(-1)
	exit(0)
ans = 0
for i in col:
	ans += len(i)
print(ans)
for i in range(n):
	for j in col[i]:
		print(n - j, i + 1)


from sys import stdin
input = stdin.readline
import sys
n = int(input())
l = list(map(int, input().split()))
if l[-1] > 1:
	print(-1)
	sys.exit(0)
next_nonzero = [1000000] * n
next_nonzero[n - 1] = n
best = n
for i in range(n - 1):
	j = n - 2 - i
	if l[j + 1] > 0:
		best = j + 1
	next_nonzero[j] = best
col = [[] for i in range(n)]
for i in range(n):
	if l[i] > 0:
		col[i].append(n - 1 - i)
for i in range(n):
	if l[i] == 3:
		if next_nonzero[i] == n:
			print(-1)
			sys.exit(0)
		else:
			col[next_nonzero[i]].append(n - i - 1)
jedynki = []
ile_jedynek = 0
ind = 0
for i in range(n):
	j = n - 1 - i
	if l[j] == 1 and len(col[j]) == 1:
		jedynki.append(j)
		ile_jedynek += 1
	if l[j] == 2:
		if ind >= ile_jedynek:
			print(-1)
			sys.exit(0)
		kolu = jedynki[ind]
		ind += 1
		col[kolu].pop(0)
		col[kolu].append(n - j - 1)
wyn = 0
for i in col:
	wyn += len(i)
print(wyn)
for i in range(n):
	for row in col[i]:
		print(n - row, i + 1)


def main():
	n = int(input())
	a = list(map(int, input().split()))
	one_col_targets = []
	three_target = -1
	targets = []
	current_row = 0
	ones = 0
	threes_good = False
	oct_z = 0
	for i in range(n - 1, -1, -1):
		if a[i] == 0:
			continue
		elif a[i] == 1:
			ones += 1
			one_col_targets.append((i, current_row))
			targets.append((i + 1, current_row + 1))
			current_row += 1
		elif a[i] == 2:
			if ones:
				ones -= 1
			else:
				print(-1)
				return
			threes_good = True
			one_reflect = one_col_targets[oct_z]
			oct_z += 1
			targets.append((i + 1, one_reflect[1] + 1))
			three_target = i
		else:
			if not threes_good:
				if ones:
					ones -= 1
					threes_good = True
				else:
					print(-1)
					return
			if three_target == -1:
				first_one = one_col_targets[oct_z]
				oct_z += 1
				three_target = first_one[0]
			targets.append((three_target + 1, current_row + 1))
			targets.append((i + 1, current_row + 1))
			three_target = i
			current_row += 1
	print(len(targets))
	for j in range(len(targets)):
		print(n + 1 - targets[j][1], targets[j][0])
main()


import sys, math
input = sys.stdin.readline
from collections import deque
n = int(input())
l = list(map(int, input().split()))
d = {}
nextBottomRow = n - 1
isPossible = True
ans = []
for i in range(n - 1, -1, -1):
	if l[i] == 0:
		continue
	elif l[i] == 1:
		try:
			d[1].append([nextBottomRow, i])
			ans.append([nextBottomRow, i])
		except:
			q = deque()
			q.append([nextBottomRow, i])
			d[1] = q
			ans.append([nextBottomRow, i])
		nextBottomRow -= 1
	elif l[i] == 2:
		try:
			a = d[1]
			current = a.popleft()
			x = [current[0], i]
			ans.append(x)
			try:
				d[2].append(x)
			except:
				q = deque()
				q.append(x)
				d[2] = q
		except:
			isPossible = False
			break
	elif l[i] == 3:
		try:
			a = d[2]
			current = a.popleft()
			x1 = [nextBottomRow, i]
			x2 = [nextBottomRow, current[1]]
			ans.append(x1)
			ans.append(x2)
			try:
				d[2].append(x1)
			except:
				q = deque()
				q.append(x1)
				d[2] = q
			nextBottomRow -= 1
		except:
			try:
				a = d[1]
				current = a.popleft()
				x1 = [nextBottomRow, i]
				x2 = [nextBottomRow, current[1]]
				ans.append(x1)
				ans.append(x2)
				try:
					d[2].append(x1)
				except:
					q = deque()
					q.append(x1)
					d[2] = q
				nextBottomRow -= 1
			except:
				isPossible = False
				break
if isPossible == False:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(i[0] + 1, i[1] + 1)


import io
import os
from collections import Counter, defaultdict

def solve(N, A):
	ans = []
	colToLowRow = {}
	canConnect = defaultdict(set)
	r = N - 1
	for c in range(N)[::-1]:
		if A[c] == 1:
			ans.append((r, c))
			colToLowRow[c] = r
			r -= 1
		elif A[c] == 2:
			if not canConnect[1]:
				return -1
			c2 = next(iter(canConnect[1]))
			r2 = colToLowRow[c2]
			canConnect[1].remove(c2)
			ans.append((r2, c))
			colToLowRow[c] = r
		elif A[c] == 3:
			for k in [3, 2, 1]:
				if canConnect[k]:
					c2 = next(iter(canConnect[k]))
					r2 = colToLowRow[c2]
					canConnect[k].remove(c2)
					ans.append((r, c))
					ans.append((r, c2))
					r -= 1
					colToLowRow[c] = r
					break
			else:
				return -1
		canConnect[A[c]].add(c)
	if not all((0 <= r < N for (r, c) in ans)):
		return -1
	if False:
		assert all((0 <= r < N and 0 <= c < N for (r, c) in ans))
		assert all((v <= 2 for v in Counter((r for (r, c) in ans)).values()))
		assert all((v <= 2 for v in Counter((c for (r, c) in ans)).values()))
		assert len(ans) <= 2 * N
	return str(len(ans)) + '\n' + '\n'.join((str(x + 1) + ' ' + str(y + 1) for (x, y) in ans))
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N,) = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
ans = solve(N, A)
print(ans)


import sys
import math

def II():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def MI():
	return map(int, sys.stdin.readline().split())

def SI():
	return sys.stdin.readline().strip()
n = II()
a = LI()
rows = [0] * n
columns = [0] * n
q = []
q2 = []
l2 = 0
l = 0
row = n - 1
ans = []
boo = True
for i in range(n - 1, -1, -1):
	if row == -1 and a[i] != 0:
		boo = False
		break
	if a[i] == 1:
		q.append([row, i])
		ans.append([row + 1, i + 1])
		columns[i] += 1
		rows[row] += 1
		row -= 1
	elif a[i] == 2:
		if l == len(q):
			boo = False
			break
		x = q[l][0]
		l += 1
		rows[x] += 1
		columns[i] += 1
		q2.append([x, i])
		ans.append([x + 1, i + 1])
		row -= 1
	elif a[i] == 3:
		if l == len(q) and l2 == len(q2):
			boo = False
			break
		if l2 != len(q2):
			x = q2[l2][1]
			l2 += 1
		else:
			x = q[l][1]
			l += 1
		rows[row] += 2
		columns[i] += 1
		columns[x] += 1
		ans.append([row + 1, x + 1])
		ans.append([row + 1, i + 1])
		q2.append([row, i])
		row -= 1
for i in range(n):
	if rows[i] > 2:
		boo = False
		break
for i in range(n):
	if columns[i] > 2:
		boo = False
		break
if not boo:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


from collections import deque

def noans():
	print(-1)
	exit()
n = int(input())
a = list(map(int, input().split()))
aa = [-1] * n
bb = [-1] * n
q1 = deque()
q2 = deque()
ans = []
m = n
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		ans.append([m, i + 1])
		q1.append(i)
		aa[i] = m
		m -= 1
	elif a[i] == 2:
		if q1:
			x = q1.popleft()
			ans.append([aa[x], i + 1])
			q2.append(i)
			bb[i] = m
			m -= 1
		else:
			noans()
	elif a[i] == 3:
		if q2:
			x = q2.popleft()
			ans.append([m, i + 1])
			ans.append([m, x + 1])
			q2.append(i)
			m -= 1
		elif q1:
			x = q1.popleft()
			ans.append([m, i + 1])
			ans.append([m, x + 1])
			q2.append(i)
			m -= 1
		else:
			noans()
t = len(ans)
print(t)
for ans0 in ans:
	print(*ans0)


import bisect
import sys
from collections import defaultdict
n = int(input())
a = list(map(int, input().split()))
threes = []
twos = []
out = []
for i in range(n):
	if a[i] == 1:
		if twos:
			p = twos.pop()
			out.append((p, i))
		elif threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
	elif a[i] == 2:
		if threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
		twos.append(i)
	elif a[i] == 3:
		if threes:
			p = threes.pop()
			out.append((p, i))
			out.append((i, i))
		else:
			out.append((i, i))
		threes.append(i)
if twos or threes:
	print(-1)
else:
	print(len(out))
	print('\n'.join(map(lambda x: str(x[0] + 1) + ' ' + str(x[1] + 1), out)))


n = int(input())
lst = list(map(int, input().split()))
ans = []
nsp = 0
edpos = []
twpos = []
for i in range(n - 1, -1, -1):
	if lst[i] == 1:
		ans.append([i, nsp])
		edpos.append([i, nsp])
		nsp += 1
	if lst[i] == 2:
		if len(edpos):
			k = edpos[-1]
			edpos.pop()
			ans.append([i, k[1]])
			twpos.append([i, k[1]])
		else:
			print(-1)
			exit()
	if lst[i] == 3:
		if len(twpos):
			k = twpos[-1]
			twpos.pop()
			ans.append([i, nsp])
			ans.append([k[0], nsp])
			twpos.append([i, nsp])
			nsp += 1
		elif len(edpos):
			k = edpos[-1]
			edpos.pop()
			ans.append([i, nsp])
			ans.append([k[0], nsp])
			twpos.append([i, nsp])
			nsp += 1
		else:
			print(-1)
			exit()
print(len(ans))
for i in ans:
	print(n - i[1], i[0] + 1)


from collections import deque
n = int(input())
ls = list(map(int, input().split()))
targets = []
singleRow = n - 1
singleBounce = deque()
doubleBounce = deque()
f = True
for i in range(n - 1, -1, -1):
	if ls[i] == 0:
		continue
	if ls[i] == 1:
		targets.append([singleRow + 1, i + 1])
		singleBounce.append([singleRow, i])
		singleRow -= 1
	elif ls[i] == 2:
		if len(singleBounce) != 0:
			elem = singleBounce.popleft()
			targets.append([elem[0] + 1, i + 1])
			doubleBounce.append([elem[0], i])
		else:
			f = False
			break
	elif ls[i] == 3:
		if len(singleBounce) != 0 or len(doubleBounce) != 0:
			if len(doubleBounce) != 0:
				elem = doubleBounce.popleft()
			else:
				elem = singleBounce.popleft()
			new = [singleRow + 1, i + 1]
			doubleBounce.append([singleRow, i])
			upper = [singleRow + 1, elem[1] + 1]
			singleRow -= 1
			targets.append(new)
			targets.append(upper)
		else:
			f = False
			break
if not f:
	print(-1)
else:
	print(len(targets))
	for i in targets:
		print(*i)


from sys import stdin
import sys
n = int(stdin.readline())
a = list(map(int, stdin.readline().split()))
one = []
ttt = []
ans = []
for i in range(n, 0, -1):
	now = a[i - 1]
	if now == 0:
		continue
	elif now == 1:
		ans.append((i, i))
		one.append(i)
	elif now == 2:
		if len(one) == 0:
			print(-1)
			sys.exit()
		ans.append((one[-1], i))
		del one[-1]
		ttt.append(i)
	elif now == 3:
		if len(ttt) == 0:
			if len(one) == 0:
				print(-1)
				sys.exit()
			ans.append((i, i))
			ans.append((i, one[-1]))
			del one[-1]
			ttt.append(i)
		else:
			ans.append((i, i))
			ans.append((i, ttt[-1]))
			del ttt[-1]
			ttt.append(i)
print(len(ans))
for i in ans:
	print(*i)


from collections import deque
from collections import OrderedDict
import math
import sys
import os
import threading
import bisect
import operator
import queue
import heapq
from atexit import register
from io import BytesIO
import io
from sys import stdin, stdout
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Pair:

	def __init__(self, first, second):
		self.first = first
		self.second = second

	def getFirst(self):
		return self.first

	def getSecond(self):
		return self.second
n = int(input())
ar = list(map(int, input().split()))
for i in range(n - 1, -1, -1):
	if ar[i] != 0:
		if ar[i] == 2 or ar[i] == 3:
			print(-1)
			sys.exit(0)
		else:
			break
answer = []
countOne = deque()
countTwoTree = deque()
idx = n
idy = n
for i in range(n - 1, -1, -1):
	if ar[i] == 1:
		countOne.append(Pair(idx, idy))
		answer.append(Pair(idx, idy))
	elif ar[i] == 2:
		countTwoTree.append(Pair(idx, idy))
		if len(countOne) == 0:
			print(-1)
			sys.exit(0)
		else:
			oneX = countOne.popleft()
			answer.append(Pair(oneX.getFirst(), idy))
	elif ar[i] == 3:
		answer.append(Pair(idx, idy))
		if len(countTwoTree) != 0:
			oneY = countTwoTree.popleft()
		else:
			oneY = countOne.popleft()
		answer.append(Pair(idx, oneY.getSecond()))
		countTwoTree.append(Pair(idx, idy))
	idx -= 1
	idy -= 1
print(len(answer))
for i in range(len(answer)):
	print(answer[i].getFirst(), answer[i].getSecond())


import sys, os
import heapq, functools, collections
import math, random
from collections import Counter, defaultdict

def solve_(lst):
	cnt = [0, 0, 0, 0]
	arr = [[], [], [], []]
	single_1 = []
	single_2 = []
	single_3 = []
	pairs_2 = []
	pairs_3 = []
	pairs_3_above = []
	i = len(lst)
	for a in lst[::-1]:
		i -= 1
		cnt[a] += 1
		if a == 1:
			single_1.append(i)
		if a == 2:
			if single_1:
				pairs_2.append((i, single_1.pop()))
				single_2.append(i)
			else:
				print(-1)
				return
		if a == 3:
			if single_2:
				pairs_3_above.append((i, single_2.pop()))
				single_2.append(i)
			elif single_1:
				pairs_3.append((i, single_1.pop()))
				single_2.append(i)
			else:
				print(-1)
				return
	cur = 0
	res = []
	for (a, b) in pairs_3_above[::-1]:
		cur += 1
		res.append((a, cur))
		res.append((b, cur))
	for (a, b) in pairs_2:
		cur += 1
		res.append((a, cur))
		res.append((b, cur))
	for (a, b) in pairs_3:
		cur += 1
		res.append((a, cur))
		res.append((b, cur))
		cur += 1
		res.append((b, cur))
	for a in single_1:
		cur += 1
		res.append((a, cur))
	if res:
		c_check_x = Counter()
		c_check_y = Counter()
		for (a, b) in res:
			c_check_x[a] += 1
			c_check_y[b] += 1
		assert max(c_check_x.values()) <= 2
		assert max(c_check_y.values()) <= 2
		assert max(c_check_x) <= len(lst)
		assert max(c_check_y) <= len(lst)
	cout = [str(len(res))]
	for (a, b) in res:
		cout.append('{} {}'.format(b, a + 1))
	print('\n'.join(cout))
	return

def console(*args):
	print('\x1b[36m', *args, '\x1b[0m', file=sys.stderr)
	pass
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

	def console(*args):
		pass

def solve(*args):
	console('----- solving ------')
	console('----- ------- ------')
	return solve_(*args)
if True:
	inp = iter(sys.stdin.buffer.readlines())
	input = lambda : next(inp)
else:
	input = sys.stdin.buffer.readline
for case_num in [1]:
	_ = int(input())
	lst = list(map(int, input().split()))
	res = solve(lst)


import sys
input = sys.stdin.readline

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input()
	return list(s[:len(s) - 1])

def invr():
	return map(int, input().split())

def solution():
	n = inp()
	a = inlt()
	ans = solve(n, a)
	if ans == -1:
		print(-1)
	else:
		print(len(ans))
		for (a, b) in ans:
			print(a, b)

def solve(n, s):
	ans = []
	a1 = n
	ones = []
	twos = []
	for i in range(n, 0, -1):
		c = s[i - 1]
		if c == 0:
			continue
		if c == 1:
			ans.append((a1, i))
			a1 -= 1
			ones.append(len(ans) - 1)
		elif c == 2:
			if not ones:
				return -1
			ans.append((ans[ones.pop()][0], i))
			twos.append(len(ans) - 1)
		else:
			if twos:
				(r, c) = ans[twos.pop()]
			elif ones:
				(r, c) = ans[ones.pop()]
			else:
				return -1
			ans.append((a1, i))
			twos.append(len(ans) - 1)
			ans.append((a1, c))
			a1 -= 1
	return ans
solution()


def die():
	print(-1)
	exit(0)
ones = []
ans = []
H = 1
lastThree = (-1, -1)
n = int(input())
arr = list(map(int, input().split(' ')))
for i in range(n - 1, -1, -1):
	if arr[i] == 0:
		continue
	elif arr[i] == 1:
		ones.append((i, H))
		ans.append((i, H))
		H += 1
	elif arr[i] == 2:
		if len(ones) == 0:
			die()
		T = ones[-1]
		ones.pop()
		ans.append((i, T[1]))
		lastThree = (i, T[1])
	elif arr[i] == 3:
		if lastThree[0] == -1:
			if len(ones) == 0:
				die()
			else:
				lastThree = ones[-1]
				ones.pop()
		ans.append((i, H))
		ans.append((lastThree[0], H))
		lastThree = (i, H)
		H += 1
print(len(ans))
for ii in ans:
	print(n - ii[1] + 1, end=' ')
	print(ii[0] + 1)


lens = int(input())
one = []
two = []
ans = []
arr = input().split()
H = 0
for i in range(lens - 1, -1, -1):
	if arr[i] == '0':
		continue
	elif arr[i] == '1':
		ans += [[i, H]]
		one += [[i, H]]
		H += 1
	elif arr[i] == '2':
		if len(one) == 0:
			print(-1)
			exit()
		ans += [[i, one[-1][1]]]
		two = [i, one[-1][1]]
		one.pop()
	elif arr[i] == '3':
		if len(two) == 0:
			if len(one) == 0:
				print(-1)
				exit()
			else:
				two = one[-1]
				one.pop()
		ans += [[two[0], H]]
		ans += [[i, H]]
		two = [i, H]
		H += 1
print(len(ans))
for k in ans:
	print(lens - int(k[1]), end=' ')
	print(k[0] + 1)


import sys

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c for j in range(b)] for i in range(a)]

def list3d(a, b, c, d):
	return [[[d for k in range(c)] for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e for l in range(d)] for k in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** (-10)
N = INT()
A = LIST()
started = False
currow = N
has1 = []
ans = []
prevcol = -1
for i in range(N - 1, -1, -1):
	if A[i] == 1:
		ans.append((currow, i + 1))
		has1.append(currow)
		prevcol = i + 1
		currow -= 1
	elif A[i] == 2:
		if not has1:
			print(-1)
			exit()
		r = has1.pop()
		ans.append((r, i + 1))
		prevcol = i + 1
	elif A[i] == 3:
		if prevcol == -1:
			print(-1)
			exit()
		if has1 and has1[-1] == currow + 1:
			has1.pop()
		ans.append((currow, prevcol))
		ans.append((currow, i + 1))
		prevcol = i + 1
		currow -= 1
print(len(ans))
for a in ans[::-1]:
	print(*a)


n = int(input())
aa = list(map(int, input().split()))
r = 1
pen2 = []
pen3 = []
ans = []
for (c, a) in enumerate(aa, 1):
	if a == 0:
		pass
	elif a == 1:
		if pen2:
			b = pen2.pop()
			ans.append((b, c))
		elif pen3:
			b = pen3.pop()
			ans.append((b, c))
			ans.append((r, c))
			r += 1
		else:
			ans.append((r, c))
			r += 1
	elif a == 2:
		pen2.append(r)
		if pen3:
			b = pen3.pop()
			ans.append((b, c))
			ans.append((r, c))
			r += 1
		else:
			ans.append((r, c))
			r += 1
	elif pen3:
		b = pen3.pop()
		ans.append((b, c))
		ans.append((r, c))
		pen3.append(r)
		r += 1
	else:
		ans.append((r, c))
		pen3.append(r)
		r += 1
if r > n + 1 or pen2 or pen3:
	print(-1)
else:
	print(len(ans))
	print('\n'.join((' '.join(map(str, x)) for x in ans)))


import sys
n = int(input())
a = list(map(int, input().split()))
height = n
ans = []
last3 = -1
fail = 0
used = -1
for i in range(n):
	if a[i] == 3:
		if height == n:
			ans.append((n - height + 1, i + 1))
			height -= 1
		else:
			ans.append((n + 1 - (height + 1), i + 1))
			ans.append((n + 1 - height, i + 1))
			height -= 1
		last3 = i
if last3 == n - 1:
	print(-1)
	sys.exit()
if last3 > -1:
	flag = 0
	for i in range(last3, n):
		if a[i] == 2:
			flag = 1
			ans.append((n + 1 - (height + 1), i + 1))
			height -= 1
			break
	if flag == 0:
		flag2 = 0
		for i in range(last3, n):
			if a[i] == 1:
				ans.append((n + 1 - (height + 1), i + 1))
				height -= 1
				flag2 = 1
				used = i
				break
		if flag2 == 0:
			print(-1)
			sys.exit()
ones = []
if used == -1:
	height -= 1
for i in range(n - 1, -1, -1):
	if a[i] == 1 and i != used:
		ones.append(i)
	if a[i] == 2:
		if len(ones) == 0:
			print(-1)
			sys.exit()
		k = ones.pop()
		ans.append((n + 1 - (height + 1), i + 1))
		ans.append((n + 1 - (height + 1), k + 1))
		height -= 1
if used > -1:
	ones.append(used)
for i in ones:
	ans.append((n + 1 - (height + 1), i + 1))
	height -= 1
print(len(ans))
for (x, y) in ans:
	print(x, y)


def testcase():
	n = int(input())
	arr = list(map(int, input().split()))
	ans = []
	os = []
	ts = []
	yi = n
	for i in range(n - 1, -1, -1):
		if arr[i] == 0:
			continue
		if arr[i] == 1:
			ans.append([yi, i + 1])
			os.append([yi, i + 1])
			yi -= 1
		if arr[i] == 2:
			if len(os) == 0:
				print(-1)
				return
			(y, _) = os.pop()
			ans.append([y, i + 1])
			ts.append([y, i + 1])
		if arr[i] == 3:
			if len(os) == 0 and len(ts) == 0:
				print(-1)
				return
			if len(ts) > 0:
				(_, x) = ts.pop()
			else:
				(_, x) = os.pop()
			ts.append([yi, i + 1])
			ans.append([yi, i + 1])
			ans.append([yi, x])
			yi -= 1
	print(len(ans))
	for a in ans:
		print(*a)
	return
t = 1
for _ in range(t):
	testcase()


import sys
n = int(input())
b = list(map(int, input().split()))
a = []
for i in range(4):
	a.append([])
for j in range(n):
	a[b[j]].append(j)
if len(a[2]) > len(a[1]):
	print(-1)
	sys.exit()
res = []
r = 0
f = 0
curr3 = 0
while curr3 < len(a[3]) - 1:
	res.append([r, a[3][curr3]])
	res.append([r, a[3][curr3 + 1]])
	r += 1
	curr3 += 1
if f == 1:
	print(-1)
	sys.exit()
else:
	if len(a[3]):
		if a[2] != []:
			if a[2][-1] > a[3][-1]:
				res.append([r, a[3][-1]])
				res.append([r, a[2][-1]])
				res.append([r + 1, a[2][-1]])
				if a[1][-1] > a[2][-1]:
					res.append([r + 1, a[1][-1]])
					a[1].pop()
					a[2].pop()
					r += 2
				else:
					print(-1)
					sys.exit()
			elif a[1][-1] > a[3][-1]:
				j = a[3][-1] + 1
				q = 0
				while j < n:
					if b[j] == 1:
						q = 1
						res.append([r, a[3][-1]])
						res.append([r, j])
						res.append([r + 1, j])
						r += 2
						a[1].remove(j)
						break
					j += 1
				if q == 0:
					print(-1)
					sys.exit()
			else:
				print(-1)
				sys.exit()
		elif a[1] == []:
			print(-1)
			sys.exit()
		elif a[1][-1] > a[3][-1]:
			res.append([r, a[3][-1]])
			res.append([r, a[1][-1]])
			res.append([r + 1, a[1][-1]])
			r += 2
			a[1].pop()
		else:
			print(-1)
			sys.exit()
	if len(a[2]) > len(a[1]):
		print(-1)
		sys.exit()
	curr2 = 0
	curr1 = 0
	while curr2 < len(a[2]) and curr1 < len(a[1]):
		if a[1][curr1] > a[2][curr2]:
			res.append([r, a[2][curr2]])
			res.append([r, a[1][curr1]])
			r += 1
			curr2 += 1
			curr1 += 1
		else:
			res.append([r, a[1][curr1]])
			r += 1
			curr1 += 1
	if curr2 < len(a[2]):
		print(-1)
		sys.exit()
	else:
		while curr1 < len(a[1]):
			res.append([r, a[1][curr1]])
			r += 1
			curr1 += 1
		if r > n:
			print(-1)
			sys.exit()
		if len(res) > 2 * n:
			print(-1)
			sys.exit()
		print(len(res))
		for j in res:
			print(j[0] + 1, j[1] + 1)


import os
import sys
from math import *
from collections import *
from heapq import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcdefghijklmnopqrstuvwxyz/'
M = 1000000007
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]
n = Int()
a = array()
over_row = defaultdict(int)
over_col = defaultdict(int)
ans = []
ones = []
two = []
link = defaultdict(lambda : -1)
ok = True
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		pass
	elif a[i] == 1:
		ones.append(i)
	elif a[i] == 2:
		if len(ones) == 0:
			ok = False
			break
		link[i] = ones.pop()
		two.append(i)
	else:
		if len(two) == 0 and len(ones) == 0:
			ok = False
			break
		if len(two):
			link[i] = two.pop()
		else:
			link[i] = ones.pop()
		two.append(i)
r = n - 1
row = defaultdict(int)
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		pass
	elif a[i] == 1:
		ans.append((r + 1, i + 1))
		row[i] = r
	elif a[i] == 2:
		ans.append((row[link[i]] + 1, i + 1))
	else:
		ans.append((r + 1, i + 1))
		ans.append((r + 1, link[i] + 1))
	r -= 1
if not ok:
	print(-1)
	exit()
else:
	print(len(ans))
	for i in ans:
		print(*i)


import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
n = int(input())
a = [int(i) for i in input().split()]
v = [[] for i in range(n)]
one = []
s = []
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		one.append(i)
	elif a[i] == 2:
		if len(one) == 0:
			print(-1)
			exit()
		ind = one.pop()
		v[ind].append(i)
		v[i].append(i)
		s.append(i)
	elif a[i] == 3:
		if len(s) == 0:
			if len(one) == 0:
				print(-1)
				exit()
			ind = one.pop()
			v[ind].append(i)
			v[i].append(i)
			v[ind].append(ind)
		else:
			ind = s.pop()
			v[ind].append(i)
			v[i].append(i)
		s.append(i)
for i in one:
	v[i].append(i)
cnt = 0
for i in v:
	cnt += len(i)
print(cnt)
for i in range(n):
	for j in v[i]:
		print(j + 1, i + 1)


n = int(input())
a = list(map(int, input().split()))
o = []
pair = []
chain = []
f = True
extra = 0
(three, two) = (False, False)
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		continue
	if a[i] == 1:
		o.append(i)
	elif a[i] == 2:
		two = True
		if not o:
			f = False
			break
		else:
			pair.append((i, o.pop()))
	else:
		if three:
			chain.append(i)
		elif two:
			chain.append(pair[-1][0])
			chain.append(i)
		elif not o:
			f = False
		else:
			chain.append(o.pop())
			chain.append(i)
			extra = 1
		three = True
if not f:
	print(-1)
	exit()
chain = chain[::-1]
ans = []
done = set(chain)
r = 1
for i in range(len(chain) - 1):
	ans.append((r, chain[i] + 1))
	ans.append((r, chain[i + 1] + 1))
	r += 1
if extra:
	ans.append((r, chain[-1] + 1))
	r += 1
for i in pair:
	ans.append((r, i[0] + 1))
	ans.append((r, i[1] + 1))
	done.add(i[0])
	done.add(i[1])
	r += 1
for i in range(n):
	if a[i] == 1 and i not in done:
		ans.append((r, i + 1))
		r += 1
print(len(ans))
for i in ans:
	print(i[0], i[1])


from sys import stdin
input = stdin.readline

def A():
	t = int(input())
	for _ in range(t):
		(x1, y1, x2, y2) = map(int, input().split())
		if x2 == x1:
			print(abs(y2 - y1))
		elif y1 == y2:
			print(abs(x2 - x1))
		else:
			print(abs(x2 - x1) + abs(y2 - y1) + 2)

def B():
	t = int(input())
	for _ in range(t):
		n = int(input())
		s = list(input().rstrip())
		(rl, ll, lr, rr) = (0, 0, 0, 0)
		(lcount, rcount) = (0, 0)
		for i in range(0, n - 1):
			if s[i] == '<':
				if s[i + 1] == '>':
					lr += 1
				elif s[i + 1] == '<':
					ll += 1
				lcount += 1
			elif s[i] == '>':
				if s[i + 1] == '>':
					rr += 1
				elif s[i + 1] == '<':
					rl += 1
				rcount += 1
		if s[n - 1] == '<':
			if s[0] == '<':
				ll += 1
			elif s[0] == '>':
				lr += 1
			lcount += 1
		elif s[n - 1] == '>':
			if s[0] == '<':
				rl += 1
			elif s[0] == '>':
				rr += 1
			rcount += 1
		if lcount == 0 or rcount == 0:
			print(n)
		else:
			print(n - ll - lr - rl - rr)

def C():
	t = int(input())
	for _ in range(t):
		s = list(input().rstrip())
		n = len(s)
		i = 0
		remaining = 0
		depth = 0
		j = n - 1
		while j >= i:
			if s[j] == 'A':
				depth += 1
				if depth > 0:
					remaining += 1
					depth = 0
			else:
				depth -= 1
			j -= 1
		remaining += depth % 2
		print(remaining)

def D():
	from collections import deque
	n = int(input())
	a = list(map(int, input().split()))
	cols = [[]] * n
	filledCols = deque()
	k = n - 1
	for i in range(n - 1, -1, -1):
		if a[i] == 1:
			cols[i] = [k]
			filledCols.appendleft(i)
			k -= 1
	filled23Cols = deque()
	for i in range(n - 1, -1, -1):
		if a[i] == 2:
			if len(filledCols) == 0 or filledCols[-1] < i:
				print('-1')
				return
			cols[i] = [cols[filledCols.pop()][0]]
			filled23Cols.append(i)
		elif a[i] == 3:
			if (len(filledCols) == 0 or filledCols[-1] < i) and len(filled23Cols) == 0:
				print('-1')
				return
			cols[i] = [k]
			if len(filled23Cols) > 0:
				cols[filled23Cols.pop()].append(k)
			else:
				cols[filledCols.pop()].append(k)
			filled23Cols.append(i)
			k -= 1
	tot = 0
	for i in cols:
		tot += len(i)
	print(tot)
	for i in range(len(cols)):
		if len(cols[i]) > 0:
			for j in cols[i]:
				print(j + 1, i + 1)
D()


n = int(input())
s = [int(x) for x in input().split()]
L1 = []
L2 = []
L3 = []
L4 = []
row = n - 1
ans = []
flag = 0
for i in range(len(s) - 1, -1, -1):
	if s[i] == 1:
		ans.append([row + 1, i + 1])
		L1.append(row)
		L3.append(i)
	elif s[i] == 2:
		L2.append(i)
		if len(L1) > 0:
			rr = L1.pop()
			L3.pop()
			ans.append([rr + 1, i + 1])
		else:
			flag = -1
	elif s[i] == 3:
		if len(L4) > 0:
			cc = L4.pop()
			ans.append([row + 1, i + 1])
			ans.append([row + 1, cc + 1])
		elif len(L2) > 0:
			cc = L2.pop()
			ans.append([row + 1, i + 1])
			ans.append([row + 1, cc + 1])
		elif len(L1) > 0:
			cc = L3.pop()
			L1.pop()
			ans.append([row + 1, i + 1])
			ans.append([row + 1, cc + 1])
		else:
			flag = -1
		L4.append(i)
	row -= 1
if flag == -1:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


from collections import defaultdict as dd, deque

def main():
	n = int(input())
	A = [int(x) for x in input().split()]
	crosses = []
	y = n - 1
	free = deque()
	free_bonus = deque()
	free_bonus_bleh = deque()
	for x in range(n)[::-1]:
		a = A[x]
		if a == 0:
			continue
		if a == 1:
			crosses.append((x, y))
			free.append((x, y))
			y -= 1
		if a == 2:
			if not free:
				print(-1)
				return
			(tx, ty) = free.popleft()
			free_bonus.append((x, ty))
			crosses.append((x, ty))
			y -= 1
		if a == 3:
			if not free and (not free_bonus):
				print(-1)
				return
			if free_bonus:
				(tx, ty) = free_bonus.popleft()
			else:
				(tx, ty) = free.popleft()
			free_bonus.append((x, y))
			crosses.append((x, y))
			crosses.append((tx, y))
			y -= 1
	print(len(crosses))
	for (x, y) in crosses:
		print(y + 1, x + 1)
main()


n = int(input())
a = [0] + list(map(int, input().split()))
b = []
poss = True
ones = []
twos = []
threes = []
row_num = n
for c in range(n, 0, -1):
	if a[c] == 0:
		continue
	elif a[c] == 1:
		ones.append((row_num, c))
		b.append((row_num, c))
		row_num -= 1
	elif a[c] == 2:
		if len(ones) > 0:
			q = ones.pop()
			b.append((q[0], c))
			twos.append((q[0], c))
		else:
			poss = False
	elif a[c] == 3:
		if len(threes) > 0:
			q = threes.pop()
			b.append((row_num, c))
			b.append((row_num, q[1]))
			threes.append((row_num, c))
			row_num -= 1
		elif len(twos) > 0:
			q = twos.pop()
			b.append((row_num, c))
			b.append((row_num, q[1]))
			threes.append((row_num, c))
			row_num -= 1
		elif len(ones) > 0:
			q = ones.pop()
			b.append((row_num, c))
			b.append((row_num, q[1]))
			threes.append((row_num, c))
			row_num -= 1
		else:
			poss = False
if poss:
	print(len(b))
	for item in b:
		print(item[0], item[1])
else:
	print(-1)


n = int(input())
aa = list(map(int, input().split()))
a = [0]
for i in aa:
	a.append(i)
r = [[] for i in range(n + 1)]
m = 0
cc = [0] * (n + 1)
rc = [0] * (n + 1)
c = []
ct = []
for i in range(1, n + 1):
	if a[i] == 0:
		cc[i] = 0
	elif a[i] == 1:
		cc[i] = 1
		rc[i] = 1
		r[n - i + 1].append(i)
		m += 1
		c.append(i)
	else:
		ct.append(i)
k = len(c)
j = len(ct)
f = 0
if a[n] > 1:
	f = 1
for i in range(n, 0, -1):
	if a[i] == 3:
		if j != 0 and i < ct[j - 1]:
			r[n - i + 1].append(i)
			r[n - i + 1].append(ct[j - 1])
			m += 2
			j -= 1
			continue
		if k == 0 or i > c[k - 1]:
			f = 1
			break
		r[n - i + 1].append(i)
		r[n - i + 1].append(c[k - 1])
		m += 2
		k -= 1
	elif a[i] == 2:
		rc[i] = 2
		if k == 0 or i > c[k - 1]:
			f = 1
			break
		r[n + 1 - i].append(i)
		r[n - i + 1].append(c[k - 1])
		r[n + 1 - c[k - 1]] = []
		k -= 1
		m += 1
if f == 1:
	print('-1')
else:
	print(m)
	for i in range(1, n + 1):
		for j in r[i]:
			if j != -1:
				print(n - i + 1, j)


import sys
import math
from collections import defaultdict, Counter
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
n = int(input())
a = list(map(int, input().split()))
l1 = []
l2 = []
l3 = []
for i in range(n):
	if a[i] == 1:
		l1.append(i)
	elif a[i] == 2:
		l2.append(i)
	elif a[i] == 3:
		l3.append(i)
top1 = 0
top2 = 0
top3 = 0
ans = []
flag = 0
level = 1
visit = [0] * n
for i in range(n):
	if a[i] == 2:
		if visit[i] == 0:
			while top1 < len(l1) and l1[top1] < i:
				top1 += 1
			if top1 == len(l1):
				flag = 1
				break
			ans.append([level, i + 1])
			ans.append([level, l1[top1] + 1])
			visit[l1[top1]] = 1
			top1 += 1
			level += 1
	elif a[i] == 3:
		if visit[i] == 0:
			cur = i
			while True:
				visit[cur] = 1
				while top2 < len(l2) and l2[top2] < cur:
					top2 += 1
				while top3 < len(l3) and l3[top3] <= cur:
					top3 += 1
				if top2 != len(l2):
					if top3 == len(l3) or l3[top3] > l2[top2]:
						ans.append([level, cur + 1])
						ans.append([level, l2[top2] + 1])
						ans.append([level + 1, l2[top2] + 1])
						level += 1
						visit[l2[top2]] = 1
						while top1 < len(l1) and l1[top1] < l2[top2]:
							top1 += 1
						if top1 == len(l1):
							flag = 1
							break
						ans.append([level, l1[top1] + 1])
						visit[l1[top1]] = 1
						top2 += 1
						top1 += 1
						level += 1
						break
					else:
						ans.append([level, cur + 1])
						ans.append([level, l3[top3] + 1])
						level += 1
						cur = l3[top3]
						top3 += 1
				elif top3 != len(l3):
					ans.append([level, cur + 1])
					ans.append([level, l3[top3] + 1])
					level += 1
					cur = l3[top3]
					top3 += 1
				else:
					while top1 < len(l1) and l1[top1] < cur:
						top1 += 1
					if top1 == len(l1):
						flag = 1
						break
					ans.append([level, cur + 1])
					ans.append([level, l1[top1] + 1])
					ans.append([level + 1, l1[top1] + 1])
					visit[l1[top1]] = 1
					top1 += 1
					level += 2
					break
			if flag:
				break
	elif a[i] == 1:
		if visit[i] == 0:
			ans.append([level, i + 1])
			level += 1
if flag:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


from collections import deque
n = int(input())
a = list(map(int, input().split()))
l = [n] * n
rowt = [2] * n
rowa = deque()
out = []
pas = []
f = 0
for i in range(n - 1, -1, -1):
	if i == n - 1 and a[i] > 1:
		f = 1
		break
	elif a[i] == 0:
		if i + 1 < n:
			l[i] = l[i + 1]
		continue
	elif a[i] == 1:
		if i + 1 < n:
			l[i] = l[i + 1] - 1
		if l[i] < 1:
			f = 1
			break
		rowt[l[i] - 1] -= 1
		out.append((l[i], i + 1))
		pasv = i
		rowa.append(l[i])
	elif a[i] == 2:
		if i + 1 < n:
			l[i] = l[i + 1]
		if rowt[l[i] - 1] < 1:
			if rowa:
				h = rowa.popleft()
			else:
				f = 1
				break
		else:
			h = rowa.pop()
		if f == 1:
			break
		rowt[h - 1] = 0
		out.append((h, i + 1))
		pasv = i
	elif a[i] == 3:
		if i + 1 < n:
			l[i] = l[i + 1] - 1
		if l[i] < 1:
			f = 1
			break
		rowt[l[i] - 1] = 0
		rowt[l[pasv] - 1] = 0
		if a[pasv] == 1:
			_ = rowa.pop()
		out.append((l[i], pasv + 1))
		out.append((l[i], i + 1))
		pasv = i
if f == 1:
	print(-1)
else:
	print(len(out))
	for i in out:
		print(*i)


n = int(input())
a = list(map(int, input().split()))
if a[-1] > 1:
	print(-1)
	return
s = set()
s2 = []
s3 = []
r = 1
for i in range(n):
	if a[i] == 1:
		if s2:
			x = s2.pop()
			s.add((x, i + 1))
		elif s3:
			x = s3.pop()
			s.add((x, i + 1))
			s.add((r, i + 1))
			r += 1
		else:
			s.add((r, i + 1))
			r += 1
	elif a[i] == 2:
		if s3:
			x = s3.pop()
			s.add((x, i + 1))
			s.add((r, i + 1))
			s2.append(r)
			r += 1
		else:
			s.add((r, i + 1))
			s2.append(r)
			r += 1
	elif a[i] == 3:
		if s3:
			x = s3.pop()
			s.add((x, i + 1))
			s.add((r, i + 1))
			s3.append(r)
		else:
			s.add((r, i + 1))
			s3.append(r)
		r += 1
	else:
		r += 1
if s2 or s3:
	print(-1)
else:
	print(len(s))
	for x in s:
		print(x[0], x[1])


import os, sys
from io import BytesIO, IOBase
from math import log2, ceil, sqrt, gcd
from _collections import deque
import heapq as hp
from bisect import bisect_left, bisect_right
from math import cos, sin
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
mod = 10 ** 9 + 7
n = int(input())
a = list(map(int, input().split()))
b = []
c = []
ans = []
for (i, v) in enumerate(a):
	if not v:
		continue
	if v == 1:
		if b:
			x = b.pop()
			ans.append([x, i + 1])
		elif c:
			x = c.pop()
			ans.append([x, i + 1])
			ans.append([i + 1, i + 1])
		else:
			ans.append([i + 1, i + 1])
	elif v == 2:
		if c:
			x = c.pop()
			ans.append([x, i + 1])
		ans.append([i + 1, i + 1])
		b.append(i + 1)
	else:
		if c:
			x = c.pop()
			ans.append([x, i + 1])
		ans.append([i + 1, i + 1])
		c.append(i + 1)
if b or c:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


n = int(input())
ans = []
ready1 = []
ready2 = []
f = True
r = list(map(int, input().split()))
for k in reversed(range(n)):
	if r[k] == 0:
		continue
	elif r[k] == 1:
		ans.append((k + 1, k + 1))
		ready1.append(k)
	elif r[k] == 2:
		if ready1:
			i = ready1.pop(0)
			ans.append((i + 1, k + 1))
			ready2.append(k)
		else:
			f = False
			break
	elif r[k] == 3:
		if ready2:
			i = ready2.pop(0)
			ans.append((k + 1, k + 1))
			ans.append((k + 1, i + 1))
			ready2.append(k)
		elif ready1:
			i = ready1.pop(0)
			ans.append((k + 1, k + 1))
			ans.append((k + 1, i + 1))
			ready2.append(k)
		else:
			f = False
			break
if f:
	print(len(ans))
	for x in ans:
		print(x[0], x[1])
else:
	print(-1)


from collections import deque

def solve(arr):
	r = 0
	heights = []
	ones_queue = deque()
	for (i, a) in enumerate(arr):
		if a > 0:
			if a == 1:
				ones_queue.append(i)
			heights.append(r)
			r += 1
		else:
			heights.append(-1)
	uppered = set()
	for (i, a) in enumerate(arr):
		if a != 2:
			continue
		while ones_queue:
			j = ones_queue.popleft()
			if j <= i:
				continue
			heights[j] = heights[i]
			uppered.add(j)
			break
		else:
			return None
	blocked = []
	all_queue = deque(range(len(arr)))
	for (i, a) in enumerate(arr):
		if a != 3:
			continue
		while all_queue:
			j = all_queue.popleft()
			if j <= i or arr[j] == 0 or j in uppered:
				continue
			blocked.append((heights[i] + 1, j + 1))
			break
		else:
			return None
	targets = blocked
	for (i, h) in enumerate(heights):
		if h >= 0:
			targets.append((h + 1, i + 1))
	targets.sort()
	return targets

def main():
	n = int(input())
	arr = list(map(int, input().split()))
	res = solve(arr)
	if res is None:
		print(-1)
	else:
		print(len(res))
		for (r, c) in res:
			print(r, c)
main()


(N,) = map(int, input().split())
X = list(map(int, input().split()))
from collections import deque
R = []
A1 = []
A2 = []
ng = 0
for i in range(N - 1, -1, -1):
	j = N - 1 - i + 1
	if X[i] == 1:
		R.append((i + 1, j))
		A1.append((i + 1, j))
	elif X[i] == 2:
		if not A1:
			ng = 1
			break
		(x, y) = A1.pop()
		R.append((i + 1, y))
		A2.append((i + 1, y))
	elif X[i] == 3:
		if A2:
			(x, y) = A2.pop()
			R.append((x, j))
			R.append((i + 1, j))
			A2.append((i + 1, j))
		elif A1:
			(x, y) = A1.pop()
			R.append((x, j))
			R.append((i + 1, j))
			A2.append((i + 1, j))
		else:
			ng = 1
if ng:
	print(-1)
else:
	print(len(R))
	for (x, y) in R:
		print(N - y + 1, x)


(n, values, row, one, ans, flag, two) = (int(input()), [int(i) for i in input().split()], 1, [], [], True, [])
for i in range(n - 1, -1, -1):
	if values[i] == 0:
		pass
	elif values[i] == 1:
		one.append([row, i])
		ans.append([row, i])
		row += 1
	elif values[i] == 2:
		if not one:
			flag = False
			break
		last = one.pop()
		ans.append([last[0], i])
		two = [last[0], i]
	elif values[i] == 3:
		if not two:
			if not one:
				flag = False
				break
			else:
				two = one.pop()
		ans.append([row, i])
		ans.append([row, two[1]])
		two = [row, i]
		row += 1
if not flag:
	print(-1)
else:
	print(len(ans))
	for row in ans:
		print(n - row[0] + 1, row[1] + 1)


import os, sys
from io import BytesIO, IOBase
from heapq import *

def solve(n, a):
	x = [[], [], []]
	xx = [[], [], []]
	row = n
	tar = []
	for (ind, val) in enumerate(a):
		if val == 1:
			tar.append((row, ind + 1))
			xx[0].append(row)
			row -= 1
		if val:
			x[val - 1].append(ind + 1)
	j = 0
	for i in x[1]:
		while j < len(x[0]) and x[0][j] < i:
			j += 1
		if j >= len(x[0]):
			print(-1)
			return
		xx[1].append(xx[0][j])
		tar.append((xx[0][j], i))
		j += 1
	rr = x[1][:]
	for k in range(j, len(x[0])):
		rr.append(x[0][k])
	heapify(rr)
	x[2].reverse()
	for i in x[2]:
		fl = 0
		while len(rr):
			xx = rr.pop()
			if xx > i:
				fl = 1
				break
		if not fl:
			print(-1)
			return
		tar.append((row, xx))
		tar.append((row, i))
		heappush(rr, i)
		row -= 1
	print(len(tar))
	for i in tar:
		print(*i)

def main():
	n = int(input())
	a = list(map(int, input().split()))
	solve(n, a)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


n = int(input())
a = list(map(int, input().split()))
b = 0
c = []
d1 = []
d2 = []
d3 = []
e1 = e2 = e3 = 0
f = 0
g = 0
z = 0
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		d1.append([b, i])
		c.append([n - b, i + 1])
		f += 1
		b += 1
		z += 1
	elif a[i] == 2:
		z -= 1
		if z < 0:
			print(-1)
			break
else:
	x = 0
	y = 0
	z = [0] * n
	k = -1
	for i in range(n):
		if a[i] == 1:
			x += 1
			y = 0
		if a[i] == 2:
			if k == -1 or b - 1 - x < k:
				d2.append([b - 1 - x, i])
				z[b - 1 - x] = 1
				c.append([n - b + 1 + x, i + 1])
				g += 1
				y += 1
				k = b - 1 - x
			else:
				d2.append([k - 1, i])
				z[k - 1] = 1
				c.append([n - k + 1, i + 1])
				g += 1
				y += 1
				k -= 1
	d2 = d2[::-1]
	d11 = []
	e1 = 0
	f = 0
	for i in d1:
		if z[i[0]] == 0:
			d11.append(i)
			f += 1
	d1 = list(d11)
	h = 0
	for i in range(n - 1, -1, -1):
		if a[i] == 3:
			if (f == 0 or d1[e1][1] <= i) and (g == 0 or d2[e2][1] <= i) and (h == 0 or d3[e3][1] <= i):
				print(-1)
				break
			d3.append([b, i])
			c.append([n - b, i + 1])
			if not (f == 0 or d1[e1][1] <= i):
				c.append([n - b, d1[e1][1] + 1])
				e1 += 1
				f -= 1
			elif not (g == 0 or d2[e2][1] <= i):
				c.append([n - b, d2[e2][1] + 1])
				e2 += 1
				g -= 1
			elif not (h == 0 or d3[e3][1] <= i):
				c.append([n - b, d3[e3][1] + 1])
				e3 += 1
				h -= 1
			b += 1
			h += 1
	else:
		print(len(c))
		for i in c:
			print(*i)


import sys
input = sys.stdin.readline

def prog():
	n = int(input())
	a = list(map(int, input().split()))
	fail = False
	if a[-1] == 2 or a[-1] == 3:
		fail = True
	if fail:
		print(-1)
		return
	empty_row = 1
	col_taken = [0] * n
	row = [0] * n
	col_2 = 1
	col_3 = 1
	placed = []
	for i in range(n):
		while col_2 < n and (col_2 <= i or a[col_2] != 1 or col_taken[col_2]):
			col_2 += 1
		while col_3 < n and (col_3 <= i or a[col_3] == 0 or col_taken[col_3]):
			col_3 += 1
		if a[i] == 0:
			continue
		elif a[i] == 1:
			if row[i] == 0:
				row[i] = empty_row
				empty_row += 1
				placed.append([row[i], i + 1])
		elif a[i] == 2:
			if col_2 >= n:
				fail = True
				break
			if row[i] == 0:
				row[i] = empty_row
				empty_row += 1
				placed.append([row[i], i + 1])
			placed.append([row[i], col_2 + 1])
			row[col_2] = row[i]
			col_taken[col_2] = 1
			col_2 += 1
		else:
			if col_3 >= n:
				fail = True
				break
			if row[i] == 0:
				row[i] = empty_row
				empty_row += 1
				placed.append([row[i], i + 1])
			placed.append([row[i], col_3 + 1])
			placed.append([empty_row, col_3 + 1])
			col_taken[col_3] = 1
			row[col_3] = empty_row
			empty_row += 1
			col_3 += 1
	if fail:
		print(-1)
		return
	else:
		print(len(placed))
		for p in placed:
			print(*p)
prog()


import sys
input = lambda : sys.stdin.readline().strip()
inp = lambda : list(map(int, input().split()))
n = int(input())
a = list(map(int, input().split()))
two = []
ft = []
three = []
fth = []
ans = []
ones = []
extra = []
ind = 0
for i in range(n):
	if a[i] == 1:
		if len(two) > len(ft):
			ft.append(i + 1)
		elif len(three) > len(fth):
			fth.append(i + 1)
		else:
			ans.append([i + 1, i + 1])
	elif a[i] == 2:
		if len(three) > len(fth):
			temp = three.pop()
			ans.append([temp, temp])
			ans.append([temp, i + 1])
		two.append(i + 1)
	elif a[i] == 3:
		if len(three) > len(fth):
			temp = three.pop()
			ans.append([temp, temp])
			ans.append([temp, i + 1])
		three.append(i + 1)
if len(two) == len(ft) and len(three) == len(fth):
	for (i, j) in zip(two, ft):
		ans.append([i, i])
		ans.append([i, j])
	for (i, j) in zip(three, fth):
		ans.append([i, i])
		ans.append([i, j])
		ans.append([j, j])
	print(len(ans))
	for (i, j) in ans:
		print(i, j)
else:
	print(-1)


mod = 10 ** 9 + 7
INF = float('inf')

def getlist():
	return list(map(int, input().split()))

def main():
	N = int(input())
	A = getlist()
	ans = []
	Q2 = []
	Q3 = []
	for i in range(N):
		if A[i] == 1:
			if len(Q2) != 0:
				val = Q2.pop()
				ans.append([val, i + 1])
			elif len(Q3) != 0:
				val = Q3.pop()
				ans.append([val, i + 1])
				ans.append([i + 1, i + 1])
			else:
				ans.append([i + 1, i + 1])
		elif A[i] == 2:
			if len(Q3) != 0:
				val = Q3.pop()
				ans.append([val, i + 1])
			ans.append([i + 1, i + 1])
			Q2.append(i + 1)
		elif A[i] == 3:
			if len(Q3) != 0:
				val = Q3.pop()
				ans.append([val, i + 1])
			ans.append([i + 1, i + 1])
			Q3.append(i + 1)
	if len(Q2) != 0 or len(Q3) != 0:
		print(-1)
		return
	M = len(ans)
	print(M)
	for bomb in ans:
		print(*bomb)
main()


import sys
from collections import defaultdict as dd
from collections import Counter as cc
from queue import Queue
import math
import itertools
try:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
except:
	pass
input = lambda : sys.stdin.buffer.readline().rstrip()
w = int(input())
q = list(map(int, input().split()))
a = []
d = 0
e = 0
f = 0
b = []
c = 0
j = w
k = 0
u = 0
for i in range(w - 1, -1, -1):
	if q[i] == 1:
		a.append(i + 1)
		d += 1
		u = 0
	elif q[i] == 2:
		if d > e + f:
			b.append([j, i + 1])
			b.append([j, a[k]])
			j -= 1
			k += 1
			e += 1
			u = 1
		else:
			c = 1
			break
	elif q[i] == 3:
		if u == 1:
			b.append([j, i + 1])
			b.append([j, b[-3][1]])
			j -= 1
		elif u == 2:
			b.append([j, i + 1])
			b.append([j, b[-3][1]])
			j -= 1
		elif d > e + f:
			b.append([j, a[k]])
			j -= 1
			b.append([j, i + 1])
			b.append([j, a[k]])
			j -= 1
			k += 1
			f += 1
		else:
			c = 1
			break
		u = 2
while k < len(a):
	b.append([j, a[k]])
	j -= 1
	k += 1
if c == 1:
	print(-1)
else:
	print(len(b))
	for i in b:
		print(*i)


import sys
n = int(input())
a = [int(i) for i in input().split()]
hit_once = [i for (i, hits) in enumerate(a) if hits == 1]
hit_twice = [i for (i, hits) in enumerate(a) if hits == 2]
hit_thrice = [i for (i, hits) in enumerate(a) if hits == 3]
if len(hit_once) < len(hit_twice):
	print(-1)
	sys.exit(0)
rows = [[None, None] for _ in range(n)]
cols = [[None, None] for _ in range(n)]
curr_row = n - 1
for col in reversed(hit_once):
	rows[curr_row][0] = col
	cols[col][0] = curr_row
	curr_row -= 1
i1 = 0
for col2 in hit_twice:
	if i1 == len(hit_once):
		print(-1)
		sys.exit(0)
	while hit_once[i1] < col2:
		i1 += 1
		if i1 == len(hit_once):
			print(-1)
			sys.exit(0)
	col1 = hit_once[i1]
	row = cols[col1][0]
	rows[row][1] = col2
	cols[col2][0] = row
	i1 += 1
if hit_thrice:
	if hit_thrice[-1] == n - 1:
		print(-1)
		sys.exit(0)
	hit_once = set(hit_once)
	hit_twice = set(hit_twice)
	curr_col = hit_thrice[-1] + 1
	while curr_col not in hit_twice and (curr_col not in hit_once or None not in rows[cols[curr_col][0]]):
		curr_col += 1
		if curr_col == n:
			print(-1)
			sys.exit(0)
	for col3 in reversed(hit_thrice):
		rows[curr_row][0] = curr_col
		cols[curr_col][1] = curr_row
		rows[curr_row][1] = col3
		cols[col3][0] = curr_row
		curr_col = col3
		curr_row -= 1
output = []
for (row, cols) in enumerate(rows):
	if cols[0] is not None:
		output.append(f'{row + 1} {cols[0] + 1}')
	if cols[1] is not None:
		output.append(f'{row + 1} {cols[1] + 1}')
print(len(output))
print('\n'.join(output))


from functools import reduce
import os
import sys
from collections import *
from math import *
from bisect import *
from heapq import *
from io import BytesIO, IOBase
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def arr():
	return [int(i) for i in input().split()]

def sarr():
	return [int(i) for i in input()]

def starr():
	return [str(x) for x in input().split()]

def inn():
	return int(input())

def svalue():
	return tuple(map(str, input().split()))

def parr():
	return [value() for i in range(n)]
mo = 1000000007
inf = 1e+18
div = 998244353
n = inn()
a = arr()
avail = []
avail2 = []
cr = [0] * n
ans = []
flag = 0
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		ans += [(i + 1, i + 1)]
		cr[i] += 1
		avail.append(i)
	elif a[i] == 2:
		if len(avail) == 0:
			flag = 1
			break
		else:
			ans += [(avail[0] + 1, i + 1)]
			cr[avail[0]] += 1
			avail.pop(0)
			avail2.append(i)
	elif a[i] == 3:
		if len(avail) == 0 and len(avail2) == 0:
			flag = 1
			break
		elif len(avail2) > 0:
			ans += [(i + 1, i + 1)]
			ans += [(i + 1, avail2[0] + 1)]
			avail2.pop(0)
			avail2.append(i)
		else:
			ans += [(i + 1, i + 1)]
			ans += [(i + 1, avail[0] + 1)]
			avail.pop(0)
			avail2.append(i)
if flag == 1:
	print(-1)
else:
	print(len(ans))
	for (i, j) in ans:
		print(i, j)


import os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
from collections import deque
n = int(input())
a = list(map(int, input().split()))
l = [n] * n
rowt = [2] * n
rowa = deque()
out = []
pas = []
f = 0
for i in range(n - 1, -1, -1):
	if i == n - 1 and a[i] > 1:
		f = 1
		break
	elif a[i] == 0:
		if i + 1 < n:
			l[i] = l[i + 1]
		continue
	elif a[i] == 1:
		if i + 1 < n:
			l[i] = l[i + 1] - 1
		if l[i] < 1:
			f = 1
			break
		rowt[l[i] - 1] -= 1
		out.append((l[i], i + 1))
		pasv = i
		rowa.append(l[i])
	elif a[i] == 2:
		if i + 1 < n:
			l[i] = l[i + 1]
		if rowt[l[i] - 1] < 1:
			if rowa:
				h = rowa.popleft()
			else:
				f = 1
				break
		else:
			h = rowa.pop()
		if f == 1:
			break
		rowt[h - 1] = 0
		out.append((h, i + 1))
		pasv = i
	elif a[i] == 3:
		if i + 1 < n:
			l[i] = l[i + 1] - 1
		if l[i] < 1:
			f = 1
			break
		rowt[l[i] - 1] = 0
		rowt[l[pasv] - 1] = 0
		if a[pasv] == 1:
			_ = rowa.pop()
		out.append((l[i], pasv + 1))
		out.append((l[i], i + 1))
		pasv = i
if f == 1:
	print(-1)
else:
	print(len(out))
	for i in out:
		print(*i)


n = int(input())
a = list(map(int, input().split()))
x = sum((1 for el in a if el == 3))
p = 0
for i in range(n - 1, -1, -1):
	if a[i] == 3:
		p = i
		break
numb = x
ans1 = []
ans2 = []
for i in range(p, -1, -1):
	if a[i] == 3:
		if numb > 1:
			ans1.append(n + 2 - numb)
			ans2.append(i)
			ans1.append(n + 1 - numb)
			ans2.append(i)
		else:
			ans1.append(n)
			ans2.append(i)
		numb -= 1
q = -1
f = False
if x > 0:
	for i in range(p + 1, n):
		if a[i] == 2:
			q = i
			break
	if q == -1:
		f = True
		for i in range(p + 1, n):
			if a[i] == 1:
				q = i
				break
if q == -1 and x > 0:
	print(-1)
else:
	if x > 0:
		ans1.append(n + 1 - x)
		ans2.append(q)
		if f:
			ans1.append(n - x)
			ans2.append(q)
	u = n - 1
	v = n - 1
	k = 1
	color = [0 for i in range(n)]
	if f and q != -1:
		color[q] = 1
	while u >= 0 and v >= 0 and (u <= v):
		if f:
			if v == q:
				v -= 1
		if a[u] == 2:
			if a[v] == 1:
				ans1.append(k)
				ans2.append(u)
				ans1.append(k)
				ans2.append(v)
				color[v] = 1
				k += 1
				u -= 1
				v -= 1
			else:
				v -= 1
		else:
			u -= 1
	if u > 0 or (u == 0 and a[u] == 2):
		print(-1)
	else:
		for i in range(n):
			if a[i] == 1 and color[i] == 0:
				ans1.append(k)
				ans2.append(i)
				k += 1
		print(len(ans1))
		for i in range(len(ans1)):
			print(n + 1 - ans1[i], ' ', ans2[i] + 1)


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush, nsmallest
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf, log
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
from decimal import Decimal
from copy import deepcopy
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(var, end='\n'):
	sys.stdout.write(str(var) + end)

def outa(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
n = int(data())
arr = l()
(answer, window, j, last) = ([], deque(), n - 1, [-1, -1])
for i in range(n - 1, -1, -1):
	if arr[i] == 1:
		answer.append((j + 1, i + 1))
		window.append(j)
		j -= 1
		last = [i, 1]
	elif arr[i] == 2:
		if not window:
			out(-1)
			exit()
		answer.append((window.popleft() + 1, i + 1))
		last = [i, 2]
	elif arr[i] == 3:
		if last[0] == -1:
			out(-1)
			exit()
		answer.append((j + 1, i + 1))
		answer.append((j + 1, last[0] + 1))
		j -= 1
		if last[1] == 1 and window:
			window.pop()
		last = [i, 3]
out(len(answer))
for (a, b) in answer:
	outa(a, b)


def main():
	import sys
	input = sys.stdin.readline
	n = int(input())
	ans = []
	arr = list(map(int, input().split()))
	amt = [2 if x else 0 for x in arr]
	bottoms = []
	bottoms1 = []
	others = []
	idx = 0
	idx1 = 0
	for i in range(n - 1, -1, -1):
		if arr[i] == 0:
			continue
		if arr[i] == 1:
			bottoms.append((i + 1, i + 1))
		if arr[i] == 2:
			if idx == len(bottoms):
				print(-1)
				return
			(r, c) = bottoms[idx]
			bottoms1.append((r, i + 1))
			idx += 1
		if arr[i] == 3:
			if idx == len(bottoms) and idx1 == len(bottoms1):
				print(-1)
				return
			elif idx1 == len(bottoms1):
				(r, c) = bottoms[idx]
				bottoms1.append((i + 1, i + 1))
				others.append((i + 1, c))
				idx += 1
			else:
				(r, c) = bottoms1[idx1]
				bottoms1.append((i + 1, i + 1))
				others.append((i + 1, c))
				idx1 += 1
	ans = others + bottoms + bottoms1
	print(len(ans))
	for (x, y) in ans:
		print(x, y)
	return 0
main()


n = int(input())
a = list(map(int, input().split()))
right_free = []
right_busy = []
ans = []
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		right_free.append(i)
	elif a[i] == 2:
		right_busy.append(i)
		if not right_free:
			print(-1)
			return
		x = right_free.pop()
		ans.append([i, i])
		ans.append([i, x])
	elif a[i] == 3:
		if not right_busy and (not right_free):
			print(-1)
			return
		if right_busy:
			x = right_busy.pop()
			ans.append([i, i])
			ans.append([i, x])
		else:
			x = right_free.pop()
			ans.append([i, i])
			ans.append([x, x])
			ans.append([i, x])
		right_busy.append(i)
while right_free:
	x = right_free.pop()
	ans.append([x, x])
print(len(ans))
for (x, y) in ans:
	print(x + 1, y + 1)


mod = 1000000007
eps = 10 ** (-9)

def main():
	import sys
	input = sys.stdin.readline
	N = int(input())
	A = list(map(int, input().split()))
	check = 0
	for a in A:
		if a == 2:
			check += 1
		elif a == 1:
			if check > 0:
				check -= 1
	if check > 0:
		print(-1)
		exit()
	for a in reversed(A):
		if a == 3:
			print(-1)
			exit()
		elif a == 1 or a == 2:
			break
	ans = []
	h = 0
	flg = 1
	if 3 in A:
		ww = -1
		for i in range(N - 1, -1, -1):
			a = A[i]
			if a == 2:
				ww = i
				flg = 0
				break
			elif a == 1 and ww == -1:
				ww = i
			elif a == 3:
				if ww == -1:
					print(-1)
					exit()
				else:
					break
		prev = -1
		for (i, a) in enumerate(A):
			if a == 3:
				if prev != -1:
					ans.append((h, prev))
					ans.append((h, i))
					h += 1
				prev = i
		ans.append((h, prev))
		ans.append((h, ww))
		ans.append((h + 1, ww))
		h += 1
		hh = h
		h += 1
	else:
		flg = 0
		ww = -1
		hh = -1
	st = []
	for (i, a) in enumerate(A):
		if a == 2:
			if i != ww:
				ans.append((h, i))
				st.append((h, i))
				h += 1
			else:
				st.append((hh, i))
		elif a == 1:
			if st:
				if flg and i == ww:
					print(-1)
					exit()
				(hhh, www) = st.pop()
				ans.append((hhh, i))
			elif i != ww:
				ans.append((h, i))
				h += 1
			else:
				pass
	print(len(ans))
	for (h, w) in ans:
		print(h + 1, w + 1)
main()


n = int(input())
a = [*map(int, input().split())]
s31 = None
s3 = None
pairs_3 = []
pairs_2 = []
pairs_31 = []
s_1 = []
s_2 = []
s_3 = []
for (i, j) in zip(reversed(a), range(n, 0, -1)):
	if i == 3:
		if s31 != None:
			s31.append(j)
		elif s3 != None:
			s3.append(j)
		elif len(pairs_3) != 0:
			(x, y, z) = pairs_3.pop()
			s3 = [x, y, z, j]
		elif len(pairs_31) != 0:
			(x, y) = pairs_31.pop()
			s31 = [x, y, j]
		elif len(pairs_2) != 0:
			(x, y) = pairs_2.pop()
			pairs_3.append((x, y, j))
		elif len(s_1) != 0:
			pairs_31.append((s_1.pop(), j))
		else:
			print(-1)
			exit()
	elif i == 2:
		if len(s_1) != 0:
			pairs_2.append((s_1.pop(), j))
		else:
			print(-1)
			exit()
	elif i == 1:
		s_1.append(j)
st = 1
ans = []
for (p1, p2, p3) in pairs_3:
	ans.append((st, p3))
	ans.append((st, p2))
	st += 1
	ans.append((st, p2))
	ans.append((st, p1))
	st += 1
for (p1, p2) in pairs_2:
	ans.append((st, p2))
	ans.append((st, p1))
	st += 1
for (p1, p3) in pairs_31:
	ans.append((st, p3))
	ans.append((st, p1))
	st += 1
	ans.append((st, p1))
	st += 1
for p1 in s_1:
	ans.append((st, p1))
	st += 1
if s3 != None:
	l = len(s3)
	for (i, j) in zip(range(l - 2, -1, -1), range(l - 1, 0, -1)):
		ans.append((st, s3[i]))
		ans.append((st, s3[j]))
		st += 1
if s31 != None:
	l = len(s31)
	for (i, j) in zip(range(l - 2, -1, -1), range(l - 1, 0, -1)):
		ans.append((st, s31[i]))
		ans.append((st, s31[j]))
		st += 1
	ans.append((st, s31[0]))
	st += 1
print(len(ans))
for i in ans:
	print(*i)


n = int(input())
possible = True
arr = []
for c in input().split():
	arr.append(int(c))
bank1 = []
bank2 = []
bank3 = []
pairs = []
rowUsed = []
for i in range(n):
	rowUsed.append(False)
for i in range(n - 1, -1, -1):
	if arr[i] == 0:
		continue
	elif arr[i] == 1:
		bank1.append(i)
	elif arr[i] == 2:
		bank2.append(i)
		if len(bank1) > 0:
			temp = bank1.pop(len(bank1) - 1)
			pairs.append((temp, i))
		else:
			possible = False
			break
	elif arr[i] == 3:
		if len(bank3) > 0:
			temp = bank3.pop(len(bank3) - 1)
			pairs.append((temp, i))
		elif len(bank2) > 0:
			temp = bank2.pop(len(bank2) - 1)
			pairs.append((temp, i))
		elif len(bank1) > 0:
			temp = bank1.pop(len(bank1) - 1)
			pairs.append((temp, i))
		else:
			possible = False
			break
		bank3.append(i)
nextRow = n
ans = []
for pair in pairs:
	if nextRow <= 0:
		possible = False
		break
	if arr[pair[1]] == 2:
		ans.append((pair[1] + 1, nextRow))
		ans.append((pair[0] + 1, nextRow))
		nextRow -= 1
	elif arr[pair[1]] == 3:
		if arr[pair[0]] == 3:
			ans.append((pair[1] + 1, nextRow))
			ans.append((pair[0] + 1, nextRow))
			nextRow -= 1
		elif arr[pair[0]] == 2:
			ans.append((pair[1] + 1, nextRow))
			ans.append((pair[0] + 1, nextRow))
			nextRow -= 1
		elif arr[pair[0]] == 1:
			ans.append((pair[0] + 1, nextRow))
			nextRow -= 1
			if nextRow <= 0:
				possible = False
				break
			ans.append((pair[0] + 1, nextRow))
			ans.append((pair[1] + 1, nextRow))
			nextRow -= 1
for bank in bank1:
	if nextRow <= 0:
		possible = False
	ans.append((bank + 1, nextRow))
	nextRow -= 1
if possible:
	print(len(ans))
	for point in ans:
		print(point[1], point[0])
else:
	print(-1)


n = int(input())
a = list(map(int, input().split(' ')))
ind = [i for i in range(len(a)) if a[i] > 0]
ind1 = [i for i in range(len(a)) if a[i] == 1]
ind2 = [i for i in range(len(a)) if a[i] == 2]
ind3 = [i for i in range(len(a)) if a[i] == 3]
ind12 = [i for i in range(len(a)) if a[i] == 1 or a[i] == 2]
t = 0
res = []
smola = False
j = 0
d2 = []
k = 0
ajaj = False
if len(ind3) > 0:
	for i in range(len(ind3) - 1):
		t += 2
		res.append([k + 1, ind3[i] + 1])
		res.append([k + 1, ind3[i + 1] + 1])
		k += 1
	t += 2
	res.append([k + 1, ind3[-1] + 1])
	if len(ind2) > 0 and ind3[-1] < ind2[-1]:
		res.append([k + 1, ind2[-1] + 1])
		k += 1
	elif len(ind1) > 0 and ind3[-1] < ind1[-1]:
		res.append([k + 1, ind12[-1] + 1])
		k += 1
		t += 1
		res.append([k + 1, ind12[-1] + 1])
		k += 1
		ind12 = ind12[0:len(ind12) - 1]
	else:
		smola = True
for i in range(len(ind12)):
	if a[ind12[i]] == 1:
		t += 1
		if len(d2) > j:
			res.append([d2[j] + 1, ind12[i] + 1])
			j += 1
		else:
			res.append([k + 1, ind12[i] + 1])
			k += 1
	else:
		t += 1
		res.append([k + 1, ind12[i] + 1])
		d2.append(k)
		k += 1
if len(d2) > j or smola:
	print(-1)
else:
	print(t)
	for i in range(len(res)):
		print(str(res[i][0]) + ' ' + str(res[i][1]))


n = int(input())
a = [int(i) for i in input().split()]
targ = [int(0) for i in range(n)]
di = [int(-1) for i in range(n)]
one = list()
two = list()
ok = 1
for i in range(n - 1, -1, -1):
	if a[i] == 1:
		one.append(i)
		targ[i] = 1
	elif a[i] == 0:
		targ[i] = 0
	elif a[i] == 2:
		if len(one) == 0:
			ok = 0
		else:
			di[i] = one[0]
			targ[one[0]] = 1
			one.pop(0)
			targ[i] = 1
			two.append(i)
	elif len(two) == 0:
		if len(one) == 0:
			ok = 0
		else:
			di[i] = one[0]
			targ[one[0]] = 2
			one.pop(0)
			targ[i] = 1
			two.append(i)
	else:
		di[i] = two[0]
		targ[two[0]] = 2
		two.pop(0)
		targ[i] = 1
		two.append(i)
if ok == 0:
	print(-1)
else:
	ind = 1
	ans = [[-1, -1] for i in range(n + 1)]
	one = list()
	for i in range(n):
		if targ[i] == 2:
			if len(one) > 0 and ans[one[0]][0] != i + 1 and (ans[one[0]][1] == -1):
				if ans[one[0]][0] == -1:
					ans[one[0]][0] = i + 1
				elif ans[one[0]][1] == -1:
					ans[one[0]][1] = i + 1
				one.pop(0)
			else:
				if ind > n:
					ok = 0
				if ans[ind][0] == -1:
					ans[ind][0] = i + 1
				elif ans[ind][1] == -1 and ans[ind][0] != i + 1:
					ans[ind][1] = i + 1
				else:
					ok = 0
				one.append(ind)
				ind += 1
		if targ[i] > 0:
			if a[i] == 1 and len(one) > 0 and (ans[one[0]][0] != i + 1) and (ans[one[0]][1] == -1):
				if ans[one[0]][0] == -1:
					ans[one[0]][0] = i + 1
				elif ans[one[0]][1] == -1:
					ans[one[0]][1] = i + 1
				one.pop(0)
			else:
				if ind > n:
					ok = 0
				if ans[ind][0] == -1:
					ans[ind][0] = i + 1
				elif ans[ind][1] == -1 and ans[ind][0] != i + 1:
					ans[ind][1] = i + 1
				else:
					ok = 0
				if di[i] != -1:
					if ans[ind][0] == -1:
						ans[ind][0] = di[i] + 1
					elif ans[ind][1] == -1:
						ans[ind][1] = di[i] + 1
					else:
						ok = 0
					targ[di[i]] -= 1
				ind += 1
	if ok == 0:
		print(-1)
	else:
		rs = list()
		for i in range(1, n + 1):
			if ans[i][0] != -1:
				rs.append((i, ans[i][0]))
			if ans[i][1] != -1:
				rs.append((i, ans[i][1]))
		print(len(rs))
		for p in rs:
			print(*p)


n = int(input())
a = list(map(int, input().split()))
(one, two, three) = ([], [], [])
row = 0
ans = []
for i in range(n):
	if a[i] == 1:
		if two:
			pop = two.pop()
			ans.append(pop)
			ans.append((pop[0], i))
		elif three:
			pop = three.pop()
			ans.append(pop)
			ans.append((pop[0], i))
			ans.append((i, i))
		else:
			ans.append((i, i))
	if a[i] == 2:
		if three:
			pop = three.pop()
			ans.append(pop)
			ans.append((pop[0], i))
		two.append((i, i))
	elif a[i] == 3:
		if three:
			pop = three.pop()
			ans.append(pop)
			ans.append((pop[0], i))
		three.append((i, i))
if two or three:
	print(-1)
else:
	print(len(ans))
	for i in range(len(ans)):
		print(ans[i][0] + 1, ans[i][1] + 1)


from collections import deque, defaultdict

def solve():
	n = int(input())
	a = list(map(int, input().split()))
	tar = []
	ful2 = []
	ful3 = []
	r = 1
	for i in range(n):
		if a[i] == 3:
			if len(ful3) != 0:
				x = ful3.pop()
				tar.append((x, i + 1))
			tar.append((r, i + 1))
			ful3.append(r)
			r += 1
		elif a[i] == 2:
			if len(ful3) != 0:
				x = ful3.pop()
				tar.append((x, i + 1))
			tar.append((r, i + 1))
			ful2.append(r)
			r += 1
		elif a[i] == 1:
			if len(ful2) != 0:
				x = ful2.pop()
				tar.append((x, i + 1))
			elif len(ful3) != 0:
				x = ful3.pop()
				tar.append((x, i + 1))
				tar.append((r, i + 1))
				r += 1
			else:
				tar.append((r, i + 1))
				r += 1
	if len(ful2) != 0 or len(ful3) != 0:
		print(-1)
	else:
		print(len(tar))
		for i in tar:
			print(i[0], i[1])

def main():
	t = 1
	for _ in range(t):
		solve()
main()


n = int(input())
a = [0] + [int(x) for x in input().split()]
_2 = []
_3 = []
unusedRow = 1
ans = []
for col in range(1, n + 1):
	v = a[col]
	if v == 0:
		continue
	else:
		prevUnusedRow = unusedRow
		if _3:
			r = _3.pop()
			ans.append([r, col])
			ans.append([unusedRow, col])
			unusedRow += 1
		elif _2 and v == 1:
			r = _2.pop()
			ans.append([r, col])
		else:
			ans.append([unusedRow, col])
			unusedRow += 1
		if v == 2:
			_2.append(prevUnusedRow)
		elif v == 3:
			_3.append(prevUnusedRow)
if _2 or _3 or unusedRow > n + 1:
	print(-1)
else:
	print(len(ans))
	ans2 = []
	for rc in ans:
		rcStr = ' '.join([str(z) for z in rc])
		ans2.append(rcStr)
	ans3 = '\n'.join(ans2)
	print(ans3)


input()
l = list(map(int, input().split()))
(a, b, c) = ([], [], [])
for (i, q) in enumerate(l):
	i += 1
	if q == 0:
		continue
	elif q == 1:
		if a:
			c += [(a.pop(), i)]
		elif b:
			c += [(b.pop(), i), (i, i)]
		else:
			c += [(i, i)]
	elif q == 2:
		c += [(i, i)]
		if b:
			c += [(b.pop(), i)]
		a += [i]
	else:
		c += [(i, i)]
		if b:
			c += [(b.pop(), i)]
		b += [i]
if not a and (not b):
	print(len(c))
	for i in c:
		print(*i)
else:
	print(-1)


import sys
input = sys.stdin.readline
n = int(input())
a = list(map(int, input().split()))
ans = []
next_column = 0
row_now = 1
flg_2 = []
for i in range(n):
	if a[i] == 0:
		pass
	elif a[i] == 1:
		if next_column == 2:
			while next_column > 0:
				ans.append([row_now, i + 1])
				row_now += 1
				next_column -= 1
		elif len(flg_2) != 0:
			q = flg_2.pop()
			ans.append([q, i + 1])
		else:
			ans.append([row_now, i + 1])
			row_now += 1
		next_column = 0
	elif a[i] == 2:
		if next_column == 2:
			ans.append([row_now, i + 1])
			row_now += 1
			ans.append([row_now, i + 1])
		else:
			ans.append([row_now, i + 1])
		next_column = 0
		flg_2.append(row_now)
		row_now += 1
	elif a[i] == 3:
		if next_column <= 1:
			ans.append([row_now, i + 1])
			next_column = 2
		else:
			ans.append([row_now, i + 1])
			row_now += 1
			ans.append([row_now, i + 1])
			next_column = 2
if a[-1] >= 2 or len(flg_2) > 0:
	print(-1)
	exit()
print(len(ans))
for i in ans:
	print(i[0], i[1])


n = int(input())
a = list(map(int, input().split()))
twos = []
threes = []
pts = []
for (i, q) in enumerate(a):
	i = i + 1
	if q == 0:
		pass
	elif q == 1:
		if twos:
			pts += [(twos.pop(), i)]
		elif threes:
			pts += [(threes.pop(), i), (i, i)]
		else:
			pts += [(i, i)]
	elif q == 2:
		pts += [(i, i)]
		if threes:
			pts += [(threes.pop(), i)]
		twos += [i]
	elif q == 3:
		pts += [(i, i)]
		if threes:
			pts += [(threes.pop(), i)]
		threes += [i]
if not twos and (not threes):
	print(len(pts))
	for x in pts:
		print(*x)
else:
	print(-1)


n = int(input())
a = list(map(int, input().split()))
ans = []
three = []
two = []
for i in range(n):
	if a[i] == 0:
		continue
	if a[i] == 3:
		if len(three) > 0:
			x = three.pop()
			ans.append((x, i))
			ans.append((i, i))
			three.append(i)
		else:
			ans.append((i, i))
			three.append(i)
	elif a[i] == 2:
		if len(three) > 0:
			x = three.pop()
			ans.append((x, i))
			ans.append((i, i))
			two.append(i)
		else:
			ans.append((i, i))
			two.append(i)
	elif len(three) > 0:
		x = three.pop()
		ans.append((x, i))
		ans.append((i, i))
	elif len(two) > 0:
		x = two.pop()
		ans.append((x, i))
	else:
		ans.append((i, i))
if len(three) > 0 or len(two) > 0:
	print(-1)
else:
	print(len(ans))
	for (i, j) in ans:
		print(i + 1, j + 1)


import sys
input = lambda : sys.stdin.readline().rstrip()
from collections import deque
n = int(input())
a = list(map(int, input().split()))
ans = []
q1 = deque()
q2 = deque()
for i in range(n - 1, -1, -1):
	if a[i] == 0:
		continue
	if a[i] == 1:
		ans.append((i + 1, i + 1))
		q1.append(i)
		continue
	if a[i] == 2:
		if not q1:
			print(-1)
			exit(0)
		idx = q1.popleft()
		ans.append((idx + 1, i + 1))
	else:
		if q2:
			idx = q2.popleft()
		elif q1:
			idx = q1.popleft()
		else:
			print(-1)
			exit(0)
		ans.append((i + 1, i + 1))
		ans.append((i + 1, idx + 1))
	q2.append(i)
print(len(ans))
for i in ans:
	print(*i)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if not True else 1):
	n = int(input())
	a = list(map(int, input().split()))
	cur_row = 0
	ans = []
	cols = [[] for i in range(n + 1)]
	two = []
	three = []
	for i in range(n):
		if a[i] == 0:
			continue
		if a[i] == 2:
			if three:
				cols[i] += [three.pop()]
			two += [cur_row]
			cols[i] += [cur_row]
			cur_row += 1
		if a[i] == 3:
			if not three:
				three += [cur_row]
				cols[i] += [cur_row]
			else:
				cols[i] += [three.pop()]
				cols[i] += [cur_row]
				three += [cur_row]
			cur_row += 1
		if a[i] == 1:
			if three:
				cols[i] += [three.pop()]
				cols[i] += [cur_row]
				cur_row += 1
			elif two:
				cols[i] += [two.pop()]
			else:
				cols[i] += [cur_row]
				cur_row += 1
	x = [k for p in cols for k in p]
	if not x:
		print(0)
		continue
	if max(x) >= n or two or three:
		print(-1)
	else:
		for i in range(n):
			for j in cols[i]:
				ans += [[j + 1, i + 1]]
		print(len(ans))
		for i in ans:
			print(*i)


input()
(a, b, c) = ([], [], [])
k = [a, b]
for (i, x) in enumerate(map(int, input().split())):
	i += 1
	if x == 1:
		if a:
			c += [(a.pop(), i)]
		elif b:
			c += [(b.pop(), i), (i, i)]
		else:
			c += [(i, i)]
	elif x != 0:
		c += [(i, i)]
		if b:
			c += [(b.pop(), i)]
		k[x - 2] += [i]
if a or b:
	print(-1)
else:
	print(len(c))
	for i in c:
		print(*i)


n = int(input())
l = list(map(int, input().split()))
row = n - 1
ans = []
ones = []
twos = []
threes = []
f = 0
for col in range(n - 1, -1, -1):
	if l[col] == 0:
		continue
	elif row == -1:
		f = 1
		break
	elif l[col] == 1:
		ans.append([row + 1, col + 1])
		ones.append([row, col])
		row -= 1
	elif l[col] == 2:
		if len(ones) == 0:
			f = 1
			break
		else:
			lastone = ones.pop()
			ans.append([lastone[0] + 1, col + 1])
			twos.append([lastone[0], col])
	else:
		if len(twos) > 0:
			lasttwo = twos.pop()
			ans.append([row + 1, col + 1])
			ans.append([row + 1, lasttwo[1] + 1])
		elif len(threes) > 0:
			lastthree = threes.pop()
			ans.append([row + 1, col + 1])
			ans.append([row + 1, lastthree[1] + 1])
		elif len(ones) > 0:
			lastone = ones.pop()
			ans.append([row + 1, col + 1])
			ans.append([row + 1, lastone[1] + 1])
		else:
			f = 1
			break
		threes.append([row, col])
		row -= 1
if f == 1:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


import sys
input = sys.stdin.buffer.readline
n = int(input())
a = [int(i) for i in input().split()]
col = []
ans = []
c = 1
col2 = []
for i in range(n):
	if a[i] == 1:
		col.append(i)
	elif a[i] == 2:
		col2.append(i)
chk = 1
if 3 in a:
	l3 = n - 1 - a[::-1].index(3)
	f3 = a.index(3)
else:
	l3 = -1
if 2 in a:
	l2 = n - 1 - a[::-1].index(2)
else:
	l2 = 0
if 1 in a:
	l1 = n - 1 - a[::-1].index(1)
else:
	l1 = -1
if l3 >= 0 and l1 >= 0:
	for i in range(n):
		if a[i] == 3 and i == f3:
			ans.append([c, i + 1])
		elif a[i] == 3:
			ans.append([c, i + 1])
			c += 1
			ans.append([c, i + 1])
	if l1 > l2 and l3 < l2:
		ans.append([c, l2 + 1])
		c += 1
		ans.append([c, l2 + 1])
		ans.append([c, l1 + 1])
		c += 1
		col.pop()
		col2.pop()
	elif l3 < l1:
		ans.append([c, l1 + 1])
		c += 1
		ans.append([c, l1 + 1])
		col.pop()
		c += 1
	else:
		chk = 0
elif l3 >= 0 and l1 < 0:
	print(-1)
	exit(0)
col.reverse()
col2.reverse()
for i in range(n):
	if a[i] == 2:
		if col2 and (not col) and (col2[-1] == i):
			chk = 0
		if col2 and col and (col2[-1] == i):
			if c > n:
				chk = 0
			ans.append([c, i + 1])
			ans.append([c, col[-1] + 1])
			col.pop()
			col2.pop()
			c += 1
	elif a[i] == 1:
		if col and col[-1] == i:
			if c > n:
				chk = 0
			ans.append([c, i + 1])
			c += 1
			col.pop()
	else:
		continue
if chk == 1:
	print(len(ans))
	for i in ans:
		print(*i)
else:
	print(-1)


import sys, math
import io, os
from bisect import bisect_left as bl, bisect_right as br, insort
from heapq import heapify, heappush, heappop
from collections import defaultdict as dd, deque, Counter

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write('\n'.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
INF = float('inf')
mod = 10 ** 9 + 7
n = int(data())
c = [[INF] for i in range(4)]
a = mdata()
for i in range(n):
	c[a[i]].append(i + 1)
for i in range(4):
	c[i].sort(reverse=True)
r = 1
ans = []
k = 1
while c:
	if c[1][-1] == INF:
		break
	if c[1][-1] < c[2][-1] and c[1][-1] < c[3][-1]:
		if k == 3:
			ans.append([r - 1, c[1][-1]])
		ans.append([r, c[1].pop()])
		r += 1
		k = 1
	elif c[3][-1] < c[2][-1] and c[3][-1] < c[1][-1]:
		if k == 3:
			ans.append([r - 1, c[3][-1]])
		ans.append([r, c[3].pop()])
		r += 1
		k = 3
	elif c[2][-1] < c[1][-1] and c[2][-1] < c[3][-1]:
		if k == 3:
			ans.append([r - 1, c[2][-1]])
		ans.append([r, c[2].pop()])
		if c[-1] == INF:
			out(-1)
			exit()
		ans.append([r, c[1].pop()])
		r += 1
		k = 2
if len(c[2]) != 1 or len(c[3]) != 1 or k == 3:
	out(-1)
else:
	for i in range(len(ans)):
		ans[i] = str(ans[i][0]) + ' ' + str(ans[i][1])
	out(len(ans))
	outl(ans)


n = int(input())
arr = list(map(int, input().split()))
trg = [-1] * n
st = []
for i in range(n):
	if arr[i] > 1 and len(st) > 0:
		trg[st.pop()] = i
	if arr[i] == 3:
		st.append(i)
st = []
for i in range(n):
	if arr[i] > 1 and trg[i] < 0:
		st.append(i)
	elif arr[i] == 1 and len(st) > 0:
		trg[st.pop()] = i
if len(st) > 0:
	print(-1)
	exit()
vis = [False] * n
res = []
fl = 0
for i in range(n):
	if vis[i] or arr[i] == 0:
		continue
	path = [i]
	vis[i] = True
	ptr = i
	while trg[ptr] >= 0:
		ptr = trg[ptr]
		vis[ptr] = True
		path.append(ptr)
	w = len(path)
	if len(path) > 1 and arr[path[-2]] == 2:
		w -= 1
	for j in range(w):
		res.append((fl + j + 1, path[j] + 1))
		if j != len(path) - 1:
			res.append((fl + j + 1, path[j + 1] + 1))
	fl += w
print(len(res))
for e in res:
	print(*e)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
n = N()
a = RLL()
now = 1
res = []
(t2, t3) = ([], [])
for i in range(n):
	if a[i] == 0:
		continue
	if a[i] == 1:
		if t2:
			res.append((t2.pop(), i))
		else:
			res.append((now, i))
			now += 1
			if t3:
				res.append((t3.pop(), i))
	elif a[i] == 2:
		res.append((now, i))
		t2.append(now)
		now += 1
		if t3:
			res.append((t3.pop(), i))
	else:
		if t3:
			res.append((t3.pop(), i))
		res.append((now, i))
		t3.append(now)
		now += 1
if t2 or t3:
	print(-1)
else:
	print(len(res))
	for (r, c) in res:
		print(r, c + 1)


n = int(input())
A = list(map(int, input().split()))
X1 = []
X2 = []
X3 = []
P21 = []
P31 = []
P32 = []
P33 = []
for i in reversed(range(n)):
	a = A[i]
	if a == 3:
		if not X1 and (not X2) and (not X3):
			print(-1)
			exit()
		elif not X1 and (not X2):
			j = X3.pop()
			P33.append((i, j))
		elif not X1 and (not X3):
			j = X2.pop()
			P32.append((i, j))
		elif not X2 and (not X3):
			j = X1.pop()
			P31.append((i, j))
		elif not X1:
			j = X3.pop()
			P33.append((i, j))
		elif not X2:
			j = X3.pop()
			P33.append((i, j))
		elif not X3:
			j = X2.pop()
			P32.append((i, j))
		else:
			j = X3.pop()
			P33.append((i, j))
		X3.append(i)
	elif a == 2:
		if not X1:
			print(-1)
			exit()
		else:
			j = X1.pop()
			P21.append((i, j))
		X2.append(i)
	elif a == 1:
		X1.append(i)
cur = n + 1
ans = []
used = set()
for (i, j) in P21:
	if cur - 1 <= 0:
		print(-1)
		exit()
	ans.append((cur - 1, j + 1))
	ans.append((cur - 1, i + 1))
	cur -= 1
	used.add(i)
	used.add(j)
for (i, j) in P31:
	if cur - 2 <= 0:
		print(-1)
		exit()
	ans.append((cur - 1, j + 1))
	ans.append((cur - 2, j + 1))
	ans.append((cur - 2, i + 1))
	cur -= 2
	used.add(i)
	used.add(j)
for (i, j) in P32:
	if cur - 1 <= 0:
		print(-1)
		exit()
	ans.append((cur - 1, j + 1))
	ans.append((cur - 1, i + 1))
	cur -= 1
	used.add(i)
	used.add(j)
for (i, j) in P33:
	if cur - 1 <= 0:
		print(-1)
		exit()
	ans.append((cur - 1, j + 1))
	ans.append((cur - 1, i + 1))
	cur -= 1
	used.add(i)
	used.add(j)
for j in X1:
	if j in used:
		continue
	if cur - 1 <= 0:
		print(-1)
		exit()
	ans.append((cur - 1, j + 1))
	cur -= 1
print(len(ans))
for i in range(len(ans)):
	print(*ans[i])


import sys
input = sys.stdin.readline
n = int(input())
a = list(map(int, input().split()))
(av1, av2, av3) = (set(), set(), set())
(ans, f, i) = ([], 0, n - 1)
for j in range(n - 1, -1, -1):
	if a[j] == 1:
		av1.add((i, j))
		ans.append((i, j))
	elif a[j] == 2:
		if av1:
			(ii, jj) = av1.pop()
			av2.add((ii, j))
			ans.append((ii, j))
		else:
			f = 1
			break
	elif a[j] == 3:
		if av3:
			(ii, jj) = av3.pop()
		elif av2:
			(ii, jj) = av2.pop()
		elif av1:
			(ii, jj) = av1.pop()
		else:
			f = 1
			break
		av3.add((i, j))
		ans.append((i, jj))
		ans.append((i, j))
	i -= 1
if f:
	print(-1)
elif ans:
	print(len(ans))
	for (i, j) in ans:
		print(i + 1, j + 1)
else:
	print(0)