There are $n$ beautiful skyscrapers in New York, the height of the $i$-th one is $h_i$. Today some villains have set on fire first $n - 1$ of them, and now the only safety building is $n$-th skyscraper.

Let's call a jump from $i$-th skyscraper to $j$-th ($i < j$) discrete, if all skyscrapers between are strictly lower or higher than both of them. Formally, jump is discrete, if $i < j$ and one of the following conditions satisfied:   $i + 1 = j$  $\max(h_{i + 1}, \ldots, h_{j - 1}) < \min(h_i, h_j)$  $\max(h_i, h_j) < \min(h_{i + 1}, \ldots, h_{j - 1})$. 

At the moment, Vasya is staying on the first skyscraper and wants to live a little longer, so his goal is to reach $n$-th skyscraper with minimal count of discrete jumps. Help him with calcualting this number.


-----Input-----

The first line contains a single integer $n$ ($2 \le n \le 3 \cdot 10^5$) — total amount of skyscrapers.

The second line contains $n$ integers $h_1, h_2, \ldots, h_n$ ($1 \le h_i \le 10^9$) — heights of skyscrapers.


-----Output-----

Print single number $k$ — minimal amount of discrete jumps. We can show that an answer always exists.


-----Examples-----
Input
5
1 3 1 4 5

Output
3
Input
4
4 2 2 4

Output
1
Input
2
1 1

Output
1
Input
5
100 1 100 1 100

Output
2


-----Note-----

In the first testcase, Vasya can jump in the following way: $1 \rightarrow 2 \rightarrow 4 \rightarrow 5$.

In the second and third testcases, we can reach last skyscraper in one jump.

Sequence of jumps in the fourth testcase: $1 \rightarrow 3 \rightarrow 5$.

Difficulty: HARD

Solutions:
def I1():
	n = int(input())
	h = [int(j) for j in input().split()]
	x = [0] * n
	y = [0]
	z = [0]
	for i in range(1, n):
		x[i] = x[i - 1] + 1
		while len(y) and h[i] >= h[y[-1]]:
			a = y[-1]
			y.pop()
			if h[i] > h[a] and len(y):
				x[i] = min(x[i], x[y[-1]] + 1)
		while len(z) and h[i] <= h[z[-1]]:
			a = z[-1]
			z.pop()
			if h[i] < h[a] and len(z):
				x[i] = min(x[i], x[z[-1]] + 1)
		y.append(i)
		z.append(i)
	print(x[-1])
I1()


import sys, heapq
input = sys.stdin.buffer.readline
n = int(input())
ls = list(map(int, input().split()))
dp = [n] * n
dp[n - 1] = 0
(up, dn) = ([n - 1], [n - 1])
for p in range(n - 2, -1, -1):
	u = ls[p]
	while up and ls[up[-1]] > u:
		dp[p] = min(dp[p], dp[up[-1]] + 1)
		up.pop()
	if up:
		dp[p] = min(dp[p], dp[up[-1]] + 1)
	while dn and ls[dn[-1]] < u:
		dp[p] = min(dp[p], dp[dn[-1]] + 1)
		dn.pop()
	if dn:
		dp[p] = min(dp[p], dp[dn[-1]] + 1)
	up.append(p)
	if len(up) > 1 and ls[up[-1]] == ls[up[-2]]:
		up.pop()
		up[-1] = p
	dn.append(p)
	if len(dn) > 1 and ls[dn[-1]] == ls[dn[-2]]:
		dn.pop()
		dn[-1] = p
print(dp[0])


def answer(n, A):
	l = [0]
	g = [0]
	dp = [float('inf')] * n
	dp[0] = 0
	for i in range(1, n):
		flag = 1
		while g and A[g[-1]] >= A[i]:
			index = g.pop()
			dp[i] = min(dp[i], dp[index] + 1)
			if A[i] == A[index]:
				flag = 0
			else:
				flag = 1
		if g and flag:
			dp[i] = min(dp[i], dp[g[-1]] + 1)
		flag = 1
		while l and A[l[-1]] <= A[i]:
			index = l.pop()
			dp[i] = min(dp[i], dp[index] + 1)
			if A[i] == A[index]:
				flag = 0
			else:
				flag = 1
		if l and flag:
			dp[i] = min(dp[i], dp[l[-1]] + 1)
		l.append(i)
		g.append(i)
	return dp[n - 1]
