#include <bits/stdc++.h>   using namespace std;   const int MAX_N = 3000 + 50;   const int MAX_D = 15;   struct DP {     int d1;     int d2;     int d3;     int v1;     int v2;     int v3;   };   bool operator<(const DP& l, const DP& r) {     return l.v1 < r.v1 || (l.v1 == r.v1 && l.v2 < r.v2) ||            (l.v1 == r.v1 && l.v2 == r.v2 && l.v3 < r.v3);   }   class SparseTable {    public:     SparseTable(vector<pair<int, int> >& vals) {       N = vals.size();       depths.assign(MAX_N, -1);       table.assign(N, vector<pair<int, int> >(MAX_D));       init();       build(vals);     }     void init() {       for (int i = 1; i < MAX_N; ++i) {         depths[i] = depths[i - 1];         if ((i & (i - 1)) == 0) {           ++depths[i];         }       }     }     void build(vector<pair<int, int> >& vals) {       for (int i = 0; i < N; ++i) {         table[i][0] = vals[i];       }       for (int d = 1; d <= depths[N] + 1; ++d) {         for (int i = 0; i < N; ++i) {           int left = i;           int right = min(N - 1, left + (1 << (d - 1)));           table[i][d] = max(table[left][d - 1], table[right][d - 1]);         }       }     }     pair<int, int> getMax(int left, int right) {       int len = right - left + 1;       int d = depths[len];       return max(table[left][d], table[left + len - (1 << d)][d]);     }       private:     vector<vector<pair<int, int> > > table;     vector<int> depths;     int N = 0;   };   int main() {     ios_base::sync_with_stdio(false);     int n;     cin >> n;     vector<int> vec(n);     vector<pair<int, int> > vec_with_index(n);     for (int i = 0; i < n; ++i) {       cin >> vec[i];       vec_with_index[i].first = vec[i];       vec_with_index[i].second = i;     }     sort(vec_with_index.begin(), vec_with_index.end());     vector<pair<int, int> > vals;     vals.push_back({vec_with_index[0].first, 0});     for (int i = 1; i < vec_with_index.size(); ++i) {       vals.push_back({vec_with_index[i].first - vec_with_index[i - 1].first, i});     }     SparseTable st(vals);     DP ret;     ret.v1 = -1;     ret.v2 = -1;     ret.v3 = -1;     for (int d1 = n - 1; d1 >= 0; --d1) {       for (int d2 = d1 - 1; d2 >= 0; --d2) {         int len1 = n - 1 - d1 + 1;         int len2 = d1 - 1 - d2 + 1;         if (len1 > 2 * len2 || len2 > 2 * len1) {           continue;         }         int min_len3 = max({1, (len1 + 1) / 2, (len2 + 1) / 2});         int max_len3 = min({d2, 2 * len1, 2 * len2});         if (min_len3 > max_len3) {           continue;         }         int min_d3 = d2 - max_len3;         int max_d3 = d2 - min_len3;         pair<int, int> max_val = st.getMax(min_d3, max_d3);         DP temp;         temp.d1 = d1;         temp.d2 = d2;         temp.d3 = max_val.second;         temp.v1 = vec_with_index[d1].first - vec_with_index[d1 - 1].first;         temp.v2 = vec_with_index[d2].first - vec_with_index[d2 - 1].first;         temp.v3 = max_val.first;         if (ret < temp) {           ret = temp;         }       }     }     vector<int> ret_vec(n);     for (int i = 0; i < ret.d3; ++i) {       ret_vec[vec_with_index[i].second] = -1;     }     for (int i = ret.d3; i < ret.d2; ++i) {       ret_vec[vec_with_index[i].second] = 3;     }     for (int i = ret.d2; i < ret.d1; ++i) {       ret_vec[vec_with_index[i].second] = 2;     }     for (int i = ret.d1; i < n; ++i) {       ret_vec[vec_with_index[i].second] = 1;     }     for (auto item : ret_vec) {       cout << item <<    ;     }     cout << endl;     return 0;   }