#include #define FOR(i, n) for(int i = 0; i < (n); ++i) #define REP(i, a, b) for(int i = (a); i < (b); ++i) #define TRAV(i, a) for(auto &i : (a)) #define X first #define Y second #define MP std::make_pair #define PR std::pair #define SZ(x) ((int)(x).size()) typedef long long ll; typedef std::pair PII; typedef std::vector VI; struct MaxTree{ int BOTTOM; std::vector t; void build(VI A){ BOTTOM = 1; while(BOTTOM < SZ(A)) BOTTOM *= 2; t.resize(2*BOTTOM, MP(0, -1)); FOR(i, SZ(A)) t[i+BOTTOM] = MP(A[i], i); for(int i = BOTTOM-1; i >= 1; --i) t[i] = std::max(t[i<<1], t[(i<<1)+1]); } PII query(int a, int b){ a += BOTTOM; b += BOTTOM+1; PII mx = MP(0, -1); while(a < b){ if(a&1) mx = std::max(mx, t[a++]); if(b&1) mx = std::max(mx, t[--b]); a>>=1; b>>=1; } return mx; } void update(int a, int what){ a += BOTTOM; t[a].X = what; while(a > 1){ a >>= 1; t[a] = std::max(t[a<<1], t[(a<<1)+1]); } } }; struct MinTree{ int BOTTOM; std::vector t; void build(VI A){ BOTTOM = 1; while(BOTTOM < SZ(A)) BOTTOM *= 2; t.resize(2*BOTTOM, MP(1000000666, -1)); FOR(i, SZ(A)) t[i+BOTTOM] = MP(A[i], i); for(int i = BOTTOM-1; i >= 1; --i) t[i] = std::min(t[i<<1], t[(i<<1)+1]); } PII query(int a, int b){ a += BOTTOM; b += BOTTOM+1; PII mx = MP(1000000666, -1); while(a < b){ if(a&1) mx = std::min(mx, t[a++]); if(b&1) mx = std::min(mx, t[--b]); a>>=1; b>>=1; } return mx; } void update(int a, int what){ a += BOTTOM; t[a].X = what; while(a > 1){ a >>= 1; t[a] = std::min(t[a<<1], t[(a<<1)+1]); } } }; bool ans[1000]; MaxTree maxtree; MinTree mintree; int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n; std::cin >> n; VI A(n); FOR(i, n) std::cin >> A[i]; std::map map; FOR(i, n){ map[A[i]].push_back(i); } mintree.build(A); maxtree.build(A); TRAV(pr, map){ if(SZ(pr.Y) >= 3) ans[111] = true; if(SZ(pr.Y) >= 2){ int sc = pr.Y[1]; if(sc < n-1){ int big = maxtree.query(sc+1, n-1).X; if(big > pr.X) ans[112] = true; int sma = mintree.query(sc+1, n-1).X; if(sma < pr.X) ans[221] = true; } sc = pr.Y[SZ(pr.Y)-2]; if(sc > 0){ int big = maxtree.query(0, sc-1).X; if(big > pr.X) ans[211] = true; int sma = mintree.query(0, sc-1).X; if(sma < pr.X) ans[122] = true; } int fs = pr.Y[0]; sc = pr.Y.back(); if((sc-1)-(fs+1)+1 > 0){ int big = maxtree.query(fs+1, sc-1).X; int sma = mintree.query(fs+1, sc-1).X; if(big > pr.X) ans[121] = true; if(sma < pr.X) ans[212] = true; } } } std::multiset lef, rig; REP(i, 1, n) rig.insert(A[i]); lef.insert(A[0]); REP(i, 1, n-1){ rig.erase(rig.find(A[i])); auto lbb = std::prev(lef.end()); auto lbs = lef.upper_bound(A[i]); auto rbb = std::prev(rig.end()); auto rbs = rig.upper_bound(A[i]); if(*lbb > A[i] && rbs != rig.end() && *lbb > *rbs) ans[312] = true; if(*rbb > A[i] && lbs != lef.end() && *rbb > *lbs) ans[213] = true; auto lss = lef.begin(); auto lsb = lef.lower_bound(A[i]); if(lsb == lef.begin()) lsb = lef.end(); else lsb--; auto rss = rig.begin(); auto rsb = rig.lower_bound(A[i]); if(rsb == rig.begin()) rsb = rig.end(); else rsb--; if(*lss < A[i] && rsb != rig.end() && *lss < *rsb) ans[132] = true; if(*rss < A[i] && lsb != lef.end() && *rss < *lsb) ans[231] = true; if(*lbb > A[i] && *rss < A[i]) ans[321] = true; if(*rbb > A[i] && *lss < A[i]) ans[123] = true; lef.insert(A[i]); } FOR(i, 1000){ if(ans[i]){ std::cout << i << "\n"; } } return 0; }