← Home
package main

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

const NEG int64 = -1 << 60

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) NextInt64() int64 {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	sign := int64(1)
	if fs.data[fs.idx] == '-' {
		sign = -1
		fs.idx++
	}
	var val int64
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		val = val*10 + int64(c-'0')
		fs.idx++
	}
	return val * sign
}

type SegTree struct {
	size int
	log  int
	d    []int64
	lz   []int64
}

func NewSegTree(n int) *SegTree {
	size, log := 1, 0
	for size < n {
		size <<= 1
		log++
	}
	d := make([]int64, 2*size)
	for i := range d {
		d[i] = NEG
	}
	lz := make([]int64, size)
	return &SegTree{size: size, log: log, d: d, lz: lz}
}

func (s *SegTree) update(k int) {
	if s.d[k<<1] >= s.d[k<<1|1] {
		s.d[k] = s.d[k<<1]
	} else {
		s.d[k] = s.d[k<<1|1]
	}
}

func (s *SegTree) allApply(k int, f int64) {
	s.d[k] += f
	if k < s.size {
		s.lz[k] += f
	}
}

func (s *SegTree) push(k int) {
	if s.lz[k] != 0 {
		f := s.lz[k]
		s.allApply(k<<1, f)
		s.allApply(k<<1|1, f)
		s.lz[k] = 0
	}
}

func (s *SegTree) Set(p int, x int64) {
	p += s.size
	for i := s.log; i >= 1; i-- {
		s.push(p >> i)
	}
	s.d[p] = x
	for i := 1; i <= s.log; i++ {
		s.update(p >> i)
	}
}

func (s *SegTree) RangeAdd(l, r int, f int64) {
	if l >= r || f == 0 {
		return
	}
	l += s.size
	r += s.size
	l0, r0 := l, r

	for i := s.log; i >= 1; i-- {
		if ((l0 >> i) << i) != l0 {
			s.push(l0 >> i)
		}
		if ((r0 >> i) << i) != r0 {
			s.push((r0 - 1) >> i)
		}
	}

	for l < r {
		if l&1 == 1 {
			s.allApply(l, f)
			l++
		}
		if r&1 == 1 {
			r--
			s.allApply(r, f)
		}
		l >>= 1
		r >>= 1
	}

	for i := 1; i <= s.log; i++ {
		if ((l0 >> i) << i) != l0 {
			s.update(l0 >> i)
		}
		if ((r0 >> i) << i) != r0 {
			s.update((r0 - 1) >> i)
		}
	}
}

func (s *SegTree) AllMax() int64 {
	return s.d[1]
}

type Pair struct {
	pos int
	val int64
}

func main() {
	fs := NewFastScanner()
	n := int(fs.NextInt64())

	seg := NewSegTree(n)
	maxStack := make([]Pair, n)
	minStack := make([]Pair, n)
	maxTop, minTop := 0, 0

	var dp int64

	for i := 1; i <= n; i++ {
		x := fs.NextInt64()

		for maxTop > 0 && maxStack[maxTop-1].val <= x {
			cur := maxStack[maxTop-1]
			maxTop--
			prev := 0
			if maxTop > 0 {
				prev = maxStack[maxTop-1].pos
			}
			seg.RangeAdd(prev, cur.pos, x-cur.val)
		}

		for minTop > 0 && minStack[minTop-1].val >= x {
			cur := minStack[minTop-1]
			minTop--
			prev := 0
			if minTop > 0 {
				prev = minStack[minTop-1].pos
			}
			seg.RangeAdd(prev, cur.pos, cur.val-x)
		}

		seg.Set(i-1, dp)

		maxStack[maxTop] = Pair{pos: i, val: x}
		maxTop++
		minStack[minTop] = Pair{pos: i, val: x}
		minTop++

		dp = seg.AllMax()
	}

	out := bufio.NewWriterSize(os.Stdout, 64)
	out.WriteString(strconv.FormatInt(dp, 10))
	out.WriteByte('\n')
	out.Flush()
}