import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import java.math.BigInteger;

import static java.lang.Math.*;

public class Solution extends PrintWriter {

	class Node {
		final int f, t;
		final Node l, r;

		List<Boolean> subLog = new ArrayList<>();

		public Node(int f, int t, Node l, Node r) {
			this.f = f;
			this.t = t;
			this.l = l;
			this.r = r;
		}

		int assign(boolean[] log, int p) {
			if (l == r) {
				return p;
			}

			p = l.assign(log, p);
			p = r.assign(log, p);

			int ls = l.t - l.f;
			int rs = r.t - r.f;
			while (ls > 0 && rs > 0) {
				boolean c = log[p++];
				subLog.add(c);
				if (c) {
					--rs;
				} else {
					--ls;
				}
			}
			return p;
		}

		void solve(List<Integer> inp, List<Integer> out) {
			if (l == r) {
				out.addAll(inp);
			} else {

				int ls = l.t - l.f;
				int rs = r.t - r.f;

				List<Integer> lnum = new ArrayList<>();
				List<Integer> rnum = new ArrayList<>();

				int p = 0;

				for (boolean b : subLog) {
					if (b) {
						rnum.add(inp.get(p++));
						--rs;
					} else {
						lnum.add(inp.get(p++));
						--ls;
					}
				}

				while (p < inp.size()) {
					if (ls > 0) {
						lnum.add(inp.get(p++));
						--ls;
					} else {
						rnum.add(inp.get(p++));
						--rs;
					}
				}

				if (ls != 0 || rs != 0) {
					throw new IllegalStateException();
				}

				l.solve(lnum, out);
				r.solve(rnum, out);
			}
		}
	}

	Node build(int f, int t) {
		if (t - f <= 1) {
			return new Node(f, t, null, null);
		}

		int m = (f + t) >> 1;
		return new Node(f, t, build(f, m), build(m, t));
	}

	void mergeSort(int[] a, int[] b, int l, int r, StringBuilder log) {
		if (r - l <= 1) {
			return;
		}
		int m = (l + r) >> 1;
		mergeSort(a, b, l, m, log);
		mergeSort(a, b, m, r, log);

		int i = l, j = m, k = l;

		while (i < m && j < r) {
			if (a[i] < a[j]) {
				log.append('0');
				b[k] = a[i];
				i += 1;
			} else {
				log.append('1');
				b[k] = a[j];
				j += 1;
			}
			k += 1;
		}
		while (i < m) {
			b[k] = a[i];
			i += 1;
			k += 1;
		}
		while (j < r) {
			b[k] = a[j];
			j += 1;
			k += 1;
		}

		for (int p = l; p < r; p++) {
			a[p] = b[p];

		}

	}

	void runsort() {
		for (int n = 5; n <= 5; n++) {
			int[] a = new int[n];
			int[] b = new int[n];

			for (int i = 0; i < n; i++) {
				int j = rnd.nextInt(i + 1);
				a[i] = a[j];
				a[j] = i;
			}

			println(Arrays.toString(a));
			StringBuilder log = new StringBuilder();
			mergeSort(a, b, 0, n, log);

			println(n + " " + log.length());
			println(log);

		}
	}

	void run() {
		String str = next();
		int m = str.length();
		boolean[] log = new boolean[m];

		for (int i = 0; i < m; i++) {
			log[i] = str.charAt(i) == '1';
		}

		for (int n = 1;; n++) {
			try {
				Node root = build(0, n);
				if (root.assign(log, 0) != m) {
					throw new IllegalStateException();
				}

				List<Integer> inp = new ArrayList<>();
				List<Integer> out = new ArrayList<>();

				for (int i = 0; i < n; i++) {
					inp.add(i);
				}

				root.solve(inp, out);

				println(out.size());
				for (int val : out) {
					print(val + " ");
				}

				return;

			} catch (RuntimeException err) {

			}
		}

	}

	public static boolean nextPermutation(int[] permutation) {
		int n = permutation.length, a = n - 2;
		while (0 <= a && permutation[a] >= permutation[a + 1]) {
			a--;
		}
		if (a == -1) {
			return false;
		}

		int b = n - 1;
		while (permutation[b] <= permutation[a]) {
			b--;
		}

		swap(permutation, a, b);
		for (int i = a + 1, j = n - 1; i < j; i++, j--) {
			swap(permutation, i, j);
		}
		return true;
	}

	public static void swap(int[] array, int i, int j) {
		if (i == j) {
			return;
		}
		array[i] ^= array[j];
		array[j] ^= array[i];
		array[i] ^= array[j];
	}

	String next() {
		while (!tokenizer.hasMoreTokens())
			tokenizer = new StringTokenizer(nextLine());
		return tokenizer.nextToken();
	}

	boolean hasNext() {
		while (!tokenizer.hasMoreTokens()) {
			String line = nextLine();
			if (line == null) {
				return false;
			}
			tokenizer = new StringTokenizer(line);
		}
		return true;
	}

	int[] nextArray(int n) {
		int[] array = new int[n];
		for (int i = 0; i < n; i++) {
			array[i] = nextInt();
		}
		return array;
	}

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

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

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

	String nextLine() {
		try {
			return reader.readLine();
		} catch (IOException err) {
			return null;
		}
	}

	public Solution(OutputStream outputStream) {
		super(outputStream);
	}

	static BufferedReader reader;
	static StringTokenizer tokenizer = new StringTokenizer("");
	static Random rnd = new Random();

	public static void main(String[] args) throws IOException {
		reader = new BufferedReader(new InputStreamReader(System.in));
		Solution solution = new Solution(System.out);
		solution.run();
		solution.close();
		reader.close();
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E {

    void solve() throws IOException {
        char[] c = reader.readLine().toCharArray();
        for (int i = 1; i <= 10000; i++) {
            int[] a = doit(i, c);
            if (a != null) {
                for (int j = 0; j < a.length; j++) {
                    out.print(a[j] + " ");
                }
                break;
            }
        }
    }

    int[] doit(int n, char[] c) {
        index = 0;
        int[] a = new int[n];
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = b[i] = i + 1;
        }
        boolean res = simulateMerge(0, n, c, a, b);
        if (res && index == c.length) {
            for (int i = 0; i < n; i++) {
                b[a[i] - 1] = i + 1;
            }
            return b;
        } else {
            return null;
        }
    }

    int index = 0;

    boolean simulateMerge(int l, int r, char[] c, int[] a, int[] b) {
        if (r - l <= 1) return true;
        int m = (l + r) >> 1;
        simulateMerge(l, m, c, a, b);
        simulateMerge(m, r, c, a, b);
        int i = l;
        int j = m;
        int k = l;
        while (i < m && j < r) {
            if (index == c.length) {
                return false;
            }
            if (c[index] == '0') {
                b[k] = a[i];
                i++;
            } else {
                b[k] = a[j];
                j++;
            }
            index++;
            k++;
        }

        while (i < m) {
            b[k] = a[i];
            i++;
            k++;
        }
        while (j < r) {
            b[k] = a[j];
            j++;
            k++;
        }
        for (int x = l; x < r; x++) {
            a[x] = b[x];
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        new E().run();
    }

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
//		reader = new BufferedReader(new FileReader("input.txt"));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
//		out = new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    int[] nextIntArray(int n) throws IOException {
        int[] result = new int[n];
        for (int i = 0; i < n; i++) {
            result[i] = nextInt();
        }
        return result;
    }

    long[] nextLongArray(int n) throws IOException {
        long[] result = new long[n];
        for (int i = 0; i < n; i++) {
            result[i] = nextLong();
        }
        return result;
    }

    double[] nextDoubleArray(int n) throws IOException {
        double[] result = new double[n];
        for (int i = 0; i < n; i++) {
            result[i] = nextDouble();
        }
        return result;
    }

    int[][] nextIntArray(int n, int m) throws IOException {
        int[][] result = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                result[i][j] = nextInt();
            }
        }
        return result;
    }

    long[][] nextLongArray(int n, int m) throws IOException {
        long[][] result = new long[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                result[i][j] = nextLong();
            }
        }
        return result;
    }

    double[][] nextDoubleArray(int n, int m) throws IOException {
        double[][] result = new double[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                result[i][j] = nextDouble();
            }
        }
        return result;
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}


