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

/**
 * Created on 5/11/2017.
 */
public class D{
    InputReader sc;
    PrintWriter pw;

    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 float nextFloat() {
            return Float.parseFloat(next());
        }

        public double nextDouble() {
            return Float.parseFloat(next());
        }

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

    class Coords {
        int r, c;

        public Coords(int r, int c) {
            this.r = r;
            this.c = c;
        }
    }

    void run() throws FileNotFoundException {
        // sc = new Scanner(new File("D.txt"));
        sc = new InputReader(System.in);
        pw = new PrintWriter(System.out);

        Vector<Coords> seeds = new Vector<>();

        int n = sc.nextInt();
        Coords[][] dsts = new Coords[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                dsts[i][j] = new Coords(sc.nextInt() - 1, sc.nextInt() - 1);
                if ((dsts[i][j].r == i) && (dsts[i][j].c == j)) {
                    seeds.add(dsts[i][j]);
                }
            }
        }

        int U = 0, D = 1, L = 2, R = 3, X = 4;
        int[] dr = {-1, 1, 0, 0, 0};
        int[] dc = {0, 0, -1, 1, 0};
        int[] rev = {1, 0, 3, 2, 0};
        char[] chars = {'U', 'D', 'L', 'R', 'X'};

        int[][] map = new int[n][n];
        boolean[][] filled = new boolean[n][n];

        for (Coords seed: seeds) {
            int r0 = seed.r;
            int c0 = seed.c;

            map[r0][c0] = X;
            filled[r0][c0] = true;

            Queue<Coords> q = new LinkedList<>();
            q.add(seed);

            while (!q.isEmpty()) {
                Coords node = q.peek();
                q.poll();

                int r = node.r;
                int c = node.c;
                for (int dir = 0; dir < 4; dir++) {
                    int r1 = r + dr[dir];
                    int c1 = c + dc[dir];
                    if (r1 >= 0 && r1 < n && c1 >= 0 && c1 < n) {
                        if (dsts[r1][c1].r == r0 && dsts[r1][c1].c == c0 && !filled[r1][c1]) {
                            map[r1][c1] = rev[dir];
                            filled[r1][c1] = true;
                            q.add(new Coords(r1, c1));
                        }
                    }
                }
            }
        }

//        for (int i = 0; i < n; i++) {
//            for (int j = 0; j < n; j++) {
//                System.out.print(map[i][j] + " ");
//            }
//            System.out.println();
//        }
//
//        for (int i = 0; i < n; i++) {
//            for (int j = 0; j < n; j++) {
//                System.out.print("(" + dsts[i][j].r + " " + dsts[i][j].c + ") ");
//            }
//            System.out.println();
//        }
//
//        for (int i = 0; i < n; i++) {
//            for (int j = 0; j < n; j++) {
//                System.out.print(filled[i][j] ? "F " : "N ");
//            }
//            System.out.println();
//        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (dsts[i][j].r >= 0) {
                    if (!filled[i][j]) {
//                        System.out.println(i + " " + j);
                        pw.println("INVALID");
                        pw.close();
                        return;
                    }
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (dsts[i][j].r < 0 && !filled[i][j]) {
                    Queue<Coords> q = new LinkedList<>();

                    for (int dir = 0; dir < 4; dir++) {
                        int r1 = i + dr[dir];
                        int c1 = j + dc[dir];
                        if (r1 >= 0 && r1 < n && c1 >= 0 && c1 < n) {
                            if (dsts[r1][c1].r < 0) {
                                map[i][j] = dir;
                                filled[i][j] = true;

                                map[r1][c1] = rev[dir];
                                filled[r1][c1] = true;

                                q.add(new Coords(i, j));
                                q.add(new Coords(r1, c1));
                                break;
                            }
                        }
                    }

                    if (q.isEmpty()) {
                        pw.println("INVALID");
                        pw.close();
                        return;
                    }

                    while (!q.isEmpty()) {
                        Coords node = q.peek();
                        q.poll();

                        int r = node.r;
                        int c = node.c;
                        for (int dir = 0; dir < 4; dir++) {
                            int r1 = r + dr[dir];
                            int c1 = c + dc[dir];
                            if (r1 >= 0 && r1 < n && c1 >= 0 && c1 < n) {
                                if (dsts[r1][c1].r < 0 && !filled[r1][c1]) {
                                    map[r1][c1] = rev[dir];
                                    filled[r1][c1] = true;
                                    q.add(new Coords(r1, c1));
                                }
                            }
                        }
                    }
                }
            }
        }

        pw.println("VALID");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                pw.print(chars[map[i][j]]);
            }
            pw.println();
        }

        pw.close();
    }

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


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.InputMismatchException;

/**
 * @author Mubtasim Shahriar
 */

public class NashMat {

	public static void main(String[] args) {

		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader sc = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Solver solver = new Solver();
//		int t = sc.nextInt();
		int t = 1;
		while(t--!=0) {
			solver.solve(sc, out);
		}
		out.close();

	}
	static int m = 1000+5;
	static char[][] mat = new char[m][m];
	static int[][] x = new int[m][m];
	static int[][] y = new int[m][m];

	static class Solver {
		public void solve(InputReader sc, PrintWriter out) {
			int n = sc.nextInt();
			for(char[] cr : mat) Arrays.fill(cr, '0');
			for(int i = 1; i <= n; i++) {
				for(int j = 1; j <= n; j++) {
					x[i][j] = sc.nextInt();
					y[i][j] = sc.nextInt();
				}
			}
			for(int i = 1; i <= n; i++) {
				for(int j = 1; j <= n; j++) {
					if(x[i][j]==-1) {
						boolean res = mat[i][j] != '0';
						if(!res) {
							res = connect(i,j,i+1,j,'D','U');
						}
						if(!res) {
							res = connect(i,j,i,j+1,'R','L');
						}
						if(!res) {
							res = connect(i,j,i-1,j,'U','D');
						}
						if(!res) {
							res = connect(i,j,i,j-1,'L','R');
						}
						if(!res) {
							out.println("INVALID");
							return;
						}
					} else if(x[i][j]==i && y[i][j]==j) {
						dfs(i,j,'X');
					}
				}
			}

			for(int i = 1; i <= n; i++) {
				for(int j = 1; j <= n; j++) {
					if(mat[i][j] == '0') {
						out.println("INVALID");
						return;
					}
				}
			}
			out.println("VALID");
			for(int i = 1; i <= n; i++) {
				for(int j = 1; j <= n; j++) {
					out.print(mat[i][j]);
				}
				out.println();
			}
		}

		private void dfs(int p, int q, char d) {
			if(mat[p][q] != '0') return;
			mat[p][q] = d;
			if(x[p][q] == x[p+1][q] && y[p][q]==y[p+1][q]) {
				dfs(p+1,q,'U');
			}
			if(x[p][q] == x[p-1][q] && y[p][q]==y[p-1][q]) {
				dfs(p-1,q,'D');
			}
			if(x[p][q] == x[p][q+1] && y[p][q]==y[p][q+1]) {
				dfs(p,q+1,'L');
			}
			if(x[p][q] == x[p][q-1] && y[p][q]==y[p][q-1]) {
				dfs(p,q-1,'R');
			}
		}

		private boolean connect(int p, int q, int r, int s, char d1, char d2) {
			if(x[r][s] == -1) {
				mat[p][q] = d1;
				if(mat[r][s] == '0') mat[r][s] = d2;
				return true;
			}
			return false;
		}
	}

	static class InputReader {
		private boolean finished = false;

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public 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++];
		}

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

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public String nextString() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				if (Character.isValidCodePoint(c)) {
					res.appendCodePoint(c);
				}
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private String readLine0() {
			StringBuilder buf = new StringBuilder();
			int c = read();
			while (c != '\n' && c != -1) {
				if (c != '\r') {
					buf.appendCodePoint(c);
				}
				c = read();
			}
			return buf.toString();
		}

		public String readLine() {
			String s = readLine0();
			while (s.trim().length() == 0) {
				s = readLine0();
			}
			return s;
		}

		public String readLine(boolean ignoreEmptyLines) {
			if (ignoreEmptyLines) {
				return readLine();
			} else {
				return readLine0();
			}
		}

		public BigInteger readBigInteger() {
			try {
				return new BigInteger(nextString());
			} catch (NumberFormatException e) {
				throw new InputMismatchException();
			}
		}

		public char nextCharacter() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			return (char) c;
		}

		public double nextDouble() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.') {
				if (c == 'e' || c == 'E') {
					return res * Math.pow(10, nextInt());
				}
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.') {
				c = read();
				double m = 1;
				while (!isSpaceChar(c)) {
					if (c == 'e' || c == 'E') {
						return res * Math.pow(10, nextInt());
					}
					if (c < '0' || c > '9') {
						throw new InputMismatchException();
					}
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

		public boolean isExhausted() {
			int value;
			while (isSpaceChar(value = peek()) && value != -1) {
				read();
			}
			return value == -1;
		}

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

		public SpaceCharFilter getFilter() {
			return filter;
		}

		public void setFilter(SpaceCharFilter filter) {
			this.filter = filter;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
		public int[] nextIntArray(int n){
			int[] array=new int[n];
			for(int i=0;i<n;++i)array[i]=nextInt();
			return array;
		}
		public int[] nextSortedIntArray(int n){
			int array[]=nextIntArray(n);
			Arrays.sort(array);
			return array;
		}
		public int[] nextSumIntArray(int n){
			int[] array=new int[n];
			array[0]=nextInt();
			for(int i=1;i<n;++i)array[i]=array[i-1]+nextInt();
			return array;
		}
		public long[] nextLongArray(int n){
			long[] array=new long[n];
			for(int i=0;i<n;++i)array[i]=nextLong();
			return array;
		}
		public long[] nextSumLongArray(int n){
			long[] array=new long[n];
			array[0]=nextInt();
			for(int i=1;i<n;++i)array[i]=array[i-1]+nextInt();
			return array;
		}
		public long[] nextSortedLongArray(int n){
			long array[]=nextLongArray(n);
			Arrays.sort(array);
			return array;
		}
	}

}


