#include <fstream>
#include <algorithm>
#define MAX_N 100004
using namespace std;
const char iname[] = "scmax.in";
const char oname[] = "scmax.out";
ifstream fin(iname);
ofstream fout(oname);
struct sweep{
int v, poz;
}x[MAX_N];
struct cmp
{
bool operator() (const sweep &b, const sweep &c)
{
if (b.v < c.v) return 1;
return 0;
};
};
int N, i, j, foo, poz, ANS;
int v[MAX_N], H[MAX_N * 3];
int a[MAX_N], best[MAX_N], t[MAX_N];
int sol[MAX_N];
inline int binary_search (int val)
{
int mid = 0, st = 0, dr = N, poz_min;
while (st <= dr)
{
mid = (st + dr) / 2;
if (x[mid].v == val)
st = mid + 1,
poz_min = x[mid].poz;
else
{
if (x[mid].v < val) st = mid + 1;
else
dr = mid - 1;
}
}
return poz_min;
}
inline void update (int node, int left, int right, int p, int ind)
{
if (left >= right)
{
H[node] = ind;
return;
}
int m = (left + right) / 2, L = node << 1, R = L | 1;
if (p <= m) update (L, left, m, p, ind);
else
update (R, m + 1, right, p, ind);
if (best[H[L]] > best[H[R]]) H[node] = H[L];
else H[node] = H[R];
}
inline void query (int node, int left, int right, int i, int j)
{
if (i <= left && right <= j)
{
if (best[H[node]] > best[poz])
poz = H[node];
return;
}
int m = (left + right) / 2, L = node << 1, R = L | 1;
if (i <= m) query (L, left, m, i, j);
if (j > m) query (R, m + 1, right, i, j);
}
int main()
{
fin >> N;
for (i = 1; i <= N; ++i) fin >> v[i], x[i].v = v[i];
sort (x + 1, x + N + 1, cmp());
for (i = 1; i <= N; ++i)
{
if (x[i].v == x[i - 1].v) x[i].poz = x[i - 1].poz;
else
x[i].poz = ++foo;
}
for (i = 1; i <= N; ++i)
{
if (v[i] == v[i - 1]) a[i] = a[i - 1];
else
a[i] = binary_search(v[i]);
}
best[1] = 1;
update (1, 1, foo, a[1], 1);
for (i = 2; i <= N; ++i)
{
poz = 0;
if (a[i] - 1 > 0)
query (1, 1, foo, 1, a[i] - 1);
best[i] = best[poz] + 1;
t[i] = poz;
update (1, 1, foo, a[i], i);
}
for (i = 1; i <= N; ++i) if (best[i] > ANS) ANS = best[i], poz = i;
fout << ANS << '\n';
i = poz;
while (i > 0)
{
sol[++j] = v[i];
i = t[i];
}
for (i = j; i >= 1; --i)
fout << sol[i] << ' ';
fout << '\n';
return 0;
}