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 Rust (1.15.1) (judge verdict: Accepted)

pub trait BinarySearch<T> {
    fn lower_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, x: &T, mut f: F) -> usize;
    fn lower_bound(&self, x: &T) -> usize;
    fn upper_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, x: &T, mut f: F) -> usize;
    fn upper_bound(&self, x: &T) -> usize;
}

impl<T: Ord + Clone> BinarySearch<T> for Vec<T> {
    fn lower_bound(&self, x: &T) -> usize {
        self.lower_bound_by_key(x, |y| y.clone())
    }

    fn lower_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, x: &T, mut f: F) -> usize {
        let mut high = self.len();
        let mut low = 0;
        while low < high {
            let mid = (low + high) / 2;
            if f(&self[mid]).lt(&f(x)) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        low
    }

    fn upper_bound(&self, x: &T) -> usize {
        self.upper_bound_by_key(x, |y| y.clone())
    }

    fn upper_bound_by_key<B: Ord, F: FnMut(&T) -> B>(&self, x: &T, mut f: F) -> usize {
        let mut high = self.len();
        let mut up = 0;
        while up < high {
            let mid = (up + high) / 2;
            if f(&self[mid]).le(&f(x)) {
                up = mid + 1;
            } else {
                high = mid;
            }
        }
        up
    }
}

fn solve(aa: Vec<isize>) -> usize {
    let n = aa.len();
    let mut dp = vec![std::isize::MAX; n];

    for a in aa {
        let a = -a;
        let p = dp.upper_bound(&a);
        if a < dp[p] {
            dp[p] = a;
        }
    }

    dp.lower_bound(&std::isize::MAX)
}

#[test]
fn upper_bound_test() {
    assert_eq!(vec![1, 1, 2].upper_bound(&1), 2);
    assert_eq!(vec![1, 1, 2, 2, 3].upper_bound(&3), 5);
    assert_eq!(vec![1, 1, 2, 2, 4].upper_bound(&3), 4);
}

#[test]
fn solve_test() {
    assert_eq!(solve(vec![2, 1, 4, 5, 3]), 2);
    assert_eq!(solve(vec![0, 0, 0, 0]), 4);
    assert_eq!(solve(vec![1, 5, 2, 6, 3, 7]), 2);
}

#[allow(unused_macros)]
macro_rules! parse_line {
    ( $t:ty ) => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            iter.next().unwrap().parse::<$t>().unwrap()
        }
    );

    ( $( $t:ty), +) => (
        {
            let mut line = String::new();
            ::std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            ( $(iter.next().unwrap().parse::<$t>().unwrap()),* )
        }
    );
}

#[allow(unused_macros)]
macro_rules! read_line {
    () => {{
        let mut line = String::new();
        ::std::io::stdin().read_line(&mut line).unwrap();
        line.pop();
        line
    }};
}

#[allow(unused_macros)]
macro_rules! parse_vec {
    ( $t:ty ) => {{
        let mut line = String::new();
        ::std::io::stdin().read_line(&mut line).unwrap();
        let iter = line.split_whitespace();
        iter.map(|v| v.parse::<$t>().unwrap()).collect::<Vec<_>>()
    }};
}

fn main() {
    let n = parse_line!(usize);
    let aa = (0..n).map(|_| parse_line!(isize)).collect::<Vec<_>>();
    println!("{}", solve(aa));
}