#include<bits/stdc++.h>
using namespace std;
const int NMAX = 1e5 + 10;
int lis[NMAX], v[NMAX], normalized_v[NMAX];
int pre[NMAX];
pair<int, int> aint[4 * NMAX];
void reconstruct_array(int current_position) {
int aux[NMAX];
int n = lis[current_position];
int i = n - 1;
do {
aux[i--] = v[current_position];
current_position = pre[current_position];
} while (current_position != -1);
for (i = 0; i < n; i++) printf("%d ", aux[i]);
}
int normalize(int n) {
map<int, int> w;
for (int i = 1; i <= n; i++)
w[v[i]] = 0;
int cnt = 1;
for (auto &x : w)
x.second = cnt++;
for (int i = 1; i <= n; i++)
normalized_v[i] = w[v[i]];
return cnt - 1;
}
void merge_nodes(pair<int, int> &dest, pair<int, int> &a, pair<int, int> &b) {
if (a.first >= b.first) {
dest = a;
return;
}
dest = b;
}
void update_recursiv(int node, int left, int right, int position, int value, int original_position) {
if (left == right) {
aint[node].first = value;
aint[node].second = original_position;
return;
}
int middle = (left + right) / 2;
if (position <= middle)
update_recursiv(2 * node, left, middle, position, value, original_position);
else
update_recursiv(2 * node + 1, middle + 1, right, position, value, original_position);
merge_nodes(aint[node], aint[2 * node], aint[2 * node + 1]);
}
void update(int n, int p, int v, int ogp) {
update_recursiv(1, 1, n, p, v, ogp);
}
pair<int, int> query_recursiv(int node, int left, int right, int query_left, int query_right) {
if (left == query_left && right == query_right) {
return aint[node];
}
int middle = (left + right) / 2;
if (query_right <= middle)
return query_recursiv(2 * node, left, middle, query_left, query_right);
if (query_left > middle)
return query_recursiv(2 * node + 1, middle + 1, right, query_left, query_right);
pair<int, int> a = query_recursiv(2 * node, left, middle, query_left, middle);
pair<int, int> b = query_recursiv(2 * node + 1, middle + 1, right, middle + 1, query_right);
pair<int, int> ans;
merge_nodes(ans, a, b);
return ans;
}
pair<int, int> query(int n, int l, int r) {
return query_recursiv(1, 1, n, l, r);
}
int main() {
freopen("scmax.in", "r", stdin);
freopen("scmax.out", "w", stdout);
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &v[i]);
}
int m = normalize(n);
for (int i = 1; i <= n; i++) {
pair<int, int> best_j;
if (normalized_v[i] - 1 != 0)
best_j = query(m, 1, normalized_v[i] - 1);
else
best_j = query(m, 1, 1);
if (best_j.first == 0) pre[i] = -1;
else pre[i] = best_j.second;
lis[i] = best_j.first + 1;
update(m, normalized_v[i], lis[i], i);
}
int best_i = 0;
for (int i = 1; i <= n; i++)
if (lis[best_i] < lis[i])
best_i = i;
printf("%d\n", lis[best_i]);
reconstruct_array(best_i);
return 0;
}