#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <tr1/unordered_map>
using namespace std;
#define N 100001
#define common int m = (l + r) >> 1, L = n << 1, R = L | 1
int n;
int v[N];
int norm[N];
int x[N];
int dp[N];
int t[N];
int H[3 * N];
tr1::unordered_map<int, int> hash;
void update(int n, int l, int r, int p, int idx) {
if (l >= r) {
H[n] = idx;
return;
}
common;
if (p <= m)
update(L, l, m, p, idx);
else
update(R, m + 1, r, p, idx);
if (dp[ H[L] ] > dp[ H[R] ])
H[n] = H[L];
else
H[n] = H[R];
}
int poz;
void query(int n, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
if (dp[ H[n] ] > dp[ poz ])
poz = H[n];
return;
}
common;
if (ql <= m)
query(L, l, m, ql, qr);
if (qr > m)
query(R, m + 1, r, ql, qr);
}
int main() {
freopen ("scmax.in", "r", stdin);
freopen ("scmax.out", "w", stdout);
scanf ("%d\n", &n);
int i;
for (i = 1; i <= n; ++i) {
scanf ("%d", &v[i]);
x[i] = v[i];
}
// normalizare
sort (x + 1, x + n + 1);
int nr = 0;
hash[ x[1] ] = ++nr;
for (i = 2; i <= n; ++i)
if (x[i] != x[i - 1])
hash[ x[i] ] = ++nr;
for (i = 1; i <= n; ++i)
norm[i] = hash[ v[i] ];
// dinamica
dp[1] = 1;
update(1, 1, nr, norm[1], 1);
for (i = 2; i <= n; ++i) {
poz = 0;
if (norm[i] - 1 > 0)
query(1, 1, nr, 1, norm[i] - 1);
dp[i] = 1 + dp[poz];
t[i] = poz;
update(1, 1, nr, norm[i], i);
}
// reconstituire
int mx = 0;
poz = 0;
for (i = 1; i <= n; ++i)
if (dp[i] > mx)
mx = dp[i],
poz = i;
printf ("%d\n", mx);
vector<int> sol;
for (i = poz; i; i = t[i])
sol.push_back( v[i] );
for (i = sol.size() - 1; i >= 0; --i)
printf ("%d ", sol[i]);
printf ("\n");
}