import java.util.Map;
import java.io.IOException;
import java.util.HashMap;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ogiekako
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		MyScanner in = new MyScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    long[] fib;
    Map<State, Long> map;

    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int t = in.nextInt();
        int n = in.nextInt();
        long[] u = new long[t];
        long[] v = new long[t];
        for (int i = 0; i < t; i++){
            u[i] = in.nextLong();
            v[i] = in.nextLong();
        }
        long[] res= solve(u,v,n);
        for(long r:res)out.println(r);
    }
    private long[] solve(long[] u, long[] v, int n){
        n = Math.min(n, 85);
        fib = new long[n + 1];
        for (int i = 0; i <= n; i++) {
            fib[i] = i <= 1 ? i + 1 : fib[i - 1] + fib[i - 2];
        }
//        map = new TreeMap<State, Long>();
        map = new HashMap<State, Long>();
        long[]res =new long[u.length];
        for (int i = 0; i < u.length; i++) {
            map.clear();
//            if(i%1000==0) System.err.println(i);
            res[i] = solve(u[i],v[i],n);
        }
        return res;
    }

    class State implements Comparable<State> {
        State(long i, long j, int n) {
            this.i = i;
            this.j = j;
            this.n = n;
        }

        long i, j;
        int n;

        public int compareTo(State o) {
            if (i != o.i) return Long.compare(i, o.i);
            if (j != o.j) return Long.compare(j, o.j);
            return Integer.compare(n, o.n);
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            State state = (State) o;

            if (i != state.i) return false;
            if (j != state.j) return false;
            if (n != state.n) return false;

            return true;
        }

        public int hashCode() {
            int result = (int) (i ^ (i >>> 32));
            result = 31 * result + (int) (j ^ (j >>> 32));
            result = 31 * result + n;
            return result;
        }
    }

    private long solve(long i, long j, int n) {
        if (i > j) return solve(j, i, n);
        if (j > fib[n]) throw new AssertionError();
        if (n == 0) return 0;
        if (n == 1) return i != j ? 1 : 0;
        State cur = new State(i, j, n);
        Long res = map.get(cur);
        if (res != null) return res;
        if (j <= fib[n - 1]) res = Math.min(
                solve(i, j, n - 1),
                Math.min(
                        solve(i, 1, n - 1) + solve(j, fib[n - 1], n - 1) + 2,
                        solve(i, fib[n - 1], n - 1) + solve(j, 1, n - 1) + 2
                )
        );
        else if (i <= fib[n - 1]) res = Math.min(
                solve(i, 1, n - 1) + solve(1, j - fib[n - 1], n - 2) + 1,
                solve(i, fib[n - 1], n - 1) + solve(1, j - fib[n - 1], n - 2) + 1
        );
        else res = solve(i - fib[n - 1], j - fib[n - 1], n - 2);
        map.put(cur, res);
        return res;
    }

    }

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextInt();
			int res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

	public long nextLong(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextLong();
			long res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

    }


import java.util.Map;
import java.io.IOException;
import java.util.HashMap;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ogiekako
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		MyScanner in = new MyScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    long[] fib;
    Map<State, Long> map1[];
    Map<Long, Long> map2[];

    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int t = in.nextInt();
        int n = in.nextInt();
        long[] u = new long[t];
        long[] v = new long[t];
        for (int i = 0; i < t; i++) {
            u[i] = in.nextLong();
            v[i] = in.nextLong();
        }
        long[] res = solve(u, v, n);
        for (long r : res) out.println(r);
    }

    private long[] solve(long[] u, long[] v, int n) {
        n = Math.min(n, 80);
        fib = new long[n + 1];
        for (int i = 0; i <= n; i++) {
            fib[i] = i <= 1 ? i + 1 : fib[i - 1] + fib[i - 2];
        }
        map1 = new HashMap[n + 1];
        map2 = new HashMap[n + 1];
        for (int i = 0; i < n + 1; i++) map1[i] = new HashMap<State, Long>();
        for (int i = 0; i < n + 1; i++) map2[i] = new HashMap<Long, Long>();
        long[] res = new long[u.length];
        for (int i = 0; i < u.length; i++) {
            for (Map m : map1) m.clear();
            res[i] = solve(u[i], v[i], n);
        }
        return res;
    }

    class State {
        //        BigInteger val;
        State(long i, long j, int n) {
            this.i = i;
            this.j = j;
            this.n = n;
//            val = BigInteger.valueOf(i).shiftLeft(128).and(BigInteger.valueOf(j).shiftLeft(64)).and(BigInteger.valueOf(n));
        }

        long i, j;
        int n;

        public boolean equals(Object o) {
            State state = (State) o;
            if (i != state.i) return false;
            if (j != state.j) return false;
            if (n != state.n) return false;
            return true;
//            return val.equals(state.val);
        }

        int hash = -1;

        public int hashCode() {
            if (hash != -1) return hash;
            int result = (int) (i ^ (i >>> 32));
            result = 31 * result + (int) (j ^ (j >>> 32));
            result = 31 * result + n;
            return hash = result;
        }
    }

    int TH = 25;

    private long solve(long i, long j, int n) {
        if (i > j) return solve(j, i, n);
        if (n <= 1) return i != j ? 1 : 0;

        Long res;
        Map map;
        Object cur;
        if (n < TH) {
            cur = i << 40 ^ j << 6 ^ n;
            map = map2[n];
            res = (Long) map.get(cur);
            if (res != null) return res;
        } else {
            cur = new State(i, j, n);
            map = map1[n];
            res = (Long) map.get(cur);
            if (res != null) return res;
        }

        long f = fib[n - 1];

        if (j <= f) res = Math.min(
                solve(i, j, n - 1),
                Math.min(
                        solve(i, 1, n - 1) + solve(j, f, n - 1) + 2,
                        solve(i, f, n - 1) + solve(j, 1, n - 1) + 2
                )
        );
        else if (i <= f) res = Math.min(
                solve(i, 1, n - 1) + solve(1, j - f, n - 2) + 1,
                solve(i, f, n - 1) + solve(1, j - f, n - 2) + 1
        );
        else res = solve(i - f, j - f, n - 2);
        map.put(cur, res);
        return res;
    }

    }

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextInt();
			int res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

	public long nextLong(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextLong();
			long res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

    }


