← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)
	a := make([]int, n+1)
	idsByVal := make([][]int, n+1)
	for i := 1; i <= n; i++ {
		fmt.Fscan(in, &a[i])
		idsByVal[a[i]] = append(idsByVal[a[i]], i)
	}

	x := make([]int, n+1)
	y := make([]int, n+1)
	target := make([]int, n+1)

	if n == 2 {
		ok := false
		if a[1] == 0 && a[2] == 0 {
			x[1], y[1], target[1] = 1, 1, 1
			x[2], y[2], target[2] = 2, 1, 2
			ok = true
		} else if a[1] == 0 {
			if a[2] == 1 {
				x[1], y[1], target[1] = 1, 1, 1
				x[2], y[2], target[2] = 2, 1, 1
				ok = true
			} else if a[2] == 2 {
				x[1], y[1], target[1] = 1, 1, 1
				x[2], y[2], target[2] = 2, 2, 1
				ok = true
			}
		} else if a[2] == 0 {
			if a[1] == 1 {
				x[2], y[2], target[2] = 1, 1, 2
				x[1], y[1], target[1] = 2, 1, 2
				ok = true
			} else if a[1] == 2 {
				x[2], y[2], target[2] = 1, 1, 2
				x[1], y[1], target[1] = 2, 2, 2
				ok = true
			}
		} else if a[1] == a[2] {
			if a[1] == 1 {
				x[1], y[1], target[1] = 1, 1, 2
				x[2], y[2], target[2] = 2, 1, 1
				ok = true
			} else if a[1] == 2 {
				x[1], y[1], target[1] = 1, 1, 2
				x[2], y[2], target[2] = 2, 2, 1
				ok = true
			}
		}
		if !ok {
			fmt.Fprintln(out, "NO")
			return
		}
		fmt.Fprintln(out, "YES")
		for i := 1; i <= n; i++ {
			fmt.Fprintln(out, x[i], y[i])
		}
		for i := 1; i <= n; i++ {
			if i > 1 {
				fmt.Fprint(out, " ")
			}
			fmt.Fprint(out, target[i])
		}
		fmt.Fprintln(out)
		return
	}

	pop := func(v int) int {
		l := len(idsByVal[v])
		id := idsByVal[v][l-1]
		idsByVal[v] = idsByVal[v][:l-1]
		return id
	}

	buildSegment := func(v, start int) int {
		c := len(idsByVal[v])
		ids := make([]int, c)
		for i := 0; i < c; i++ {
			ids[i] = pop(v)
		}
		for i, id := range ids {
			x[id] = start + i
			if i%2 == 0 {
				y[id] = 1
			} else {
				y[id] = v
			}
		}
		for i, id := range ids {
			if i+1 < c {
				target[id] = ids[i+1]
			} else {
				target[id] = ids[i-1]
			}
		}
		return c
	}

	allDistinctPositive := len(idsByVal[0]) == 0
	if allDistinctPositive {
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) != 1 {
				allDistinctPositive = false
				break
			}
		}
	}

	if allDistinctPositive {
		id1 := pop(1)
		id2 := pop(2)
		id3 := pop(3)

		x[id1], y[id1], target[id1] = 1, 1, id2
		x[id2], y[id2], target[id2] = 2, 1, id3
		x[id3], y[id3], target[id3] = 3, 2, id1

		for v := 4; v <= n; v++ {
			id := pop(v)
			x[id] = v
			y[id] = 2
			target[id] = id1
		}
	} else if len(idsByVal[0]) > 0 {
		anchor := pop(0)
		x[anchor], y[anchor], target[anchor] = 1, 1, anchor

		singletons := make([]int, 0)
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) == 1 {
				singletons = append(singletons, v)
			}
		}

		for i, v := range singletons {
			id := pop(v)
			idx := i + 1
			x[id] = 1 + idx
			y[id] = v - idx + 1
			target[id] = anchor
		}

		cur := len(singletons) + 2
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) >= 2 {
				cur += buildSegment(v, cur)
			}
		}
		for len(idsByVal[0]) > 0 {
			id := pop(0)
			x[id] = cur
			y[id] = 1
			target[id] = id
			cur++
		}
	} else {
		p, coreSize := 0, 0
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) >= 2 && len(idsByVal[v]) != 3 {
				p = v
				coreSize = 2
				break
			}
		}
		if p == 0 {
			for v := 1; v <= n; v++ {
				if len(idsByVal[v]) == 3 {
					p = v
					coreSize = 3
					break
				}
			}
		}

		core := make([]int, coreSize)
		for i := 0; i < coreSize; i++ {
			core[i] = pop(p)
		}

		singletons := make([]int, 0)
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) == 1 {
				singletons = append(singletons, v)
			}
		}

		k := len(singletons)
		anchorCol := k + 1
		A := core[0]
		x[A], y[A] = anchorCol, 1

		for i, v := range singletons {
			id := pop(v)
			idx := i + 1
			x[id] = anchorCol - idx
			y[id] = v - idx + 1
			target[id] = A
		}

		if coreSize == 2 {
			B := core[1]
			x[B], y[B] = anchorCol+1, p
			target[A] = B
			target[B] = A
		} else {
			B := core[1]
			C := core[2]
			x[B], y[B] = anchorCol+1, p
			x[C], y[C] = anchorCol+2, 1
			target[A] = B
			target[B] = C
			target[C] = B
		}

		cur := k + coreSize + 1
		for v := 1; v <= n; v++ {
			if len(idsByVal[v]) >= 2 {
				cur += buildSegment(v, cur)
			}
		}
	}

	fmt.Fprintln(out, "YES")
	for i := 1; i <= n; i++ {
		fmt.Fprintln(out, x[i], y[i])
	}
	for i := 1; i <= n; i++ {
		if i > 1 {
			fmt.Fprint(out, " ")
		}
		fmt.Fprint(out, target[i])
	}
	fmt.Fprintln(out)
}