Ivan has an array consisting of n different integers. He decided to reorder all elements in increasing order. Ivan loves merge sort so he decided to represent his array with one or several increasing sequences which he then plans to merge into one sorted array.

Ivan represent his array with increasing sequences with help of the following algorithm.

While there is at least one unused number in array Ivan repeats the following procedure:  iterate through array from the left to the right;  Ivan only looks at unused numbers on current iteration;  if current number is the first unused number on this iteration or this number is greater than previous unused number on current iteration, then Ivan marks the number as used and writes it down. 

For example, if Ivan's array looks like [1, 3, 2, 5, 4] then he will perform two iterations. On first iteration Ivan will use and write numbers [1, 3, 5], and on second one — [2, 4].

Write a program which helps Ivan and finds representation of the given array with one or several increasing sequences in accordance with algorithm described above.


-----Input-----

The first line contains a single integer n (1 ≤ n ≤ 2·10^5) — the number of elements in Ivan's array.

The second line contains a sequence consisting of distinct integers a_1, a_2, ..., a_{n} (1 ≤ a_{i} ≤ 10^9) — Ivan's array.


-----Output-----

Print representation of the given array in the form of one or more increasing sequences in accordance with the algorithm described above. Each sequence must be printed on a new line.


-----Examples-----
Input
5
1 3 2 5 4

Output
1 3 5 
2 4 

Input
4
4 3 2 1

Output
4 
3 
2 
1 

Input
4
10 30 50 101

Output
10 30 50 101

Difficulty: MEDIUM_HARD
Tags: Sorting

Data structures
Skill types: Sorting

Data structures

Starter code:

Solutions:
n = int(input())
from bisect import bisect_left
a = list(map(int, input().split()))
ss = []
ms = []
for i in range(n):
	k = a[i]
	ind = bisect_left(ms, -k)
	if ind == len(ms):
		ss.append([])
		ms.append(0)
	ss[ind].append(k)
	ms[ind] = -k
for s in ss:
	print(' '.join([str(i) for i in s]))


n = int(input())
arr = list(map(int, input().strip().split()))
res = [[arr[0]]]
start = [arr[0]]
done = False
for i in range(1, n):
	t = arr[i]
	if start[len(start) - 1] > t:
		res.append([t])
		start.append(t)
	else:
		(l, r) = (0, len(start) - 1)
		while r - l > 1:
			mm = l + int((r - l) / 2)
			if start[mm] < t:
				r = mm
			else:
				l = mm
		if start[l] < t:
			res[l].append(t)
			start[l] = t
		else:
			res[r].append(t)
			start[r] = t
for ls in res:
	for i in ls:
		print(i, end=' ')
	print()


import bisect
n = int(input())
a = list(map(int, input().split()))
d = []
ms = []
for i in range(n):
	idx = bisect.bisect_left(ms, -a[i])
	if idx == len(ms):
		d.append([a[i]])
		ms.append(-a[i])
	else:
		ms[idx] = -a[i]
		d[idx].append(a[i])
for x in d:
	print(*x)


input()
numbers = [int(i) for i in input().split()]
runs = [[numbers[0]]]
for n in numbers[1:]:
	if n < runs[-1][-1]:
		runs.append([n])
		continue
	lo = 0
	hi = len(runs) - 1
	valid = -1
	while lo <= hi:
		to_search = (lo + hi) // 2
		if n > runs[to_search][-1]:
			valid = to_search
			hi = to_search - 1
		else:
			lo = to_search + 1
	runs[valid].append(n)
for r in runs:
	print(' '.join((str(n) for n in r)))


n = int(input())
a = list(map(int, input().split()))
groups = []
groupTail = []
for elem in a:
	if not groups:
		groups.append([elem])
		groupTail.append(elem)
	else:
		l = 0
		r = len(groups)
		while l <= r:
			m = (l + r) // 2
			if m == len(groups):
				break
			if l == r:
				break
			if groupTail[m] < elem:
				r = m
			else:
				l = m + 1
		if m == len(groups):
			groups.append([elem])
			groupTail.append(elem)
		else:
			groups[m].append(elem)
			groupTail[m] = elem
for line in groups:
	print(' '.join(map(str, line)))


ans = []
n = int(input())
arr = list(map(int, input().split()))
for x in arr:
	(lo, hi) = (0, len(ans))
	while lo < hi:
		mid = (lo + hi) // 2
		if ans[mid][-1] < x:
			hi = mid
		else:
			lo = mid + 1
	if lo == len(ans):
		ans.append([x])
	else:
		ans[lo].append(x)