import java.util.Map;
import java.io.IOException;
import java.util.HashMap;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ogiekako
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		MyScanner in = new MyScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    long[] fib;
    Map<State, Long> map;

    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int t = in.nextInt();
        int n = in.nextInt();
        long[] u = new long[t];
        long[] v = new long[t];
        for (int i = 0; i < t; i++){
            u[i] = in.nextInt();
            v[i] = in.nextInt();
        }
        long[] res= solve(u,v,n);
        for(long r:res)out.println(r);
    }
    private long[] solve(long[] u, long[] v, int n){
        n = Math.min(n, 85);
        fib = new long[n + 1];
        for (int i = 0; i <= n; i++) {
            fib[i] = i <= 1 ? i + 1 : fib[i - 1] + fib[i - 2];
        }
//        map = new TreeMap<State, Long>();
        map = new HashMap<State, Long>();
        long[]res =new long[u.length];
        for (int i = 0; i < u.length; i++) {
            map.clear();
//            if(i%1000==0) System.err.println(i);
            res[i] = solve(u[i],v[i],n);
        }
        return res;
    }

    class State implements Comparable<State> {
        State(long i, long j, int n) {
            this.i = i;
            this.j = j;
            this.n = n;
        }

        long i, j;
        int n;

        public int compareTo(State o) {
            if (i != o.i) return Long.compare(i, o.i);
            if (j != o.j) return Long.compare(j, o.j);
            return Integer.compare(n, o.n);
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            State state = (State) o;

            if (i != state.i) return false;
            if (j != state.j) return false;
            if (n != state.n) return false;

            return true;
        }

        public int hashCode() {
            int result = (int) (i ^ (i >>> 32));
            result = 31 * result + (int) (j ^ (j >>> 32));
            result = 31 * result + n;
            return result;
        }
    }

    private long solve(long i, long j, int n) {
        if (i > j) return solve(j, i, n);
        if (j > fib[n]) throw new AssertionError();
        if (n == 0) return 0;
        if (n == 1) return i != j ? 1 : 0;
        State cur = new State(i, j, n);
        Long res = map.get(cur);
        if (res != null) return res;
        if (j <= fib[n - 1]) res = Math.min(
                solve(i, j, n - 1),
                Math.min(
                        solve(i, 1, n - 1) + solve(j, fib[n - 1], n - 1) + 2,
                        solve(i, fib[n - 1], n - 1) + solve(j, 1, n - 1) + 2
                )
        );
        else if (i <= fib[n - 1]) res = Math.min(
                solve(i, 1, n - 1) + solve(1, j - fib[n - 1], n - 2) + 1,
                solve(i, fib[n - 1], n - 1) + solve(1, j - fib[n - 1], n - 2) + 1
        );
        else res = solve(i - fib[n - 1], j - fib[n - 1], n - 2);
        map.put(cur, res);
        return res;
    }

    }

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextInt();
			int res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

    }


import java.io.IOException;
import java.util.Arrays;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author ogiekako
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		MyScanner in = new MyScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    long[] D;
    long[][] last;
    long[][] first;

    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int t = in.nextInt(), n = in.nextInt();
        n = Math.min(n, 80);
        D = new long[n + 1];
        first = new long[n + 1][2];
        last = new long[n + 1][3];
        for (int i = 0; i <= n; i++) D[i] = i <= 1 ? i + 1 : D[i - 1] + D[i - 2];
        for (int i = 0; i < t; i++) {
            out.println(solve(in.nextLong(), in.nextLong(), n));
        }
    }

    private long solve(long x, long y, int n) {
        if (x > y) return solve(y, x, n);
        for (int i = 0; i < n + 1; i++) Arrays.fill(first[i], -1);
        for (int i = 0; i < n + 1; i++) Arrays.fill(last[i], -1);
        return dfs(x, y, n);
    }

    private long dfs(long x, long y, int n) {
        if (n == 0) return 0;
        if (n == 1) return x == y ? 0 : 1;
        long f = D[n - 1];
        if (y <= f) {
            long d1 = dfs(x, y, n - 1);
            long d2 = first(0, x, n - 1) + last(1, y, n - 1) + 2;
            long d3 = last(0, x, n - 1) + first(1, y, n - 1) + 2;
            return Math.min(d1, Math.min(d2, d3));
        } else if (x > f) {
            return dfs(x - f, y - f, n - 2);
        } else {
            long d1 = first(1, y - f, n - 2) + first(0, x, n - 1) + 1;
            long d2 = first(1, y - f, n - 2) + last(0, x, n - 1) + 1;
            return Math.min(d1, d2);
        }
    }

    private long last(int type, long x, int n) {
        if (n == 0) return 0;
        if (n == 1) return x == 2 ? 0 : 1;
        if (last[n][type] >= 0) return last[n][type];
        long f = D[n - 1];
        long res;
        if (x <= f) {
            long d1 = first(type, x, n - 1) + last(2, 1, n - 2) + 1;
            long d2 = last(type, x, n - 1) + last(2, 1, n - 2) + 1;
            res = Math.min(d1, d2);
        } else {
            res = last(type, x - f, n - 2);
        }
        return last[n][type] = res;
    }

    private long first(int type, long x, int n) {
        if (n == 0) return 0;
        if (n == 1) return x == 1 ? 0 : 1;
        if (first[n][type] >= 0) return first[n][type];
        long f = D[n - 1];
        long res;
        if (x <= f) {
            long d1 = first(type, x, n - 1);
            long d2 = last(type, x, n - 1) + 2;
            res = Math.min(d1, d2);
        } else {
            res = first(type, x - f, n - 2) + 1;
        }
        return first[n][type] = res;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextInt();
			int res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

	public long nextLong(){
		try{
			int c=in.read();
			if(c==-1) return c;
			while(c!='-'&&(c<'0'||'9'<c)){
				c=in.read();
				if(c==-1) return c;
			}
			if(c=='-') return -nextLong();
			long res=0;
			do{
				res*=10;
				res+=c-'0';
				c=in.read();
			}while('0'<=c&&c<='9');
			return res;
		}catch(Exception e){
			return -1;
		}
	}

    }


import java.util.*;
import java.io.*;

public class D {
    FastScanner in;
    PrintWriter out;

    public static void main(String[] args) {
        new D().run();
    }

    void solve() throws IOException {
        int n = in.nextInt();
        long m = 1; // one is bad number
        int[] primes = new int[n + 1];
        int[] primesMin = new int[n + 1];
        int primesCnt = 0;
        int[] sieve = new int[n + 1];
        for (int i = 2; i < n + 1; i++) {
            if (sieve[i] == 0) {
                primes[primesCnt++] = i;
                if (2 * i > n) {
                    m++;
                }
                int cnt = 0;
                for (int j = i; j < n + 1; j += i) {
                    if (sieve[j] == 0) {
                        sieve[j] = i;
                        cnt++;
                    }
                }
                primesMin[primesCnt - 1] = cnt;
            }
        }
        int[] prefPrimesMin = new int[n + 1];
        for (int i = 0; i < primesCnt; i++) {
            prefPrimesMin[i + 1] = prefPrimesMin[i] + primesMin[i];
        }
        boolean[] squareFree = new boolean[n + 1];
        squareFree[1] = true;
        for (int i = 2; i < n + 1; i++) {
            int prev = i / sieve[i];
            squareFree[i] = prev % sieve[i] != 0 && squareFree[prev];
//            out.print(squareFree[i] + " ");
        }
//        out.println();

        int[] countPrimeInDecomposition = new int[n + 1];
        for (int i = 2; i < n + 1; i++) {
            if (sieve[i] == 0) {
                countPrimeInDecomposition[i] = 1;
            } else {
                countPrimeInDecomposition[i] = 1 + countPrimeInDecomposition[i / sieve[i]];
            }
        }
        long sum1 = 0;
        for (int i = 2; i < n + 1; i++) {
            if (!squareFree[i]) continue;
            long cnt = n / i;
            cnt *= cnt;
            if (countPrimeInDecomposition[i] % 2 == 0) {
                sum1 -= cnt;
            } else {
                sum1 += cnt;
            }
        }
        long sum0 = 2 * (n - m) * m + m * (m - 1) + 1;
//        out.println(sum0);
        long sum3 = 0;
        int p1i = -1;
        for (int pi = 0; pi < primesCnt; pi++) {
            long p2 = primes[pi];
            if (p2 * 2 > n) {
                break;
            }
            if (p2 * p2 > n) {
                if (p1i == -1) {
                    p1i = pi;
                }
                while (p1i >= 0 && primes[p1i] * p2 > n) {
                    p1i--;
                }
                p1i++;
                sum3 += prefPrimesMin[pi] - prefPrimesMin[p1i];
            }
        }
        sum3 *= 2;
        long sum2 = (long) n * n - sum0 - sum1 - sum3;
//        out.println(m + " " + sum0 + " " + sum1 + " " + sum2 + " " + sum3);
        out.println((sum1 + sum2 * 2 + sum3 * 3 - (n - 1)) / 2);
    }

