← Home
package main

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

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

type SegTree struct {
	maxVal []int
	lazy   []int
	n      int
}

func NewSegTree(n int) *SegTree {
	return &SegTree{
		maxVal: make([]int, 4*n+1),
		lazy:   make([]int, 4*n+1),
		n:      n,
	}
}

func (st *SegTree) push(node int) {
	if st.lazy[node] != 0 {
		st.maxVal[2*node] += st.lazy[node]
		st.lazy[2*node] += st.lazy[node]
		st.maxVal[2*node+1] += st.lazy[node]
		st.lazy[2*node+1] += st.lazy[node]
		st.lazy[node] = 0
	}
}

func (st *SegTree) Add(node, l, r, ql, qr, val int) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		st.maxVal[node] += val
		st.lazy[node] += val
		return
	}
	st.push(node)
	mid := (l + r) / 2
	st.Add(2*node, l, mid, ql, qr, val)
	st.Add(2*node+1, mid+1, r, ql, qr, val)
	st.maxVal[node] = max(st.maxVal[2*node], st.maxVal[2*node+1])
}

type Item struct {
	val, idx, depth int
}

func compute_depths(C []int) []int {
	L := len(C)
	D := make([]int, L+1)
	D[0] = 0
	if L == 0 {
		return D
	}

	st := NewSegTree(L)
	stack := make([]Item, 0, L)

	for i := 1; i <= L; i++ {
		val := C[i-1]
		for len(stack) > 0 && stack[len(stack)-1].val > val {
			stack = stack[:len(stack)-1]
		}

		left_idx := 1
		if len(stack) > 0 {
			left_idx = stack[len(stack)-1].idx + 1
		}

		right_idx := i - 1
		if left_idx <= right_idx {
			st.Add(1, 1, L, left_idx, right_idx, 1)
		}

		depth := 1
		if len(stack) > 0 {
			depth = stack[len(stack)-1].depth + 1
		}

		st.Add(1, 1, L, i, i, depth)
		stack = append(stack, Item{val: val, idx: i, depth: depth})

		D[i] = st.maxVal[1]
	}
	return D
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())

	A := make([]int, n)
	p0 := -1
	for i := 0; i < n; i++ {
		scanner.Scan()
		A[i], _ = strconv.Atoi(scanner.Text())
		if A[i] == 1 {
			p0 = i
		}
	}

	if n == 1 {
		fmt.Println("1 0")
		return
	}

	B := make([]int, n-1)
	for i := 0; i < n-1; i++ {
		B[i] = A[(p0+1+i)%n]
	}

	D_pref := compute_depths(B)

	B_rev := make([]int, n-1)
	for i := 0; i < n-1; i++ {
		B_rev[i] = B[n-2-i]
	}
	D_pref_rev := compute_depths(B_rev)

	minDepth := int(1e9)
	bestS := -1

	for k := 0; k < n; k++ {
		dY := D_pref[k]
		dX := D_pref_rev[n-1-k]
		depth := 1 + max(dY, dX)
		if depth < minDepth {
			minDepth = depth
			bestS = (p0 + 1 + k) % n
		}
	}

	fmt.Printf("%d %d\n", minDepth, bestS)
}