import bisect

global L, arr, n
def _input(n):
    #return [int(raw_input()) for i in xrange(n)]
    for i in xrange(n):
        arr[i] = int(raw_input())

def _lower_bound(arr, n, target):
    '''
    :return: a value not less than target, value >= target
    '''
    l, r = 0, n - 1 # r is index at 1
    pos = 0
    while l < r:
        pos = (l + r) / 2
        if arr[pos] > target:
            r = pos
        else: # <=
            l = pos + 1

    return r#(l + r) / 2 # Need to fix

# Wrapper for built-in function
def lower_bound(arr, target):
    return bisect.bisect_right(arr, target)

L = [0] * 100000
arr = [0] * 100001
def LIS():
    global L, arr, n

    L[0] = arr[0]
    length = 1

    for i in xrange(1, n):
        if L[length - 1] < arr[i]:
            L[length] = arr[i]#L.append(A[i])
            length += 1
        else:
            L[lower_bound(L[:length], arr[i])] = arr[i]
    return length, L

#==============================================
def main():
    global L, arr, n

    n = int(raw_input())
    _input(n)
    LIS()
    print len(set(L))

if __name__ == "__main__":
    main()