#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
int n, bl, pre[100005], bp, before[100005];
pair<int, int> v[100005];
vector<int> sol;
struct Node {
int val, prev, pos;
};
class SegmentTree {
public:
int n;
Node* tree;
SegmentTree(int n) {
this->n = n;
tree = new Node[4 * n]();
}
void update2(int id, int start, int end, int pos, int val, int prev, int idx) {
if (start > pos || end < pos) return;
if (start == end) {
tree[id].val = val;
tree[id].prev = prev;
tree[id].pos = idx;
return;
}
int mid = (start + end) / 2;
update2(id * 2, start, mid, pos, val, prev, idx);
update2(id * 2 + 1, mid + 1, end, pos, val, prev, idx);
if (tree[id * 2].val >= tree[id * 2 + 1].val) {
tree[id] = tree[id * 2];
} else {
tree[id] = tree[id * 2 + 1];
}
}
void update(int id, int start, int end, int pos, int val, int prev) {
if (start > pos || end < pos) return;
if (start == end) {
tree[id].val = val;
tree[id].prev = prev;
return;
}
int mid = (start + end) / 2;
update(id * 2, start, mid, pos, val, prev);
update(id * 2 + 1, mid + 1, end, pos, val, prev);
if (tree[id * 2].val >= tree[id * 2 + 1].val) {
tree[id] = tree[id * 2];
} else {
tree[id] = tree[id * 2 + 1];
}
}
Node query(int id, int start, int end, int a, int b) {
if (start > b || end < a) return {0, 0, 0};
if (start >= a && end <= b) return tree[id];
int mid = (start + end) / 2;
Node left = query(id * 2, start, mid, a, b);
Node right = query(id * 2 + 1, mid + 1, end, a, b);
if (left.val >= right.val) return left;
return right;
}
} *T;
int main()
{
in >> n;
for (int i = 1; i <= n; ++i) {
in >> v[i].first;
v[i].second = i;
before[i] = v[i].first;
}
sort(v + 1, v + n + 1);
int last = 1;
for (int i = 1; i <= n; ++i) {
bool ok = false;
if (v[i + 1].first > v[i].first) ok = true;
v[i].first = last;
if (ok) last++;
}
sort(v + 1, v + n + 1, [](pair<int, int> a, pair<int, int> b) -> bool {
return a.second < b.second;
});
T = new SegmentTree(n);
for (int i = 2; i <= n; ++i) {
T->update2(1, 1, n, v[i].first, 0, i, i);
}
T->update2(1, 1, n, v[1].first, 1, 1, 1);
for (int i = 2; i <= n; ++i) {
Node best = T->query(1, 1, n, 1, v[i].first - 1);
if (best.val == 0) {
best.pos = 0;
best.prev = 0;
}
T->update(1, 1, n, v[i].first, best.val + 1, best.pos);
pre[i] = best.pos;
if (best.val + 1 > bl) {
bl = best.val + 1;
bp = i;
}
}
out << bl << "\n";
while (bp != 0) {
sol.push_back(before[bp]);
bp = pre[bp];
}
for (int i = sol.size() - 1; i >= 0; --i) {
out << sol[i] << " ";
}
return 0;
}