Problem:
Longest Increasing Subsequence

For a given sequence A = {a0, a1, ... , an-1}, find the length of the longest increasing subsequnece (LIS) in A.

An increasing subsequence of A is defined by a subsequence {ai0, ai1, ... , aik} where 0 ≤ i0 < i1 < ... < ik < n and ai0 < ai1 < ... < aik.

Input

n
a0
a1
:
an-1

In the first line, an integer n is given. In the next n lines, elements of A are given.

Output

The length of the longest increasing subsequence of A.

Constraints

1 ≤ n ≤ 100000

0 ≤ ai ≤ 109

Sample Input 1

5
5
1
3
2
4

Sample Output 1

3

Sample Input 2

3
1
1
1

Sample Output 2

1

Solution in C# (judge verdict: Accepted)

using System;

namespace DPL_1_D_Longest_Increasing_Subsequence
{
	class Program
	{
		static void Main ( string[] args )
		{
			int inputCount = int.Parse (Console.ReadLine ());
			int[] elements = new int[inputCount];

			for (int lp = 0; lp < inputCount; lp++)
			{
				elements[lp] = int.Parse (Console.ReadLine ());
			}

			var result = LongestIncreasingSubsequence (elements);
			Console.WriteLine (result);
		}

		static int LongestIncreasingSubsequence ( int[] numArray )
		{
			int[] temporaryArray = new int[numArray.Length];
			temporaryArray[0] = numArray[0];
			int length = 1;

			for (int lp = 1; lp < numArray.Length; lp++)
			{
				if (temporaryArray[length - 1] < numArray[lp])
				{
					temporaryArray[length++] = numArray[lp];
				}
				else
				{
					int index = LowerBound (temporaryArray, 0, length, numArray[lp]);
					temporaryArray[index] = numArray[lp];
				}
			}

			return length;
		}

		static int LowerBound ( int[] numArray, int lowerIndex, int upperIndex, int element )
		{
			while (1 < upperIndex - lowerIndex)
			{
				int middleIndex = (lowerIndex + upperIndex) / 2;

				if (numArray[middleIndex] < element)
				{
					lowerIndex = middleIndex;
				}
				else
				{
					upperIndex = middleIndex;
				}
			}

			if (numArray[lowerIndex] < element)
			{
				return upperIndex;
			}
			else
			{
				return lowerIndex;
			}
		}
	}
}