for line in ans:
	print(' '.join([str(i) for i in line]))


n = int(input())
arr = list(map(int, input().split()))
ans = [0] * 1
ans[0] = []
ans[0].append(arr[0])
for i in range(1, n, 1):
	(lo, hi) = (0, len(ans))
	idx = -1
	while lo <= hi:
		mid = (lo + hi) // 2
		if lo != len(ans) and ans[mid][len(ans[mid]) - 1] < arr[i]:
			idx = mid
			hi = mid - 1
		else:
			lo = mid + 1
	if len(ans) == hi:
		ans.append([])
		ans[hi].append(arr[i])
	else:
		ans[idx].append(arr[i])
for i in range(len(ans)):
	for j in range(len(ans[i])):
		print(ans[i][j], end=' ')
	print()


class CodeforcesTask847BSolution:

	def __init__(self):
		self.result = ''
		self.n = 0
		self.sequence = []

	def read_input(self):
		self.n = int(input())
		self.sequence = [int(x) for x in input().split(' ')]

	def process_task(self):
		mx = 2000001
		ans = [[] for x in range(mx)]
		crf = [0] * mx
		cnt = 0
		id = 0
		for x in range(self.n):
			if not x:
				ans[cnt].append(self.sequence[x])
				crf[cnt] = self.sequence[x]
			else:
				if self.sequence[x] <= crf[cnt]:
					cnt += 1
					id = cnt
				else:
					l = 0
					r = cnt
					while l < r:
						mid = (l + r) // 2
						if crf[mid] >= self.sequence[x]:
							l = mid + 1
						else:
							r = mid
					id = r
				ans[id].append(self.sequence[x])
				crf[id] = self.sequence[x]
		self.result = '\n'.join([' '.join([str(x) for x in row]) for row in ans[:cnt + 1]])

	def get_result(self):
		return self.result

def __starting_point():
	Solution = CodeforcesTask847BSolution()
	Solution.read_input()
	Solution.process_task()
	print(Solution.get_result())
__starting_point()


from sys import stdin
from collections import deque
from bisect import bisect_right as br
n = int(stdin.readline().strip())
s = list(map(int, stdin.readline().strip().split()))
arr = deque([s[0]])
ans = deque([[s[0]]])
for i in range(1, n):
	x = br(arr, s[i])
	if x == 0:
		arr.appendleft(s[i])
		ans.appendleft([s[i]])
	else:
		arr[x - 1] = s[i]
		ans[x - 1].append(s[i])
ans.reverse()
for i in ans:
	print(*i)


n = int(input())
lst = list(map(int, input().strip().split()))
ans = [[lst[0]]]
head = [lst[0]]
added = False
for i in range(1, n):
	t = lst[i]
	if head[len(head) - 1] > t:
		ans.append([t])
		head.append(t)
	else:
		(l, r) = (0, len(head) - 1)
		while r - l > 1:
			mm = l + int((r - l) / 2)
			if head[mm] < t:
				r = mm
			else:
				l = mm
		if head[l] < t:
			ans[l].append(t)
			head[l] = t
		else:
			ans[r].append(t)
			head[r] = t
for ls in ans:
	print(' '.join((str(x) for x in ls)))


n = int(input())
a = []
arr = list(map(int, input().split()))
for i in range(n):
	if len(a) == 0:
		a.append([arr[i]])
		continue
	el = arr[i]
	(l, r) = (0, len(a) - 1)
	while r - l >= 1:
		m = (l + r) // 2
		if el > a[m][-1]:
			r = m
		else:
			l = m + 1
	if el < a[l][-1]:
		a.append([el])
	else:
		a[l].append(el)
for x in a:
	for el in x:
		print(el, end=' ')
	print()


n = int(input())
a = list(map(int, input().split()))
ans = []
for i in range(n):
	l = 0
	r = len(ans)
	while l < r:
		mid = l + (r - l) // 2
		if ans[mid][-1] < a[i]:
			r = mid
		else:
			l = mid + 1
	if l == len(ans):
		ans.append([a[i]])
	else:
		ans[l].append(a[i])
for x in ans:
	print(*x)


from collections import defaultdict, deque
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
import random