/*
javac d.java && java d
*/

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

public class d {
	public static void main(String[] args) { new d(); }
	FS in = new FS();
	PrintWriter out = new PrintWriter(System.out);

	int n;
	char[][] a;
	int[][][] e;
	boolean[][] block;

	int[] dx = {-1, 1, 0, 0};
	int[] dy = {0, 0, -1, 1};
	char[] u = {'D', 'U', 'R', 'L'};

	d() {
		n = in.nextInt();
		e = new int[n][n][2];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 0; k < 2; k++) {
					e[i][j][k] = in.nextInt();
					if (e[i][j][k] > 0)
						e[i][j][k]--;
				}
		a = new char[n][n];
		block = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				block[i][j] = i == e[i][j][0] && j == e[i][j][1];
				if (block[i][j])
					a[i][j] = 'X';
			}

		int N = n * n;
		int[] q = new int[N << 1];
		int l = 0, r = 0, x, nx, y, ny;
		boolean[][] v = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (block[i][j]) {
					l = 0; r = 0;
					q[r++] = i;
					q[r++] = j;
					v[i][j] = true;
					while (l != r) {
						x = q[l++];
						y = q[l++];
						for (int k = 0; k < 4; k++) {
							nx = x + dx[k];
							ny = y + dy[k];
							if (!bound(nx, ny))
								continue;
							if (v[nx][ny])
								continue;
							if (e[nx][ny][0] == i && e[nx][ny][1] == j) {
								v[nx][ny] = true;
								q[r++] = nx;
								q[r++] = ny;
								a[nx][ny] = u[k];
							}
						}
					}
				}

		boolean imp = true;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (e[i][j][0] == -1) {
					v[i][j] = true;
					boolean has = false;
					for (int k = 0; k < 4; k++) {
						nx = i + dx[k];
						ny = j + dy[k];
						if (!bound(nx, ny))
							continue;
						if (e[nx][ny][0] == -1) {
							has = true;
							a[i][j] = u[k ^ 1];
							break;
						}
					}
					imp &= has;
				}
		if (!imp) {
			out.println("INVALID");
			out.close();
			return;
		}
		out.println("VALID");
		for (char[] row : a)
			out.println(new String(row));
		out.close();
	}

	boolean bound(int x, int y) {
		return 0 <= x && x < n && 0 <= y && y < n;
	}

	int abs(int x) { return x < 0 ? -x : x; }
	long abs(long x) { return x < 0 ? -x : x; }
	double abs(double x) { return x < 0 ? -x : x; }
	int min(int x, int y) { return x < y ? x : y; }
	int max(int x, int y) { return x > y ? x : y; }
	long min(long x, long y) { return x < y ? x : y; }
	long max(long x, long y) { return x > y ? x : y; }
	double min(double x, double y) { return x < y ? x : y; }
	double max(double x, double y) { return x > y ? x : y; }
	int gcd(int x, int y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long gcd(long x, long y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long lcm(int x, int y) { return ((long) x / gcd(x, y)) * y; }
	long lcm(long x, long y) { return (x / gcd(x, y)) * y; }

	void sort(int[] arr) {
		int sz = arr.length, j;
		Random r = new Random();
		for (int i = 0; i < sz; i++) {
			j = r.nextInt(i + 1);
			arr[i] = arr[j]^(arr[i]^(arr[j] = arr[i]));
		} Arrays.sort(arr);
	}

	class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch (Exception e) {}
			} return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next()); }
		long nextLong() { return Long.parseLong(next()); }
		double nextDouble() { return Double.parseDouble(next()); }
	}
}


/*
javac d.java && java d
*/

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

public class d {
	public static void main(String[] args) { new d(); }
	FS in = new FS();
	PrintWriter out = new PrintWriter(System.out);

	int n;
	char[][] a;
	int[][][] e;
	boolean[][] block;

	int[] dx = {-1, 1, 0, 0};
	int[] dy = {0, 0, -1, 1};
	char[] u = {'D', 'U', 'R', 'L'};

	d() {
		n = in.nextInt();
		e = new int[n][n][2];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 0; k < 2; k++) {
					e[i][j][k] = in.nextInt();
					if (e[i][j][k] > 0)
						e[i][j][k]--;
				}
		a = new char[n][n];
		block = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				block[i][j] = i == e[i][j][0] && j == e[i][j][1];
				if (block[i][j])
					a[i][j] = 'X';
			}

		int nx, ny;
		boolean imp = true, can, yes;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				if (block[i][j])
					continue;
				can = false;
				for (int k = 0; k < 4; k++) {
					nx = i + dx[k];
					ny = j + dy[k];
					if (!bound(nx, ny))
						continue;
					yes = true;
					yes &= e[nx][ny][0] == e[i][j][0];
					yes &= e[nx][ny][1] == e[i][j][1];
					can |= yes;
				}
				imp &= can;
			}

		int N = n * n;
		int[] q = new int[N << 1];
		int l = 0, r = 0, x, y;
		boolean[][] v = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (block[i][j]) {
					l = 0; r = 0;
					q[r++] = i;
					q[r++] = j;
					v[i][j] = true;
					while (l != r) {
						x = q[l++];
						y = q[l++];
						for (int k = 0; k < 4; k++) {
							nx = x + dx[k];
							ny = y + dy[k];
							if (!bound(nx, ny))
								continue;
							if (v[nx][ny])
								continue;
							if (e[nx][ny][0] == i && e[nx][ny][1] == j) {
								q[r++] = nx;
								q[r++] = ny;
								a[nx][ny] = u[k];
								v[nx][ny] = true;
							}
						}
					}
				}

		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (e[i][j][0] == -1) {
					for (int k = 0; k < 4; k++) {
						nx = i + dx[k];
						ny = j + dy[k];
						if (!bound(nx, ny))
							continue;
						if (e[nx][ny][0] == -1) {
							a[i][j] = u[k ^ 1];
							break;
						}
					}
				}

		if (!imp) {
			out.println("INVALID");
			out.close();
			return;
		}
		out.println("VALID");
		for (char[] row : a)
			out.println(new String(row));
		out.close();
	}

	boolean bound(int x, int y) {
		return 0 <= x && x < n && 0 <= y && y < n;
	}

	int abs(int x) { return x < 0 ? -x : x; }
	long abs(long x) { return x < 0 ? -x : x; }
	double abs(double x) { return x < 0 ? -x : x; }
	int min(int x, int y) { return x < y ? x : y; }
	int max(int x, int y) { return x > y ? x : y; }
	long min(long x, long y) { return x < y ? x : y; }
	long max(long x, long y) { return x > y ? x : y; }
	double min(double x, double y) { return x < y ? x : y; }
	double max(double x, double y) { return x > y ? x : y; }
	int gcd(int x, int y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long gcd(long x, long y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long lcm(int x, int y) { return ((long) x / gcd(x, y)) * y; }
	long lcm(long x, long y) { return (x / gcd(x, y)) * y; }

	void sort(int[] arr) {
		int sz = arr.length, j;
		Random r = new Random();
		for (int i = 0; i < sz; i++) {
			j = r.nextInt(i + 1);
			arr[i] = arr[j]^(arr[i]^(arr[j] = arr[i]));
		} Arrays.sort(arr);
	}

	class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch (Exception e) {}
			} return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next()); }
		long nextLong() { return Long.parseLong(next()); }
		double nextDouble() { return Double.parseDouble(next()); }
	}
}


/*
javac d.java && java d
*/

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

