#include <bits/stdc++.h>
using namespace std;
struct DP {
  int d1;
  int d2;
  int d3;
  int d1_val;
  int d2_val;
  int d3_val;
};
bool operator<(const DP& l, const DP& r) {
  return l.d1_val < r.d1_val || (l.d1_val == r.d1_val && l.d2_val < r.d2_val) ||
         (l.d1_val == r.d1_val && l.d2_val == r.d2_val && l.d3_val < r.d3_val);
}
const int MAX_N = 3000 + 50;
const int MAX_D = 15;
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> a(n);
  vector<pair<int, int> > b(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    b[i].first = a[i];
    b[i].second = i;
  }
  sort(b.begin(), b.end());
  vector<pair<int, int> > c;
  c.push_back({b[0].first, 0});
  for (int i = 1; i < b.size(); ++i) {
    c.push_back({b[i].first - b[i - 1].first, i});
  }
  SparseTable st(c);
  DP ret;
  ret.d1_val = -1;
  ret.d2_val = -1;
  ret.d3_val = -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 d3_min = d2 - max_len3;
      int d3_max = d2 - min_len3;
      pair<int, int> max_d3_val = st.getMax(d3_min, d3_max);
      DP temp;
      temp.d1 = d1;
      temp.d2 = d2;
      temp.d3 = max_d3_val.second;
      temp.d1_val = b[d1].first - b[d1 - 1].first;
      temp.d2_val = b[d2].first - b[d2 - 1].first;
      temp.d3_val = max_d3_val.first;
      if (ret < temp) {
        ret = temp;
      }
    }
  }
  vector<int> vec(n, 0);
  for (int i = 0; i < ret.d3; ++i) {
    vec[b[i].second] = -1;
  }
  for (int i = ret.d3; i < ret.d2; ++i) {
    vec[b[i].second] = 3;
  }
  for (int i = ret.d2; i < ret.d1; ++i) {
    vec[b[i].second] = 2;
  }
  for (int i = ret.d1; i < n; ++i) {
    vec[b[i].second] = 1;
  }
  for (auto item : vec) {
    cout << item << " ";
  }
  cout << endl;
  return 0;
}