class TreapMultiSet(object):
	root = 0
	size = 0

	def __init__(self, data=None):
		if data:
			data = sorted(data)
			self.root = treap_builder(data)
			self.size = len(data)

	def add(self, key):
		self.root = treap_insert(self.root, key)
		self.size += 1

	def remove(self, key):
		self.root = treap_erase(self.root, key)
		self.size -= 1

	def discard(self, key):
		try:
			self.remove(key)
		except KeyError:
			pass

	def ceiling(self, key):
		x = treap_ceiling(self.root, key)
		return treap_keys[x] if x else None

	def higher(self, key):
		x = treap_higher(self.root, key)
		return treap_keys[x] if x else None

	def floor(self, key):
		x = treap_floor(self.root, key)
		return treap_keys[x] if x else None

	def lower(self, key):
		x = treap_lower(self.root, key)
		return treap_keys[x] if x else None

	def max(self):
		return treap_keys[treap_max(self.root)]

	def min(self):
		return treap_keys[treap_min(self.root)]

	def __len__(self):
		return self.size

	def __nonzero__(self):
		return bool(self.root)
	__bool__ = __nonzero__

	def __contains__(self, key):
		return self.floor(key) == key

	def __repr__(self):
		return 'TreapMultiSet({})'.format(list(self))

	def __iter__(self):
		if not self.root:
			return iter([])
		out = []
		stack = [self.root]
		while stack:
			node = stack.pop()
			if node > 0:
				if right_child[node]:
					stack.append(right_child[node])
				stack.append(~node)
				if left_child[node]:
					stack.append(left_child[node])
			else:
				out.append(treap_keys[~node])
		return iter(out)

class TreapSet(TreapMultiSet):

	def add(self, key):
		(self.root, duplicate) = treap_insert_unique(self.root, key)
		if not duplicate:
			self.size += 1

	def __repr__(self):
		return 'TreapSet({})'.format(list(self))

class TreapHashSet(TreapMultiSet):

	def __init__(self, data=None):
		if data:
			self.keys = set(data)
			super(TreapHashSet, self).__init__(self.keys)
		else:
			self.keys = set()

	def add(self, key):
		if key not in self.keys:
			self.keys.add(key)
			super(TreapHashSet, self).add(key)

	def remove(self, key):
		self.keys.remove(key)
		super(TreapHashSet, self).remove(key)

	def discard(self, key):
		if key in self.keys:
			self.remove(key)

	def __contains__(self, key):
		return key in self.keys

	def __repr__(self):
		return 'TreapHashSet({})'.format(list(self))

class TreapHashMap(TreapMultiSet):

	def __init__(self, data=None):
		if data:
			self.map = dict(data)
			super(TreapHashMap, self).__init__(self.map.keys())
		else:
			self.map = dict()

	def __setitem__(self, key, value):
		if key not in self.map:
			super(TreapHashMap, self).add(key)
		self.map[key] = value

	def __getitem__(self, key):
		return self.map[key]

	def add(self, key):
		raise TypeError('add on TreapHashMap')

	def get(self, key, default=None):
		return self.map.get(key, default=default)

	def remove(self, key):
		self.map.pop(key)
		super(TreapHashMap, self).remove(key)

	def discard(self, key):
		if key in self.map:
			self.remove(key)

	def __contains__(self, key):
		return key in self.map

	def __repr__(self):
		return 'TreapHashMap({})'.format(list(self))
left_child = [0]
right_child = [0]
treap_keys = [0]
treap_prior = [0.0]

def treap_builder(sorted_data):

	def build(begin, end):
		if begin == end:
			return 0
		mid = (begin + end) // 2
		root = treap_create_node(sorted_data[mid])
		left_child[root] = build(begin, mid)
		right_child[root] = build(mid + 1, end)
		ind = root
		while True:
			lc = left_child[ind]
			rc = right_child[ind]
			if lc and treap_prior[lc] > treap_prior[ind]:
				if rc and treap_prior[rc] > treap_prior[rc]:
					(treap_prior[ind], treap_prior[rc]) = (treap_prior[rc], treap_prior[ind])
					ind = rc
				else:
					(treap_prior[ind], treap_prior[lc]) = (treap_prior[lc], treap_prior[ind])
					ind = lc
			elif rc and treap_prior[rc] > treap_prior[ind]:
				(treap_prior[ind], treap_prior[rc]) = (treap_prior[rc], treap_prior[ind])
				ind = rc
			else:
				break
		return root
	return build(0, len(sorted_data))

def treap_create_node(key):
	treap_keys.append(key)
	treap_prior.append(random.random())
	left_child.append(0)
	right_child.append(0)
	return len(treap_keys) - 1

def treap_split(root, key):
	left_pos = right_pos = 0
	while root:
		if key < treap_keys[root]:
			left_child[right_pos] = right_pos = root
			root = left_child[root]
		else:
			right_child[left_pos] = left_pos = root
			root = right_child[root]
	(left, right) = (right_child[0], left_child[0])
	right_child[left_pos] = left_child[right_pos] = right_child[0] = left_child[0] = 0
	return (left, right)

