← Home
package main
 
import (
	"bufio"
	"fmt"
	"os"
	"sort"
)
 
type Segment struct {
	id int
	l  int
	r  int
}
 
func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int
	if _, err := fmt.Fscan(reader, &n); err != nil {
		return
	}
 
	segments := make([]Segment, n)
	for i := 0; i < n; i++ {
		segments[i].id = i
		fmt.Fscan(reader, &segments[i].l, &segments[i].r)
	}
 
	adj := make([][]int, n)
	for i := 0; i < n; i++ {
		for j := i + 1; j < n; j++ {
			if max(segments[i].l, segments[j].l) <= min(segments[i].r, segments[j].r) {
				adj[i] = append(adj[i], j)
				adj[j] = append(adj[j], i)
			}
		}
	}
 
	orderSegs := make([]Segment, n)
	copy(orderSegs, segments)
	sort.Slice(orderSegs, func(i, j int) bool {
		if orderSegs[i].r != orderSegs[j].r {
			return orderSegs[i].r < orderSegs[j].r
		}
		return orderSegs[i].l < orderSegs[j].l
	})
 
	order := make([]int, n)
	for i := 0; i < n; i++ {
		order[i] = orderSegs[i].id
	}
 
	ans := make([]int, n)
	for i := 0; i < n; i++ {
		ans[i] = i
	}
 
	if n == 1 {
		fmt.Println(1)
		return
	}
 
	limit := make([]int, n)
	placed := make([]bool, n)
	cnt := make([]int, n)
	curAns := make([]int, n)
	freq := make([]int, n)
 
	check := func(M int) bool {
		for i := 0; i < n; i++ {
			limit[i] = n - 1
			placed[i] = false
		}
 
		for i := 0; i < n; i++ {
			for j := 0; j < n; j++ {
				cnt[j] = 0
			}
			for j := 0; j < n; j++ {
				if !placed[j] {
					cnt[limit[j]]++
				}
			}
			for x := 1; x < n; x++ {
				cnt[x] += cnt[x-1]
			}
 
			if i > 0 && cnt[i-1] > 0 {
				return false
			}
 
			reqX := n - 1
			for x := i; x < n; x++ {
				allowed := x - i + 1 - cnt[x]
				if allowed == 0 {
					if x < reqX {
						reqX = x
					}
				} else if allowed < 0 {
					return false
				}
			}
 
			bestJ := -1
			for _, j := range order {
				if placed[j] {
					continue
				}
				if limit[j] > reqX {
					continue
				}
 
				possible := true
				if i+M < n {
					for x := 0; x < n; x++ {
						freq[x] = 0
					}
					for _, k := range adj[j] {
						if !placed[k] {
							freq[limit[k]]++
						}
					}
 
					c := 0
					for x := n - 1; x >= i+M; x-- {
						allowed := x - i + 1 - cnt[x]
						if limit[j] <= x {
							if c > allowed {
								possible = false
								break
							}
						} else {
							if c > allowed-1 {
								possible = false
								break
							}
						}
						c += freq[x]
					}
				}
 
				if possible {
					bestJ = j
					break
				}
			}
 
			if bestJ == -1 {
				return false
			}
 
			placed[bestJ] = true
			curAns[i] = bestJ
			for _, k := range adj[bestJ] {
				if !placed[k] && limit[k] > i+M {
					limit[k] = i + M
				}
			}
		}
		return true
	}
 
	low := 1
	high := n - 1
	for low <= high {
		mid := (low + high) / 2
		if check(mid) {
			copy(ans, curAns)
			high = mid - 1
		} else {
			low = mid + 1
		}
	}
 
	for i := 0; i < n; i++ {
		if i > 0 {
			fmt.Print(" ")
		}
		fmt.Print(ans[i] + 1)
	}
	fmt.Println()
}
 
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
 
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}