#include <bits/stdc++.h>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
const int NMAX = 1e5 + 1;
int n, m, arr[NMAX], aux[NMAX], dp[NMAX];
map<int, int> real_value;
class SegmentTree
{
private:
int tree[4 * NMAX];
public:
void update(int node, int st, int dr, int poz, int val)
{
if(st == dr)
{
tree[node] = val;
return;
}
int mid = (st + dr) / 2;
if(poz <= mid)
update(2 * node, st, mid, poz, val);
else
update(2 * node + 1, mid + 1, dr, poz, val);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
int query(int node, int st, int dr, int qst, int qdr)
{
if(qdr < st || dr < qst)
return 0;
if(qst <= st && dr <= qdr)
return tree[node];
int mid = (st + dr) / 2;
return max(query(2 * node, st, mid, qst, qdr), query(2 * node + 1, mid + 1, dr, qst, qdr));
}
};
SegmentTree aint;
void compress()
{
memcpy(aux, arr, sizeof(arr));
sort(aux + 1, aux + n + 1);
for(int i = 1; i <= n; i++)
if(aux[i] != aux[i - 1])
aux[++m] = aux[i];
for(int i = 1; i <= n; i++)
{
int c = lower_bound(aux + 1, aux + m + 1, arr[i]) - aux;
real_value[c] = arr[i];
arr[i] = c;
}
}
int main()
{
fin >> n;
for(int i = 1; i <= n; i++)
fin >> arr[i];
compress();
for(int i = 1; i <= n; i++)
{
dp[i] = 1 + aint.query(1, 1, m, 1, arr[i] - 1);
aint.update(1, 1, m, arr[i], dp[i]);
}
int length = *max_element(dp + 1, dp + n + 1), last = 1e9;
fout << length << "\n";
vector<int> subsir;
for(int i = n; i >= 1; i--)
{
if(dp[i] == length && arr[i] < last)
{
subsir.push_back(arr[i]);
length--;
last = subsir.back();
}
}
reverse(subsir.begin(), subsir.end());
for(int i : subsir)
fout << real_value[i] << " ";
fin.close();
fout.close();
return 0;
}