← Home
package main

import (
	"io"
	"os"
	"strconv"
)

type Pair struct {
	key int
	id  int
}

type MinHeap struct {
	a []Pair
}

func less(x, y Pair) bool {
	if x.key != y.key {
		return x.key < y.key
	}
	return x.id < y.id
}

func (h *MinHeap) Len() int {
	return len(h.a)
}

func (h *MinHeap) Top() Pair {
	return h.a[0]
}

func (h *MinHeap) Push(x Pair) {
	h.a = append(h.a, x)
	i := len(h.a) - 1
	for i > 0 {
		p := (i - 1) >> 1
		if less(h.a[p], x) {
			break
		}
		h.a[i] = h.a[p]
		i = p
	}
	h.a[i] = x
}

func (h *MinHeap) Pop() Pair {
	n := len(h.a)
	res := h.a[0]
	last := h.a[n-1]
	h.a = h.a[:n-1]
	if n == 1 {
		return res
	}
	i := 0
	for {
		l := i*2 + 1
		if l >= n-1 {
			break
		}
		r := l + 1
		c := l
		if r < n-1 && less(h.a[r], h.a[l]) {
			c = r
		}
		if !less(h.a[c], last) {
			break
		}
		h.a[i] = h.a[c]
		i = c
	}
	h.a[i] = last
	return res
}

const INF int = 1 << 60

type SegTree struct {
	n    int
	min  []int
	lazy []int
	pos  []int
}

func NewSegTree(arr []int, n int) *SegTree {
	st := &SegTree{
		n:    n,
		min:  make([]int, 4*n+5),
		lazy: make([]int, 4*n+5),
		pos:  make([]int, 4*n+5),
	}
	st.build(1, 1, n, arr)
	return st
}

func (st *SegTree) build(node, l, r int, arr []int) {
	if l == r {
		st.min[node] = arr[l]
		st.pos[node] = l
		return
	}
	m := (l + r) >> 1
	st.build(node<<1, l, m, arr)
	st.build(node<<1|1, m+1, r, arr)
	st.pull(node)
}

func (st *SegTree) pull(node int) {
	ln := node << 1
	rn := ln | 1
	if st.min[ln] <= st.min[rn] {
		st.min[node] = st.min[ln]
		st.pos[node] = st.pos[ln]
	} else {
		st.min[node] = st.min[rn]
		st.pos[node] = st.pos[rn]
	}
}

func (st *SegTree) apply(node, v int) {
	st.min[node] += v
	st.lazy[node] += v
}

func (st *SegTree) push(node int) {
	if st.lazy[node] != 0 {
		v := st.lazy[node]
		st.apply(node<<1, v)
		st.apply(node<<1|1, v)
		st.lazy[node] = 0
	}
}

func (st *SegTree) rangeAdd(node, l, r, ql, qr, v int) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		st.apply(node, v)
		return
	}
	st.push(node)
	m := (l + r) >> 1
	if ql <= m {
		st.rangeAdd(node<<1, l, m, ql, qr, v)
	}
	if qr > m {
		st.rangeAdd(node<<1|1, m+1, r, ql, qr, v)
	}
	st.pull(node)
}

func (st *SegTree) pointSetInf(node, l, r, idx int) {
	if l == r {
		st.min[node] = INF
		st.lazy[node] = 0
		return
	}
	st.push(node)
	m := (l + r) >> 1
	if idx <= m {
		st.pointSetInf(node<<1, l, m, idx)
	} else {
		st.pointSetInf(node<<1|1, m+1, r, idx)
	}
	st.pull(node)
}

func appendPerm(out []byte, p []int, n int) []byte {
	for i := 1; i <= n; i++ {
		if i > 1 {
			out = append(out, ' ')
		}
		out = strconv.AppendInt(out, int64(p[i]), 10)
	}
	out = append(out, '\n')
	return out
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		val := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			val = val*10 + int(data[idx]-'0')
			idx++
		}
		return val
	}

	n := nextInt()
	a := make([]int, n+1)
	b := make([]int, n+1)
	byA := make([][]int, n+2)
	for i := 1; i <= n; i++ {
		a[i] = nextInt()
		b[i] = nextInt()
		byA[a[i]] = append(byA[a[i]], i)
	}

	ans1 := make([]int, n+1)
	t := make([]int, n+1)

	var h MinHeap
	for x := 1; x <= n; x++ {
		for _, id := range byA[x] {
			h.Push(Pair{b[id], id})
		}
		p := h.Pop()
		id := p.id
		ans1[id] = x
		t[x] = id
	}

	L := make([]int, n+1)
	R := make([]int, n+1)
	for x := 1; x <= n; x++ {
		id := t[x]
		L[x] = a[id]
		R[x] = b[id]
	}

	diff := make([]int, n+3)
	for x := 1; x <= n; x++ {
		diff[L[x]]++
		diff[R[x]+1]--
	}
	indeg := make([]int, n+1)
	cur := 0
	for i := 1; i <= n; i++ {
		cur += diff[i]
		indeg[i] = cur - 1
	}

	st := NewSegTree(indeg, n)
	removed := make([]bool, n+1)
	remCount := n
	for st.min[1] == 0 {
		x := st.pos[1]
		removed[x] = true
		remCount--
		st.pointSetInf(1, 1, n, x)
		if L[x] <= x-1 {
			st.rangeAdd(1, 1, n, L[x], x-1, -1)
		}
		if x+1 <= R[x] {
			st.rangeAdd(1, 1, n, x+1, R[x], -1)
		}
	}

	out := make([]byte, 0, n*16)

	if remCount == 0 {
		out = append(out, 'Y', 'E', 'S', '\n')
		out = appendPerm(out, ans1, n)
		os.Stdout.Write(out)
		return
	}

	byL := make([][]int, n+2)
	start := 0
	for x := 1; x <= n; x++ {
		if !removed[x] {
			byL[L[x]] = append(byL[L[x]], x)
			if start == 0 {
				start = x
			}
		}
	}

	pred := make([]int, n+1)
	var h2 MinHeap
	for y := 1; y <= n; y++ {
		for _, x := range byL[y] {
			h2.Push(Pair{R[x], x})
		}
		for h2.Len() > 0 && h2.Top().key < y {
			h2.Pop()
		}
		if !removed[y] {
			first := h2.Pop()
			if first.id != y {
				pred[y] = first.id
				h2.Push(first)
			} else {
				second := h2.Pop()
				pred[y] = second.id
				h2.Push(second)
				h2.Push(first)
			}
		}
	}

	seen := make([]int, n+1)
	seq := make([]int, 0, remCount)
	x := start
	for seen[x] == 0 {
		seen[x] = len(seq) + 1
		seq = append(seq, x)
		x = pred[x]
	}
	s := seen[x] - 1
	cycle := make([]int, 0, len(seq)-s)
	cycle = append(cycle, x)
	for i := len(seq) - 1; i > s; i-- {
		cycle = append(cycle, seq[i])
	}

	ans2 := make([]int, n+1)
	copy(ans2, ans1)
	m := len(cycle)
	for i := 0; i < m; i++ {
		curSlot := cycle[i]
		nextSlot := cycle[(i+1)%m]
		pos := t[curSlot]
		ans2[pos] = nextSlot
	}

	out = append(out, 'N', 'O', '\n')
	out = appendPerm(out, ans1, n)
	out = appendPerm(out, ans2, n)
	os.Stdout.Write(out)
}