#include using namespace std; struct Triple { int x, y, z; bool operator < (const Triple &rhs) const { return make_pair(make_pair(x, y), z) < make_pair(make_pair(rhs.x, rhs.y), rhs.z); } bool operator == (const Triple &rhs) const { return x == rhs.x and y == rhs.y and z == rhs.z; } }; int sgn(int x) { if(x < 0) return -1; if(x == 0) return 0; return 1; } Triple character(Triple t) { return {sgn(t.y - t.x), sgn(t.z - t.y), sgn(t.z - t.x)}; } constexpr int maxn = 200005; int n, t[maxn]; bool check_middle(int a, int b, int c) { assert(a != c); if(a > c) { for(int i = 1; i <= n; i++) t[i] *= -1; auto res = check_middle(-a, -b, -c); for(int i = 1; i <= n; i++) t[i] *= -1; return res; } multiset pref, suf; for(int i = 1; i <= n; i++) suf.insert(t[i]); auto ch = character({a, b, c}); for(int i = 1; i <= n; i++) { suf.erase(suf.find(t[i])); if(pref.empty()) { pref.insert(t[i]); continue; } if(suf.empty()) { pref.insert(t[i]); continue; } if(ch == Triple{1, -1, 1}) { auto l = *pref.begin(); auto it = suf.lower_bound(t[i]); if(it != suf.begin()) { auto r = *(--it); if(l < r) return true; } } else if(ch == Triple{1, 0, 1}) { auto l = *pref.begin(); if(l < t[i] and suf.count(t[i])) return true; } else if(ch == Triple{1, 1, 1}) { auto l = *pref.begin(); auto r = *suf.rbegin(); if(l < t[i] and t[i] < r) return true; } else if(ch == Triple{0, 1, 1}) { auto r = *suf.rbegin(); if(t[i] < r and pref.count(t[i])) return true; } else { auto r = *suf.rbegin(); auto it = pref.upper_bound(t[i]); if(it != pref.end()) { auto l = *it; if(l > t[i] and t[i] < r and l < r) return true; } } pref.insert(t[i]); } return false; } int base, przed[maxn * 4]; void init() { base = 1 << __lg(2 * n - 1); for(int i = 1; i <= n; i++) { przed[i + base - 1] = t[i]; } for(int i = base + n; i < 2 * base; i++) przed[i] = numeric_limits::min(); for(int i = base - 1; i > 0; i--) przed[i] = max(przed[2 * i], przed[2 * i + 1]); } int query(int l, int r) { if(l > r) return numeric_limits::min(); l += base - 1; r += base - 1; int res = max(przed[l], przed[r]); while(l / 2 != r / 2) { if(l % 2 == 0) res = max(res, przed[l + 1]); if(r % 2 == 0) res = max(res, przed[r - 1]); r /= 2; l /= 2; } return res; } bool check_right(int a, int b, int c) { assert(a == c); if(b < a) { for(int i = 1; i <= n; i++) t[i] *= -1; auto res = check_right(-a, -b, -c); for(int i = 1; i <= n; i++) t[i] *= -1; return res; } init(); map cnt, fst; for(int i = 1; i <= n; i++) { if(not fst.count(t[i])) { fst[t[i]] = i; cnt[t[i]]++; continue; } if(a == b) { if(cnt[t[i]] >= 2) return true; } else { assert(a < b); auto mx = query(fst[t[i]], i); if(mx > t[i]) return true; } fst[t[i]] = i; cnt[t[i]]++; } return false; } bool check(int a, int b, int c) { if(sgn(c - a) != 0) return check_middle(a, b, c); else { return check_right(a, b, c); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n; for(int i = 1; i <= n; i++) { cin >> t[i]; } vector res, checked; for(int a = 1; a <= 3; a++) { for(int b = 1; b <= 3; b++) { for(int c = 1; c <= 3; c++) { auto ch = character({a, b, c}); bool flag = false; for(const auto &x : checked) { if(character(x) == ch) { flag = true; break; } } if(flag) continue; if(check(a, b, c)) { res.push_back({a, b, c}); } checked.push_back({a, b, c}); } } } for(auto t : res) { cout << t.x << t.y << t.z << "\n"; } }