#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
std::pair<int, int> querySegTree(const std::vector<std::pair<int, int>>& segTree, const std::vector<int>& values,
int node, int treeLeft, int treeRight, int left, int right)
{
if (right < treeLeft || left > treeRight)
{
return {0, -1};
}
if (left <= treeLeft && right >= treeRight)
{
return segTree[node];
}
int treeMid = (treeLeft + treeRight) / 2;
return std::max(querySegTree(segTree, values, 2 * node + 1, treeLeft, treeMid, left, right),
querySegTree(segTree, values, 2 * node + 2, treeMid + 1, treeRight, left, right));
}
void updateSegTree(std::vector<std::pair<int, int>>& segTree, const std::vector<int>& values,
int node, int treeLeft, int treeRight, int position, const std::pair<int, int>& newValue)
{
if (treeLeft == treeRight)
{
segTree[node] = newValue;
return;
}
int treeMid = (treeLeft + treeRight) / 2;
if (position <= treeMid)
{
updateSegTree(segTree, values, 2 * node + 1, treeLeft, treeMid, position, newValue);
}
else
{
updateSegTree(segTree, values, 2 * node + 2, treeMid + 1, treeRight, position, newValue);
}
segTree[node] = std::max(segTree[2 * node + 1], segTree[2 * node + 2]);
}
int main()
{
std::ifstream fin("scmax.in");
int n;
fin >> n;
std::vector<int> numbers(n);
for (int i = 0; i < n; ++i)
{
fin >> numbers[i];
}
fin.close();
std::vector<int> sortedIndexes(n);
std::iota(sortedIndexes.begin(), sortedIndexes.end(), 0);
std::sort(sortedIndexes.begin(), sortedIndexes.end(), [refNumbers = std::cref(numbers)](int a, int b){
return refNumbers.get()[a] < refNumbers.get()[b] || (refNumbers.get()[a] == refNumbers.get()[b] && a > b);
});
std::vector<int> indexAfterSort(n);
for (int i = 0; i < n; ++i)
{
indexAfterSort[sortedIndexes[i]] = i;
}
std::vector<int> bestLen(n), previous(n, -1);
std::vector<std::pair<int, int>> segTree(4 * n, {0, -1});
for (int i = 0; i < n; ++i)
{
std::pair<int, int> result = querySegTree(segTree, bestLen, 0, 0, n - 1, 0, indexAfterSort[i] - 1);
bestLen[indexAfterSort[i]] = result.first + 1;
updateSegTree(segTree, bestLen, 0, 0, n - 1, indexAfterSort[i], {bestLen[indexAfterSort[i]], indexAfterSort[i]});
previous[indexAfterSort[i]] = result.second;
}
std::ofstream fout("scmax.out");
int ansIndex = std::max_element(bestLen.begin(), bestLen.end()) - bestLen.begin();
fout << bestLen[ansIndex] << '\n';
std::vector<int> ansNumbers;
ansNumbers.reserve(bestLen[ansIndex]);
while (ansIndex != -1)
{
ansNumbers.push_back(numbers[sortedIndexes[ansIndex]]);
ansIndex = previous[ansIndex];
}
std::reverse(ansNumbers.begin(), ansNumbers.end());
for (int number: ansNumbers)
{
fout << number << ' ';
}
fout.close();
return 0;
}