public class d {
	public static void main(String[] args) { new d(); }
	FS in = new FS();
	PrintWriter out = new PrintWriter(System.out);

	int n;
	char[][] a;
	int[][][] e;
	boolean[][] block;

	int[] dx = {-1, 1, 0, 0};
	int[] dy = {0, 0, -1, 1};
	char[] u = {'D', 'U', 'R', 'L'};

	d() {
		n = in.nextInt();
		e = new int[n][n][2];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 0; k < 2; k++) {
					e[i][j][k] = in.nextInt();
					if (e[i][j][k] > 0)
						e[i][j][k]--;
				}
		a = new char[n][n];
		block = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				block[i][j] = i == e[i][j][0] && j == e[i][j][1];
				if (block[i][j])
					a[i][j] = 'X';
			}

		int nx, ny;
		boolean imp = true, can, yes;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				if (block[i][j])
					continue;
				can = false;
				for (int k = 0; k < 4; k++) {
					nx = i + dx[k];
					ny = j + dy[k];
					if (!bound(nx, ny))
						continue;
					yes = true;
					yes &= e[nx][ny][0] == e[i][j][0];
					yes &= e[nx][ny][1] == e[i][j][1];
					can |= yes;
				}
				imp &= can;
			}

		int N = n * n;
		int[] q = new int[N << 1];
		int l = 0, r = 0, x, y;
		boolean[][] v = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (block[i][j]) {
					l = 0; r = 0;
					q[r++] = i;
					q[r++] = j;
					v[i][j] = true;
					while (l != r) {
						x = q[l++];
						y = q[l++];
						for (int k = 0; k < 4; k++) {
							nx = x + dx[k];
							ny = y + dy[k];
							if (!bound(nx, ny))
								continue;
							if (v[nx][ny])
								continue;
							if (e[nx][ny][0] == i && e[nx][ny][1] == j) {
								q[r++] = nx;
								q[r++] = ny;
								a[nx][ny] = u[k];
								v[nx][ny] = true;
							}
						}
					}
				}
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (!v[i][j]) {
					yes = true;
					yes &= e[i][j][0] != -1;
					yes &= e[i][j][1] != -1;
					if (yes)
						imp = true;
				}

		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (e[i][j][0] == -1) {
					for (int k = 0; k < 4; k++) {
						nx = i + dx[k];
						ny = j + dy[k];
						if (!bound(nx, ny))
							continue;
						if (e[nx][ny][0] == -1) {
							a[i][j] = u[k ^ 1];
							break;
						}
					}
				}

		if (!imp) {
			out.println("INVALID");
			out.close();
			return;
		}
		out.println("VALID");
		for (char[] row : a)
			out.println(new String(row));
		out.close();
	}

	boolean bound(int x, int y) {
		return 0 <= x && x < n && 0 <= y && y < n;
	}

	int abs(int x) { return x < 0 ? -x : x; }
	long abs(long x) { return x < 0 ? -x : x; }
	double abs(double x) { return x < 0 ? -x : x; }
	int min(int x, int y) { return x < y ? x : y; }
	int max(int x, int y) { return x > y ? x : y; }
	long min(long x, long y) { return x < y ? x : y; }
	long max(long x, long y) { return x > y ? x : y; }
	double min(double x, double y) { return x < y ? x : y; }
	double max(double x, double y) { return x > y ? x : y; }
	int gcd(int x, int y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long gcd(long x, long y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long lcm(int x, int y) { return ((long) x / gcd(x, y)) * y; }
	long lcm(long x, long y) { return (x / gcd(x, y)) * y; }

	void sort(int[] arr) {
		int sz = arr.length, j;
		Random r = new Random();
		for (int i = 0; i < sz; i++) {
			j = r.nextInt(i + 1);
			arr[i] = arr[j]^(arr[i]^(arr[j] = arr[i]));
		} Arrays.sort(arr);
	}

	class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch (Exception e) {}
			} return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next()); }
		long nextLong() { return Long.parseLong(next()); }
		double nextDouble() { return Double.parseDouble(next()); }
	}
}


/*
javac d.java && java d
*/

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

public class d {
	public static void main(String[] args) { new d(); }
	FS in = new FS();
	PrintWriter out = new PrintWriter(System.out);

	int n;
	char[][] a;
	int[][][] e;
	boolean[][] block;

	int[] dx = {-1, 1, 0, 0};
	int[] dy = {0, 0, -1, 1};
	char[] u = {'D', 'U', 'R', 'L'};

	d() {
		n = in.nextInt();
		e = new int[n][n][2];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 0; k < 2; k++) {
					e[i][j][k] = in.nextInt();
					if (e[i][j][k] > 0)
						e[i][j][k]--;
				}
		a = new char[n][n];
		block = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				block[i][j] = i == e[i][j][0] && j == e[i][j][1];
				if (block[i][j])
					a[i][j] = 'X';
			}

		int nx, ny;
		boolean imp = true, can, yes;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				if (block[i][j])
					continue;
				can = false;
				for (int k = 0; k < 4; k++) {
					nx = i + dx[k];
					ny = j + dy[k];
					if (!bound(nx, ny))
						continue;
					yes = true;
					yes &= e[nx][ny][0] == e[i][j][0];
					yes &= e[nx][ny][1] == e[i][j][1];
					can |= yes;
				}
				imp &= can;
			}

		int N = n * n;
		int[] q = new int[N << 1];
		int l = 0, r = 0, x, y;
		boolean[][] v = new boolean[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (block[i][j]) {
					l = 0; r = 0;
					q[r++] = i;
					q[r++] = j;
					v[i][j] = true;
					while (l != r) {
						x = q[l++];
						y = q[l++];
						for (int k = 0; k < 4; k++) {
							nx = x + dx[k];
							ny = y + dy[k];
							if (!bound(nx, ny))
								continue;
							if (v[nx][ny])
								continue;
							if (e[nx][ny][0] == i && e[nx][ny][1] == j) {
								q[r++] = nx;
								q[r++] = ny;
								a[nx][ny] = u[k];
								v[nx][ny] = true;
							}
						}
					}
				}
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (!v[i][j]) {
					yes = true;
					yes &= e[i][j][0] != -1;
					yes &= e[i][j][1] != -1;
					if (yes)
						imp = false;
				}

		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				if (e[i][j][0] == -1) {
					for (int k = 0; k < 4; k++) {
						nx = i + dx[k];
						ny = j + dy[k];
						if (!bound(nx, ny))
							continue;
						if (e[nx][ny][0] == -1) {
							a[i][j] = u[k ^ 1];
							break;
						}
					}
				}

		if (!imp) {
			out.println("INVALID");
			out.close();
			return;
		}
		out.println("VALID");
		for (char[] row : a)
			out.println(new String(row));
		out.close();
	}

	boolean bound(int x, int y) {
		return 0 <= x && x < n && 0 <= y && y < n;
	}

	int abs(int x) { return x < 0 ? -x : x; }
	long abs(long x) { return x < 0 ? -x : x; }
	double abs(double x) { return x < 0 ? -x : x; }
	int min(int x, int y) { return x < y ? x : y; }
	int max(int x, int y) { return x > y ? x : y; }
	long min(long x, long y) { return x < y ? x : y; }
	long max(long x, long y) { return x > y ? x : y; }
	double min(double x, double y) { return x < y ? x : y; }
	double max(double x, double y) { return x > y ? x : y; }
	int gcd(int x, int y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long gcd(long x, long y) { while (y > 0) { x = y^(x^(y = x)); y %= x; } return x; }
	long lcm(int x, int y) { return ((long) x / gcd(x, y)) * y; }
	long lcm(long x, long y) { return (x / gcd(x, y)) * y; }

	void sort(int[] arr) {
		int sz = arr.length, j;
		Random r = new Random();
		for (int i = 0; i < sz; i++) {
			j = r.nextInt(i + 1);
			arr[i] = arr[j]^(arr[i]^(arr[j] = arr[i]));
		} Arrays.sort(arr);
	}

	class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch (Exception e) {}
			} return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next()); }
		long nextLong() { return Long.parseLong(next()); }
		double nextDouble() { return Double.parseDouble(next()); }
	}
}


import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Scanner;

public class ProblemE {

    public static InputStream inputStream = System.in;

