Problem:
Score : 500 points

Problem Statement

You are given a sequence with N integers: A = \{ A_1, A_2, \cdots, A_N \}.
For each of these N integers, we will choose a color and paint the integer with that color. Here the following condition must be satisfied:

If A_i and A_j (i < j) are painted with the same color, A_i < A_j.

Find the minimum number of colors required to satisfy the condition.

Constraints

1 \leq N \leq 10^5

0 \leq A_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
A_1
:
A_N

Output

Print the minimum number of colors required to satisfy the condition.

Sample Input 1

5
2
1
4
5
3

Sample Output 1

2

We can satisfy the condition with two colors by, for example, painting 2 and 3 red and painting 1, 4, and 5 blue.

Sample Input 2

4
0
0
0
0

Sample Output 2

4

We have to paint all the integers with distinct colors.

Solution in PHP (7.4.4) (judge verdict: Time Limit Exceeded)

<?php

[$N] = fscanf(STDIN, "%d");

$array = [];


[$tmp] = fscanf(STDIN, "%d");

$array[] = PHP_INT_MAX;
$array[] = $tmp;
$min = $tmp;
for($i=2;$i<=$N;$i++){
    [$tmp] = fscanf(STDIN, "%d");
//    $max = count($array) - 1;
    if($tmp <= $min){
        $array[] = $tmp;
        $min = $tmp;
    }else {
        $ans = binarySearch($array, $tmp, intdiv(count($array), 2), 0, count($array) - 1);
        if ($ans[0] === 1) {
            $array[$ans[1][1]+1] = $tmp;
//            rsort($array);
        } else {
            $array[$ans[1][1]] = $tmp;
//            rsort($array);
        }
    }
}
echo count($array)-1;

function binarySearch(array $array, int $target, int $pivot, int $min, int $max, $mode=1)
{
    $evaluation = evaluation($pivot, $target);
    if ($mode === 1) {
        if ($max - $min <= 1) {
            if (evaluation($min, $target) === 1 && evaluation($max, $target) === -1) {
                return [false, [$min, $max]];
            }
        }
        if ($array[$pivot] < $target) {
            $max = $pivot;
            $pivot = $min + intdiv($max - $min, 2);
        } elseif ($array[$pivot] > $target) {
            $min = $pivot;
            $pivot = $min + intdiv($max - $min + 1, 2);
        } else {
            if (evaluation($pivot + 1, $target) === -1) {
                $max = $pivot;
                $pivot = $min + intdiv($pivot - $min, 2);
                if (evaluation($min, $target) === 0) {
                    return [1, [$min, $max]];
                }
                $mode = 2;
            } else {
                $pivot = $pivot + intdiv($max - $pivot + 1, 2);
            }
        }
    } elseif ($mode === 2) {
        if ($array[$pivot] > $target) {
            $pivot = $pivot + intdiv($max - $pivot + 1, 2);
        } else {
            if ($array[$pivot-1] > $target) {
                return [1, [$pivot, $max]];
            } else {
                $pivot = $min + intdiv($pivot - $min, 2);
            }
        }
    }
    return binarySearch($array, $target, $pivot, $min, $max);
}

//評価関数
//-1 : 小さいほうを探索
//0 : 探索値を発見
//1 : 大きいほうを探索
function evaluation(int $check, int $target)
{
    global $array;

    if ($array[$check] > $target) {
        return 1;
    } elseif ($array[$check] < $target) {
        return -1;
    } else {
        return 0;
    }

}