#include <fstream>
#include <vector>
#include <algorithm>
std::pair<int, int> querySegmentTree(const std::vector<std::pair<int, int>> &segmentTree, int node, int treeLeft, int treeRight, int left, int right)
{
if (left > right)
return {0, -1};
if (treeLeft == left && treeRight == right)
return segmentTree[node];
int treeMiddle = (treeLeft + treeRight) / 2;
std::pair<int, int> resultLeft = querySegmentTree(segmentTree, 2 * node + 1, treeLeft, treeMiddle, left, std::min(right, treeMiddle));
std::pair<int, int> resultRight = querySegmentTree(segmentTree, 2 * node + 2, treeMiddle + 1, treeRight, std::max(treeMiddle + 1, left), right);
if (resultLeft.first > resultRight.first)
return resultLeft;
return resultRight;
}
void updateSegmentTree(std::vector<std::pair<int, int>> &segmentTree, int node, int left, int right, int position, std::pair<int, int> value)
{
if (left == right)
{
segmentTree[node] = value;
return;
}
int middle = (left + right) / 2;
if (position <= middle)
updateSegmentTree(segmentTree, 2 * node + 1, left, middle, position, value);
else
updateSegmentTree(segmentTree, 2 * node + 2, middle + 1, right, position, value);
if (segmentTree[2 * node + 1].first > segmentTree[2 * node + 2].first)
segmentTree[node] = segmentTree[2 * node + 1];
else
segmentTree[node] = segmentTree[2 * node + 2];
}
int main()
{
std::ifstream inFile;
inFile.open("scmax.in");
int n;
inFile >> n;
std::vector<int> numbers(n), sortedNumbers(n);
for (int i = 0; i < n; ++i)
{
inFile >> numbers[i];
sortedNumbers[i] = numbers[i];
}
inFile.close();
std::sort(sortedNumbers.begin(), sortedNumbers.end());
auto endIt = std::unique(sortedNumbers.begin(), sortedNumbers.end());
sortedNumbers.erase(endIt, sortedNumbers.end());
std::vector<int> sortedIndex(n);
for (int i = 0; i < n; ++i)
{
sortedIndex[i] = (int) (std::lower_bound(sortedNumbers.begin(), sortedNumbers.end(), numbers[i]) - sortedNumbers.begin());
}
std::vector<std::pair<int, int>> segmentTree(4 * sortedNumbers.size(), {0, -1});
std::vector<int> bestLength(sortedNumbers.size()), previous(sortedNumbers.size());
for (int i = 0; i < n; ++i)
{
std::pair<int, int> result = querySegmentTree(segmentTree, 0, 0, (int) sortedNumbers.size() - 1, 0, sortedIndex[i] - 1);
if (result.first + 1 > bestLength[sortedIndex[i]])
{
bestLength[sortedIndex[i]] = result.first + 1;
previous[sortedIndex[i]] = result.second;
updateSegmentTree(segmentTree, 0, 0, (int) sortedNumbers.size() - 1, sortedIndex[i], {result.first + 1, sortedIndex[i]});
}
}
int endIndex = (int) (std::max_element(bestLength.begin(), bestLength.end()) - bestLength.begin());
std::vector<int> indexPath;
indexPath.push_back(endIndex);
while (previous[indexPath.back()] != -1)
{
indexPath.push_back(previous[indexPath.back()]);
}
std::ofstream outFile;
outFile.open("scmax.out");
outFile << bestLength[indexPath.front()] << '\n';
for (int i = (int) indexPath.size() - 1; i >= 0; --i)
{
outFile << sortedNumbers[indexPath[i]] << ' ';
}
outFile.close();
return 0;
}