Problem: Iahub isn't well prepared on geometry problems, but he heard that this year there will be a lot of geometry problems on the IOI selection camp. Scared, Iahub locked himself in the basement and started thinking of new problems of this kind. One of them is the following.

Iahub wants to draw n distinct segments [li, ri] on the OX axis. He can draw each segment with either red or blue. The drawing is good if and only if the following requirement is met: for each point x of the OX axis consider all the segments that contains point x; suppose, that rx red segments and bx blue segments contain point x; for each point x inequality |rx - bx| ≤ 1 must be satisfied.

A segment [l, r] contains a point x if and only if l ≤ x ≤ r.

Iahub gives you the starting and ending points of all the segments. You have to find any good drawing for him.

Input

The first line of input contains integer n (1 ≤ n ≤ 105) — the number of segments. The i-th of the next n lines contains two integers li and ri (0 ≤ li ≤ ri ≤ 109) — the borders of the i-th segment.

It's guaranteed that all the segments are distinct.

Output

If there is no good drawing for a given test, output a single integer -1. Otherwise output n integers; each integer must be 0 or 1. The i-th number denotes the color of the i-th segment (0 is red and 1 is blue).

If there are multiple good drawings you can output any of them.

Examples

Input

2
0 2
2 3


Output

0 1


Input

6
1 5
1 3
3 5
2 10
11 11
12 12


Output

0 1 0 1 0 0

Solution (in JAVA):

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


/**
 * Created by Katushka on 14.02.2021.
 */
public class Main {

    static void sortArray(long[] a, boolean rev) {
        Random random = new Random();

        for (int i = 0; i < a.length; i++) {
            int randomPos = random.nextInt(a.length);
            long t = a[i];
            a[i] = a[randomPos];
            a[randomPos] = t;
        }
        Arrays.sort(a);
        if (rev) {
            for (int i = 0; i < a.length / 2; i++) {
                long t = a[i];
                a[i] = a[a.length - i - 1];
                a[a.length - i - 1] = t;
            }
        }
    }