    public static OutputStream outputStream = System.out;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int n = scanner.nextInt();
        int[][] matrix = new int[n + 1][n + 1];
        boolean[][] visited = new boolean[n + 1][n + 1];
        Pair<Integer, Integer>[][] pairs = new Pair[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                int x = scanner.nextInt();
                int y = scanner.nextInt();
                pairs[i][j] = new Pair<>(x, y);
            }
        }

        boolean cant = false;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (!visited[i][j]) {
                    int x = pairs[i][j].first;
                    int y = pairs[i][j].second;
                    if (x != -1) {
                        Pair<Integer, Integer> root = new Pair<>(x, y);
                        if (!pairs[x][y].equals(root)) {
                            cant = true;
                            break;
                        }
                        if (visited[x][y]) {
                            cant = true;
                            break;
                        }
                        LinkedList<Pair<Integer, Integer>> toVisit = new LinkedList<>();
                        toVisit.add(root);
                        visited[x][y] = true;
                        matrix[x][y] = -1;
                        while (!toVisit.isEmpty()) {
                            Pair<Integer, Integer> node = toVisit.poll();
                            if (node.first != 1 && pairs[node.first - 1][node.second].equals(root) && !visited[node.first - 1][node.second]) {
                                matrix[node.first - 1][node.second] = 2;
                                toVisit.add(new Pair<>(node.first - 1, node.second));
                                visited[node.first - 1][node.second] = true;
                            }
                            if (node.first != n && pairs[node.first + 1][node.second].equals(root) && !visited[node.first + 1][node.second]) {
                                matrix[node.first + 1][node.second] = 1;
                                toVisit.add(new Pair<>(node.first + 1, node.second));
                                visited[node.first + 1][node.second] = true;
                            }
                            if (node.second != 1 && pairs[node.first][node.second - 1].equals(root) && !visited[node.first][node.second - 1]) {
                                matrix[node.first][node.second - 1] = 4;
                                toVisit.add(new Pair<>(node.first, node.second - 1));
                                visited[node.first][node.second - 1] = true;
                            }
                            if (node.second != n && pairs[node.first][node.second + 1].equals(root) && !visited[node.first][node.second + 1]) {
                                matrix[node.first][node.second + 1] = 3;
                                toVisit.add(new Pair<>(node.first, node.second + 1));
                                visited[node.first][node.second + 1] = true;
                            }
                        }
                    }
                }
            }
            if (cant) {
                break;
            }
        }

        Pair<Integer, Integer> minusPair = new Pair<>(-1, -1);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (pairs[i][j].first == -1) {
                    if (i != 1 && minusPair.equals(pairs[i - 1][j])) {
                        matrix[i][j] = 1;
                        continue;
                    }
                    if (i != n && minusPair.equals(pairs[i + 1][j])) {
                        matrix[i][j] = 2;
                        continue;
                    }
                    if (j != 1 && minusPair.equals(pairs[i][j - 1])) {
                        matrix[i][j] = 3;
                        continue;
                    }
                    if (j != n && minusPair.equals(pairs[i][j + 1])) {
                        matrix[i][j] = 4;
                        continue;
                    }
                    cant = true;
                    break;
                }
            }
            if (cant) {
                break;
            }
        }

        if (cant) {
            out.println("INVALID");
        } else {
            out.println("VALID");
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (matrix[i][j] == -1) {
                        out.print("X");
                    }
                    if (matrix[i][j] == 1) {
                        out.print("U");
                    }
                    if (matrix[i][j] == 2) {
                        out.print("D");
                    }
                    if (matrix[i][j] == 3) {
                        out.print("L");
                    }
                    if (matrix[i][j] == 4) {
                        out.print("R");
                    }
                }
                out.println();
            }
        }

        out.flush();
    }

    private static class Pair<F, S> {

        private F first;

        private S second;

        public Pair() {}

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(first, pair.first) &&
                    Objects.equals(second, pair.second);
        }

        @Override
        public int hashCode() {
            return Objects.hash(first, second);
        }
    }
}


import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.Scanner;

public class ProblemE {

    public static InputStream inputStream = System.in;

    public static OutputStream outputStream = System.out;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int n = scanner.nextInt();
        int[][] matrix = new int[n + 1][n + 1];
        Pair<Integer, Integer>[][] pairs = new Pair[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                int x = scanner.nextInt();
                int y = scanner.nextInt();
                pairs[i][j] = new Pair<>(x, y);
            }
        }

        boolean cant = false;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {

                if (i == pairs[i][j].first && j == pairs[i][j].second) {
                    matrix[i][j] = -1;
                    continue;
                }
                if (i != 1 && pairs[i][j].equals(pairs[i - 1][j])) {
                    matrix[i][j] = 1;
                    continue;
                }
                if (i != n && pairs[i][j].equals(pairs[i + 1][j])) {
                    matrix[i][j] = 2;
                    continue;
                }
                if (j != 1 && pairs[i][j].equals(pairs[i][j - 1])) {
                    matrix[i][j] = 3;
                    continue;
                }
                if (j != n && pairs[i][j].equals(pairs[i][j + 1])) {
                    matrix[i][j] = 4;
                    continue;
                }
                cant = true;
                break;
            }
            if (cant) {
                break;
            }
        }

        if (cant) {
            out.println("INVALID");
        } else {
            out.println("VALID");
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (matrix[i][j] == -1) {
                        out.print("X");
                    }
                    if (matrix[i][j] == 1) {
                        out.print("U");
                    }
                    if (matrix[i][j] == 2) {
                        out.print("D");
                    }
                    if (matrix[i][j] == 3) {
                        out.print("L");
                    }
                    if (matrix[i][j] == 4) {
                        out.print("R");
                    }
                }
                out.println();
            }
        }

        out.flush();
    }

    private static class Pair<F, S> {

        private F first;

        private S second;

        public Pair() {}

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(first, pair.first) &&
                    Objects.equals(second, pair.second);
        }

        @Override
        public int hashCode() {
            return Objects.hash(first, second);
        }
    }
}


import java.io.*;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Scanner;
import java.util.StringTokenizer;

public class ProblemE {

    public static InputStream inputStream = System.in;

    public static OutputStream outputStream = System.out;

    public static void main(String[] args) {
        MyScanner scanner = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int n = scanner.nextInt();
        int[][] matrix = new int[n + 1][n + 1];
        boolean[][] visited = new boolean[n + 1][n + 1];
        Pair<Integer, Integer>[][] pairs = new Pair[n + 1][n + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                int x = scanner.nextInt();
                int y = scanner.nextInt();
                pairs[i][j] = new Pair<>(x, y);
            }
        }

