```go
package main
import (
"bufio"
"fmt"
"os"
)
const INF = 1000000000
const NINF = -1000000000
const NO_VAL = 2000000000
var treeX []int
var treeY []int
func setX(node, l, r, ql, qr, val int) {
if ql > qr {
return
}
if ql <= l && r <= qr {
treeX[node] = val
return
}
if treeX[node] != NO_VAL {
treeX[2*node] = treeX[node]
treeX[2*node+1] = treeX[node]
treeX[node] = NO_VAL
}
mid := (l + r) / 2
if ql <= mid {
setX(2*node, l, mid, ql, qr, val)
}
if qr > mid {
setX(2*node+1, mid+1, r, ql, qr, val)
}
}
func setY(node, l, r, ql, qr, val int) {
if ql > qr {
return
}
if ql <= l && r <= qr {
treeY[node] = val
return
}
if treeY[node] != NO_VAL {
treeY[2*node] = treeY[node]
treeY[2*node+1] = treeY[node]
treeY[node] = NO_VAL
}
mid := (l + r) / 2
if ql <= mid {
setY(2*node, l, mid, ql, qr, val)
}
if qr > mid {
setY(2*node+1, mid+1, r, ql, qr, val)
}
}
func queryX(n, idx int) int {
node, l, r := 1, 1, n
for l < r {
if treeX[node] != NO_VAL {
return treeX[node]
}
mid := (l + r) / 2
if idx <= mid {
node = 2 * node
r = mid
} else {
node = 2 * node + 1
l = mid + 1
}
}
return treeX[node]
}
func queryY(n, idx int) int {
node, l, r := 1, 1, n
for l < r {
if treeY[node] != NO_VAL {
return treeY[node]
}
mid := (l + r) / 2
if idx <= mid {
node = 2 * node
r = mid
} else {
node = 2 * node + 1
l = mid + 1
}
}
return treeY[node]
}
func binarySearchX_greater(low, high, val, n int) int {
ans := high + 1
l, r := low, high
for l <= r {
mid := (l + r) / 2
if queryX(n, mid) > val {
ans = mid
r = mid - 1
} else {
l = mid + 1
}
}
return ans
}
func binarySearchY_less(low, high, val, n int) int {
ans := high + 1
l, r := low, high
for l <= r {
mid := (l + r) / 2
if queryY(n, mid) < val {
ans = mid
r = mid - 1
} else {
l = mid + 1
}
}
return ans
}
func binarySearchX_greater_equal(low, high, val, n int) int {
ans := high + 1
l, r := low, high
for l <= r {
mid := (l + r) / 2
if queryX(n, mid) >= val {
ans = mid
r = mid - 1
} else {
l = mid + 1
}
}
return ans
}
func binarySearchY_less_equal(low, high, val, n int) int {
ans := high + 1
l, r := low, high
for l <= r {
mid := (l + r) / 2
if queryY(n, mid) <= val {
ans = mid
r = mid - 1
} else {
l = mid + 1
}
}
return ans
}
func readInt(in *bufio.Reader) int {
n := 0
c, err := in.ReadByte()
if err != nil {
return 0
}
for c <= 32 {
c, err = in.ReadByte()
if err != nil {
return 0
}
}
for c > 32 {
n = n*10 + int(c-'0')
c, err = in.ReadByte()
if err != nil {
break
}
}
return n
}
func main() {
in := bufio.NewReader(os.Stdin)
n := readInt(in)
if n == 0 {
return
}
p := make([]int, n+1)
for i := 1; i <= n; i++ {
p[i] = readInt(in)
}
treeX = make([]int, 4*n+1)
treeY = make([]int, 4*n+1)
for i := range treeX {
treeX[i] = NO_VAL
treeY[i] = NO_VAL
}
ansTotal := 0
for i := 1; i <= n; i++ {
if i == 1 {
setX(1, 1, n, 1, 1, INF)
setY(1, 1, n, 1, 1, NINF)
ansTotal += 1
continue
}
u := p[i-1]
v := p[i]
if v > u {
ly := binarySearchY_less(1, i-1, v, n)
lx := binarySearchX_greater(1, i-1, v, n)
if ly <= i-1 {
idx := binarySearchX_greater_equal(ly, i-1, u, n)
if ly <= idx-1 {
setX(1, 1, n, ly, idx-1, u)
}
}
if lx > 1 {
setY(1, 1, n, 1, lx-1, INF)
}
if lx <= i-1 {
setY(1, 1, n, lx, i-1, u)
}
} else {
ly := binarySearchY_less(1, i-1, v, n)
lx := binarySearchX_greater(1, i-1, v, n)
if ly > 1 {
setX(1, 1, n, 1, ly-1, NINF)
}
if ly <= i-1 {
setX(1, 1, n, ly, i-1, u)
}
if lx <= i-1 {
idy := binarySearchY_less_equal(lx, i-1, u, n)
if lx <= idy-1 {
setY(1, 1, n, lx, idy-1, u)
}
}
}
setX(1, 1, n, i, i, INF)
setY(1, 1, n, i, i, NINF)
validX := binarySearchX_greater(1, i, NINF, n)
validY := binarySearchY_less(1, i, INF, n)
firstValid := validX
if validY < firstValid {
firstValid = validY
}
ansTotal += (i - firstValid + 1)
}
fmt.Println(ansTotal)
}
```