#include <bits/stdc++.h>
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
using namespace std;
template <class T>
using vec = std::vector<T>;
template <class T>
using vec2d = std::vector<std::vector<T>>;
template <class T>
vec2d<T> makeVec2d(const int n1, const int n2) {
  return vec2d<T>(n1, vec<T>(n2));
}
bool __hack = std::ios::sync_with_stdio(false);
auto __hack1 = cin.tie(nullptr);
struct Input {
  Input(istream &in) : in(&in) {}
  template <class T>
  T next() const {
    T x;
    *in >> x;
    return x;
  }
  int ni() const { return next<int>(); }
  istream *in;
};
Input in(cin);
class Output {
 private:
  ostream *out;
  template <typename T>
  void printSingle(const T &value) {
    *out << value;
  }
  template <typename T>
  void printSingle(const vec<T> &v) {
    for (std::size_t i = 0; i < v.size(); ++i) {
      if (i == 0) {
        printSingle(v[i]);
      } else {
        *out << ' ';
        printSingle(v[i]);
      }
    }
  }

 public:
  Output(ostream &out) : out(&out) {}
  inline void print() {}
  template <typename T, typename... Ts>
  inline void print(const T &f, const Ts &...args) {
    printSingle(f);
    if (sizeof...(args) != 0) {
      *out << ' ';
      print(args...);
    }
  }
  template <typename... Ts>
  inline void println(const Ts &...args) {
    print(args...);
    (*out) << '\n';
  }
  template <typename... Ts>
  inline void operator()(const Ts &...args) {
    println(args...);
  }
};
Output out(cout);
namespace template_util {
constexpr int bytecount(uint64_t x) { return x ? 1 + bytecount(x >> 8) : 0; }
template <int N>
struct bytetype {};
template <uint64_t N>
struct minimal_uint : bytetype<bytecount(N)> {};
}  // namespace template_util
template <class T>
struct RMQ {
  vec2d<T> st;
  vec<int> logs;
  function<T(T, T)> f;
  int n;
  int k;
  RMQ(const vec<T> &a, const function<T(T, T)> &f_) : f(f_) {
    n = (int)a.size();
    logs = vec<int>(n + 1);
    logs[1] = 0;
    for (int i = 2; i <= n; i++) {
      logs[i] = logs[i / 2] + 1;
    }
    k = 1;
    while (k < logs[n] + 1) {
      k++;
    }
    st = makeVec2d<T>(k + 1, n);
    st[0] = a;
    for (int j = 1; j <= k; j++) {
      for (int i = 0; i + (1 << j) <= n; ++i) {
        st[j][i] = f(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
      }
    }
  }
  T get(int left, int right) {
    int j = logs[right - left + 1];
    return f(st[j][left], st[j][right - (1 << j) + 1]);
  }
};
void solve(istream &inStream, ostream &outStream) {
  in = Input(inStream);
  out = Output(outStream);
  auto n = in.ni();
  vec<pair<int, int>> a(n);
  for (int i = 0; i < (n); ++i) {
    a[i] = {in.ni(), i};
  }
  sort(a.begin(), a.end());
  reverse(a.begin(), a.end());
  vec<int> mx = {-1, -1, -1};
  vec<pair<int, int>> delta(n);
  for (int i = (1); i < (n); ++i) {
    delta[i - 1] = {a[i - 1].first - a[i].first, i - 1};
  }
  delta[n - 1] = {a[n - 1].first, n - 1};
  auto mxfn = [](const pair<int, int> &p1, const pair<int, int> &p2) {
    return max(p1, p2);
  };
  RMQ<pair<int, int>> rmq(delta, mxfn);
  ;
  ;
  ;
  ;
  vec<int> bestC = {-1, -1, -1};
  for (int c0 = (1); c0 <= (n); ++c0) {
    for (int c1 = (1); c1 <= (n); ++c1) {
      if (c0 <= c1 * 2 && c1 <= c0 * 2) {
        int rest = n - c0 - c1;
        if (rest >= 1) {
          int d1 = a[c0 - 1].first - a[c0].first;
          if (d1 < mx[0]) continue;
          int d2 = a[c0 + c1 - 1].first - a[c0 + c1].first;
          if (d1 == mx[0] && d2 < mx[1]) continue;
          auto mic = min(c0, c1);
          auto mac = max(c0, c1);
          int le = (mac + 1) / 2;
          int ri = mic * 2;
          le += c0 + c1 - 1;
          ri += c0 + c1 - 1;
          if (le >= n) continue;
          le = min(le, n - 1);
          ri = min(ri, n - 1);
          ;
          ;
          auto d3mx = rmq.get(le, ri);
          int d3 = d3mx.first;
          vec<int> cnd = {d1, d2, d3};
          if (cnd > mx) {
            mx = cnd;
            bestC = {c0, c1, d3mx.second - c0 - c1 + 1};
          }
        }
      }
    }
  };
  ;
  vec<int> res(n, -1);
  for (int i = 0; i < (n); ++i) {
    if (bestC[0]) {
      res[a[i].second] = 1;
      --bestC[0];
    } else if (bestC[1]) {
      res[a[i].second] = 2;
      --bestC[1];
    } else if (bestC[2]) {
      res[a[i].second] = 3;
      --bestC[2];
    }
  }
  out(res);
}
int main() {
  solve(cin, cout);
  return 0;
}