def treap_merge(left, right):
	(where, pos) = (left_child, 0)
	while left and right:
		if treap_prior[left] > treap_prior[right]:
			where[pos] = pos = left
			where = right_child
			left = right_child[left]
		else:
			where[pos] = pos = right
			where = left_child
			right = left_child[right]
	where[pos] = left or right
	node = left_child[0]
	left_child[0] = 0
	return node

def treap_insert(root, key):
	if not root:
		return treap_create_node(key)
	(left, right) = treap_split(root, key)
	return treap_merge(treap_merge(left, treap_create_node(key)), right)

def treap_insert_unique(root, key):
	if not root:
		return (treap_create_node(key), False)
	(left, right) = treap_split(root, key)
	if left and treap_keys[left] == key:
		return (treap_merge(left, right), True)
	return (treap_merge(treap_merge(left, treap_create_node(key)), right), False)

def treap_erase(root, key):
	if not root:
		raise KeyError(key)
	if treap_keys[root] == key:
		return treap_merge(left_child[root], right_child[root])
	node = root
	while root and treap_keys[root] != key:
		parent = root
		root = left_child[root] if key < treap_keys[root] else right_child[root]
	if not root:
		raise KeyError(key)
	if root == left_child[parent]:
		left_child[parent] = treap_merge(left_child[root], right_child[root])
	else:
		right_child[parent] = treap_merge(left_child[root], right_child[root])
	return node

def treap_ceiling(root, key):
	while root and treap_keys[root] < key:
		root = right_child[root]
	if not root:
		return 0
	min_node = root
	min_key = treap_keys[root]
	while root:
		if treap_keys[root] < key:
			root = right_child[root]
		else:
			if treap_keys[root] < min_key:
				min_key = treap_keys[root]
				min_node = root
			root = left_child[root]
	return min_node

def treap_higher(root, key):
	while root and treap_keys[root] <= key:
		root = right_child[root]
	if not root:
		return 0
	min_node = root
	min_key = treap_keys[root]
	while root:
		if treap_keys[root] <= key:
			root = right_child[root]
		else:
			if treap_keys[root] < min_key:
				min_key = treap_keys[root]
				min_node = root
			root = left_child[root]
	return min_node

def treap_floor(root, key):
	while root and treap_keys[root] > key:
		root = left_child[root]
	if not root:
		return 0
	max_node = root
	max_key = treap_keys[root]
	while root:
		if treap_keys[root] > key:
			root = left_child[root]
		else:
			if treap_keys[root] > max_key:
				max_key = treap_keys[root]
				max_node = root
			root = right_child[root]
	return max_node

def treap_lower(root, key):
	while root and treap_keys[root] >= key:
		root = left_child[root]
	if not root:
		return 0
	max_node = root
	max_key = treap_keys[root]
	while root:
		if treap_keys[root] >= key:
			root = left_child[root]
		else:
			if treap_keys[root] > max_key:
				max_key = treap_keys[root]
				max_node = root
			root = right_child[root]
	return max_node

def treap_min(root):
	if not root:
		raise ValueError('min on empty treap')
	while left_child[root]:
		root = left_child[root]
	return root

def treap_max(root):
	if not root:
		raise ValueError('max on empty treap')
	while right_child[root]:
		root = right_child[root]
	return root

def floyd_warshall(n, edges):
	dist = [[0 if i == j else float('inf') for i in range(n)] for j in range(n)]
	pred = [[None] * n for _ in range(n)]
	for (u, v, d) in edges:
		dist[u][v] = d
		pred[u][v] = u
	for k in range(n):
		for i in range(n):
			for j in range(n):
				if dist[i][k] + dist[k][j] < dist[i][j]:
					dist[i][j] = dist[i][k] + dist[k][j]
					pred[i][j] = pred[k][j]
	return (dist, pred)
input = lambda : sys.stdin.readline().rstrip('\r\n')
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
import bisect
n = int(input())
arr = list(map(int, input().split()))
find_set = TreapMultiSet(arr)
ans = defaultdict(list)
added = set()
cnt = 0
q = deque()
q.append(arr[0])
ans[0].append(arr[0])
cnt += 1
for i in range(1, n):
	res = bisect.bisect_left(q, arr[i])
	if res == 0:
		q.appendleft(arr[i])
		ans[cnt].append(arr[i])
		cnt += 1
	elif res < len(q) and arr[i] == q[res - 1]:
		q.appendleft(arr[i])
		ans[cnt].append(arr[i])
		cnt += 1
	else:
		ans[len(q) - res].append(arr[i])
		q[res - 1] = arr[i]