        boolean cant = false;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (!visited[i][j]) {
                    int x = pairs[i][j].first;
                    int y = pairs[i][j].second;
                    if (x != -1) {
                        Pair<Integer, Integer> root = new Pair<>(x, y);
                        if (!pairs[x][y].equals(root)) {
                            cant = true;
                            break;
                        }
                        if (visited[x][y]) {
                            cant = true;
                            break;
                        }
                        LinkedList<Pair<Integer, Integer>> toVisit = new LinkedList<>();
                        toVisit.add(root);
                        visited[x][y] = true;
                        matrix[x][y] = -1;
                        while (!toVisit.isEmpty()) {
                            Pair<Integer, Integer> node = toVisit.poll();
                            if (node.first != 1 && pairs[node.first - 1][node.second].equals(root) && !visited[node.first - 1][node.second]) {
                                matrix[node.first - 1][node.second] = 2;
                                toVisit.add(new Pair<>(node.first - 1, node.second));
                                visited[node.first - 1][node.second] = true;
                            }
                            if (node.first != n && pairs[node.first + 1][node.second].equals(root) && !visited[node.first + 1][node.second]) {
                                matrix[node.first + 1][node.second] = 1;
                                toVisit.add(new Pair<>(node.first + 1, node.second));
                                visited[node.first + 1][node.second] = true;
                            }
                            if (node.second != 1 && pairs[node.first][node.second - 1].equals(root) && !visited[node.first][node.second - 1]) {
                                matrix[node.first][node.second - 1] = 4;
                                toVisit.add(new Pair<>(node.first, node.second - 1));
                                visited[node.first][node.second - 1] = true;
                            }
                            if (node.second != n && pairs[node.first][node.second + 1].equals(root) && !visited[node.first][node.second + 1]) {
                                matrix[node.first][node.second + 1] = 3;
                                toVisit.add(new Pair<>(node.first, node.second + 1));
                                visited[node.first][node.second + 1] = true;
                            }
                        }
                    }
                }
            }
            if (cant) {
                break;
            }
        }

        Pair<Integer, Integer> minusPair = new Pair<>(-1, -1);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (pairs[i][j].first == -1) {
                    if (i != 1 && minusPair.equals(pairs[i - 1][j])) {
                        matrix[i][j] = 1;
                        continue;
                    }
                    if (i != n && minusPair.equals(pairs[i + 1][j])) {
                        matrix[i][j] = 2;
                        continue;
                    }
                    if (j != 1 && minusPair.equals(pairs[i][j - 1])) {
                        matrix[i][j] = 3;
                        continue;
                    }
                    if (j != n && minusPair.equals(pairs[i][j + 1])) {
                        matrix[i][j] = 4;
                        continue;
                    }
                    cant = true;
                    break;
                }
            }
            if (cant) {
                break;
            }
        }

        if (cant) {
            out.println("INVALID");
        } else {
            out.println("VALID");
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (matrix[i][j] == -1) {
                        out.print("X");
                    }
                    if (matrix[i][j] == 1) {
                        out.print("U");
                    }
                    if (matrix[i][j] == 2) {
                        out.print("D");
                    }
                    if (matrix[i][j] == 3) {
                        out.print("L");
                    }
                    if (matrix[i][j] == 4) {
                        out.print("R");
                    }
                }
                out.println();
            }
        }

        out.flush();
    }

    private static class Pair<F, S> {

        private F first;

        private S second;

        public Pair() {}

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(first, pair.first) &&
                    Objects.equals(second, pair.second);
        }

        @Override
        public int hashCode() {
            return Objects.hash(first, second);
        }
    }

    private static class MyScanner {
        private BufferedReader bufferedReader;
        private StringTokenizer stringTokenizer;

        private MyScanner(InputStream inputStream) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        }

        private String next() {
            while (stringTokenizer == null || !stringTokenizer.hasMoreElements()) {
                try {
                    stringTokenizer = new StringTokenizer(bufferedReader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return stringTokenizer.nextToken();
        }

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

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

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

        private String nextLine(){
            String str = "";
            try {
                str = bufferedReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}


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

public class Main {
    static PrintWriter out = new PrintWriter(System.out);
    static Scanner sc = new Scanner(System.in);
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    int[] dr = new int[]{1,0,-1,0}, dc = new int[]{0,1,0,-1};
    char[] dirFrom = new char[]{'U','L','D','R'}; // here the char in dirFrom is to be written in TARGET cell
    char[] dirTo = new char[]{'D','R','U','L'};
    public static void main(String[] args) throws IOException {
        Main main = new Main();
        main.solve();
        out.flush();
//        main.solve();
//        System.out.println(main.solve());
    }
    void solve() throws IOException{
        String[] buf = reader.readLine().split(" ");
        int n = Integer.parseInt(buf[0]);
        int[][][] end = new int[n][n][];
        List<int[]>[][] sameEnd = new List[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++) sameEnd[i][j] = new ArrayList<>();
        }
        for(int i=0;i<n;i++){
            buf = reader.readLine().split(" ");
            for(int j=0;j<n;j++){
                int rend = Integer.parseInt(buf[2*j])-1, cend = Integer.parseInt(buf[2*j+1])-1;
                end[i][j] = new int[]{rend,cend};
                // if not infinite loop
                if(rend>=0&&cend>=0) sameEnd[rend][cend].add(new int[]{i,j});
            }
        }
        // first check
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(sameEnd[i][j].size()>0){
                    if(end[i][j][0]!=i||end[i][j][1]!=j){
                        out.println("INVALID");
                        return;
                    }
                }
            }
        }
        char[][] res = new char[n][n];
        boolean[][] vis = new boolean[n][n];
        // firstly handle the end case
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(end[i][j][0]!=i||end[i][j][1]!=j) continue; // this is not an end that we want
                int temp = singleSource(n,end,sameEnd[i][j],i,j,res,vis);
                if(temp<0){
                    out.println("INVALID");
                    return;
                }
            }
        }
        // Then the infinite loops
        // all the non loop cells should have been visited
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(end[i][j][0]>=0) continue;
                // since they are loops. overwriting doesn't matter
                boolean flag = false;
                for(int k=0;k<4&&(!flag);k++){
                    int r=i+dr[k], c=j+dc[k];
                    if(r<0||r>=n||c<0||c>=n||end[r][c][0]>=-1) continue;
                    flag = true;
                    res[i][j] = dirTo[k];
                }
                if(!flag){
                    out.println("INVALID"); return;
                }
            }
        }
        out.println("VALID");
        for(int i=0;i<n;i++){
            StringBuilder sb = new StringBuilder();
            for(int j=0;j<n;j++) sb.append(res[i][j]);
            out.println(sb.toString());
        }
    }
    int singleSource(int n, int[][][] end, List<int[]> sameEnd, int sR, int sC, char[][] res, boolean[][] vis){
        List<int[]> cur = new LinkedList<>(), next = new LinkedList<>();
        cur.add(new int[]{sR,sC}); vis[sR][sC] = true; res[sR][sC] = 'X';
        while(cur.size()>0){
            for(int[] now:cur){
                int r0 = now[0], c0 = now[1];
                // look upwards
                for(int k=0;k<4;k++){
                    int r = r0+dr[k], c = c0+dc[k];
                    if(r<0||r>=n||c<0||c>=n||vis[r][c]) continue;
                    if(end[r][c][0]!=sR||end[r][c][1]!=sC) continue;
                    vis[r][c] = true;
                    next.add(new int[]{r,c});
                    res[r][c] = dirFrom[k];
                }
            }
            cur = next; next = new LinkedList<>();
        }
        for(int[] cell:sameEnd){
            if(!vis[cell[0]][cell[1]]) return -1;
        }
        return 1;
    }
}


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

