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: interview

Starter code:

Solutions:
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()

class SegmentTree:
    def __init__(self, data, default=0, func=max):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(list(range(_size))):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        """func of data[start, stop)"""
        start += self._size
        stop += self._size

        res_left = res_right = self._default
        while start < stop:
            if start & 1:
                res_left = self._func(res_left, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res_right = self._func(self.data[stop], res_right)
            start >>= 1
            stop >>= 1

        return self._func(res_left, res_right)

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

n = int(input())
l = list(map(int, input().split()))

stMax = SegmentTree(l)
stMin = SegmentTree(l, default = 10**10,func=min)

nexSmol = [-1] * n
nexTol = [-1] * n

smolS = [n-1]
tolS = [n-1]

for i in range(n - 2, -1 ,-1):
    while smolS and l[smolS[-1]] >= l[i]:
        smolS.pop()
    if smolS:
        nexSmol[i] = smolS[-1]
    smolS.append(i)

    while tolS and l[tolS[-1]] <= l[i]:
        tolS.pop()
    if tolS:
        nexTol[i] = tolS[-1]
    tolS.append(i)

best = [n] * n
best[0] = 0

for i in range(n - 1):
    curr = best[i]

    if l[i + 1] > l[i]:
        reach = i + 1
        best[i+1] = min(curr + 1, best[i+1])
        while nexSmol[reach] != -1:
            reach = nexSmol[reach]
            if stMin.query(i+1,reach) < l[i]:
                break
            best[reach] = min(curr + 1, best[reach])
        
    elif l[i + 1] < l[i]:
        reach = i + 1
        best[i+1] = min(curr + 1, best[i+1])
        while nexTol[reach] != -1:
            reach = nexTol[reach]
            if stMax.query(i+1,reach) > l[i]:
                break
            best[reach] = min(curr + 1, best[reach])
            
    else:
        best[i+1] = min(curr + 1, best[i+1])
print(best[-1])