#include <fstream>
#include <string.h>
#include <limits.h>
#include <stack>
#define MAX_DIM_TREE 262150 // 2^18 - 1
#define MAX_DIM_VECT 100002
using namespace std;
typedef struct node
{
int val;
int pos;
struct node *next;
}Node;
void Initialise(int n, int &treeDim, int *tree, Node **parentVect);
void Process(int n, int treeDim, int &max, int* tree, Node** parentVect, istream &fin);
int Update (int pos, int x, int treeDim, int* tree, Node** parentVect);
void WriteResult(int max, Node** parentVect, ostream &fout);
int main()
{
int treeDim;
int tree[MAX_DIM_TREE];
Node* parentVect[MAX_DIM_VECT];
int n, max;
ifstream fin;
ofstream fout;
fout.open("scmax.out");
fin.open("scmax.in");
fin >> n;
Initialise(n, treeDim, tree, parentVect);
Process(n, treeDim, max, tree, parentVect, fin);
WriteResult(max, parentVect, fout);
fin.close();
fout.close();
return 0;
}
void Initialise(int n, int &treeDim, int *tree, Node **parentVect)
{
treeDim = 1;
int exp = 1;
while(exp < n)
{
exp *= 2;
treeDim += exp;
}
for(int i = 1; i <= treeDim +1; i++)
{
tree[i] = INT_MAX;
}
memset(parentVect, 0, MAX_DIM_VECT * sizeof(Node*));
}
void Process (int n, int treeDim, int &max, int* tree, Node **parentVect, istream &fin)
{
int x;
for(int i = 0; i < n; ++i)
{
fin >> x;
int pos = Update(1, x, treeDim, tree, parentVect);
if(pos != 0)
{
Node* newNode = new Node();
newNode->pos = pos;
newNode->val = x;
newNode->next = parentVect[pos];
parentVect[pos] = newNode;
if(pos > max)
{
max = pos;
}
}
}
}
int Update (int pos, int x, int treeDim, int* tree, Node **parentVect)
{
if(2 * pos > treeDim && x < tree[pos])
{
tree[pos] = x;
return pos - treeDim / 2;
}
if(tree[2 * pos] >= x)
{
return Update(2 * pos, x, treeDim, tree, parentVect);
}
else if (tree [2 * pos + 1] > x)
{
int result = Update(2 * pos + 1, x, treeDim, tree, parentVect);
tree[pos] = tree[2 * pos + 1];
return result;
}
return 0;
}
void WriteResult(int max, Node** parentVect, ostream &fout)
{
stack<Node*> result;
fout << max << "\n";
Node* prev = parentVect[max];
result.push(prev);
for(int i = max - 1; i > 0; --i)
{
Node* current = parentVect[i];
Node* selected = NULL;
while(current != NULL)
{
if(current->pos < prev->pos && current->val < prev->val &&(selected == NULL || current->val < selected->val))
{
selected = current;
}
current = current->next;
}
prev = selected;
result.push(prev);
}
while(!result.empty())
{
fout << result.top()->val << " ";
result.pop();
}
}