public class Main {
    static PrintWriter out = new PrintWriter(System.out);
    static Scanner sc = new Scanner(System.in);
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    int[] dr = new int[]{1,0,-1,0}, dc = new int[]{0,1,0,-1};
    char[] dirFrom = new char[]{'U','L','D','R'}; // here the char in dirFrom is to be written in TARGET cell
    char[] dirTo = new char[]{'D','R','U','L'};
    public static void main(String[] args) throws IOException {
        Main main = new Main();
        main.solve();
        out.flush();
//        main.solve();
//        System.out.println(main.solve());
    }
    void solve() throws IOException{
        int n = sc.nextInt();
        int[][][] end = new int[n][n][];
        List<int[]>[][] sameEnd = new List[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++) sameEnd[i][j] = new ArrayList<>();
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int rend = sc.nextInt()-1, cend = sc.nextInt()-1;
                end[i][j] = new int[]{rend,cend};
                // if not infinite loop
                if(rend>=0&&cend>=0) sameEnd[rend][cend].add(new int[]{i,j});
            }
        }
        // first check
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(sameEnd[i][j].size()>0){
                    if(end[i][j][0]!=i||end[i][j][1]!=j){
                        out.println("INVALID");
                        return;
                    }
                }
            }
        }
        char[][] res = new char[n][n];
        boolean[][] vis = new boolean[n][n];
        // firstly handle the end case
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(end[i][j][0]!=i||end[i][j][1]!=j) continue; // this is not an end that we want
                int temp = singleSource(n,end,sameEnd[i][j],i,j,res,vis);
                if(temp<0){
                    out.println("INVALID");
                    return;
                }
            }
        }
        // Then the infinite loops
        // all the non loop cells should have been visited
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(end[i][j][0]>=0) continue;
                // since they are loops. overwriting doesn't matter
                boolean flag = false;
                for(int k=0;k<4&&(!flag);k++){
                    int r=i+dr[k], c=j+dc[k];
                    if(r<0||r>=n||c<0||c>=n||end[r][c][0]>=-1) continue;
                    flag = true;
                    res[i][j] = dirTo[k];
                }
                if(!flag){
                    out.println("INVALID"); return;
                }
            }
        }
        out.println("VALID");
        for(int i=0;i<n;i++){
            StringBuilder sb = new StringBuilder();
            for(int j=0;j<n;j++) sb.append(res[i][j]);
            out.println(sb.toString());
        }
    }
    int singleSource(int n, int[][][] end, List<int[]> sameEnd, int sR, int sC, char[][] res, boolean[][] vis){
        List<int[]> cur = new LinkedList<>(), next = new LinkedList<>();
        cur.add(new int[]{sR,sC}); vis[sR][sC] = true; res[sR][sC] = 'X';
        while(cur.size()>0){
            for(int[] now:cur){
                int r0 = now[0], c0 = now[1];
                // look upwards
                for(int k=0;k<4;k++){
                    int r = r0+dr[k], c = c0+dc[k];
                    if(r<0||r>=n||c<0||c>=n||vis[r][c]) continue;
                    if(end[r][c][0]!=sR||end[r][c][1]!=sC) continue;
                    vis[r][c] = true;
                    next.add(new int[]{r,c});
                    res[r][c] = dirFrom[k];
                }
            }
            cur = next; next = new LinkedList<>();
        }
        for(int[] cell:sameEnd){
            if(!vis[cell[0]][cell[1]]) return -1;
        }
        return 1;
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {

	private static final int MAXN = 5000;
	private static final String NO = "NO";
	private static final String YES = "YES";
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long MOD = 1000000007L;
	private static final long MAX = Long.MAX_VALUE / 2;

	void solve() {
		int N = ni();
		int[][][] a = new int[N][N][];
		char[][] ans = new char[N][N];
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++)
				a[r][c] = new int[] { ni(), ni() };

		int dirs[][] = new int[][] { { 1, 0, 'U', 'D' }, { -1, 0, 'D', 'U' }, { 0, 1, 'L', 'R' }, { 0, -1, 'R', 'L' } };
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++) {
				if (a[r][c][0] == r + 1 && a[r][c][1] == c + 1) {
					ans[r][c] = 'X';
					ArrayDeque<int[]> q = new ArrayDeque<int[]>();
					q.add(new int[] { r, c, (r + 1) * N + (c + 1) });
					while (!q.isEmpty()) {
						int p[] = q.poll();
						for (int d[] : dirs) {
							int[] p2 = new int[] { p[0] + d[0], p[1] + d[1] };
							if (p2[0] >= 0 && p2[0] < N && p2[1] >= 0 && p2[1] < N
									&& a[p2[0]][p2[1]][0] * N + a[p2[0]][p2[1]][1] == p[2]
									&& ans[p2[0]][p2[1]] == '\0') {
								ans[p2[0]][p2[1]] = (char) d[2];
								q.add(new int[] { p2[0], p2[1], p[2] });
							}
						}
					}
				}
			}
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++) {
				if (a[r][c][0] == -1 && ans[r][c] == '\0') {
					for (int d[] : dirs) {
						int[] p2 = new int[] { r + d[0], c + d[1] };
						if (p2[0] >= 0 && p2[0] < N && p2[1] >= 0 && p2[1] < N && a[p2[0]][p2[1]][0] == -1)
							if (ans[p2[0]][p2[1]] != '\0')
								ans[p2[0]][p2[1]] = (char) d[2];
						ans[r][c] = (char) d[3];
					}
				}
				if (ans[r][c] == '\0') {
					out.println("INVALID");
					return;
				}
			}

		out.println("VALID");
		for (int r = 0; r < N; r++)
			out.println(new String(ans[r]));
	}

	long power(long a, long b) {
		long x = 1, y = a;
		while (b > 0) {
			if (b % 2 != 0) {
				x = (x * y) % MOD;
			}
			y = (y * y) % MOD;
			b /= 2;
		}
		return x % MOD;
	}

	private long gcd(long a, long b) {
		while (a != 0) {
			long tmp = b % a;
			b = a;
			a = tmp;
		}
		return b;
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	private boolean vis[];

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private Integer[] na2(int n) {
		Integer[] a = new Integer[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private Integer[][] na2(int n, int m) {
		Integer[][] a = new Integer[n][];
		for (int i = 0; i < n; i++)
			a[i] = na2(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long[] nl(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {

	private static final int MAXN = 5000;
	private static final String NO = "NO";
	private static final String YES = "YES";
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long MOD = 1000000007L;
	private static final long MAX = Long.MAX_VALUE / 2;

	void solve() {
		int N = ni();
		int[][][] a = new int[N][N][];
		char[][] ans = new char[N][N];
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++)
				a[r][c] = new int[] { ni(), ni() };

		int dirs[][] = new int[][] { { 1, 0, 'U', 'D' }, { -1, 0, 'D', 'U' }, { 0, 1, 'L', 'R' }, { 0, -1, 'R', 'L' } };
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++) {
				if (a[r][c][0] == r + 1 && a[r][c][1] == c + 1) {
					ans[r][c] = 'X';
					ArrayDeque<int[]> q = new ArrayDeque<int[]>();
					q.add(new int[] { r, c, (r + 1) * N + (c + 1) });
					while (!q.isEmpty()) {
						int p[] = q.poll();
						for (int d[] : dirs) {
							int[] p2 = new int[] { p[0] + d[0], p[1] + d[1] };
							if (p2[0] >= 0 && p2[0] < N && p2[1] >= 0 && p2[1] < N
									&& a[p2[0]][p2[1]][0] * N + a[p2[0]][p2[1]][1] == p[2]
									&& ans[p2[0]][p2[1]] == '\0') {
								ans[p2[0]][p2[1]] = (char) d[2];
								q.add(new int[] { p2[0], p2[1], p[2] });
							}
						}
					}
				}
			}
		for (int r = 0; r < N; r++)
			for (int c = 0; c < N; c++) {
				if (a[r][c][0] == -1 && ans[r][c] == '\0') {
					for (int d[] : dirs) {
						int[] p2 = new int[] { r + d[0], c + d[1] };
						if (p2[0] >= 0 && p2[0] < N && p2[1] >= 0 && p2[1] < N && a[p2[0]][p2[1]][0] == -1) {
							if (ans[p2[0]][p2[1]] != '\0')
								ans[p2[0]][p2[1]] = (char) d[2];
							ans[r][c] = (char) d[3];
						}
					}
				}
				if (ans[r][c] == '\0') {
					out.println("INVALID");
					return;
				}
			}

		out.println("VALID");
		for (int r = 0; r < N; r++)
			out.println(new String(ans[r]));
	}

	long power(long a, long b) {
		long x = 1, y = a;
		while (b > 0) {
			if (b % 2 != 0) {
				x = (x * y) % MOD;
			}
			y = (y * y) % MOD;
			b /= 2;
		}
		return x % MOD;
	}

	private long gcd(long a, long b) {
		while (a != 0) {
			long tmp = b % a;
			b = a;
			a = tmp;
		}
		return b;
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	private boolean vis[];

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private Integer[] na2(int n) {
		Integer[] a = new Integer[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private Integer[][] na2(int n, int m) {
		Integer[][] a = new Integer[n][];
		for (int i = 0; i < n; i++)
			a[i] = na2(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long[] nl(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


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

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

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	int[][] dir= {{0,1},{1,0},{-1,0},{0,-1}};
	int[][][] A;
	char[][] ret;
	int n;
	void work() {
		n=ni();
		ret=new char[n][n];
		for(char[] chs:ret) {
			Arrays.fill(chs, 'N');
		}
		A=new int[n][n][];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				A[i][j]=new int[] {in.nextInt()-1,in.nextInt()-1};
			}
		}
		boolean[][] vis=new boolean[n][n];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==i&&A[i][j][1]==j) {
					ret[i][j]='X';
					dfs1(i,j,i,j,vis);
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]!=-2&&!vis[i][j]) {
					out.println("INVALID");
					return;
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==-2) {
					boolean f=false;
					for(int k=0;k<4;k++) {
						int ni=i+dir[k][0],nj=j+dir[k][1];
						if(ni<0||ni>=n||nj<0||nj>=n)continue;
						f=true;
					}
					if(!f) {
						out.println("INVALID");
						return;
					}
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(!vis[i][j]) {
					dfs2(i,j,vis);
				}
			}
		}
		out.println("VALID");
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				out.print(ret[i][j]);
			}
			out.println();
		}
	}

	private void dfs2(int x, int y, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
				if(ret[x][y]=='N') ret[x][y]='R';
			}else if(i==1) {
				ret[nx][ny]='U';
				if(ret[x][y]=='N') ret[x][y]='D';
			}else if(i==2) {
				ret[nx][ny]='D';
				if(ret[x][y]=='N') ret[x][y]='U';
			}else {
				ret[nx][ny]='R';
				if(ret[x][y]=='N') ret[x][y]='L';
			}
			dfs2(nx,ny,vis);
		}
	}

	private void dfs1(int x, int y, int rx, int ry, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||A[nx][ny][0]!=rx||A[nx][ny][1]!=ry||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
			}else if(i==1) {
				ret[nx][ny]='U';
			}else if(i==2) {
				ret[nx][ny]='D';
			}else {
				ret[nx][ny]='R';
			}
			dfs1(nx,ny,rx,ry,vis);
		}
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		while(st==null || !st.hasMoreElements())//回车，空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

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


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

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

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	int[][] dir= {{0,1},{1,0},{-1,0},{0,-1}};
	int[][][] A;
	char[][] ret;
	int n;
	void work() {
		n=ni();
		ret=new char[n][n];
		for(char[] chs:ret) {
			Arrays.fill(chs, 'N');
		}
		A=new int[n][n][];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				A[i][j]=new int[] {in.nextInt()-1,in.nextInt()-1};
			}
		}
		boolean[][] vis=new boolean[n][n];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==i&&A[i][j][1]==j) {
					ret[i][j]='X';
					dfs1(i,j,i,j,vis);
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]!=-2&&!vis[i][j]) {
					out.println("INVALID");
					return;
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==-2) {
					boolean f=false;
					for(int k=0;k<4;k++) {
						int ni=i+dir[k][0],nj=j+dir[k][1];
						if(ni<0||ni>=n||nj<0||nj>=n||A[ni][nj][0]!=-2)continue;
						f=true;
					}
					if(!f) {
						out.println("INVALID");
						return;
					}
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(!vis[i][j]) {
					dfs2(i,j,vis);
				}
			}
		}
		out.println("VALID");
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				out.print(ret[i][j]);
			}
			out.println();
		}
	}

	private void dfs2(int x, int y, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
				if(ret[x][y]=='N') ret[x][y]='R';
			}else if(i==1) {
				ret[nx][ny]='U';
				if(ret[x][y]=='N') ret[x][y]='D';
			}else if(i==2) {
				ret[nx][ny]='D';
				if(ret[x][y]=='N') ret[x][y]='U';
			}else {
				ret[nx][ny]='R';
				if(ret[x][y]=='N') ret[x][y]='L';
			}
			dfs2(nx,ny,vis);
		}
	}

	private void dfs1(int x, int y, int rx, int ry, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||A[nx][ny][0]!=rx||A[nx][ny][1]!=ry||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
			}else if(i==1) {
				ret[nx][ny]='U';
			}else if(i==2) {
				ret[nx][ny]='D';
			}else {
				ret[nx][ny]='R';
			}
			dfs1(nx,ny,rx,ry,vis);
		}
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		while(st==null || !st.hasMoreElements())//回车，空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

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


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

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

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	int[][] dir= {{0,1},{1,0},{-1,0},{0,-1}};
	int[][][] A;
	char[][] ret;
	int n;
	void work() {
		n=ni();
		ret=new char[n][n];
		for(char[] chs:ret) {
			Arrays.fill(chs, 'N');
		}
		A=new int[n][n][];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				A[i][j]=new int[] {in.nextInt()-1,in.nextInt()-1};
			}
		}
		boolean[][] vis=new boolean[n][n];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==i&&A[i][j][1]==j) {
					ret[i][j]='X';
					dfs1(i,j,i,j,vis);
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]!=-2&&!vis[i][j]) {
					out.println("INVALID");
					return;
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(A[i][j][0]==-2) {
					boolean f=false;
					for(int k=0;k<4;k++) {
						int ni=i+dir[k][0],nj=j+dir[k][1];
						if(ni<0||ni>=n||nj<0||nj>=n)continue;
						f=true;
					}
					if(!f) {
						out.println("INVALID");
						return;
					}
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(!vis[i][j]) {
					dfs2(i,j,vis);
				}
			}
		}
		out.println("VILID");
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				out.print(ret[i][j]);
			}
			out.println();
		}
	}

	private void dfs2(int x, int y, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
				if(ret[x][y]=='N') ret[x][y]='R';
			}else if(i==1) {
				ret[nx][ny]='U';
				if(ret[x][y]=='N') ret[x][y]='D';
			}else if(i==2) {
				ret[nx][ny]='D';
				if(ret[x][y]=='N') ret[x][y]='U';
			}else {
				ret[nx][ny]='R';
				if(ret[x][y]=='N') ret[x][y]='L';
			}
			dfs2(nx,ny,vis);
		}
	}

	private void dfs1(int x, int y, int rx, int ry, boolean[][] vis) {
		vis[x][y]=true;
		for(int i=0;i<4;i++) {
			int nx=x+dir[i][0],ny=y+dir[i][1];
			if(nx<0||nx>=n||ny<0||ny>=n||A[nx][ny][0]!=rx||A[nx][ny][1]!=ry||vis[nx][ny])continue;
			if(i==0) {
				ret[nx][ny]='L';
			}else if(i==1) {
				ret[nx][ny]='U';
			}else if(i==2) {
				ret[nx][ny]='D';
			}else {
				ret[nx][ny]='R';
			}
			dfs1(nx,ny,rx,ry,vis);
		}
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		while(st==null || !st.hasMoreElements())//回车，空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

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


import java.util.*;
import java.util.Map.Entry;

import java.math.*;
import java.io.*;
import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		// InputReader in = new InputReader(new
		// File("ethan_traverses_a_tree.txt"));
		// PrintWriter out = new PrintWriter(new
		// File("ethan_traverses_a_tree-output.txt"));

		int n = in.nextInt();
		Node[][] a = new Node[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = in.nextInt();
				int y = in.nextInt();
				if (x != -1) {
					x--;
				}
				if (y != -1) {
					y--;
				}
				a[i][j] = new Node(x, y);
			}
		}

		char[][] ans = new char[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = a[i][j].x;
				int y = a[i][j].y;
				if (a[i][j].isLoop()) {
					dfsLoop(a, ans, i, j, n);
				} else {
					dfsNotLoop(a, ans, x, y, n);
				}
			}
		}
		boolean ok = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (ans[i][j] == 0) {
					ok = false;
				}
			}
		}
		if (ok) {
			out.printf("%s\n", "VALID");
			for (int i = 0; i < n; i++) {
				String s = String.valueOf(ans[i]);
				out.printf("%s\n", s);
			}
		} else {
			out.printf("%s\n", "INVALID");
		}

		out.close();
	}

	static void dfsLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if(ans[x][y] != 0) {
			return;
		}

		if (x - 1 >= 0 && a[x - 1][y].isLoop()) {
			ans[x][y] = 'U';
		} else if (x + 1 < n && a[x + 1][y].isLoop()) {
			ans[x][y] = 'D';
		} else if (y - 1 >= 0 && a[x][y - 1].isLoop()) {
			ans[x][y] = 'L';
		} else if (y + 1 < 0 && a[x][y + 1].isLoop()) {
			ans[x][y] = 'R';
		} else {
			return;
		}
		dfs(a, a[x][y], ans, x, y, -1, -1, n);
	}

	static void dfsNotLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if ((a[x][y].x == x) && (a[x][y].y == y) && (ans[x][y] == 0)) {
			ans[x][y] = 'X';
			dfs(a, a[x][y], ans, x, y, -1, -1, n);
		}
	}

	static void dfs(Node[][] a, Node end, char[][] ans, int x, int y, int prex, int prey, int n) {
		if (x - 1 >= 0 && a[x - 1][y].equals(end) && ans[x - 1][y] == 0) {
			ans[x - 1][y] = 'D';
			dfs(a, end, ans, x - 1, y, x, y, n);
		}
		if (x + 1 < n && a[x + 1][y].equals(end) && ans[x + 1][y] == 0) {
			ans[x + 1][y] = 'U';
			dfs(a, end, ans, x + 1, y, x, y, n);
		}
		if (y - 1 >= 0 && a[x][y - 1].equals(end) && ans[x][y - 1] == 0) {
			ans[x][y - 1] = 'R';
			dfs(a, end, ans, x, y - 1, x, y, n);
		}
		if (y + 1 < n && a[x][y + 1].equals(end) && ans[x][y + 1] == 0) {
			ans[x][y + 1] = 'L';
			dfs(a, end, ans, x, y + 1, x, y, n);
		}
	}

	static class Node {
		int x;
		int y;

		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public boolean isLoop() {
			return (x == -1) && (y == -1);
		}

		@Override
		public boolean equals(Object obj) {
			Node node = (Node) obj;
			return (x == node.x) && (y == node.y);
		}
	}

	static class InputReader {
		BufferedReader br;
		StringTokenizer st;

		public InputReader(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public InputReader(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

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

		public boolean hasNext() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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


import java.util.*;
import java.util.Map.Entry;

import java.math.*;
import java.io.*;
import java.lang.reflect.Constructor;

public class Main {
	static int n;
	static Node[][] a;
	static char[][] ans;
	static Node end;

	public static void main(String[] args) throws FileNotFoundException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		// InputReader in = new InputReader(new
		// File("ethan_traverses_a_tree.txt"));
		// PrintWriter out = new PrintWriter(new
		// File("ethan_traverses_a_tree-output.txt"));

		n = in.nextInt();
		a = new Node[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = in.nextInt();
				int y = in.nextInt();
				if (x != -1) {
					x--;
				}
				if (y != -1) {
					y--;
				}
				a[i][j] = new Node(x, y);
			}
		}

		ans = new char[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = a[i][j].x;
				int y = a[i][j].y;
				if (a[i][j].isLoop()) {
					dfsLoop(i, j);
				} else {
					dfsNotLoop(x, y);
				}
			}
		}
		boolean ok = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (ans[i][j] == 0) {
					ok = false;
				}
			}
		}
		if (ok) {
			out.printf("%s\n", "VALID");
			for (int i = 0; i < n; i++) {
				String s = String.valueOf(ans[i]);
				out.printf("%s\n", s);
			}
		} else {
			out.printf("%s\n", "INVALID");
		}

		out.close();
	}

	static void dfsLoop(int x, int y) {
		if (ans[x][y] != 0) {
			return;
		}

		if (x - 1 >= 0 && a[x - 1][y].isLoop()) {
			ans[x][y] = 'U';
		} else if (x + 1 < n && a[x + 1][y].isLoop()) {
			ans[x][y] = 'D';
		} else if (y - 1 >= 0 && a[x][y - 1].isLoop()) {
			ans[x][y] = 'L';
		} else if (y + 1 < n && a[x][y + 1].isLoop()) {
			ans[x][y] = 'R';
		} else {
			return;
		}
		end = a[x][y];
		dfs(x, y);
	}

	static void dfsNotLoop(int x, int y) {
		if ((a[x][y].x == x) && (a[x][y].y == y) && (ans[x][y] == 0)) {
			ans[x][y] = 'X';
			end = a[x][y];
			dfs(x, y);
		}
	}

	static void dfs(int x, int y) {
		if ((x - 1 >= 0) && (a[x - 1][y].equals(end)) && (ans[x - 1][y] == 0)) {
			ans[x - 1][y] = 'D';
			dfs(x - 1, y);
		}
		if ((x + 1 < n) && (a[x + 1][y].equals(end)) && (ans[x + 1][y] == 0)) {
			ans[x + 1][y] = 'U';
			dfs(x + 1, y);
		}
		if ((y - 1 >= 0) && (a[x][y - 1].equals(end)) && (ans[x][y - 1] == 0)) {
			ans[x][y - 1] = 'R';
			dfs(x, y - 1);
		}
		if ((y + 1 < n) && (a[x][y + 1].equals(end)) && (ans[x][y + 1] == 0)) {
			ans[x][y + 1] = 'L';
			dfs(x, y + 1);
		}
	}

	static class Node {
		int x;
		int y;

		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public boolean isLoop() {
			return (x == -1) && (y == -1);
		}

		@Override
		public boolean equals(Object obj) {
			Node node = (Node) obj;
			return (x == node.x) && (y == node.y);
		}
	}

	static class InputReader {
		BufferedReader br;
		StringTokenizer st;

		public InputReader(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public InputReader(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

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

		public boolean hasNext() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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


import java.util.*;
import java.util.Map.Entry;

import java.math.*;
import java.io.*;
import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		// InputReader in = new InputReader(new
		// File("ethan_traverses_a_tree.txt"));
		// PrintWriter out = new PrintWriter(new
		// File("ethan_traverses_a_tree-output.txt"));

		int n = in.nextInt();
		Node[][] a = new Node[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = in.nextInt();
				int y = in.nextInt();
				if (x != -1) {
					x--;
				}
				if (y != -1) {
					y--;
				}
				a[i][j] = new Node(x, y);
			}
		}

		char[][] ans = new char[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = a[i][j].x;
				int y = a[i][j].y;
				if (a[i][j].isLoop()) {
					dfsLoop(a, ans, i, j, n);
				} else {
					dfsNotLoop(a, ans, x, y, n);
				}
			}
		}
		boolean ok = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (ans[i][j] == 0) {
					ok = false;
				}
			}
		}
		if (ok) {
			out.printf("%s\n", "VALID");
			for (int i = 0; i < n; i++) {
				String s = String.valueOf(ans[i]);
				out.printf("%s\n", s);
			}
		} else {
			out.printf("%s\n", "INVALID");
		}

		out.close();
	}

	static void dfsLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if(ans[x][y] != 0) {
			return;
		}

		if (x - 1 >= 0 && a[x - 1][y].isLoop()) {
			ans[x][y] = 'U';
		} else if (x + 1 < n && a[x + 1][y].isLoop()) {
			ans[x][y] = 'D';
		} else if (y - 1 >= 0 && a[x][y - 1].isLoop()) {
			ans[x][y] = 'L';
		} else if (y + 1 < n && a[x][y + 1].isLoop()) {
			ans[x][y] = 'R';
		} else {
			return;
		}
		dfs(a, a[x][y], ans, x, y, -1, -1, n);
	}

	static void dfsNotLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if ((a[x][y].x == x) && (a[x][y].y == y) && (ans[x][y] == 0)) {
			ans[x][y] = 'X';
			dfs(a, a[x][y], ans, x, y, -1, -1, n);
		}
	}

	static void dfs(Node[][] a, Node end, char[][] ans, int x, int y, int prex, int prey, int n) {
		if (x - 1 >= 0 && a[x - 1][y].equals(end) && ans[x - 1][y] == 0) {
			ans[x - 1][y] = 'D';
			dfs(a, end, ans, x - 1, y, x, y, n);
		}
		if (x + 1 < n && a[x + 1][y].equals(end) && ans[x + 1][y] == 0) {
			ans[x + 1][y] = 'U';
			dfs(a, end, ans, x + 1, y, x, y, n);
		}
		if (y - 1 >= 0 && a[x][y - 1].equals(end) && ans[x][y - 1] == 0) {
			ans[x][y - 1] = 'R';
			dfs(a, end, ans, x, y - 1, x, y, n);
		}
		if (y + 1 < n && a[x][y + 1].equals(end) && ans[x][y + 1] == 0) {
			ans[x][y + 1] = 'L';
			dfs(a, end, ans, x, y + 1, x, y, n);
		}
	}

	static class Node {
		int x;
		int y;

		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public boolean isLoop() {
			return (x == -1) && (y == -1);
		}

		@Override
		public boolean equals(Object obj) {
			Node node = (Node) obj;
			return (x == node.x) && (y == node.y);
		}
	}

	static class InputReader {
		BufferedReader br;
		StringTokenizer st;

		public InputReader(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public InputReader(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

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

		public boolean hasNext() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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


import java.util.*;
import java.util.Map.Entry;

import java.math.*;
import java.io.*;
import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		// InputReader in = new InputReader(new
		// File("ethan_traverses_a_tree.txt"));
		// PrintWriter out = new PrintWriter(new
		// File("ethan_traverses_a_tree-output.txt"));

		int n = in.nextInt();
		Node[][] a = new Node[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = in.nextInt();
				int y = in.nextInt();
				if (x != -1) {
					x--;
				}
				if (y != -1) {
					y--;
				}
				a[i][j] = new Node(x, y);
			}
		}

		char[][] ans = new char[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int x = a[i][j].x;
				int y = a[i][j].y;
				if (a[i][j].isLoop()) {
					dfsLoop(a, ans, i, j, n);
				} else {
					dfsNotLoop(a, ans, x, y, n);
				}
			}
		}
		boolean ok = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (ans[i][j] == 0) {
					ok = false;
				}
			}
		}
		if (ok) {
			out.printf("%s\n", "VALID");
			for (int i = 0; i < n; i++) {
				String s = String.valueOf(ans[i]);
				out.printf("%s\n", s);
			}
		} else {
			out.printf("%s\n", "INVALID");
		}

		out.close();
	}

	static void dfsLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if(ans[x][y] != 0) {
			return;
		}

		if (x - 1 >= 0 && a[x - 1][y].isLoop()) {
			ans[x][y] = 'U';
		} else if (x + 1 < n && a[x + 1][y].isLoop()) {
			ans[x][y] = 'D';
		} else if (y - 1 >= 0 && a[x][y - 1].isLoop()) {
			ans[x][y] = 'L';
		} else if (y + 1 < n && a[x][y + 1].isLoop()) {
			ans[x][y] = 'R';
		} else {
			return;
		}
		dfs(a, a[x][y], ans, x, y, -1, -1, n);
	}

	static void dfsNotLoop(Node[][] a, char[][] ans, int x, int y, int n) {
		if ((a[x][y].x == x) && (a[x][y].y == y) && (ans[x][y] == 0)) {
			ans[x][y] = 'X';
			dfs(a, a[x][y], ans, x, y, -1, -1, n);
		}
	}

	static void dfs(Node[][] a, Node end, char[][] ans, int x, int y, int prex, int prey, int n) {
		if ((x - 1 >= 0) && (a[x - 1][y].equals(end)) && (ans[x - 1][y] == 0)) {
			ans[x - 1][y] = 'D';
			dfs(a, end, ans, x - 1, y, x, y, n);
		}
		if ((x + 1 < n) && (a[x + 1][y].equals(end)) && (ans[x + 1][y] == 0)) {
			ans[x + 1][y] = 'U';
			dfs(a, end, ans, x + 1, y, x, y, n);
		}
		if ((y - 1 >= 0) && (a[x][y - 1].equals(end)) && (ans[x][y - 1] == 0)) {
			ans[x][y - 1] = 'R';
			dfs(a, end, ans, x, y - 1, x, y, n);
		}
		if ((y + 1 < n) && (a[x][y + 1].equals(end)) && (ans[x][y + 1] == 0)) {
			ans[x][y + 1] = 'L';
			dfs(a, end, ans, x, y + 1, x, y, n);
		}
	}

	static class Node {
		int x;
		int y;

		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public boolean isLoop() {
			return (x == -1) && (y == -1);
		}

		@Override
		public boolean equals(Object obj) {
			Node node = (Node) obj;
			return (x == node.x) && (y == node.y);
		}
	}

	static class InputReader {
		BufferedReader br;
		StringTokenizer st;

		public InputReader(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public InputReader(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

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

		public boolean hasNext() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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