Squirrel Liss is interested in sequences. She also has preferences of integers. She thinks *n* integers *a*<sub class="lower-index">1</sub>, *a*<sub class="lower-index">2</sub>, ..., *a*<sub class="lower-index">*n*</sub> are good.

Now she is interested in good sequences. A sequence *x*<sub class="lower-index">1</sub>, *x*<sub class="lower-index">2</sub>, ..., *x*<sub class="lower-index">*k*</sub> is called good if it satisfies the following three conditions:
 -  The sequence is strictly increasing, i.e. *x*<sub class="lower-index">*i*</sub> &lt; *x*<sub class="lower-index">*i* + 1</sub> for each *i* (1 ≤ *i* ≤ *k* - 1). -  No two adjacent elements are coprime, i.e. *gcd*(*x*<sub class="lower-index">*i*</sub>, *x*<sub class="lower-index">*i* + 1</sub>) &gt; 1 for each *i* (1 ≤ *i* ≤ *k* - 1) (where *gcd*(*p*, *q*) denotes the greatest common divisor of the integers *p* and *q*). -  All elements of the sequence are good integers. 
Find the length of the longest good sequence.
The input consists of two lines. The first line contains a single integer *n* (1 ≤ *n* ≤ 10<sup class="upper-index">5</sup>) — the number of good integers. The second line contains a single-space separated list of good integers *a*<sub class="lower-index">1</sub>, *a*<sub class="lower-index">2</sub>, ..., *a*<sub class="lower-index">*n*</sub> in strictly increasing order (1 ≤ *a*<sub class="lower-index">*i*</sub> ≤ 10<sup class="upper-index">5</sup>; *a*<sub class="lower-index">*i*</sub> &lt; *a*<sub class="lower-index">*i* + 1</sub>).
from collections import Counter
from functools import lru_cache
# from itertools import combinations
import bisect
import heapq
from itertools import product
import math
from re import S
import sys
from types import GeneratorType

# sys.stdin = open('grey.in', 'r')
# sys.setrecursionlimit(5 * 10**5)


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
 
result = []


input = sys.stdin.readline

LOG = 18

array = [1, 2, 3, 4, 5, 6, 7, 8]



def genSparseTable(array):
        
    sparseTable = [[float('inf') for i in range(LOG)] for x in range(len(array))]


    for i in range(len(array)):
        sparseTable[i][0] = array[i]



    for i in range(1, LOG):
        j = 0
        while((j + (1 << i) - 1) < len(array)):
            sparseTable[j][i] = max(sparseTable[j][i - 1], sparseTable[j + (1 << (i  - 1))][i - 1])
            j += 1

    return sparseTable

def query(l, r, sparseTable):
    length = (r - l) + 1
    idx = int(math.log(length, 2))
    return max(sparseTable[l][idx], sparseTable[r - (1 << idx) + 1][idx])





def calc(numOne, numTwo):
    
    currentSum = 0
    for i in range(32):
        firstBit, secondBit = min(1, numOne & (1 << i)), min(1, numTwo & (1 << i))
        
        currentSum += (firstBit ^ secondBit)

    return currentSum    


# counter = Counter()
# for i in range(0, 119000):
#     counter[calc(i, i + 1)] += 1


# print(counter)



 
input = sys.stdin.readline
 
# 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
 

# t = int(input())
# result = []
# for _ in range(t):
#     a, b = map(int, input().split())


#     def solve():
#         state = False
#         count = 0
        
#         currentMin = float('inf')
#         for z in range(0, b + 5):
#             currentB = b + z
#             count = 0
#             for i in range(32):
#                 firstBit, secondBit = a & (1 << i), currentB & (1 << i)

#                 if secondBit and not firstBit:
#                     state = True
#                     continue

#                 if firstBit and not secondBit:
#                     count += (2**i)
#             currentMin = min(currentMin, count + 1 + z if state else count + z)        
#         return min(currentMin, b - a)

#     print(solve())           

# # print(result)



class SegmentTree2D:

    
    def __init__(self, row, col, inMatrix):
        self.rows = row
        self.cols = col
        self.inMatrix = inMatrix
        self.matrix = [[0 for z in range(col + 1)] for i in range(row + 1)]
        self.genTable()


    

    def genTable(self):
        self.matrix[0][0] = 0


        for row in range(self.rows):
            currentSum = 0
            for col in range(self.cols):
                currentSum += self.inMatrix[row][col]
                above = self.matrix[row][col + 1]
                self.matrix[row + 1][col + 1] = currentSum + above

    


    def sumRegion(self, rowOne, colOne, rowTwo, colTwo):
        rowOne += 1
        rowTwo += 1
        colOne += 1
        colTwo += 1

        bottomRight, above = self.matrix[rowTwo][colTwo], self.matrix[rowOne - 1][colTwo]
        left, topLeft = self.matrix[rowTwo][colOne - 1], self.matrix[rowOne - 1][colOne - 1]
        return bottomRight - above - left + topLeft







# n, m = map(int, input().split())


# matrix = []


# for i in range(m):
#     matrix.append(list(map(int, input().split())))

# q = int(input())


# queries = []


# for i in range(q):
#     samo7aData, moo7aData = map(int, input().split()), map(int, input().split())
#     queries.append([samo7aData, moo7aData])


# powers = []
# for i in range(0, 11):
#     newMat = [[0 for i in range(m)] for x in range(n)]

#     for row in range(len(matrix)):
#         for col in range(len(matrix[0])):
#             if i > matrix[row][col]:
#                 newMat[row][col] += 1

#     powers.append(SegmentTree2D(n, m, newMat))          



# def execute(data):

#     rowOne, colOne, rowTwo, colTwo, power = data
#     rowOne -= 1
#     colOne -= 1
#     rowTwo -= 1
#     colTwo -= 1

#     return powers[power].sumRegion(rowOne, colOne, rowTwo, colTwo)

# result = []
# for moo7aData, samoo7aData in queries:
    
#     currentMax = 0
#     samoo7a, moo7a = execute(samoo7aData), execute(moo7aData)
    

#     if not samoo7a and not moo7a:
#         result.append("Sameh")
#         continue

#     if samoo7a > moo7a:
#         result.append(f"Samo7a {samoo7a}")
#     elif moo7a > samoo7a:
#         result.append(f"Mo7a {moo7a}")
#     else:
#         result.append(f"Draw {moo7a}")


# for res in result:
#     print(res)

n = int(input())

array = list(map(int, input().split()))


divisors = [0 for i in range(367)]



for num in array:
    currentMax = 0
    for i in range(2, len(divisors)):
        if num % i == 0:
            currentMax = max(currentMax, divisors[i])

    for i in range(2, len(divisors)):
        if num % i == 0:
            divisors[i] = currentMax + 1

print(max(divisors))