n=int(eval(input()))

# 降順のリストで二分探索

# 自分より小さい数字で最も大きいものを自分でアップデート

# 該当がなければ最後に追加

d=[]

d.append(int(eval(input())))

for i in range(n-1):

  a=int(eval(input()))

  ok=len(d)

  ng=-1

  while abs(ok-ng)>1:

    mid=abs(ok+ng)//2

    if d[mid]<a:

      ok=mid

    else:

      ng=mid

  if ok==len(d):

    d.append(a)

  else:

    d[ok]=a

print((len(d)))
import sys

readline = sys.stdin.readline



N = int(readline())

ans = []

import bisect

for i in range(N):

  a = -int(readline())

  ind = bisect.bisect_right(ans, a)

  if ind == len(ans):

    ans.append(a)

  else:

    ans[ind] = a

    

print((len(ans)))

n = int(eval(input()))
# 降順のリストで二分探索
# 自分より小さい数字で最も大きいものを自分でアップデート
# 該当がなければ最後に追加
d = []
d.append(int(eval(input())))
for i in range(n - 1):
    a = int(eval(input()))
    ok = len(d)
    ng = -1
    while abs(ok - ng) > 1:
        mid = abs(ok + ng) // 2
        if d[mid] < a:
            ok = mid
        else:
            ng = mid
    if ok == len(d):
        d.append(a)
    else:
        d[ok] = a
print((len(d)))

import sys

readline = sys.stdin.readline
N = int(readline())
ans = []
import bisect

for i in range(N):
    a = -int(readline())
    ind = bisect.bisect_right(ans, a)
    if ind == len(ans):
        ans.append(a)
    else:
        ans[ind] = a
print((len(ans)))

-n = int(eval(input())) -# 降順のリストで二分探索 -# 自分より小さい数字で最も大きいものを自分でアップデート -# 該当がなければ最後に追加 -d = [] -d.append(int(eval(input()))) -for i in range(n - 1): -    a = int(eval(input())) -    ok = len(d) -    ng = -1 -    while abs(ok - ng) > 1: -        mid = abs(ok + ng) // 2 -        if d[mid] < a: -            ok = mid -        else: -            ng = mid -    if ok == len(d): -        d.append(a) +import sys + +readline = sys.stdin.readline +N = int(readline()) +ans = [] +import bisect + +for i in range(N): +    a = -int(readline()) +    ind = bisect.bisect_right(ans, a) +    if ind == len(ans): +        ans.append(a) -        d[ok] = a -print((len(d))) +        ans[ind] = a +print((len(ans)))