Problem: Alexey recently held a programming contest for students from Berland. n students participated in a contest, i-th of them solved ai problems. Now he wants to award some contestants. Alexey can award the students with diplomas of three different degrees. Each student either will receive one diploma of some degree, or won't receive any diplomas at all. Let cntx be the number of students that are awarded with diplomas of degree x (1 ≤ x ≤ 3). The following conditions must hold:

  * For each x (1 ≤ x ≤ 3) cntx > 0; 
  * For any two degrees x and y cntx ≤ 2·cnty. 



Of course, there are a lot of ways to distribute the diplomas. Let bi be the degree of diploma i-th student will receive (or  - 1 if i-th student won't receive any diplomas). Also for any x such that 1 ≤ x ≤ 3 let cx be the maximum number of problems solved by a student that receives a diploma of degree x, and dx be the minimum number of problems solved by a student that receives a diploma of degree x. Alexey wants to distribute the diplomas in such a way that:

  1. If student i solved more problems than student j, then he has to be awarded not worse than student j (it's impossible that student j receives a diploma and i doesn't receive any, and also it's impossible that both of them receive a diploma, but bj < bi); 
  2. d1 - c2 is maximum possible; 
  3. Among all ways that maximize the previous expression, d2 - c3 is maximum possible; 
  4. Among all ways that correspond to the two previous conditions, d3 - c - 1 is maximum possible, where c - 1 is the maximum number of problems solved by a student that doesn't receive any diploma (or 0 if each student is awarded with some diploma). 



Help Alexey to find a way to award the contestants!

Input

The first line contains one integer number n (3 ≤ n ≤ 3000).

The second line contains n integer numbers a1, a2, ..., an (1 ≤ ai ≤ 5000).

Output

Output n numbers. i-th number must be equal to the degree of diploma i-th contestant will receive (or  - 1 if he doesn't receive any diploma).

If there are multiple optimal solutions, print any of them. It is guaranteed that the answer always exists.

Examples

Input

4
1 2 3 4


Output

3 3 2 1 


Input

6
1 4 3 1 1 2


Output

-1 1 2 -1 -1 3 

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

public class Solution {


    static MyScanner sc;
    private static PrintWriter out;
    static long M2 = 1_000_000_000L + 7;

    private static HashMap<Long, Long>[] mods;

    public static void main(String[] s) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();

//        stringBuilder.append("7 3\n" +
//                "1 5 2 6 3 7 4\n" +
//                "2 5 3\n" +
//                "4 4 1\n" +
//                "1 7 3");

//
//        Random r = new Random(5);
//        stringBuilder.append("100000 5000 ");
//        for (int i = 0; i < 100000; i++) {
//            stringBuilder.append(" " + (r.nextInt(2000000000) - 1000000000) + " ");
//
//        }
//        for (int k = 0; k < 5000; k++) {
//            stringBuilder.append(" 1 100000 777 ");
//        }

        if (stringBuilder.length() == 0) {
            sc = new MyScanner(System.in);
        } else {
            sc = new MyScanner(new BufferedReader(new StringReader(stringBuilder.toString())));
        }

        out = new PrintWriter(new OutputStreamWriter(System.out));

        initData();
        solve();

        out.flush();
    }


    private static void initData() {


    }

    static char[][] data;
    static String cmd;

    private static final class STree {
        private final Comparator<Integer> comparator;
        int[] val1;
        int[] from1;
        int[] to1;
        int[] max1;

        public STree(int c, Comparator<Integer> comparator) {
            this.comparator = comparator;
            int size = Integer.highestOneBit(c);
            if (size != c) {
                size <<= 1;
            }
            int rs = size << 1;
            val1 = new int[rs];
            from1 = new int[rs];
            max1 = new int[rs];
            to1 = new int[rs];

            Arrays.fill(from1, Integer.MAX_VALUE);
            for (int r = rs - 1; r > 1; r--) {
                if (r >= size) {
                    from1[r] = r - size;
                    to1[r] = r - size;
                }
                from1[r / 2] = Math.min(from1[r / 2], from1[r]);
                to1[r / 2] = Math.max(to1[r / 2], to1[r]);
            }
        }

        public int max(int from, int to) {
            return max(1, from, to);
        }

        private int max(int cur, int from, int to) {
            if (cur >= val1.length) return -1;
            if (from <= from1[cur] && to1[cur] <= to) {
                return max1[cur];
            }
            if (from1[cur] > to || from > to1[cur]) {
                return -1;
            }
            cur <<= 1;

            return max0(max(cur, from, to), max(cur + 1, from, to));
        }


        public void put(int x, int val) {
            x += val1.length >> 1;
            val1[x] = val;
            max1[x] = val;
            addToParent(x);
        }


        private void addToParent(int cur) {
            while (cur > 1) {
                cur >>= 1;
                max1[cur] = max0(max1[cur << 1], max1[1 + (cur << 1)]);
            }
        }

        private int max0(int i, int i1) {
            if (i == -1) return i1;
            if (i1 == -1) return i;
            return comparator.compare(i, i1) > 0 ? i1 : i;
        }
    }


    private static void solve() throws IOException {
        int n = sc.nextInt();
        int[][] res = new int[n][3];
        for (int l = 0; l < n; l++) {
            res[l][1] = l;
            res[l][0] = sc.nextInt();
            res[l][2] = -1;
        }
        Arrays.sort(res, Comparator.comparingInt(t -> -t[0]));
        STree sTree = new STree(n, Comparator.comparingInt(t -> t == n - 1 ? -res[t][0] : (-res[t][0] + res[t + 1][0])));

        for (int i = 0; i < n; i++) {
            sTree.put(i, i);
        }

        int[] ans = null;

        int max = Math.max((n / 4) * 2, 1);
        for (int s1 = 1; s1 <= max; s1++) {
            for (int s2 = 1; s2 <= max; s2++) {
                if (s2 * 2 < s1) continue;
                if (s1 * 2 < s2) break;
                int mins3 = (Math.max(s1, s2) + 1) / 2;
                int maxs3 = Math.min(s1, s2) * 2;
                maxs3 = Math.min(maxs3, n - s1 - s2);
                if (mins3 > maxs3) continue;
                int s3 = sTree.max(s1 + s2 + mins3 - 1, s1 + s2 + maxs3 - 1) - s1 - s2 + 1;

                if (ans != null) {

                    int d1 = res[s1 - 1][0] - res[s1][0];
                    int d2 = res[s1 + s2 - 1][0] - res[s1 + s2][0];
                    int d3 = res[s1 + s2 + s3 - 1][0] - ((s1 + s2 + s3 == n) ? 0 : res[s1 + s2 + s3][0]);

                    if (d1 < res[ans[0] - 1][0] - res[ans[0]][0]) continue;
                    if (d1 > res[ans[0] - 1][0] - res[ans[0]][0]) {
                        ans = new int[]{s1, s2, s3};
                        continue;
                    }

                    if (d2 < res[ans[0] + ans[1] - 1][0] - res[ans[0] + ans[1]][0]) continue;
                    if (d2 > res[ans[0] + ans[1] - 1][0] - res[ans[0] + ans[1]][0]) {
                        ans = new int[]{s1, s2, s3};
                        continue;
                    }


                    if (d3 < res[ans[0] + ans[1] + ans[2] - 1][0] - ((ans[0] + ans[1] + ans[2] == n) ? 0 : res[ans[0] + ans[1] + ans[2]][0]))
                        continue;

                }
                ans = new int[]{s1, s2, s3};
            }
        }

        for (int k = 0; k < ans[0]; k++) {
            res[k][2] = 1;
        }
        for (int k = ans[0]; k < ans[0] + ans[1]; k++) {
            res[k][2] = 2;
        }
        for (int k = ans[0] + ans[1]; k < ans[0] + ans[1] + ans[2]; k++) {
            res[k][2] = 3;
        }

        Arrays.sort(res, Comparator.comparingInt(t -> t[1]));
        for (int[] r : res) {
            out.print(r[2] + " ");
        }
    }


    private static boolean isset(long i, int k) {
        return (i & (1 << k)) > 0;
    }

    private static void solveT() throws IOException {
        int t = sc.nextInt();
        while (t-- > 0) {
            solve();
        }
    }


    private static long gcd(long l, long l1) {
        if (l > l1) return gcd(l1, l);
        if (l == 0) return l1;
        return gcd(l1 % l, l);
    }

    private static long pow(long a, long b, long m) {
        if (b == 0) return 1;
        if (b == 1) return a;
        long pp = pow(a, b / 2, m);
        pp *= pp;
        pp %= m;
        return (pp * (b % 2 == 0 ? 1 : a)) % m;
    }


    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        MyScanner(BufferedReader br) {
            this.br = br;
        }

        public MyScanner(InputStream in) {
            this(new BufferedReader(new InputStreamReader(in)));
        }

        void findToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        String next() {
            findToken();
            return st.nextToken();
        }

        Integer[] nab(int n) {
            Integer[] k = new Integer[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        int[] na(int n) {
            int[] k = new int[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        long[] nl(int n) {
            long[] k = new long[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.nextLong();
            }
            return k;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int fi() {
            String t = next();
            int cur = 0;
            boolean n = t.charAt(0) == '-';
            for (int a = n ? 1 : 0; a < t.length(); a++) {
                cur = cur * 10 + t.charAt(a) - '0';
            }
            return n ? -cur : cur;
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }


}