n = int(input())
arr = list(map(int, input().split()))
print(answer(n, arr))


def empty(l):
	if len(l) == 0:
		return True
	return False
n = int(input())
h = list(map(int, input().split(' ')))
(inc, dec) = ([0], [0])
dp = [0] * n
for i in range(1, n):
	(f1, f2) = (0, 0)
	dp[i] = dp[i - 1] + 1
	while not empty(inc) and h[i] >= h[inc[-1]]:
		x = h[inc[-1]]
		inc.pop()
		if h[i] > x and (not empty(inc)):
			dp[i] = min(dp[i], dp[inc[-1]] + 1)
	while not empty(dec) and h[i] <= h[dec[-1]]:
		x = h[dec[-1]]
		dec.pop()
		if h[i] < x and (not empty(dec)):
			dp[i] = min(dp[i], dp[dec[-1]] + 1)
	inc.append(i)
	dec.append(i)
print(dp[-1])


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
n = int(input())
a = RLL()
dp = [0] * n
high = [n - 1]
low = [n - 1]
for i in range(n - 2, -1, -1):
	dp[i] = dp[i + 1] + 1
	if a[i] > a[i + 1]:
		high.pop()
		while high and a[high[-1]] < a[i]:
			dp[i] = min(dp[i], dp[high[-1]] + 1)
			high.pop()
		if high:
			dp[i] = min(dp[i], dp[high[-1]] + 1)
			if a[high[-1]] == a[i]:
				high.pop()
	elif a[i] < a[i + 1]:
		low.pop()
		while low and a[low[-1]] > a[i]:
			dp[i] = min(dp[i], dp[low[-1]] + 1)
			low.pop()
		if low:
			dp[i] = min(dp[i], dp[low[-1]] + 1)
			if a[low[-1]] == a[i]:
				low.pop()
	else:
		dp[i] = dp[i + 1] + 1
		high.pop()
		low.pop()
	high.append(i)
	low.append(i)
print(dp[0])


try:
	n = int(input())
	a = [int(i) for i in input().split(' ')]
	dp = [n] * n
	dp[0] = 0
	(s1, s2) = ([], [])
	s1.append(0)
	s2.append(0)
	i = 1
	while i < n:
		dp[i] = dp[i - 1] + 1
		while s1 and a[i] <= a[s1[len(s1) - 1]]:
			item = a[s1[len(s1) - 1]]
			s1.pop()
			if a[i] < item and s1:
				dp[i] = min(dp[i], dp[s1[len(s1) - 1]] + 1)
		while s2 and a[i] >= a[s2[len(s2) - 1]]:
			item = a[s2[len(s2) - 1]]
			s2.pop()
			if a[i] > item and s2:
				dp[i] = min(dp[i], dp[s2[len(s2) - 1]] + 1)
		s1.append(i)
		s2.append(i)
		i += 1
	print(dp[n - 1])
except:
	pass