for index in range(len(ans)):
	print(' '.join((str(i) for i in ans[index])))


def readInt():
	return int(input())

def readInts():
	return [int(i) for i in input().split()]
n = readInt()
a = readInts()
nexts = [-1] * n
heads = [-1] * n
lasts = [-1] * n
cnt = 0
for i in range(n):
	value = a[i]
	left = -1
	right = cnt
	while right - left > 1:
		mid = (right + left) // 2
		if a[lasts[mid]] < value:
			right = mid
		else:
			left = mid
	if right == cnt:
		heads[right] = i
		cnt += 1
	else:
		last = lasts[right]
		nexts[last] = i
	lasts[right] = i
for i in range(cnt):
	index = heads[i]
	while index != -1:
		print(a[index], end=' ')
		index = nexts[index]
	print()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def pre(s):
	n = len(s)
	pi = [0] * n
	for i in range(1, n):
		j = pi[i - 1]
		while j and s[i] != s[j]:
			j = pi[j - 1]
		if s[i] == s[j]:
			j += 1
		pi[i] = j
	return pi

def prod(a):
	ans = 1
	for each in a:
		ans = ans * each
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
from math import inf
from bisect import bisect_left
from math import inf
from bisect import bisect_left
from collections import deque

def get_lis(a):
	dp = [0] * len(a)
	aux = [inf] * (len(a) + 1)
	aux[0] = -inf
	high = 0
	ans = [deque([]) for __ in range(len(a) + 1)]
	for i in range(len(a)):
		dp[i] = bisect_left(aux, a[i])
		aux[dp[i]] = min(aux[dp[i]], a[i])
		high = max(high, dp[i])
		ans[dp[i]].append(a[i])
	return ans

def get_subsequence(a, k):
	if k > len(a):
		return None
	dp = [0] * len(a)
	aux = [inf] * (k + 1)
	aux[0] = -inf
	high = 0
	for i in range(len(a)):
		dp[i] = bisect_left(aux, a[i])
		aux[dp[i]] = min(aux[dp[i]], a[i])
		high = max(high, dp[i])
		if high == k:
			return aux[1:]
	return None
for _ in range(int(input()) if not True else 1):
	n = int(input())
	a = list(map(int, input().split()))
	x = [[a[0]]]
	for i in range(1, n):
		(alpha, omega) = (0, len(x) - 1)
		while alpha < omega:
			mid = (alpha + omega) // 2
			if x[mid][-1] < a[i]:
				omega = mid
			else:
				alpha = mid + 1
		if a[i] >= x[alpha][-1]:
			x[alpha] += [a[i]]
		else:
			x += [[a[i]]]
	for i in x:
		print(*i)


from bisect import bisect_left
n = int(input())
A = list(map(int, input().split()))
max_vals = []
result_lists = []
for i in range(n):
	val = -A[i]
	idx = bisect_left(max_vals, val)
	if idx == len(max_vals):
		max_vals.append(0)
		result_lists.append([])
	max_vals[idx] = val
	result_lists[idx].append(-val)
for res in result_lists:
	print(' '.join([str(i) for i in res]))


import os.path
from math import gcd, floor, ceil
from collections import *
import sys
mod = 1000000007
INF = float('inf')

def st():
	return list(sys.stdin.readline().strip())

def li():
	return list(map(int, sys.stdin.readline().split()))

def mp():
	return map(int, sys.stdin.readline().split())

def inp():
	return int(sys.stdin.readline())

def pr(n):
	return sys.stdout.write(str(n) + '\n')

def prl(n):
	return sys.stdout.write(str(n) + ' ')
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
n = inp()
l = li()
ans = [[l[0]]]
cur = [l[0]]
for i in range(1, n):
	if l[i] < cur[-1]:
		cur.append(l[i])
		ans.append([l[i]])
	else:
		low = len(cur) - 1
		high = 0
		ind = -1
		while low >= high:
			mid = (low + high) // 2
			if cur[mid] > l[i]:
				high = mid + 1
			else:
				ind = mid
				low = mid - 1
		cur[ind] = l[i]
		ans[ind].append(l[i])
for i in ans:
	print(*i)


from bisect import bisect_left
n = int(input())
a = list(map(int, input().split()))
p = []
result = []
for x in a:
	r = bisect_left(p, -x)
	if r == len(result):
		result.append([])
		p.append(0)
	result[r].append(x)
	p[r] = -x
for arr in result:
	for i in range(len(arr) - 1):
		print(arr[i], end=' ')
	print(arr[-1])