import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.util.*;

class Entry implements Comparable<Entry> {
    int count, pos;

    public Entry(int count, int pos) {
        this.count = count;
        this.pos = pos;
    }

    public int compareTo(Entry other) {
        return other.count-this.count;
    }
}

public class Antti_buffered {
    public static void main(String[] args) {
        Kattio io = new Kattio(System.in);
        int n = io.getInt();
        ArrayList<Integer>[] graph = new ArrayList[n+1];
        for (int i = 1; i <= n; i++) graph[i] = new ArrayList<Integer>();
        int[][] history = new int[n][2];
        int hi = -1;
        for (int i = 1; i <= n; i++) {
            int rem = io.getInt();
            int add = io.getInt();
            while (rem > 0) {
                if (history[hi][1] > 0) {
                    graph[i].add(history[hi][0]);
                    graph[history[hi][0]].add(i);
                }
                if (rem >= history[hi][1]) {
                    rem -= history[hi][1];
                    hi--;
                } else {
                    history[hi][1] -= rem;
                    break;
                }
            }
            hi++;
            history[hi][0] = i;
            history[hi][1] = add;
        }
        int[][] bad = new int[n+1][4];
        int[] count = new int[n+1];
        int[] color = new int[n+1];
        PriorityQueue<Entry> queue = new PriorityQueue<>();
        for (int i = 1; i <= n; i++) {
            queue.add(new Entry(0,i));
        }
        int what = 0;
        while (true) {
            int pos = 0;
            while (!queue.isEmpty()) {
                int newPos = queue.poll().pos;
                if (color[newPos] == 0) {
                    pos = newPos;
                    break;
                }
            }
            if (pos == 0) break;
            for (int i = 1; i <= 4; i++) {
                if (i == 4) {
                    System.out.println("ERROR");
                    System.exit(0);
                }
                if (bad[pos][i] == 0) {
                    color[pos] = i;
                    if (i > what) what = i;
                    for (int adj : graph[pos]) {
                        if (bad[adj][i] == 0) {
                            bad[adj][i] = 1;
                            count[adj]++;
                            queue.add(new Entry(count[adj],adj));
                        }
                    }
                    break;
                }
            }
        }
        io.println(what);
        for (int i = 1; i <= n; i++) {
            io.print(color[i]+" ");
        }
        io.println();
        io.flush();
    }
}

/** Simple yet moderately fast I/O routines.
 *
 * Example usage:
 *
 * Kattio io = new Kattio(System.in, System.out);
 *
 * while (io.hasMoreTokens()) {
 *    int n = io.getInt();
 *    double d = io.getDouble();
 *    double ans = d*n;
 *
 *    io.println("Answer: " + ans);
 * }
 *
 * io.close();
 *
 *
 * Some notes:
 *
 * - When done, you should always do io.close() or io.flush() on the
 *   Kattio-instance, otherwise, you may lose output.
 *
 * - The getInt(), getDouble(), and getLong() methods will throw an
 *   exception if there is no more data in the input, so it is generally
 *   a good idea to use hasMoreTokens() to check for end-of-file.
 *
 * @author: Kattis
 */

class Kattio extends PrintWriter {
    public Kattio(InputStream i) {
        super(new BufferedOutputStream(System.out));
        r = new BufferedReader(new InputStreamReader(i));
    }
    public Kattio(InputStream i, OutputStream o) {
        super(new BufferedOutputStream(o));
        r = new BufferedReader(new InputStreamReader(i));
    }

    public boolean hasMoreTokens() {
        return peekToken() != null;
    }

    public int getInt() {
        return Integer.parseInt(nextToken());
    }

    public double getDouble() {
        return Double.parseDouble(nextToken());
    }

    public long getLong() {
        return Long.parseLong(nextToken());
    }

    public String getWord() {
        return nextToken();
    }



    private BufferedReader r;
    private String line;
    private StringTokenizer st;
    private String token;

    private String peekToken() {
        if (token == null)
            try {
                while (st == null || !st.hasMoreTokens()) {
                    line = r.readLine();
                    if (line == null) return null;
                    st = new StringTokenizer(line);
                }
                token = st.nextToken();
            } catch (IOException e) { }
        return token;
    }

    private String nextToken() {
        String ans = peekToken();
        token = null;
        return ans;
    }
}