    void run() {
        try {
            in = new FastScanner(System.in);
            out = new PrintWriter(System.out);
            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DPaths solver = new DPaths();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DPaths {
        Debug debug = new Debug(true);

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            MultiplicativeFunctionSieve sieve = new MultiplicativeFunctionSieve(n, false, true, false);

            long twoCnt = 0;
            long threeCnt = 0;
            int[] ps = new int[n + 1];
            for (int i = 2; i <= n; i++) {
                ps[sieve.smallestPrimeFactor[i]]++;
            }
            for (int i = 1; i <= n; i++) {
                ps[i] += ps[i - 1];
            }
            for (int i = 1; i * 2 <= n; i++) {
                int num = (ps[i] - ps[i - 1]);

                int j = Math.min(i - 1, n / i);
                twoCnt += (long) ps[j] * num;

                int k = Math.min(i - 1, n / 2);
                threeCnt += (long) ps[k] * num;
            }
            for (int i = 1; i <= n; i++) {
                int num = ps[i] - ps[i - 1];
                if (i * i <= n) {
                    twoCnt += (long) num * (num - 1) / 2;
                }
                if (i * 2 <= n) {
                    threeCnt += (long) num * (num - 1) / 2;
                }
            }

            threeCnt -= twoCnt;
            long coprime = 0;
            for (int i = 2; i <= n; i++) {
                coprime += sieve.euler[i];
            }

            long notCoprime = (long) n * (n - 1) / 2 - coprime;
            long ans = twoCnt * 2 - notCoprime + threeCnt * 3;

            debug.debug("coprime", coprime);
            debug.debug("twoCnt", twoCnt);
            debug.debug("notCporime", notCoprime);
            debug.debug("threeCnt", threeCnt);
            out.println(ans);
        }

    }

    static class Debug {
        private boolean offline;
        private PrintStream out = System.err;

        public Debug(boolean enable) {
            offline = enable && System.getSecurityManager() == null;
        }

        public Debug debug(String name, long x) {
            if (offline) {
                debug(name, "" + x);
            }
            return this;
        }

        public Debug debug(String name, String x) {
            if (offline) {
                out.printf("%s=%s", name, x);
                out.println();
            }
            return this;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(long c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(long c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class MultiplicativeFunctionSieve {
        public int[] primes;
        public boolean[] isComp;
        public int primeLength;
        public int[] mobius;
        public int[] euler;
        public int[] factors;
        public int[] smallestPrimeFactor;
        public int[] numberOfSmallestPrimeFactor;

        public MultiplicativeFunctionSieve(int limit, boolean enableMobius, boolean enableEuler, boolean enableFactors) {
            isComp = new boolean[limit + 1];
            primes = new int[limit + 1];
            numberOfSmallestPrimeFactor = new int[limit + 1];
            smallestPrimeFactor = new int[limit + 1];
            primeLength = 0;
            for (int i = 2; i <= limit; i++) {
                if (!isComp[i]) {
                    primes[primeLength++] = i;
                    numberOfSmallestPrimeFactor[i] = smallestPrimeFactor[i] = i;
                }
                for (int j = 0, until = limit / i; j < primeLength && primes[j] <= until; j++) {
                    int pi = primes[j] * i;
                    smallestPrimeFactor[pi] = primes[j];
                    numberOfSmallestPrimeFactor[pi] = smallestPrimeFactor[i] == primes[j]
                            ? (numberOfSmallestPrimeFactor[i] * numberOfSmallestPrimeFactor[primes[j]])
                            : numberOfSmallestPrimeFactor[primes[j]];
                    isComp[pi] = true;
                    if (i % primes[j] == 0) {
                        break;
                    }
                }
            }

            if (enableMobius) {
                mobius = new int[limit + 1];
                mobius[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        mobius[i] = -1;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] != smallestPrimeFactor[i]) {
                            mobius[i] = 0;
                        } else {
                            mobius[i] = mobius[numberOfSmallestPrimeFactor[i]] * mobius[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }

            if (enableEuler) {
                euler = new int[limit + 1];
                euler[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        euler[i] = i - 1;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] == i) {
                            euler[i] = i - i / smallestPrimeFactor[i];
                        } else {
                            euler[i] = euler[numberOfSmallestPrimeFactor[i]] * euler[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }

            if (enableFactors) {
                factors = new int[limit + 1];
                factors[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        factors[i] = 2;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] == i) {
                            factors[i] = 1 + factors[i / smallestPrimeFactor[i]];
                        } else {
                            factors[i] = factors[numberOfSmallestPrimeFactor[i]]
                                    * factors[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }
        }

    }
}


import java.util.*;
import java.io.*;

public class p926J {
	public static void main(String[] args) throws IOException {
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		StringTokenizer st;
		int times = Integer.parseInt(f.readLine());
		IntervalList list = new IntervalList();
		while(times-- > 0)
		{
			st = new StringTokenizer(f.readLine());
			int s = Integer.parseInt(st.nextToken());
			int e = Integer.parseInt(st.nextToken());
			list.add(s, e);
			out.println(list.size());
		}
		out.close();
	}

	static class IntervalList
	{
		public TreeSet<Interval> set;
		public IntervalList()
		{
			set = new TreeSet<Interval>();
		}

		public void add(int s, int e)
		{
			Iterator<Interval> iter = set.tailSet(new Interval(s, s), true).iterator();
			while(iter.hasNext())
			{
				Interval i = iter.next();
				if(i.s > e)
					break;
				if(i.s < s)
					s = i.s;
				if(i.e > e)
					e = i.e;
				iter.remove();
			}
			set.add(new Interval(s, e));
		}

		public int size()
		{
			return set.size();
		}
	}

	static class Interval implements Comparable<Interval>
	{
		int s, e;
		public Interval(int s, int e)
		{
			this.s = s;
			this.e = e;
		}

		public int compareTo(Interval i)
		{
			return e - i.e;
		}

		public String toString()
		{
			return s + " " + e;
		}
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;

public class D {
	static long M = 1000L*1000*1000+7;
	static long A(long x, long y) { return (x+y)%M; }
	static long M(long x, long y) { return (x*y)%M; }

	static long f(long n) {
		long ans = 1;
		for(int i=2; i<=n; i++)
			ans = M(ans, i);
		return ans;
	}
	static long C(long n, long k) {
		long ans = 1;
		for(long i=n-k+1; i<=n; i++)
			ans = M(ans, i);
		return ans;
	}
	static Long[][] DP;
	public static long f(int a, int b) {
		if(a+b <= 1) return 1;
		if(DP[a][b]!=null) return DP[a][b];
		if(a==0) {
			return DP[a][b]=f(b);
		} else {
			long ans = f(a-1, b);
			if(a>=2) {
				for(int k=0; k<=b; k++)
					ans = A(ans, M(a-1, M(C(b,k), f(a-2, b-k))));
			}
			if(b>=1) ans = A(ans, M(b, f(a,b-1)));
			return DP[a][b]=ans;
		}
	}
	static int i(String s) { return Integer.parseInt(s); }
	public static void main(String[] args) throws Exception {
		/*int L = 5;
		for(int n=0; n<=L; n++)
			for(int a=0; a<=n; a++)
				System.out.printf("f(%d,%d) = %d\n", a, n-a, f(a,n-a));*/

		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		int n = i(in.readLine());
		int C1 = 0;
		int C2 = 0;
		String[] arr = in.readLine().split(" ");
		for(int i=0; i<n; i++) {
			if(i(arr[i])==1) C1++;
			else C2++;
		}
		DP = new Long[n+1][n+1];
		System.out.println(f(C1,C2));
	}
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Solution {

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws Exception {
		if (st == null || !st.hasMoreTokens()) st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	int nextInt() throws Exception {
		return Integer.parseInt(nextToken());
	}

	long[] fkt = new long[1000100];
	long modd = 1000000007;
	long[][] c = new long[1001][1001];

	TreeMap<Long, Long> cash = new TreeMap<Long, Long>();

	long f(int n, int t) {
		if (cash.containsKey(n * 10000000l + t)) return cash.get(n * 10000000l + t);
		long res = 0;
		if (n == t) res = fkt[n]; else {
			for (int i = 0; i <= t; i++) {
				long tmp = c[t][i];
				res = (res + (tmp * fkt[i]) % modd * f(n - i - 1, t - i)) % modd;
				if (n > t + 1) res = (res + ((tmp * fkt[i + 1]) % modd * f(n - i - 2, t - i) * (n - t - 1)) % modd) % modd;
			}
		}
		cash.put(n * 10000000l + t, res);
		return res;
	}

	void solve() throws Exception {
		fkt[0] = 1;
		for (int i = 1; i <= 1000000; i++) fkt[i] = (fkt[i - 1] * i) % modd;
		c[0][0] = 1;
		for (int i = 1; i <= 1000; i++) {
			c[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % modd;
			}
		}
		int n = nextInt();
		int t = 0;
		for (int i = 0; i < n; i++) {
			t += nextInt() - 1;
		}
		out.println(f(n, t));
	}

	void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			Locale.setDefault(Locale.US);
			solve();
		} catch(Exception e) {
			e.printStackTrace();
			System.exit(1);
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) {
		new Solution().run();
	}

}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;

public class A {
	static final long mod = 1000000007;
	public static void main(String[] args) {
		MScanner sc = new MScanner();
		PrintWriter out = new PrintWriter(System.out);
		int N = sc.nextInt(), ONE = 0, TWO = 0;
		for(int a=0;a<N;a++)if(sc.nextInt()==1)ONE++;else TWO++;
		long[] inv = new long[N];
		inv[0]=inv[1]=1;
		for(int a=2;a<=ONE;a++)
			inv[a]=(inv[a-1]+(a-1)*inv[a-2])%mod;
		long ans = inv[ONE];
		for(int a=0;a<TWO;a++)
			ans = (ans*(TWO+ONE-a))%mod;
		out.println(ans);
		out.close();
	}
	static class MScanner{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public MScanner(){
			stream = System.in;
			//stream = new FileInputStream(new File("dec.in"));

		}
		int read(){
			if(numChars==-1)
				throw new InputMismatchException();
			if(curChar>=numChars){
				curChar = 0;
				try{
					numChars = stream.read(buf);
				} catch (IOException e){
					throw new InputMismatchException();
				}
				if(numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		boolean isSpaceChar(int c){
			return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
		}
		boolean isEndline(int c){
			return c=='\n'||c=='\r'||c==-1;
		}
		int nextInt(){
			return Integer.parseInt(next());
		}
		int[] nextInt(int N){
			int[] ret = new int[N];
			for(int a=0;a<N;a++)
				ret[a] = nextInt();
			return ret;
		}
		long nextLong(){
			return Long.parseLong(next());
		}
		long[] nextLong(int N){
			long[] ret = new long[N];
			for(int a=0;a<N;a++)
				ret[a] = nextLong();
			return ret;
		}
		double nextDouble(){
			return Double.parseDouble(next());
		}
		double[] nextDouble(int N){
			double[] ret = new double[N];
			for(int a=0;a<N;a++)
				ret[a] = nextDouble();
			return ret;
		}
		String next(){
			int c = read();
			while(isSpaceChar(c))
				c=read();
			StringBuilder res = new StringBuilder();
			do{
				res.appendCodePoint(c);
				c=read();
			} while(!isSpaceChar(c));
			return res.toString();
		}
		String[] next(int N){
			String[] ret = new String[N];
			for(int a=0;a<N;a++)
				ret[a] = next();
			return ret;
		}
		String nextLine(){
			int c = read();
			while(isEndline(c))
				c=read();
			StringBuilder res = new StringBuilder();
			do{
				res.appendCodePoint(c);
				c = read();
			}while(!isEndline(c));
			return res.toString();
		}
		String[] nextLine(int N){
			String[] ret = new String[N];
			for(int a=0;a<N;a++)
				ret[a] = nextLine();
			return ret;
		}

	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Locale;
import java.util.StringTokenizer;

import static java.util.Arrays.deepToString;

public class D {

	static long get(int ones, int twos) {
		if (ones + twos == 1) {
			return 1;
		}
		if (ones == 0) {
			return fact(twos);
		}
		long ans = get(ones - 1, twos);
		if (ones >= 2) {
			ans += (ones - 1) * get(ones - 2, twos);
		}
		if (twos >= 1) {
			ans += (twos) * get(ones, twos - 1);
		}
		if (ones >= 2 && twos >= 1) {
			long typeSum = 0;
			for (int len = 1; len <= twos; len++) {
				typeSum += special(twos, len) * get(ones - 2, twos - len);
			}
			ans += (ones - 1) * typeSum;
		}
		return ans;
	}

	static long fact(int k) {
		return k <= 1 ? 1 : k * fact(k - 1);
	}

	static long special(int k, int len) {
		long res = 1;
		for (int t = k; t >= k - len + 1; t--) {
			res *= t;
		}
		return res;
	}

	static void solve() {
		int n = nextInt();
		int ones = 0, twos = 0;
		for (int i = 0; i < n; i++) {
			int k = nextInt();
			if (k == 1)
				ones++;
			else
				twos++;
		}
		debug(get(ones, twos));
	}

	public static void main(String[] args) throws Exception {
		reader = new BufferedReader(new InputStreamReader(System.in));
		writer = new PrintWriter(System.out);
		Locale.setDefault(Locale.US);

		setTime();
		solve();
		printTime();
		printMemory();

		writer.close();
	}

	static BufferedReader reader;
	static PrintWriter writer;
	static StringTokenizer tok = new StringTokenizer("");
	static long systemTime;

	static void debug(Object... o) {
		System.err.println(deepToString(o));
	}

	static void setTime() {
		systemTime = System.currentTimeMillis();
	}

	static void printTime() {
		System.err.println("Time consumed: " + (System.currentTimeMillis() - systemTime));
	}

	static void printMemory() {
		System.err.println("Memory consumed: "
				+ (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000 + "kb");
	}

	static String next() {
		while (!tok.hasMoreTokens()) {
			String w = null;
			try {
				w = reader.readLine();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (w == null)
				return null;
			tok = new StringTokenizer(w);
		}
		return tok.nextToken();
	}

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

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

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

	static BigInteger nextBigInteger() {
		return new BigInteger(next());
	}
}


import java.util.*;

// BiGraph Matching

public class CF_212A {
    static Scanner scanner = new Scanner(System.in);

    public static void main(String args[]) {
        while (task()) {
        }
    }

    private static int n, m, k, t;

    private static int maxK = 5000;
    private static int maxT = 2000;
    private static int[] a = new int[maxK + 10];
    private static int[] b = new int[maxK + 10];

    private static int[] X = new int[maxT * maxT + 10];
    private static int[] Y = new int[maxT * maxT + 10];
    private static int[] xBegin = new int[maxT * maxT + 10];
    private static int[] yBegin = new int[maxT * maxT + 10];

    private static int[] degree = new int[maxK + 10];
    private static int maxDegree = 0;

    private static int[] degreeX = new int[maxK + 10];
    private static int[] degreeY = new int[maxK + 10];

    private static int[][] col = new int[2 * maxT + 10][maxT + 10];
    private static int[][] colH = new int[2 * maxT + 10][2 * maxT + 10];

    private static int[][] realEdge = new int[2 * maxT + 10][2 * maxT + 10];
    private static int[][] fakeEdge = new int[2 * maxT + 10][2 * maxT + 10];

    public static boolean task() {
        n = scanner.nextInt();
        m = scanner.nextInt();
        k = scanner.nextInt();
        t = scanner.nextInt();

        for (int i = 0; i < k; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            y += n;
            a[i] = x;
            b[i] = y;
            degree[x]++;
            degree[y]++;
        }

        int ans = 0;
        for (int i = 1; i <= n + m; i++) {
            ans += degree[i] % t == 0? 0: 1;
            // System.out.println("deg " + i + " " + degree[i]);
        }
        System.out.println(ans);

        maxDegree = t;

        int hX = 1, hY = 1;
        for (int i = 1; i <= n; i++) {
            // System.out.println("deg " + i + " " + degree[i] + " " + hX);
            int deg = degree[i];
            xBegin[i] = hX;
            while (deg > 0) {
                X[hX] = i;
                hX++;
                deg -= maxDegree;
            }
        }

        for (int i = 1; i <= m; i++) {
            int deg = degree[n + i];
            yBegin[i] = hY;
            while (deg > 0) {
                Y[hY] = i;
                hY++;
                deg -= maxDegree;
            }
        }

        int h = hX - 1;
        if (h < hY - 1) {
            h = hY - 1;
        }

        /*
        for (int i = 1; i <= h; i++) {
            System.out.println(i + " " + X[i]);
        }

        System.out.println(" -- ");

        for (int i = 1; i <= h; i++) {
            System.out.println(i + " " + Y[i]);
        }
         */

        Matcher matcher = new Matcher(h, h);

        for (int i = 0; i < k; i++) {
            int x = a[i];
            int y = b[i] - n;
            int realX = xBegin[x];
            int realY = yBegin[y];
            matcher.addEdge(realX, realY);
            realEdge[realX][realY] = 1;
            degreeX[realX]++;
            if (degreeX[realX] == maxDegree) {
                xBegin[x]++;
            }
            degreeY[realY]++;
            if (degreeY[realY] == maxDegree) {
                yBegin[y]++;
            }
        }

        int hy = 1;

        for (int i = 1; i <= h; i++) {
            int need = maxDegree - degreeX[i];
            while (need > 0) {
                while (degreeY[hy] == maxDegree) {
                    hy++;
                }
                matcher.addEdge(i, hy);
                fakeEdge[i][hy] = 1;
                need--;
                degreeY[hy]++;
                degreeX[i]++;
            }
        }

        /*
        for (int i = 1; i <= h; i++) {
            System.out.println("check deg x " + i + " " + degreeX[i]);
        }
        for (int i = 1; i <= h; i++) {
            System.out.println("check deg y " + i + " " + degreeY[i]);
        }
         */

        for (int i = 0; i < maxDegree; i++) {
            matcher.match();
            // System.out.println(matcher.ans());
            int c = i + 1;
            for (int x = 1; x <= h; x++) {
                int y = matcher.matching[x] - h;
                if (y + h == -1) {
                    continue;
                }
                int originalX = X[x];
                int originalY = Y[y];
                if (originalX == 5 && originalY == 4) {
                    //System.out.println("hit !! " + originalX + " " + originalY + " " + col[originalX][originalY]);
                    //System.out.println("hit !! " + x + " " + y + " " + c);
                }
                if (realEdge[x][y] == 1 && colH[x][y] == 0) {
                    colH[x][y] = c;
                    if (col[originalX][originalY] == 0) {
                        col[originalX][originalY] = c;
                        //col[originalY][originalX] = c;
                    } else {
                    }
                }
               //  System.out.println("col " + originalX + " " + originalY + " " + c);
                matcher.delEdge(x, y);
            }
        }

        int tot = 0;
        for (int i = 0; i < k; i++) {
            int x = a[i];
            int y = b[i] - n;
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print(col[x][y]);
            tot++;
        }
        System.out.println();

        /*
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                System.out.print(col[i][j] + " ");
                if (col[i][j] > 0) {
                }
            }
            System.out.println();
        }
        System.out.println(tot);

        // check
        int [][] sumX = new int[maxT + 10][4];
        int [][] sumY = new int[maxT + 10][4];
        for (int i = 1; i <= n; i++) {
            sumX[i][1] = sumX[i][2] = sumX[i][3] = 0;
            sumY[i][1] = sumY[i][2] = sumY[i][3] = 0;
        }
        for (int i = 0; i < k; i++) {
            int x = a[i];
            int y = b[i] - n;
            sumX[x][col[x][y]]++;
            sumY[y][col[x][y]]++;
            if (x == 5) {
                System.out.println("check " + x  + " " + y + "  " + col[x][y]);
            }
        }
        for (int i = 1; i <= n; i++) {
            int min = sumX[i][1];
            int max = sumX[i][1];
            if (min > sumX[i][2]) {
                min = sumX[i][2];
            }
            if (min > sumX[i][3]) {
                min = sumX[i][3];
            }
            if (max < sumX[i][2]) {
                max = sumX[i][2];
            }
            if (max < sumX[i][3]) {
                max = sumX[i][3];
            }
            int yes = 0;
            if (degree[i] % 3 == 0) {
                if (min == max) {
                    yes = 1;
                }
            } else {
                if (min == max - 1) {
                    yes = 1;
                }
            }
            if (i == 5) {
                System.out.println("x " + i + " " + degree[i] + " " + min + " " + max + " " + yes);
            }
        }

        System.out.println("---");
        for (int i = 1; i <= m; i++) {
            int min = sumY[i][1];
            int max = sumY[i][1];
            if (min > sumY[i][2]) {
                min = sumY[i][2];
            }
            if (min > sumY[i][3]) {
                min = sumY[i][3];
            }
            if (max < sumY[i][2]) {
                max = sumY[i][2];
            }
            if (max < sumY[i][3]) {
                max = sumY[i][3];
            }
            int yes = 0;
            if (degree[i + n] % 3 == 0) {
                if (min == max) {
                    yes = 1;
                }
            } else {
                if (min == max - 1) {
                    yes = 1;
                }
            }
            System.out.println("y " + i + " " + degree[i + n] + " " + min + " " + max + " " + yes);
        }
         */

        return false;
    }

    public static final int maxN = 10000;

    public static class Matcher {
        public Map<Integer, Integer>[] g = new Map[2 * maxN + 10];
        private int nx, ny;
        private int nEdge;

        public static int[] matching = new int[2 * maxN + 10];
        private static int[] checked = new int[2 * maxN + 10];

        public Matcher(int nx, int ny) {
            this.nx = nx;
            this.ny = ny;
            nEdge = 0;
            for (int i = 0; i < g.length; i++) {
                g[i] = new HashMap<>();
            }
        }

        public void addEdge(int x, int y) {
            int now = g[x].getOrDefault(nx + y, 0);
            g[x].put(nx + y, now + 1);
            nEdge++;
            // System.out.println(("add " + x + " " + y));
        }

        public void delEdge(int x, int y) {
            int now = g[x].getOrDefault(nx + y, 0);
            if (now > 1) {
                g[x].put(nx + y, now - 1);
            } else {
                g[x].remove(nx + y);
            }
            nEdge--;
  //          System.out.println(("del " + x + " " + y));
        }

        public void reset() {
            ans = 0;
            for (int i = 0; i < matching.length; i++) {
                matching[i] = -1;
            }
            for (int i = 0; i < checked.length; i++) {
                checked[i] = -1;
            }
        }

        private int ans = 0;

        private Queue<Integer> q = new LinkedList<>();
        private int[] prev = new int[2 * maxN + 10];

        public void match() {
            reset();
            for (int x = 1; x <= nx; x++) {
                int step = x;
                if (matching[x] == -1) {
                    q.clear();
                    q.add(x);
                    prev[x] = -1;
                    boolean flag = false;
                    while (!q.isEmpty() && !flag) {
                        int u = q.poll();
                        //System.out.println(u);
                        for (int v: g[u].keySet()) {
                            if (flag) {
                                break;
                            }
                            if (checked[v] != step) {
                                checked[v] = step;
                                q.add(matching[v]);
                                if (matching[v] >= 0) {
                                    prev[matching[v]] = u;
                                } else {
                                    flag = true;
                                    int d = u;
                                    int e = v;
                                    while (d != -1) {
                                        int t = matching[d];
                                        matching[d] = e;
                                        matching[e] = d;
                                        d = prev[d];
                                        e = t;
                                    }
                                }
                            }
                        }
                        // q.poll();
                    }
                    if (matching[x] != -1) {
                        ans++;
                    }
                }
            }
        }

        public int ans() {
            return ans;
        }

    }

}


import java.util.*;

// BiGraph Matching

public class CF_212A {
    static Scanner scanner = new Scanner(System.in);

    public static void main(String args[]) {
        while (task()) {
        }
    }

    private static int n, m, k, t;

    private static int maxK = 5000;
    private static int maxT = 200;
    private static int[] a = new int[maxK + 10];
    private static int[] b = new int[maxK + 10];

    private static int[] X = new int[maxT * maxT + 10];
    private static int[] Y = new int[maxT * maxT + 10];
    private static int[] xBegin = new int[maxT * maxT + 10];
    private static int[] yBegin = new int[maxT * maxT + 10];
    private static int[] sum = new int[2 * maxT + 10];

    private static int[] degree = new int[maxK + 10];
    private static int maxDegree = 0;

    private static int[] degreeX = new int[maxK + 10];
    private static int[] degreeY = new int[maxK + 10];

    private static int[][] col = new int[2 * maxT + 10][maxT + 10];

    public static boolean task() {
        n = scanner.nextInt();
        m = scanner.nextInt();
        k = scanner.nextInt();
        t = scanner.nextInt();

        for (int i = 0; i < k; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            y += n;
            a[i] = x;
            b[i] = y;
            degree[x]++;
            degree[y]++;
        }

        int ans = 0;
        for (int i = 1; i <= n + m; i++) {
            ans += degree[i] % t == 0? 0: 1;
            /*
            if (degree[i] > maxDegree) {
                maxDegree = degree[i];
            }
             */
        }
        System.out.println(ans);

        maxDegree = t;

        int hA = 1, hB = 1;
        for (int i = 1; i <= n; i++) {
            // System.out.println("deg " + i + " " + degree[i] + " " + hA);
            int deg = degree[i];
            xBegin[i] = hA;
            while (deg > 0) {
                X[hA] = i;
                hA++;
                deg -= maxDegree;
            }
        }

        for (int i = 1; i <= m; i++) {
            int deg = degree[n + i];
            yBegin[i] = hB;
            while (deg > 0) {
                Y[hB] = i;
                hB++;
                deg -= maxDegree;
            }
        }

        int h = hA - 1;
        if (h < hB - 1) {
            h = hB - 1;
        }

        /*
        for (int i = 1; i <= h; i++) {
            System.out.println(i + " " + X[i]);
        }

        System.out.println(" -- ");

        for (int i = 1; i <= h; i++) {
            System.out.println(i + " " + Y[i]);
        }
         */

        Matcher matcher = new Matcher(h, h);

        for (int i = 0; i < k; i++) {
            int x = a[i];
            int y = b[i] - n;
            int realX = xBegin[x];
            int realY = yBegin[y];
            matcher.addEdge(realX, realY);
            degreeX[realX]++;
            if (degreeX[realX] == maxDegree) {
                xBegin[x]++;
            }
            degreeY[realY]++;
            if (degreeY[realY] == maxDegree) {
                yBegin[y]++;
            }
        }

        int hy = 1;

        for (int i = 1; i <= h; i++) {
            int need = maxDegree - degreeX[i];
            while (need > 0) {
                while (degreeY[hy] == maxDegree) {
                    hy++;
                }
                matcher.addEdge(i, hy);
                need--;
                degreeY[hy]++;
            }
        }

        for (int i = 0; i < maxDegree; i++) {
            matcher.match();
            // System.out.println(matcher.ans());
            int c = i + 1;
            for (int x = 1; x <= h; x++) {
                int originalX = X[x];
                int originalY = Y[matcher.matching[x] - h];
                col[originalX][originalY] = c;
                col[originalY][originalX] = c;
                matcher.delEdge(x, matcher.matching[x] - h);
            }
        }

        for (int i = 0; i < k; i++) {
            int x = a[i];
            int y = b[i] - n;
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print(col[x][y]);
        }
        System.out.println();

        return false;
    }

    public static final int maxN = 1000;

    public static class Matcher {
        public Map<Integer, Integer>[] g = new Map[2 * maxN + 10];
        private int nx, ny;
        private int nEdge;

        public static int[] matching = new int[2 * maxN + 10];
        private static int[] checked = new int[2 * maxN + 10];

        public Matcher(int nx, int ny) {
            this.nx = nx;
            this.ny = ny;
            nEdge = 0;
            for (int i = 0; i < g.length; i++) {
                g[i] = new HashMap<>();
            }
        }

        public void addEdge(int x, int y) {
            int now = g[x].getOrDefault(nx + y, 0);
            g[x].put(nx + y, now);
            nEdge++;
            // System.out.println(("add " + x + " " + y));
        }

        public void delEdge(int x, int y) {
            int now = g[x].getOrDefault(nx + y, 0);
            if (now > 1) {
                g[x].put(nx + y, now - 1);
            } else {
                g[x].remove(nx + y);
            }
            nEdge--;
            // System.out.println(("del " + x + " " + y));
        }

        public void reset() {

        }

        private int ans = 0;

        private Queue<Integer> q = new LinkedList<>();
        private int[] prev = new int[2 * maxN + 10];

        public void match() {
            ans = 0;
            for (int i = 0; i < matching.length; i++) {
                matching[i] = -1;
            }
            for (int i = 0; i < checked.length; i++) {
                checked[i] = -1;
            }
            for (int x = 1; x <= nx; x++) {
                int step = x;
                if (matching[x] == -1) {
                    q.clear();
                    q.add(x);
                    prev[x] = -1;
                    boolean flag = false;
                    while (!q.isEmpty() && !flag) {
                        int u = q.poll();
                        //System.out.println(u);
                        for (int v: g[u].keySet()) {
                            if (flag) {
                                break;
                            }
                            if (checked[v] != step) {
                                checked[v] = step;
                                q.add(matching[v]);
                                if (matching[v] >= 0) {
                                    prev[matching[v]] = u;
                                } else {
                                    flag = true;
                                    int d = u;
                                    int e = v;
                                    while (d != -1) {
                                        int t = matching[d];
                                        matching[d] = e;
                                        matching[e] = d;
                                        d = prev[d];
                                        e = t;
                                    }
                                }
                            }
                        }
                        // q.poll();
                    }
                    if (matching[x] != -1) {
                        ans++;
                    }
                }
            }
        }

        public int ans() {
            return ans;
        }

    }

}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.Vector;

public class Test {

	static int n, m, k, t;
	static int[] deg = new int[501];
	static int[] w1 = new int[501];
	static int[] w2 = new int[501];
	static int[][] f = new int[50001][201];
	static int[][] index = new int[501][201];
	static int[] color = new int[5001];
	static void alter(int y, int c1, int c2)
	{
		//swap f[y][c1] and f[y][c2]
		int temp = f[y][c1];
		f[y][c1] = f[y][c2];
		f[y][c2] = temp;
		temp = index[y][c1];
		index[y][c1] = index[y][c2];
		index[y][c2] = temp;
		color[index[y][c2]] = c2;
		if(f[y][c2] != 0) alter(f[y][c2], c2, c1);
	}

	public static void main(String[] args) throws Exception
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter writer = new PrintWriter(System.out);
		StringTokenizer st  = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());
		int t = Integer.parseInt(st.nextToken());
		int cnt = 0;
		for(int i = 1; i <= k; i++)
		{
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			if(deg[a]%t == 0) w1[a] = ++cnt;
			if(deg[n+b]%t == 0) w2[n+b] = ++cnt;
			++deg[a];
			++deg[n+b];
			int x = w1[a];
			int y = w2[n+b];
			int c1 = -1;
			int c2 = -1;
			for(int j = 1; j <= t; j++) if(f[x][j] == 0) { c1 = j; break; }
			for(int j = 1; j <= t; j++) if(f[y][j] == 0) { c2 = j; break; }

			if(f[y][c1] != 0) alter(y, c1, c2);
			f[x][c1] = y;
			f[y][c1] = x;
			index[x][c1] = i;
			index[y][c1] = i;
			color[i] = c1;
		}
		int uneven = 0;
		for(int i = 1; i <= n; i++) if(deg[i]%t != 0) uneven++;
		for(int i = n+1; i <= n+m; i++) if(deg[i]%t != 0) uneven++;
		writer.println(uneven);
		for(int i = 1; i <= k; i++) writer.print(color[i]+" ");
		br.close();
		writer.close();
	}

}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.Vector;

public class Test {

	static int n, m, k, t;
	static int[] deg = new int[501];
	static int[] w1 = new int[501];
	static int[] w2 = new int[501];
	static int[][] f = new int[501][201];
	static int[][] index = new int[501][201];
	static int[] color = new int[5001];
	static void alter(int y, int c1, int c2)
	{
		//swap f[y][c1] and f[y][c2]
		int temp = f[y][c1];
		f[y][c1] = f[y][c2];
		f[y][c2] = temp;
		temp = index[y][c1];
		index[y][c1] = index[y][c2];
		index[y][c2] = temp;
		color[index[y][c2]] = c2;
		if(f[y][c2] != 0) alter(f[y][c2], c2, c1);
	}

	public static void main(String[] args) throws Exception
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter writer = new PrintWriter(System.out);
		StringTokenizer st  = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());
		int t = Integer.parseInt(st.nextToken());
		int cnt = 0;
		for(int i = 1; i <= k; i++)
		{
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			if(deg[a]%t == 0) w1[a] = ++cnt;
			if(deg[n+b]%t == 0) w2[n+b] = ++cnt;
			++deg[a];
			++deg[n+b];
			int x = w1[a];
			int y = w2[n+b];
			int c1 = -1;
			int c2 = -1;
			for(int j = 1; j <= t; j++) if(f[x][j] == 0) { c1 = j; break; }
			for(int j = 1; j <= t; j++) if(f[y][j] == 0) { c2 = j; break; }

			if(f[y][c1] != 0) alter(y, c1, c2);
			f[x][c1] = y;
			f[y][c1] = x;
			index[x][c1] = i;
			index[y][c1] = i;
			color[i] = c1;
		}
		int uneven = 0;
		for(int i = 1; i <= n; i++) if(deg[i]%t != 0) uneven++;
		for(int i = n+1; i <= n+m; i++) if(deg[i]%t != 0) uneven++;
		writer.println(uneven);
		for(int i = 1; i <= k; i++) writer.print(color[i]+" ");
		br.close();
		writer.close();
	}

}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskG solver = new TaskG();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + xminusy) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev)) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)));
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                if (j % 2 == 0)
                    out.print("L");
                else
                    out.print("R");
            }
            prev = i;
        }
        out.println();
    }
}

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 int nextInt() {
        return Integer.parseInt(next());
    }

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

}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskG solver = new TaskG();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                if ((px + py + l) % 2 != 0) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + l) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                if ((xminusy + l) % 2 != 0) {
                    if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev) || (Math.abs(dx) + Math.abs(dy) + (i - prev)) % 2 != 0) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)) / 2);
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                out.print("LR");
            }
            prev = i;
        }
        out.println();
    }
}

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 int nextInt() {
        return Integer.parseInt(next());
    }

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

}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ChallengeG solver = new ChallengeG();
        solver.solve(1, in, out);
        out.close();
    }
}

class ChallengeG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                if ((px + py + l) % 2 != 0) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + l) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                if ((xminusy + l) % 2 != 0) {
                    if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev) || (Math.abs(dx) + Math.abs(dy) + (i - prev)) % 2 != 0) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)) / 2);
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                out.print("LR");
            }
            prev = i;
        }
        out.println();
    }
}

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 int nextInt() {
        return Integer.parseInt(next());
    }

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

}