from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def linc(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t > f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rinc(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t < f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def ldec(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t < f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rdec(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t > f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def binfun(x):
	c = 0
	for w in arr:
		c += ceil(w / x)
	return c

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class smt:

	def __init__(self, l, r, arr):
		self.l = l
		self.r = r
		self.value = (1 << 31) - 1 if l < r else arr[l]
		mid = (l + r) // 2
		if l < r:
			self.left = smt(l, mid, arr)
			self.right = smt(mid + 1, r, arr)
			self.value &= self.left.value & self.right.value

	def setvalue(self, x, val):
		if self.l == self.r:
			self.value = val
			return
		mid = (self.l + self.r) // 2
		if x <= mid:
			self.left.setvalue(x, val)
		else:
			self.right.setvalue(x, val)
		self.value = self.left.value & self.right.value

	def ask(self, l, r):
		if l <= self.l and r >= self.r:
			return self.value
		val = (1 << 31) - 1
		mid = (self.l + self.r) // 2
		if l <= mid:
			val &= self.left.ask(l, r)
		if r > mid:
			val &= self.right.ask(l, r)
		return val

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return prime

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [(ch, len(list(g))) for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None

def query(x, y):
	print('?', x, y)
	sys.stdout.flush()
	return N()
t = 1
for i in range(t):
	n = N()
	h = RLL()
	res = [[] for i in range(n)]
	stack = []
	for i in range(n):
		flag = True
		while stack and h[stack[-1]] <= h[i]:
			cur = stack.pop()
			res[i].append(cur)
			if h[cur] == h[i]:
				flag = False
		if flag and stack:
			res[i].append(stack[-1])
		stack.append(i)
	stack = []
	for i in range(n):
		flag = True
		while stack and h[stack[-1]] >= h[i]:
			cur = stack.pop()
			res[i].append(cur)
			if h[cur] == h[i]:
				flag = False
		if flag and stack:
			res[i].append(stack[-1])
		stack.append(i)
	dp = [inf] * n
	dp[0] = 0
	for i in range(1, n):
		for j in res[i]:
			dp[i] = min(dp[i], dp[j] + 1)
	ans = dp[-1]
	print(ans)


import sys, math
import io, os
from bisect import bisect_left as bl, bisect_right as br, insort
from heapq import heapify, heappush, heappop
from collections import defaultdict as dd, deque, Counter

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write(' '.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
INF = float('inf')
mod = 10 ** 9 + 7
n = int(data())
h = mdata()
stack1 = [h[0]]
stack2 = [h[0]]
d = dd(int)
for i in range(1, n):
	k = INF
	while stack1 and stack1[-1] > h[i]:
		if stack1[-1] < h[i - 1]:
			k = min(k, d[stack1[-1]])
		stack1.pop()
	while stack2 and stack2[-1] < h[i]:
		if stack2[-1] > h[i - 1]:
			k = min(k, d[stack2[-1]])
		stack2.pop()
	if stack1:
		k = min(k, d[stack1[-1]])
	if stack2:
		k = min(k, d[stack2[-1]])
	d[h[i]] = k + 1
	stack1.append(h[i])
	stack2.append(h[i])
out(d[h[-1]])


import sys
input = sys.stdin.readline
n = int(input())
h = list(map(int, input().split()))
prev_small = [-1] * n
stack = []
for i in range(n):
	while stack and stack[-1][0] > h[i]:
		stack.pop()
	if stack:
		prev_small[i] = stack[-1][1]
	stack.append([h[i], i])
prev_large = [-1] * n
stack = []
for i in range(n):
	while stack and stack[-1][0] < h[i]:
		stack.pop()
	if stack:
		prev_large[i] = stack[-1][1]
	stack.append([h[i], i])
next_small = [-1] * n
stack = []
for i in range(n)[::-1]:
	while stack and stack[-1][0] > h[i]:
		stack.pop()
	if stack:
		next_small[i] = stack[-1][1]
	stack.append([h[i], i])
next_large = [-1] * n
stack = []
for i in range(n)[::-1]:
	while stack and stack[-1][0] < h[i]:
		stack.pop()
	if stack:
		next_large[i] = stack[-1][1]
	stack.append([h[i], i])
can = [[] for i in range(n)]
for i in range(n):
	if prev_small[i] >= 0:
		can[prev_small[i]].append(i)
	if prev_large[i] >= 0:
		can[prev_large[i]].append(i)
	if next_small[i] >= 0:
		can[i].append(next_small[i])
	if next_large[i] >= 0:
		can[i].append(next_large[i])
dp = [10 ** 9] * n
dp[0] = 0
for i in range(n):
	for j in can[i]:
		dp[j] = min(dp[j], dp[i] + 1)
print(dp[n - 1])


mod = 1000000007
eps = 10 ** (-9)
inf = 10 ** 9

def main():
	import sys
	input = sys.stdin.readline

	class Bit:

		def __init__(self, n):
			self.size = n
			self.tree = [0] * (n + 1)

		def sum(self, i):
			s = 0
			while i > 0:
				s += self.tree[i]
				i -= i & -i
			return s

		def add(self, i, x):
			while i <= self.size:
				self.tree[i] += x
				i += i & -i

		def lower_bound(self, w):
			if w <= 0:
				return 0
			x = 0
			k = 1 << self.size.bit_length() - 1
			while k:
				if x + k <= self.size and self.tree[x + k] < w:
					w -= self.tree[x + k]
					x += k
				k >>= 1
			return x + 1
	N = int(input())
	A = list(map(int, input().split()))
	adj = [[] for _ in range(N + 1)]
	AA = sorted(list(set(A)))
	a2i = {a: i for (i, a) in enumerate(AA)}
	AI = [[] for _ in range(len(AA))]
	for (i, a) in enumerate(A):
		ii = a2i[a]
		AI[ii].append(i + 1)
	bit_high = Bit(N)
	for i_list in AI:
		for i in i_list:
			bit_high.add(i, 1)
		for i in i_list:
			val = bit_high.sum(i)
			il = bit_high.lower_bound(val - 1)
			ir = bit_high.lower_bound(val + 1)
			if il > 0:
				adj[il].append(i)
			if ir <= N:
				adj[i].append(ir)
	bit_low = Bit(N)
	AI.reverse()
	for i_list in AI:
		for i in i_list:
			bit_low.add(i, 1)
		for i in i_list:
			val = bit_low.sum(i)
			il = bit_low.lower_bound(val - 1)
			ir = bit_low.lower_bound(val + 1)
			if il > 0:
				adj[il].append(i)
			if ir <= N:
				adj[i].append(ir)
	dp = [inf] * (N + 1)
	dp[1] = 0
	for i in range(1, N + 1):
		for j in adj[i]:
			dp[j] = min(dp[j], dp[i] + 1)
	print(dp[N])

def __starting_point():
	main()
__starting_point()


import io
import os
import sys
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def printd(*args, **kwargs):
	pass

def get_str():
	return input().decode().strip()

def rint():
	return map(int, input().split())

def oint():
	return int(input())

def solve():
	n = oint()
	h = list(rint())
	pair = [{i + 1} for i in range(n)]
	pair[n - 1] = set()
	st = [[h[0], 0]]
	for i in range(1, n):
		while st and st[-1][0] <= h[i]:
			pair[st[-1][1]].add(i)
			st.pop()
		st.append([h[i], i])
	st = [[h[-1], n - 1]]
	for i in range(n - 2, -1, -1):
		while st and st[-1][0] <= h[i]:
			pair[i].add(st[-1][1])
			st.pop()
		st.append([h[i], i])
	st = [[h[-1], n - 1]]
	for i in range(n - 2, -1, -1):
		while st and st[-1][0] >= h[i]:
			pair[i].add(st[-1][1])
			st.pop()
		st.append([h[i], i])
	st = [[h[0], 0]]
	for i in range(1, n):
		while st and st[-1][0] >= h[i]:
			pair[st[-1][1]].add(i)
			st.pop()
		st.append([h[i], i])
	dp = [float('inf')] * n
	dp[0] = 0
	for (i, js) in enumerate(pair):
		for j in js:
			dp[j] = min(dp[j], dp[i] + 1)
	printd(h)
	printd(pair)
	printd(dp)
	print(dp[-1])
solve()


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from itertools import *
import bisect
from heapq import *
from math import *
from copy import *
from collections import deque
from collections import Counter as counter
from itertools import combinations as comb
from itertools import permutations as permutate
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func
mod = 1000000007

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def zerolist(n):
	return [0] * n

def nextline():
	out('\n')

def testcase(t):
	for pp in range(t):
		solve(pp)

def printlist(a):
	for p in range(0, len(a)):
		out(str(a[p]) + ' ')

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def bfs(g, st):
	visited = [-1] * len(g)
	visited[st] = 0
	queue = deque([])
	queue.append(st)
	new = []
	while len(queue) != 0:
		s = queue.popleft()
		new.append(s)
		for i in g[s]:
			if visited[i] == -1:
				visited[i] = visited[s] + 1
				queue.append(i)
	return visited[-1]

def solve(case):
	n = int(inp())
	h = lis()
	new = []
	for i in range(n):
		new.append([h[i], i])
	g = [[] for i in range(n)]
	stack = deque([])
	for i in range(n):
		while len(stack) != 0 and new[stack[-1]][0] < new[i][0]:
			g[stack[-1]].append(i)
			stack.pop()
		if len(stack) != 0:
			g[stack[-1]].append(i)
		if len(stack) != 0 and new[stack[-1]][0] == new[i][0]:
			stack.pop()
		stack.append(i)
	for i in range(n):
		new[i][0] = new[i][0] * -1
	stack = deque([])
	for i in range(n):
		while len(stack) != 0 and new[stack[-1]][0] < new[i][0]:
			g[stack[-1]].append(i)
			stack.pop()
		if len(stack) != 0:
			g[stack[-1]].append(i)
		if len(stack) != 0 and new[stack[-1]][0] == new[i][0]:
			stack.pop()
		stack.append(i)
	print(bfs(g, 0))
testcase(1)


from collections import deque

def solve(n, height):
	pos = deque()
	neg = deque()
	dp = [n] * n
	dp[0] = 0
	for i in range(n):
		while len(pos) != 0 and height[pos[-1]] > height[i]:
			dp[i] = min(dp[i], dp[pos[-1]] + 1)
			pos.pop()
		if len(pos) != 0:
			dp[i] = min(dp[i], dp[pos[-1]] + 1)
			if height[pos[-1]] == height[i]:
				pos.pop()
		pos.append(i)
		while len(neg) != 0 and height[neg[-1]] < height[i]:
			dp[i] = min(dp[i], dp[neg[-1]] + 1)
			neg.pop()
		if len(neg) != 0:
			dp[i] = min(dp[i], dp[neg[-1]] + 1)
			if height[neg[-1]] == height[i]:
				neg.pop()
		neg.append(i)
	print(dp[n - 1])
n = int(input())
ar = list(map(int, input().split()))
solve(n, ar)


from sys import stdin, stdout

def discrete_centrifugal_jumps(n, h_a):
	jump_a1 = [[] for _ in range(n)]
	jump_a2 = [[] for _ in range(n)]
	st1 = []
	st2 = []
	for i in range(n):
		if not st1 or h_a[i] <= st1[-1][1]:
			st1.append([i, h_a[i]])
		else:
			pre = -1
			while st1 and st1[-1][1] < h_a[i]:
				p = st1.pop()
				if pre != p[1]:
					jump_a1[p[0]].append(i)
				pre = p[1]
			if st1:
				jump_a1[st1[-1][0]].append(i)
			st1.append([i, h_a[i]])
		if not st2 or h_a[i] >= st2[-1][1]:
			st2.append([i, h_a[i]])
		else:
			pre = -1
			while st2 and st2[-1][1] > h_a[i]:
				p = st2.pop()
				if pre != p[1]:
					jump_a2[p[0]].append(i)
				pre = p[1]
			if st2:
				jump_a2[st2[-1][0]].append(i)
			st2.append([i, h_a[i]])
	dp = [2 ** 31 - 1 for _ in range(n)]
	dp[n - 1] = 0
	for i in range(n - 2, -1, -1):
		dp[i] = 1 + dp[i + 1]
		for nxt in jump_a1[i]:
			dp[i] = min(dp[i], 1 + dp[nxt])
		for nxt in jump_a2[i]:
			dp[i] = min(dp[i], 1 + dp[nxt])
	return dp[0]

def dfs(i, jump_a1, jump_a2, n, memo):
	if i == n - 1:
		return 0
	if memo[i] != -1:
		return memo[i]
	res = 2 ** 31 - 1
	for nxt in jump_a1[i]:
		res = min(res, 1 + dfs(nxt, jump_a1, jump_a2, n, memo))
	for nxt in jump_a2[i]:
		res = min(res, 1 + dfs(nxt, jump_a1, jump_a2, n, memo))
	res = min(res, 1 + dfs(i + 1, jump_a1, jump_a2, n, memo))
	memo[i] = res
	return res
n = int(stdin.readline())
h_a = list(map(int, stdin.readline().split()))
k = discrete_centrifugal_jumps(n, h_a)
stdout.write(str(k) + '\n')


import os
import sys
from io import BytesIO, IOBase
import threading
from collections import defaultdict, Counter
from math import gcd

def main():
	n = int(input())
	arr = list(map(int, input().split()))
	trans = [[] for i in range(n)]
	mxs = []
	mis = []
	for i in range(n):
		while len(mxs) and mxs[-1][1] < arr[i]:
			mxs.pop()
		if len(mxs):
			trans[mxs[-1][0]].append(i)
		while len(mis) and mis[-1][1] > arr[i]:
			mis.pop()
		if len(mis):
			trans[mis[-1][0]].append(i)
		mxs.append((i, arr[i]))
		mis.append((i, arr[i]))
	mis = []
	mxs = []
	for i in range(n - 1, -1, -1):
		while len(mxs) and mxs[-1][1] < arr[i]:
			mxs.pop()
		if len(mxs):
			trans[i].append(mxs[-1][0])
		while len(mis) and mis[-1][1] > arr[i]:
			mis.pop()
		if len(mis):
			trans[i].append(mis[-1][0])
		mxs.append((i, arr[i]))
		mis.append((i, arr[i]))
	ans = [float('inf')] * n
	ans[0] = 0
	for i in range(n):
		for nxt in trans[i]:
			ans[nxt] = min(ans[nxt], ans[i] + 1)
	print(ans[-1])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
for i in range(1):
	main()


import sys
import math as mt
input = sys.stdin.readline
t = 1
for _ in range(t):
	n = int(input())
	l = list(map(int, input().split()))
	dp = [n] * (n + 1)
	dp[0] = 0
	to = [set() for _ in range(n)]
	stack = []
	for i in range(n):
		while stack and stack[-1][1] < l[i]:
			stack.pop()
		if stack:
			to[i].add(stack[-1][0])
		if stack and stack[-1][1] == l[i]:
			stack.pop()
		stack.append((i, l[i]))
	stack = []
	for i in range(n):
		while stack and stack[-1][1] > l[i]:
			stack.pop()
		if stack:
			to[i].add(stack[-1][0])
		if stack and stack[-1][1] == l[i]:
			stack.pop()
		stack.append((i, l[i]))
	stack = []
	for i in range(n - 1, -1, -1):
		while stack and stack[-1][1] < l[i]:
			stack.pop()
		if stack:
			to[stack[-1][0]].add(i)
		if stack and stack[-1][1] == l[i]:
			stack.pop()
		stack.append((i, l[i]))
	stack = []
	for i in range(n - 1, -1, -1):
		while stack and stack[-1][1] > l[i]:
			stack.pop()
		if stack:
			to[stack[-1][0]].add(i)
		if stack and stack[-1][1] == l[i]:
			stack.pop()
		stack.append((i, l[i]))
	for i in range(1, n):
		for j in to[i]:
			dp[i] = min(dp[i], dp[j] + 1)
	print(dp[n - 1])


import sys
input = sys.stdin.readline
(N,) = map(int, input().split())
X = list(map(int, input().split()))
d = [set() for _ in range(N)]
stack = [(-1, -1)]
for i in range(N):
	while stack and stack[-1][0] > X[i]:
		stack.pop()
	if stack[-1][1] >= 0:
		d[stack[-1][1]].add(i)
	stack.append((X[i], i))
stack = [(10 ** 18, -1)]
for i in range(N):
	while stack and stack[-1][0] < X[i]:
		stack.pop()
	if stack[-1][1] >= 0:
		d[stack[-1][1]].add(i)
	stack.append((X[i], i))
stack = [(-1, N)]
for i in range(N - 1, -1, -1):
	while stack and stack[-1][0] > X[i]:
		stack.pop()
	if stack[-1][1] < N:
		d[i].add(stack[-1][1])
	stack.append((X[i], i))
stack = [(10 ** 18, N)]
for i in range(N - 1, -1, -1):
	while stack and stack[-1][0] < X[i]:
		stack.pop()
	if stack[-1][1] < N:
		d[i].add(stack[-1][1])
	stack.append((X[i], i))
from collections import deque
queue = deque([0])
vs = set([0])
dist = [0] * N
while queue:
	v = queue.popleft()
	for u in d[v]:
		if u in vs:
			continue
		vs.add(u)
		queue.append(u)
		dist[u] = dist[v] + 1
print(dist[-1])


n = int(input())
num = list(map(int, input().split()))
dp = [i for i in range(n)]
dp[0] = 0
higher = []
lower = []
for i in range(n):
	flag = True
	while higher and num[higher[-1]] >= num[i]:
		val = higher.pop()
		dp[i] = min(dp[i], dp[val] + 1)
		flag = False if num[i] == num[val] else True
	if higher and flag:
		dp[i] = min(dp[higher[-1]] + 1, dp[i])
	while lower and num[lower[-1]] <= num[i]:
		val = lower.pop()
		dp[i] = min(dp[i], dp[val] + 1)
		flag = False if num[i] == num[val] else True
	if lower and flag:
		dp[i] = min(dp[lower[-1]] + 1, dp[i])
	higher.append(i)
	lower.append(i)
print(dp[-1])


n = int(input())
h = list(map(int, input().split()))
dp = [0] * n
s = [0]
p = [0]
for i in range(1, n):
	dp[i] = dp[i - 1] + 1
	while len(s) and h[i] >= h[s[-1]]:
		x = s[-1]
		s.pop()
		if h[i] > h[x] and len(s):
			dp[i] = min(dp[i], dp[s[-1]] + 1)
	while len(p) and h[i] <= h[p[-1]]:
		x = p[-1]
		p.pop()
		if h[i] < h[x] and len(p):
			dp[i] = min(dp[i], dp[p[-1]] + 1)
	s.append(i)
	p.append(i)
print(dp[-1])


from collections import deque
import sys
n = int(input())
s = list(map(int, input().split()))
mn = deque()
mx = deque()
p = s + []
i = 0
j = 0
mn.append(i)
mx.append(i)
ans = [sys.maxsize for i in range(n)]
ans[0] = 0
for i in range(1, n):
	while len(mx) > 0 and p[mx[-1]] < p[i]:
		ans[i] = min(ans[i], ans[mx[-1]] + 1)
		index = mx[-1]
		while len(mx) > 0 and p[mx[-1]] == p[index]:
			mx.pop()
	if len(mx) > 0:
		ans[i] = min(ans[i], ans[mx[-1]] + 1)
	mx.append(i)
	while len(mn) > 0 and p[mn[-1]] > p[i]:
		ans[i] = min(ans[i], ans[mn[-1]] + 1)
		index = mn[-1]
		while len(mn) > 0 and p[mn[-1]] == p[index]:
			mn.pop()
	if len(mn) > 0:
		ans[i] = min(ans[i], ans[mn[-1]] + 1)
	mn.append(i)
print(ans[n - 1])


from collections import *
import sys

def ri():
	return int(input())

def rl():
	return list(map(int, input().split()))
n = ri()
h = rl()
g = defaultdict(list)
for rot in range(2):
	stack = []
	for i in range(n):
		while stack and h[stack[-1]] < h[i]:
			g[stack[-1]].append(i)
			stack.pop()
		if stack:
			g[stack[-1]].append(i)
			if h[stack[-1]] == h[i]:
				stack.pop()
		stack.append(i)
	for i in range(n):
		h[i] = -h[i]
dist = [-1] * n
dist[0] = 0
que = [0]
for b in que:
	for j in g[b]:
		if dist[j] == -1:
			que.append(j)
			dist[j] = dist[b] + 1
print(dist[n - 1])


n = int(input())
a = list(map(int, input().split()))
llvisited = [-1 for i in range(n)]
lhvisited = [-1 for i in range(n)]
rlvisited = [-1 for i in range(n)]
rhvisited = [-1 for i in range(n)]
stack = []
for i in range(n):
	while stack and a[i] > stack[-1][0]:
		stack.pop(-1)
	if stack:
		llvisited[i] = stack[-1][1]
	stack.append([a[i], i])
stack = []
for i in range(n):
	while stack and a[i] < stack[-1][0]:
		stack.pop(-1)
	if stack:
		lhvisited[i] = stack[-1][1]
	stack.append([a[i], i])
stack = []
for i in range(n - 1, -1, -1):
	while stack and a[i] > stack[-1][0]:
		stack.pop(-1)
	if stack:
		rlvisited[i] = stack[-1][1]
	stack.append([a[i], i])
stack = []
for i in range(n - 1, -1, -1):
	while stack and a[i] < stack[-1][0]:
		stack.pop(-1)
	if stack:
		rhvisited[i] = stack[-1][1]
	stack.append([a[i], i])
pointers = [[] for i in range(n)]
for i in range(n):
	if llvisited[i] != -1:
		pointers[llvisited[i]].append(i)
	if lhvisited[i] != -1:
		pointers[lhvisited[i]].append(i)
	if rlvisited[i] != -1:
		pointers[i].append(rlvisited[i])
	if rhvisited[i] != -1:
		pointers[i].append(rhvisited[i])
dp = [i for i in range(n)]
for i in range(n):
	for j in pointers[i]:
		dp[j] = min(dp[j], dp[i] + 1)
print(dp[-1])


import sys
read = lambda : sys.stdin.readline().strip()
readi = lambda : map(int, read().split())
from collections import deque
n = int(read())
nums = list(readi())
dp = [float('inf')] * n
dp[0] = 0
incrStk = deque()
decrStk = deque()
for (i, num) in enumerate(nums):
	while incrStk and nums[incrStk[-1]] > num:
		dp[i] = min(dp[i], dp[incrStk.pop()] + 1)
	if incrStk:
		dp[i] = min(dp[i], dp[incrStk[-1]] + 1)
		if nums[incrStk[-1]] == num:
			incrStk.pop()
	incrStk.append(i)
	while decrStk and nums[decrStk[-1]] < num:
		dp[i] = min(dp[i], dp[decrStk.pop()] + 1)
	if decrStk:
		dp[i] = min(dp[i], dp[decrStk[-1]] + 1)
		if nums[decrStk[-1]] == num:
			decrStk.pop()
	decrStk.append(i)
print(dp[-1])


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]
inf = 10 ** 9
n = II()
aa = LI()
to = [set() for _ in range(n)]
stack = []
for i in range(n):
	while stack and stack[-1][1] < aa[i]:
		stack.pop()
	if stack:
		to[stack[-1][0]].add(i)
	if stack and stack[-1][1] == aa[i]:
		stack.pop()
	stack.append((i, aa[i]))
stack = []
for i in range(n):
	while stack and stack[-1][1] > aa[i]:
		stack.pop()
	if stack:
		to[stack[-1][0]].add(i)
	if stack and stack[-1][1] == aa[i]:
		stack.pop()
	stack.append((i, aa[i]))
stack = []
for i in range(n - 1, -1, -1):
	while stack and stack[-1][1] < aa[i]:
		stack.pop()
	if stack:
		to[i].add(stack[-1][0])
	if stack and stack[-1][1] == aa[i]:
		stack.pop()
	stack.append((i, aa[i]))
stack = []
for i in range(n - 1, -1, -1):
	while stack and stack[-1][1] > aa[i]:
		stack.pop()
	if stack:
		to[i].add(stack[-1][0])
	if stack and stack[-1][1] == aa[i]:
		stack.pop()
	stack.append((i, aa[i]))

def chmin(i, val):
	if val < dp[i]:
		dp[i] = val
dp = [inf] * n
dp[0] = 0
for i in range(n - 1):
	for j in to[i]:
		chmin(j, dp[i] + 1)
print(dp[-1])