package main

import (
	"fmt"
)

func max(i, j int) int {
	if i > j {
		return i
	}
	return j
}
func main() {
	num := 0
	for {
		n, _ := fmt.Scan(&num)
		if n == 0 {
			break
		} else {
			arr := make([]int, num)
			for i := 0; i < num; i++ {
				fmt.Scan(&arr[i])
			}
			res := f(arr)
			for i := 0; i < len(res); i++ {
				if i == len(res)-1 {
					fmt.Println(res[i])
				} else {
					fmt.Printf("%d ", res[i])
				}
			}
		}
	}
}

func f(arr []int) []int {
	end := []int{arr[0]} // end数组每个值的含义end[i],长度为i+1,对应arr所在位置的最小值
	dp := make([]int, len(arr)) // 记录每个位置的长度
	dp[0] = 1 // 初始时,0位置对应的长度为1,最大长度为1,所在位置为0
	maxvalue := dp[0] // 递增系序列最大值
	index := 0 // 递增系序列最大值所在位置
	for i := 1; i < len(arr); i++ {
		k := find(end, arr[i]) // 在end数组中,找到大于arr[i]的第一个位置
		if k == len(end) { // k右边越界,表示在当前end数组中找不到比arr[i]大的数
			end = append(end, arr[i])  // 添加arr[i],表示以arr[i]结尾,最长递增子序列长度为k+1
			dp[i] = k + 1 // 表示以arr[i]结尾,最长递增子序列长度为k+1
			maxvalue = dp[i]
			index = i
		} else if k < len(end) && end[k] > arr[i] { // 找到1个可比较的位置,对以下2种情况合并:
		  // 情况1: 能够找到一个位置,这个位置大于等于arr[i],只有大于大时候需要更新
		  // 情况2: 左边越界,此时k返回为0,这个位置要么end[k] > arr[i]进行更新,要么保留返回值
			end[k] = arr[i]
			dp[i] = k + 1
			if maxvalue == k+1 { 
			  //当递增系序列在最大长度上进行更新较小的arr[i]值,对应的位置也需要修改
				index = i
			}
		} else {
		}
	}

	res := make([]int, maxvalue)
	for i, j := index, 0; i >= 0 && maxvalue != 0; i-- {
		// 每次按最大长度,
	    // 每次只取最后的一个值,肯定为最小值
		if dp[i] == maxvalue {
			maxvalue--
			res[len(res)-j-1] = arr[i]
			j++
		}
	}

	return res
}
// find方法,数组中的值升序,且没有重复值
// 返回值表示
// 右边越界,找不到对应的值
// 返回[0..len(end)-1] 在end数组中可以找到一个位置,这个位置>=target
// 例外,返回为0时,可能表示找到,也可能表示找不到,左边越界。
func find(end []int, target int) int {
	l, r := 0, len(end)-1
	for l <= r {
		mid := (r-l)/2 + l
		if end[mid] > target {
			r = mid - 1
		} else if end[mid] == target {
			return mid
		} else {
			l = mid + 1
		}
	}
	return l
}