    static int[] readArray(int size, InputReader in, boolean subOne) {
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = in.nextInt() + (subOne ? -1 : 0);
        }
        return a;
    }

    static long[] readLongArray(int size, InputReader in) {
        long[] a = new long[size];
        for (int i = 0; i < size; i++) {
            a[i] = in.nextLong();
        }
        return a;
    }

    public static final Comparator<int[]> TRIPLE_COMPARATOR = (o1, o2) -> {
        if (o1[0] == o2[0]) {
            if (o1[1] == o2[1]) {
                return Long.compare(o1[2], o2[2]);
            }
            return Long.compare(o1[1], o2[1]);
        }
        return Long.compare(o1[0], o2[0]);
    };

    private static class Edge {
        int v;
        int u;
        int segNum;
        int edgeNum;

        Edge(int v, int u, int segNum, int edgeNum) {
            this.u = u;
            this.v = v;
            this.segNum = segNum;
            this.edgeNum = edgeNum;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Edge edge = (Edge) o;
            return u == edge.u && v == edge.v && segNum == edge.segNum;
        }

        @Override
        public int hashCode() {
            return Objects.hash(u, v, segNum);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        int n = in.nextInt();
        long[][] segments = new long[n][2];
        long[] points = new long[n << 1];
        long[] ls = new long[n];
        long[] rs = new long[n];
        for (int i = 0; i < n; i++) {
            ls[i] = in.nextInt();
            rs[i] = in.nextInt();
            segments[i][0] = ls[i];
            segments[i][1] = rs[i];
            points[i << 1] = (ls[i] << 1);
            points[(i << 1) + 1] = (rs[i] << 1);
        }

        sortArray(ls, false);
        sortArray(rs, false);
        sortArray(points, false);

        long[] vs = new long[points.length << 1];
        Map<Long, Integer> occs = new HashMap<>();
        int i = 0;
        for (int j = 0; j < points.length; j++) {
            long point = points[j];
            if (j > 0 && point == points[j - 1]) {
                continue;
            }
            if (i > 0) {
                vs[i] = (point + vs[i - 1]) / 2;
                i++;
            }
            vs[i] = point;
            occs.put(point, i);
            i++;
        }
        vs[i] = vs[i - 1] + 1;
        List<Edge>[] edges = new List[vs.length];
        for (i = 0; i < vs.length; i++) {
            edges[i] = new ArrayList<>();
        }

        int edgeCnt = 0;
        for (i = 0; i < segments.length; i++) {
            int li = occs.get(segments[i][0] * 2);
            int ri = occs.get(segments[i][1] * 2);
            edges[li].add(new Edge(li, ri + 1, i, edgeCnt));
            edges[ri + 1].add(new Edge(ri + 1, li, i, edgeCnt));
            edgeCnt++;
        }

        int li = 0;
        int ri = 0;
        int cnt = 0;
        for (i = 0; i < vs.length; i++) {
            while (li < n && ls[li] * 2 == vs[i]) {
                cnt++;
                li++;
            }
            while (ri < n && i > 0 && rs[ri] * 2 == vs[i - 1]) {
                cnt--;
                ri++;
            }
            if (cnt % 2 != 0) {
                edges[i].add(new Edge(i, i + 1, -1, edgeCnt));
                edges[i + 1].add(new Edge(i + 1, i, -1, edgeCnt));
                edgeCnt++;
            }
        }

        boolean[] visited = new boolean[vs.length];
        boolean[] visitedEdges = new boolean[edgeCnt];
        int[] colors = new int[n];
        for (i = 0; i < vs.length; i++) {
            if (!visited[i]) {
                ArrayList<Edge> path = new ArrayList<>();
                dfs(i, edges, visited, visitedEdges, path);

                for (int j = 0; j < path.size(); j++) {
                    if (path.get(j).segNum >= 0) {
                        if (path.get(j).v < path.get(j).u) {
                            colors[path.get(j).segNum] = 1;
                        }
                    }

                }
            }
        }

        outputArray(colors, out, false);

        out.close();
    }

    private static void dfs(int v, List<Edge>[] edges, boolean[] visited, boolean[] visitedEdges, List<Edge> path) {
        visited[v] = true;
        for (int i = 0; i < edges[v].size(); i++) {
            Edge vu = edges[v].get(i);
            if (!visitedEdges[vu.edgeNum]) {
                visitedEdges[vu.edgeNum] = true;
                dfs(vu.u, edges, visited, visitedEdges, path);
                if (vu.v < vu.u) {
                    path.add(vu);
                }
            }

        }
    }


    private static void outputArray(int[] ans, PrintWriter out, boolean addOne) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < ans.length; i++) {
            long an = ans[i] + (addOne ? 1 : 0);
            str.append(an).append(' ');
        }
        out.println(str);
        out.flush();
    }

    private static void outputArray(List<Integer> ans, PrintWriter out, boolean addOne) {
        StringBuilder str = new StringBuilder();
        for (int i : ans) {
            long an = i + (addOne ? 1 : 0);
            str.append(an).append(' ');
        }
        out.println(str);
        out.flush();
    }

    private static int[] getBinary(long a, int size) {
        int[] result = new int[size];
        for (int i = 0; i < size; i++) {
            result[i] = (int) ((a >> i) & 1);
        }
        return result;
    }

    private static int fromBinary(int[] binary) {
        int res = 0;
        int d = 1;
        for (int i = 0; i < binary.length; i++) {
            if (binary[i] == 1) {
                res = res | d;
            }
            d = d << 1;
        }
        return res;
    }

    private static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextString() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

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

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

        public char nextChar() {
            return next().charAt(0);
        }

        public String nextWord() {
            return next();
        }

        private List<Integer>[] readTree(int n) {
            List<Integer>[] result = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                result[i] = new ArrayList<>();
            }
            for (int i = 0; i < n - 1; i++) {
                int u = nextInt() - 1;
                int v = nextInt() - 1;
                result[u].add(v);
                result[v].add(u);
            }
            return result;
        }

    }
}