import java.io.*;
import java.util.*;
import java.math.*;
import java.awt.Point;

public class Main {
	//static final long MOD = 998244353L;
	static final long INF = 1000000000000000007L;
	//static final long MOD = 1000000007L;
	//static final int INF = 1000000007;

	//static long[] factorial;

	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		PrintWriter pw = new PrintWriter(System.out);
		int N = sc.ni();
		int[][][] ends = new int[N][N][2];
		char[][] grid = new char[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++)
				grid[i][j] ='-';
		}
		int[][] cnt = new int[N][N];
		boolean[][] vis = new boolean[N][N];
		int[][] reg = new int[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				int r = sc.ni()-1;
				int c = sc.ni()-1;
				ends[i][j][0] = r;
				ends[i][j][1] = c;
				if (r != -2 && c != -2) {
					grid[r][c] = 'X';
					cnt[r][c] += 1;
				}
			}
		}
		ArrayDeque<int[]> bfs = new ArrayDeque<int[]>();
		int[][] dirs = {{-1,0},{0,1},{0,-1},{1,0}};
		char[] move = {'D','L','R','U'};

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (vis[i][j]) continue;
				if (grid[i][j] != 'X' && ends[i][j][0] != -2) continue;
				int[] type = ends[i][j];
				vis[i][j] = true;
				int size = 0;
				bfs.add(new int[]{i,j});
				while (!bfs.isEmpty()) {
					int[] point = bfs.poll();
					size++;
					for (int d = 0; d < 4; d++) {
						int[] dir = dirs[d];
						int newR = point[0]+dir[0];
						int newC = point[1]+dir[1];
						if (newR >= 0 && newR < N && newC >= 0 && newC < N && ends[newR][newC][0]==ends[i][j][0] && ends[newR][newC][1]==ends[i][j][1] && !vis[newR][newC]) {
							vis[newR][newC] = true;
							bfs.add(new int[]{newR,newC});
							grid[newR][newC] = move[d];
						}
					}
				}

				if (type[0]==-2&&type[1]==-2) {
					if (size == 1) {
						pw.println("INVALID");
						pw.close();
						return;
					} else {
						for (int d = 0; d < 4; d++) {
							int[] dir = dirs[d];
							int newR = i+dir[0];
							int newC = j+dir[1];
							if (newR >= 0 && newR < N && newC >= 0 && newC < N && ends[newR][newC][0]==ends[i][j][0] && ends[newR][newC][1]==ends[i][j][1]) {
								grid[i][j] = move[3-d];
								break;
							}
						}
					}
				} else {
					if (size < cnt[i][j]) {
						pw.println("INVALID");
						pw.close();
						return;
					}
				}
			}
		}

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (grid[i][j]=='-') {
					pw.println("INVALID");
					pw.close();
					return;
				}
			}
		}
		pw.println("VALID");
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++)
				pw.print(grid[i][j]);
			pw.println();
		}
		pw.close();
	}

	public static long dist(long[] p1, long[] p2) {
		return (Math.abs(p2[0]-p1[0])+Math.abs(p2[1]-p1[1]));
	}

	//Find the GCD of two numbers
	public static long gcd(long a, long b) {
		if (a < b) return gcd(b,a);
		if (b == 0)
			return a;
		else
			return gcd(b,a%b);
	}

	//Fast exponentiation (x^y mod m)
	public static long power(long x, long y, long m) {
		if (y < 0) return 0L;
		long ans = 1;
		x %= m;
		while (y > 0) {
			if(y % 2 == 1)
				ans = (ans * x) % m;
			y /= 2;
			x = (x * x) % m;
		}
		return ans;
	}

	public static int[][] shuffle(int[][] array) {
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    int[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		return array;
	}

    public static int[][] sort(int[][] array) {
    	//Sort an array (immune to quicksort TLE)

		Arrays.sort(array, new Comparator<int[]>() {
			  @Override
        	  public int compare(int[] a, int[] b) {
				  //return a[0]-b[0]; //ascending order
				  if (a[1] != b[1]) {
					  return (a[1]-b[1]);
				  } else {
					  return (a[0]-b[0]);
				  }
	          }
		});
		return array;
	}

    public static long[][] sort(long[][] array) {
    	//Sort an array (immune to quicksort TLE)
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    long[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		Arrays.sort(array, new Comparator<long[]>() {
			  @Override
        	  public int compare(long[] a, long[] b) {
				  if (a[0] < b[0])
					  return -1;
				  else
					  return 1;
	          }
		});
		return array;
	}

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1316D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         Point[][] grid = new Point[N][N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            for(int a=0; a < N; a++)
            {
               int x = Integer.parseInt(st.nextToken());
               int y = Integer.parseInt(st.nextToken());
               grid[i][a] = new Point(x-1, y-1);
            }
         }
         Queue<Node> q = new LinkedList<Node>();
         char[][] res = new char[N][N];
         for(int i=0; i < N; i++)
            Arrays.fill(res[i], '?');
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(grid[r][c].x != -2)
               {
                  int a = grid[r][c].x;
                  int b = grid[r][c].y;
                  res[a][b] = 'X';
                  Node lol = new Node(new Point(a,b), new Point(a,b));
                  q.add(lol);
               }
         while(q.size() > 0)
         {
            Node curr = q.poll();
            int x = curr.p.x;
            int y = curr.p.y;
            int xt = curr.target.x;
            int yt = curr.target.y;
            if(x-1 >= 0 && res[x-1][y] == '?' && grid[x-1][y].x == xt && grid[x-1][y].y == yt)
            {
               Node next = new Node(new Point(x-1, y), new Point(xt,yt));
               res[x-1][y] = 'D';
               q.add(next);
            }
            if(y-1 >= 0 && res[x][y-1] == '?' && grid[x][y-1].x == xt && grid[x][y-1].y == yt)
            {
               Node next = new Node(new Point(x, y-1), new Point(xt,yt));
               res[x][y-1] = 'R';
               q.add(next);
            }
            if(y+1 < N && res[x][y+1] == '?' && grid[x][y+1].x == xt && grid[x][y+1].y == yt)
            {
               Node next = new Node(new Point(x, y+1), new Point(xt,yt));
               res[x][y+1] = 'L';
               q.add(next);
            }
            if(x+1 < N && res[x+1][y] == '?' && grid[x+1][y].x == xt && grid[x+1][y].y == yt)
            {
               Node next = new Node(new Point(x+1, y), new Point(xt,yt));
               res[x+1][y] = 'U';
               q.add(next);
            }
         }
         //2nd part (force cycles)
         boolean bad = false;
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  int cnt = 0;
                  if(r-1 >= 0 && res[r-1][c] == '?')
                     cnt++;
                  if(c-1 >= 0 && res[r][c-1] == '?')
                     cnt++;
                  if(r+1 < N && res[r+1][c] == '?')
                     cnt++;
                  if(c+1 < N && res[r][c+1] == '?')
                     cnt++;
                  if(cnt == 0)
                     bad = true;
               }
         if(bad)
         {
            System.out.println("INVALID");
            return;
         }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  Point p1 = new Point(r, c);
                  Point p2 = new Point(r, c);
                  if(r-1 >= 0 && res[r-1][c] == '?')
                  {
                     p2 = new Point(r-1, c);
                     res[r-1][c] = 'D';
                     res[r][c] = 'U';
                  }
                  else if(c-1 >= 0 && res[r][c-1] == '?')
                  {
                     p2 = new Point(r, c-1);
                     res[r][c-1] = 'R';
                     res[r][c] = 'L';
                  }
                  else if(r+1 < N && res[r+1][c] == '?')
                  {
                     p2 = new Point(r+1, c);
                     res[r+1][c] = 'U';
                     res[r][c] = 'D';
                  }
                  else if(c+1 < N && res[r][c+1] == '?')
                  {
                     p2 = new Point(r, c+1);
                     res[r][c+1] = 'L';
                     res[r][c] = 'R';
                  }
                  //bfs shit
                  Queue<Point> qq = new LinkedList<Point>();
                  qq.add(p1);
                  qq.add(p2);
                  while(qq.size() > 0)
                  {
                     Point curr = qq.poll();
                     int x = curr.x;
                     int y = curr.y;
                     if(x-1 >= 0 && res[x-1][y] == '?')
                     {
                        Point next = new Point(x-1, y);
                        res[x-1][y] = 'D';
                        qq.add(next);
                     }
                     if(y-1 >= 0 && res[x][y-1] == '?')
                     {
                        Point next = new Point(x, y-1);
                        res[x][y-1] = 'R';
                        qq.add(next);
                     }
                     if(y+1 < N && res[x][y+1] == '?')
                     {
                        Point next = new Point(x, y+1);
                        res[x][y+1] = 'L';
                        qq.add(next);
                     }
                     if(x+1 < N && res[x+1][y] == '?')
                     {
                        Point next = new Point(x+1, y);
                        res[x+1][y] = 'U';
                        qq.add(next);
                     }
                  }
               }
         //final check
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  System.out.println("INVALID");
                  return;
               }
         System.out.println("VALID");
         StringBuilder sb = new StringBuilder();
         for(int i=0; i < N; i++)
            sb.append(res[i]).append("\n");
         System.out.print(sb);
      }
   }
   class Node
   {
      public Point p;
      public Point target;

      public Node(Point a, Point b)
      {
         p = a;
         target = b;
      }
   }
   class Point
   {
      public int x;
      public int y;

      public Point(int a, int b)
      {
         x = a;
         y = b;
      }
   }


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1316D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         Point[][] grid = new Point[N][N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            for(int a=0; a < N; a++)
            {
               int x = Integer.parseInt(st.nextToken());
               int y = Integer.parseInt(st.nextToken());
               grid[i][a] = new Point(x-1, y-1);
            }
         }
         Queue<Node> q = new LinkedList<Node>();
         char[][] res = new char[N][N];
         for(int i=0; i < N; i++)
            Arrays.fill(res[i], '?');
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(grid[r][c].x != -2)
               {
                  int a = grid[r][c].x;
                  int b = grid[r][c].y;
                  res[a][b] = 'X';
                  Node lol = new Node(new Point(a,b), new Point(a,b));
                  q.add(lol);
               }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == 'X' && (grid[r][c].x != r || grid[r][c].y != c))
               {
                  System.out.println("INVALID");
                  return;
               }
         while(q.size() > 0)
         {
            Node curr = q.poll();
            int x = curr.p.x;
            int y = curr.p.y;
            int xt = curr.target.x;
            int yt = curr.target.y;
            if(x-1 >= 0 && res[x-1][y] == '?' && grid[x-1][y].x == xt && grid[x-1][y].y == yt)
            {
               Node next = new Node(new Point(x-1, y), new Point(xt,yt));
               res[x-1][y] = 'D';
               q.add(next);
            }
            else if(x-1 >= 0 && res[x-1][y] != '?')
            {
               System.out.println("INVALID");
               return;
            }

            if(y-1 >= 0 && res[x][y-1] == '?' && grid[x][y-1].x == xt && grid[x][y-1].y == yt)
            {
               Node next = new Node(new Point(x, y-1), new Point(xt,yt));
               res[x][y-1] = 'R';
               q.add(next);
            }
            else if(y-1 >= 0 && res[x][y-1] != '?')
            {
               System.out.println("INVALID");
               return;
            }

            if(y+1 < N && res[x][y+1] == '?' && grid[x][y+1].x == xt && grid[x][y+1].y == yt)
            {
               Node next = new Node(new Point(x, y+1), new Point(xt,yt));
               res[x][y+1] = 'L';
               q.add(next);
            }
            else if(y+1 < N && res[x][y+1] != '?')
            {
               System.out.println("INVALID");
               return;
            }

            if(x+1 < N && res[x+1][y] == '?' && grid[x+1][y].x == xt && grid[x+1][y].y == yt)
            {
               Node next = new Node(new Point(x+1, y), new Point(xt,yt));
               res[x+1][y] = 'U';
               q.add(next);
            }
            else if(x+1 < N && res[x+1][y] != '?')
            {
               System.out.println("INVALID");
               return;
            }
         }
         //2nd part (force cycles)
         boolean bad = false;
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  int cnt = 0;
                  if(r-1 >= 0 && res[r-1][c] == '?')
                     cnt++;
                  if(c-1 >= 0 && res[r][c-1] == '?')
                     cnt++;
                  if(r+1 < N && res[r+1][c] == '?')
                     cnt++;
                  if(c+1 < N && res[r][c+1] == '?')
                     cnt++;
                  if(cnt == 0)
                     bad = true;
               }
         if(bad)
         {
            System.out.println("INVALID");
            return;
         }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  Point p1 = new Point(r, c);
                  Point p2 = new Point(r, c);
                  if(r-1 >= 0 && res[r-1][c] == '?')
                  {
                     p2 = new Point(r-1, c);
                     res[r-1][c] = 'D';
                     res[r][c] = 'U';
                  }
                  else if(c-1 >= 0 && res[r][c-1] == '?')
                  {
                     p2 = new Point(r, c-1);
                     res[r][c-1] = 'R';
                     res[r][c] = 'L';
                  }
                  else if(r+1 < N && res[r+1][c] == '?')
                  {
                     p2 = new Point(r+1, c);
                     res[r+1][c] = 'U';
                     res[r][c] = 'D';
                  }
                  else if(c+1 < N && res[r][c+1] == '?')
                  {
                     p2 = new Point(r, c+1);
                     res[r][c+1] = 'L';
                     res[r][c] = 'R';
                  }
                  //bfs shit
                  Queue<Point> qq = new LinkedList<Point>();
                  qq.add(p1);
                  qq.add(p2);
                  while(qq.size() > 0)
                  {
                     Point curr = qq.poll();
                     int x = curr.x;
                     int y = curr.y;
                     if(x-1 >= 0 && res[x-1][y] == '?')
                     {
                        Point next = new Point(x-1, y);
                        res[x-1][y] = 'D';
                        qq.add(next);
                     }
                     if(y-1 >= 0 && res[x][y-1] == '?')
                     {
                        Point next = new Point(x, y-1);
                        res[x][y-1] = 'R';
                        qq.add(next);
                     }
                     if(y+1 < N && res[x][y+1] == '?')
                     {
                        Point next = new Point(x, y+1);
                        res[x][y+1] = 'L';
                        qq.add(next);
                     }
                     if(x+1 < N && res[x+1][y] == '?')
                     {
                        Point next = new Point(x+1, y);
                        res[x+1][y] = 'U';
                        qq.add(next);
                     }
                  }
               }
         //final check
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  System.out.println("INVALID");
                  return;
               }
         System.out.println("VALID");
         StringBuilder sb = new StringBuilder();
         for(int i=0; i < N; i++)
            sb.append(res[i]).append("\n");
         System.out.print(sb);
      }
   }
   class Node
   {
      public Point p;
      public Point target;

      public Node(Point a, Point b)
      {
         p = a;
         target = b;
      }
   }
   class Point
   {
      public int x;
      public int y;

      public Point(int a, int b)
      {
         x = a;
         y = b;
      }
   }


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1316D2
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         Point[][] grid = new Point[N][N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            for(int a=0; a < N; a++)
            {
               int x = Integer.parseInt(st.nextToken());
               int y = Integer.parseInt(st.nextToken());
               grid[i][a] = new Point(x-1, y-1);
            }
         }
         Queue<Node> q = new LinkedList<Node>();
         char[][] res = new char[N][N];
         for(int i=0; i < N; i++)
            Arrays.fill(res[i], '?');
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(grid[r][c].x != -2)
               {
                  int a = grid[r][c].x;
                  int b = grid[r][c].y;
                  res[a][b] = 'X';
                  Node lol = new Node(new Point(a,b), new Point(a,b));
                  q.add(lol);
               }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == 'X' && (grid[r][c].x != r || grid[r][c].y != c))
               {
                  System.out.println("INVALID");
                  return;
               }
         while(q.size() > 0)
         {
            Node curr = q.poll();
            int x = curr.p.x;
            int y = curr.p.y;
            int xt = curr.target.x;
            int yt = curr.target.y;
            if(x-1 >= 0 && res[x-1][y] == '?' && grid[x-1][y].x == xt && grid[x-1][y].y == yt)
            {
               Node next = new Node(new Point(x-1, y), new Point(xt,yt));
               res[x-1][y] = 'D';
               q.add(next);
            }
            if(y-1 >= 0 && res[x][y-1] == '?' && grid[x][y-1].x == xt && grid[x][y-1].y == yt)
            {
               Node next = new Node(new Point(x, y-1), new Point(xt,yt));
               res[x][y-1] = 'R';
               q.add(next);
            }
            if(y+1 < N && res[x][y+1] == '?' && grid[x][y+1].x == xt && grid[x][y+1].y == yt)
            {
               Node next = new Node(new Point(x, y+1), new Point(xt,yt));
               res[x][y+1] = 'L';
               q.add(next);
            }
            if(x+1 < N && res[x+1][y] == '?' && grid[x+1][y].x == xt && grid[x+1][y].y == yt)
            {
               Node next = new Node(new Point(x+1, y), new Point(xt,yt));
               res[x+1][y] = 'U';
               q.add(next);
            }
         }
         //2nd part (force cycles)
         boolean bad = false;
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  int cnt = 0;
                  if(r-1 >= 0 && res[r-1][c] == '?')
                     cnt++;
                  if(c-1 >= 0 && res[r][c-1] == '?')
                     cnt++;
                  if(r+1 < N && res[r+1][c] == '?')
                     cnt++;
                  if(c+1 < N && res[r][c+1] == '?')
                     cnt++;
                  if(cnt == 0)
                     bad = true;
               }
         if(bad)
         {
            System.out.println("INVALID");
            return;
         }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  Point p1 = new Point(r, c);
                  Point p2 = new Point(r, c);
                  if(r-1 >= 0 && res[r-1][c] == '?')
                  {
                     p2 = new Point(r-1, c);
                     res[r-1][c] = 'D';
                     res[r][c] = 'U';
                  }
                  else if(c-1 >= 0 && res[r][c-1] == '?')
                  {
                     p2 = new Point(r, c-1);
                     res[r][c-1] = 'R';
                     res[r][c] = 'L';
                  }
                  else if(r+1 < N && res[r+1][c] == '?')
                  {
                     p2 = new Point(r+1, c);
                     res[r+1][c] = 'U';
                     res[r][c] = 'D';
                  }
                  else if(c+1 < N && res[r][c+1] == '?')
                  {
                     p2 = new Point(r, c+1);
                     res[r][c+1] = 'L';
                     res[r][c] = 'R';
                  }
                  //bfs shit
                  Queue<Point> qq = new LinkedList<Point>();
                  qq.add(p1);
                  qq.add(p2);
                  while(qq.size() > 0)
                  {
                     Point curr = qq.poll();
                     int x = curr.x;
                     int y = curr.y;
                     if(x-1 >= 0 && res[x-1][y] == '?')
                     {
                        Point next = new Point(x-1, y);
                        res[x-1][y] = 'D';
                        if(grid[x-1][y].x != -2)
                        {
                           System.out.println("INVALID");
                           return;
                        }
                        qq.add(next);
                     }
                     if(y-1 >= 0 && res[x][y-1] == '?')
                     {
                        Point next = new Point(x, y-1);
                        res[x][y-1] = 'R';
                        if(grid[x][y-1].x != -2)
                        {
                           System.out.println("INVALID");
                           return;
                        }
                        qq.add(next);
                     }
                     if(y+1 < N && res[x][y+1] == '?')
                     {
                        Point next = new Point(x, y+1);
                        res[x][y+1] = 'L';
                        if(grid[x][y+1].x != -2)
                        {
                           System.out.println("INVALID");
                           return;
                        }
                        qq.add(next);
                     }
                     if(x+1 < N && res[x+1][y] == '?')
                     {
                        Point next = new Point(x+1, y);
                        res[x+1][y] = 'U';
                        if(grid[x+1][y].x != -2)
                        {
                           System.out.println("INVALID");
                           return;
                        }
                        qq.add(next);
                     }
                  }
               }
         //final check
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  System.out.println("INVALID");
                  return;
               }
         System.out.println("VALID");
         StringBuilder sb = new StringBuilder();
         for(int i=0; i < N; i++)
            sb.append(res[i]).append("\n");
         System.out.print(sb);
      }
   }
   class Node
   {
      public Point p;
      public Point target;

      public Node(Point a, Point b)
      {
         p = a;
         target = b;
      }
   }
   class Point
   {
      public int x;
      public int y;

      public Point(int a, int b)
      {
         x = a;
         y = b;
      }
   }


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1316D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         Point[][] grid = new Point[N][N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            for(int a=0; a < N; a++)
            {
               int x = Integer.parseInt(st.nextToken());
               int y = Integer.parseInt(st.nextToken());
               grid[i][a] = new Point(x-1, y-1);
            }
         }
         Queue<Node> q = new LinkedList<Node>();
         char[][] res = new char[N][N];
         for(int i=0; i < N; i++)
            Arrays.fill(res[i], '?');
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(grid[r][c].x != -2)
               {
                  int a = grid[r][c].x;
                  int b = grid[r][c].y;
                  res[a][b] = 'X';
                  Node lol = new Node(new Point(a,b), new Point(a,b));
                  q.add(lol);
               }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == 'X' && (grid[r][c].x != r || grid[r][c].y != c))
               {
                  System.out.println("INVALID");
                  return;
               }
         while(q.size() > 0)
         {
            Node curr = q.poll();
            int x = curr.p.x;
            int y = curr.p.y;
            int xt = curr.target.x;
            int yt = curr.target.y;
            if(x-1 >= 0 && res[x-1][y] == '?' && grid[x-1][y].x == xt && grid[x-1][y].y == yt)
            {
               Node next = new Node(new Point(x-1, y), new Point(xt,yt));
               res[x-1][y] = 'D';
               q.add(next);
            }
            if(y-1 >= 0 && res[x][y-1] == '?' && grid[x][y-1].x == xt && grid[x][y-1].y == yt)
            {
               Node next = new Node(new Point(x, y-1), new Point(xt,yt));
               res[x][y-1] = 'R';
               q.add(next);
            }
            if(y+1 < N && res[x][y+1] == '?' && grid[x][y+1].x == xt && grid[x][y+1].y == yt)
            {
               Node next = new Node(new Point(x, y+1), new Point(xt,yt));
               res[x][y+1] = 'L';
               q.add(next);
            }
            if(x+1 < N && res[x+1][y] == '?' && grid[x+1][y].x == xt && grid[x+1][y].y == yt)
            {
               Node next = new Node(new Point(x+1, y), new Point(xt,yt));
               res[x+1][y] = 'U';
               q.add(next);
            }
         }
         //2nd part (force cycles)
         boolean bad = false;
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  int cnt = 0;
                  if(r-1 >= 0 && res[r-1][c] == '?')
                     cnt++;
                  if(c-1 >= 0 && res[r][c-1] == '?')
                     cnt++;
                  if(r+1 < N && res[r+1][c] == '?')
                     cnt++;
                  if(c+1 < N && res[r][c+1] == '?')
                     cnt++;
                  if(cnt == 0)
                     bad = true;
               }
         if(bad)
         {
            System.out.println("INVALID");
            return;
         }
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  Point p1 = new Point(r, c);
                  Point p2 = new Point(r, c);
                  if(r-1 >= 0 && res[r-1][c] == '?')
                  {
                     p2 = new Point(r-1, c);
                     res[r-1][c] = 'D';
                     res[r][c] = 'U';
                  }
                  else if(c-1 >= 0 && res[r][c-1] == '?')
                  {
                     p2 = new Point(r, c-1);
                     res[r][c-1] = 'R';
                     res[r][c] = 'L';
                  }
                  else if(r+1 < N && res[r+1][c] == '?')
                  {
                     p2 = new Point(r+1, c);
                     res[r+1][c] = 'U';
                     res[r][c] = 'D';
                  }
                  else if(c+1 < N && res[r][c+1] == '?')
                  {
                     p2 = new Point(r, c+1);
                     res[r][c+1] = 'L';
                     res[r][c] = 'R';
                  }
                  //bfs shit
                  Queue<Point> qq = new LinkedList<Point>();
                  qq.add(p1);
                  qq.add(p2);
                  while(qq.size() > 0)
                  {
                     Point curr = qq.poll();
                     int x = curr.x;
                     int y = curr.y;
                     if(x-1 >= 0 && res[x-1][y] == '?')
                     {
                        Point next = new Point(x-1, y);
                        res[x-1][y] = 'D';
                        qq.add(next);
                     }
                     if(y-1 >= 0 && res[x][y-1] == '?')
                     {
                        Point next = new Point(x, y-1);
                        res[x][y-1] = 'R';
                        qq.add(next);
                     }
                     if(y+1 < N && res[x][y+1] == '?')
                     {
                        Point next = new Point(x, y+1);
                        res[x][y+1] = 'L';
                        qq.add(next);
                     }
                     if(x+1 < N && res[x+1][y] == '?')
                     {
                        Point next = new Point(x+1, y);
                        res[x+1][y] = 'U';
                        qq.add(next);
                     }
                  }
               }
         //final check
         for(int r=0; r < N; r++)
            for(int c=0; c < N; c++)
               if(res[r][c] == '?')
               {
                  System.out.println("INVALID");
                  return;
               }
         System.out.println("VALID");
         StringBuilder sb = new StringBuilder();
         for(int i=0; i < N; i++)
            sb.append(res[i]).append("\n");
         System.out.print(sb);
      }
   }
   class Node
   {
      public Point p;
      public Point target;

      public Node(Point a, Point b)
      {
         p = a;
         target = b;
      }
   }
   class Point
   {
      public int x;
      public int y;

      public Point(int a, int b)
      {
         x = a;
         y = b;
      }
   }


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

public class Main {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter pw = new PrintWriter(System.out);
    static int MOD = 1000000007;

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.solve();
        m.close();
    }

    void close() throws IOException {
        pw.flush();
        pw.close();
        br.close();
    }

    int ri() throws IOException {
        return Integer.parseInt(br.readLine());
    }

    long rl() throws IOException {
        return Long.parseLong(br.readLine());
    }

    int[] ril(int n) throws IOException {
        int[] nums = new int[n];
        int c = 0;
        for (int i = 0; i < n; i++) {
            int sign = 1;
            c = br.read();
            int x = 0;
            if (c == '-') {
                sign = -1;
                c = br.read();
            }
            while (c >= '0' && c <= '9') {
                x = x * 10 + c - '0';
                c = br.read();
            }
            nums[i] = x * sign;
        }
        while (c != '\n' && c != -1) c = br.read();
        return nums;
    }

    long[] rll(int n) throws IOException {
        long[] nums = new long[n];
        int c = 0;
        for (int i = 0; i < n; i++) {
            int sign = 1;
            c = br.read();
            long x = 0;
            if (c == '-') {
                sign = -1;
                c = br.read();
            }
            while (c >= '0' && c <= '9') {
                x = x * 10 + c - '0';
                c = br.read();
            }
            nums[i] = x * sign;
        }
        while (c != '\n' && c != -1) c = br.read();
        return nums;
    }

    char[] rs() throws IOException {
        return br.readLine().toCharArray();
    }

    void solve() throws IOException {
        n = ri();

        // if (r, c) -> (r, c), then this cell is X
        // if there is a path (a, b) -> (x, y)
        // then there must be a cell adjacent to a blocked cell
        // we can immediately determine that cell's direction
        // continuing inductively (one step at a time), we can
        // determine the letters for all cells along a path
        //
        // another observation: the (-1, -1) paths must form some
        // sort of connected component with each other with size > 1
        // all you have to do is have two cells point to each other,
        // then have all cells in the same CC funnel into one of them
        // (bfs or dfs work)

        int[][] A = new int[n][n];       // destination
        char[][] grid = new char[n][n];  // letter

        Deque<Integer> q = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            int[] xys = ril(2 * n);
            for (int j = 0; j < xys.length; j++) xys[j]--;
            for (int j = 0; j < n; j++) {
                int r = xys[2*j];
                int c = xys[2*j+1];
                if (r == -2 && c == -2) {
                    A[i][j] = -1;
                } else {
                    A[i][j] = r*n + c;
                }
                if (i*n + j == r*n + c) {
                    q.addLast(i*n + j);
                    grid[i][j] = 'X';
                }
            }
        }

        // Do BFS from all blocked states; solves non-infinite cases
        while (!q.isEmpty()) {
            int rc = q.removeFirst();
            int r = rc / n;
            int c = rc % n;
            if (r-1>=0 && grid[r-1][c] == 0 && A[r-1][c] == A[r][c]) {
                grid[r-1][c] = 'D';
                q.addLast(rc - n);
            }
            if (r+1<n && grid[r+1][c] == 0 && A[r+1][c] == A[r][c]) {
                grid[r+1][c] = 'U';
                q.addLast(rc + n);
            }
            if (c-1>=0 && grid[r][c-1] == 0 && A[r][c-1] == A[r][c]) {
                grid[r][c-1] = 'R';
                q.addLast(rc - 1);
            }
            if (c+1<n && grid[r][c+1] == 0 && A[r][c+1] == A[r][c]) {
                grid[r][c+1] = 'L';
                q.addLast(rc + 1);
            }
        }

        // Find CCs of infinite cases.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (A[i][j] >= 0 && grid[i][j] == 0) {
                    pw.println("INVALID");
                    return;
                }
                if (A[i][j] == -1 && grid[i][j] == 0) {
                    boolean ok = false;
                    if (i+1<n && A[i+1][j] == -1) {
                        ok = true;
                        grid[i][j] = 'D';
                        grid[i+1][j] = 'U';
                        dfs(i+1, j, A, grid);
                    }
                    if (j+1<n && A[i][j+1] == -1 && grid[i][j+1] == 0) {
                        ok = true;
                        grid[i][j] = 'R';
                        grid[i][j+1] = 'L';
                        dfs(i, j+1, A, grid);
                    }
                    if (!ok) {
                        pw.println("INVALID");
                        return;
                    }
                }
            }
        }

        pw.println("VALID");
        for (char[] row : grid) {
            pw.println(new String(row));
        }
    }

    int n;

    // pdir points to guy who called me
    void dfs(int r, int c, int[][] A, char[][] grid) {
        if (r-1>=0 && A[r-1][c] == -1 && grid[r-1][c] == 0) {
            grid[r-1][c] = 'D';
            dfs(r-1, c, A, grid);
        }
        if (r+1<n && A[r+1][c] == -1 && grid[r+1][c] == 0) {
            grid[r+1][c] = 'U';
            dfs(r+1, c, A, grid);
        }
        if (c-1>=0 && A[r][c-1] == -1 && grid[r][c-1] == 0) {
            grid[r][c-1] = 'R';
            dfs(r, c-1, A, grid);
        }
        if (c+1<n && A[r][c+1] == -1 && grid[r][c+1] == 0) {
            grid[r][c+1] = 'L';
            dfs(r, c+1, A, grid);
        }
    }
}


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

public class Main
{
	PrintWriter out = new PrintWriter(System.out);
	BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer tok = new StringTokenizer("");
    String next() throws IOException {
        if (!tok.hasMoreTokens()) { tok = new StringTokenizer(in.readLine()); }
        return tok.nextToken();
    }
    int ni() throws IOException { return Integer.parseInt(next()); }
    long nl() throws IOException { return Long.parseLong(next()); }

    int[][] X,Y,A;
    int n;

    void solve() throws IOException {
        n=ni();
        X=new int[n+1][n+1];
        Y=new int[n+1][n+1];
        A=new int[n+1][n+1];

        for (int x=1;x<=n;x++) {
            for (int y=1;y<=n;y++) {
                X[x][y]=ni();
                Y[x][y]=ni();
                if (X[x][y]==x && Y[x][y]==y) A[x][y]=1;
            }
        }

        for (int x=1;x<=n;x++) {
            for (int y=1;y<=n;y++) {
                if (A[x][y]!=1) continue;
                fr(x,y,x,y);
            }
        }

        boolean f=true;

        outer:
        for (int x=1;x<=n;x++) {
            for (int y=1;y<=n;y++) {
                if (A[x][y]>0) continue;
                if (X[x][y]>-1 || Y[x][y]>-1) { f=false; break outer; }
                if (!fr2(x,y)) { f=false; break outer; }
            }
        }

        if (!f) out.println("INVALID");
        else {
            out.println("VALID");
            for (int x=1;x<=n;x++) {
                for (int y=1;y<=n;y++) {
                    if (A[x][y]==1) out.print("X");
                    if (A[x][y]==2) out.print("D");
                    if (A[x][y]==3) out.print("U");
                    if (A[x][y]==4) out.print("R");
                    if (A[x][y]==5) out.print("L");
                }
                out.println();
            }
        }
        out.flush();

    }

    boolean fr2(int x,int y) {

        if (x>1) {
            if (X[x-1][y]==-1) {
                if (A[x-1][y]==0) A[x-1][y]=2;
                A[x][y]=3;
                return true;
            }
        }
        if (x<n) {
            if (X[x+1][y]==-1) {
                if (A[x+1][y]==0) A[x+1][y]=3;
                A[x][y]=2;
                return true;
            }
        }
        if (y>1) {
            if (X[x][y-1]==-1) {
                if (A[x][y-1]==0) A[x-1][y]=4;
                A[x][y]=5;
                return true;
            }
        }
        if (y<n) {
            if (X[x][y+1]==-1) {
                if (A[x][y+1]==0) A[x][y+1]=5;
                A[x][y]=4;
                return true;
            }
        }
        return false;
    }

    void fr (int a,int b,int x,int y) {
        if (x>1) {
            if (A[x-1][y]==0 && X[x-1][y]==a && Y[x-1][y]==b) {
                A[x-1][y]=2;
                fr (a,b,x-1,y);
            }
        }
        if (x<n) {
            if (A[x+1][y]==0 && X[x+1][y]==a && Y[x+1][y]==b) {
                A[x+1][y]=3;
                fr (a,b,x+1,y);
            }
        }
        if (y>1) {
            if (A[x][y-1]==0 && X[x][y-1]==a && Y[x][y-1]==b) {
                A[x][y-1]=4;
                fr (a,b,x,y-1);
            }
        }
        if (y<n) {
            if (A[x][y+1]==0 && X[x][y+1]==a && Y[x][y+1]==b) {
                A[x][y+1]=5;
                fr (a,b,x,y+1);
            }
        }
    }

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


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

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

    static class DNashMatrix {
        pair par;
        pair[][] p;
        char[][] ans;
        boolean[][] vis;
        int n;

        public void solve(int testNumber, FastReader s, PrintWriter w) {
            n = s.nextInt();
            p = new pair[n][n];
            vis = new boolean[n][n];
            ans = new char[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) p[i][j] = new pair(s.nextInt() - 1, s.nextInt() - 1);
            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans[i][j] = 'a';
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                    if (vis[i][j]) continue;
                    if (p[i][j].x == i && p[i][j].y == j) {
                        par = p[i][j];
                        ans[i][j] = 'X';
                        dfs(p[i][j].x, p[i][j].y);
                    } else if (p[i][j].x == -2) {
                        pair cur = new pair(i, j);
                        par = p[i][j];
                        if (cur.x + 1 < n && p[cur.x + 1][cur.y].equals(par)) {
                            ans[i][j] = 'D';
                            dfs(i, j);
                        } else if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                            ans[i][j] = 'U';
                            dfs(i, j);
                        } else if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                            ans[i][j] = 'R';
                            dfs(i, j);
                        } else if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                            ans[i][j] = 'L';
                            dfs(i, j);
                        } else {
                            w.println("INVALID");
                            return;
                        }
                    }
                }
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (ans[i][j] == 'a') {
                        w.println("INVALID");
                        return;
                    }
            w.println("VALID");
            for (char[] c : ans) w.println(c);
        }

        void dfs(int x, int y) {
            pair cur = new pair(x, y);
            vis[cur.x][cur.y] = true;
            if (cur.x + 1 < n && !vis[cur.x + 1][cur.y] && p[cur.x + 1][cur.y].equals(par)) {
                ans[cur.x + 1][cur.y] = 'U';
                dfs(cur.x + 1, cur.y);
            }
            if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                ans[cur.x - 1][cur.y] = 'D';
                dfs(cur.x - 1, cur.y);
            }
            if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                ans[cur.x][cur.y + 1] = 'L';
                dfs(cur.x, cur.y + 1);
            }
            if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                ans[cur.x][cur.y - 1] = 'R';
                dfs(cur.x, cur.y - 1);
            }
        }

        class pair {
            int x;
            int y;

            pair(int xx, int yy) {
                x = xx;
                y = yy;
            }

            boolean equals(pair other) {
                return x == other.x && y == other.y;
            }

        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 boolean isSpaceChar(int c) {

            if (filter != null)
                return filter.isSpaceChar(c);

            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.AbstractCollection;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.LinkedList;
import java.io.InputStream;

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

    static class DNashMatrix {
        pair<Integer, Integer> par;
        pair<Integer, Integer>[][] p;
        char[][] ans;
        boolean[][] vis;
        int n;

        public void solve(int testNumber, FastReader s, PrintWriter w) {
            n = s.nextInt();
            p = new pair[n][n];
            vis = new boolean[n][n];
            ans = new char[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) p[i][j] = new pair<>(s.nextInt() - 1, s.nextInt() - 1);
            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans[i][j] = 'a';
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                    if (vis[i][j]) continue;
                    if (p[i][j].x == i && p[i][j].y == j) {
                        par = p[i][j];
                        ans[i][j] = 'X';
                        LinkedList<pair<Integer, Integer>> l = new LinkedList<>();
                        vis[i][j] = true;
                        l.add(new pair<>(i, j));
                        bfs(l);
                    } else if (p[i][j].x == -2) {
                        pair<Integer, Integer> cur = new pair<>(i, j);
                        par = p[i][j];
                        LinkedList<pair<Integer, Integer>> l = new LinkedList<>();
                        vis[i][j] = true;
                        l.add(new pair<>(i, j));
                        if (cur.x + 1 < n && p[cur.x + 1][cur.y].equals(par)) {
                            ans[i][j] = 'D';
                            bfs(l);
                        } else if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                            ans[i][j] = 'U';
                            bfs(l);
                        } else if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                            ans[i][j] = 'R';
                            bfs(l);
                        } else if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                            ans[i][j] = 'L';
                            bfs(l);
                        } else {
                            w.println("INVALID");
                            return;
                        }
                    }
                }
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (ans[i][j] == 'a') {
                        w.println("INVALID");
                        return;
                    }
            w.println("VALID");
            for (char[] c : ans) w.println(c);
        }

        void bfs(LinkedList<pair<Integer, Integer>> l) {
            while (!l.isEmpty()) {
                pair<Integer, Integer> cur = l.poll();
                if (cur.x + 1 < n && !vis[cur.x + 1][cur.y] && p[cur.x + 1][cur.y].equals(par)) {
                    ans[cur.x + 1][cur.y] = 'U';
                    vis[cur.x + 1][cur.y] = true;
                    l.add(new pair<>(cur.x + 1, cur.y));
                }
                if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                    ans[cur.x - 1][cur.y] = 'D';
                    vis[cur.x - 1][cur.y] = true;
                    l.add(new pair<>(cur.x - 1, cur.y));
                }
                if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                    ans[cur.x][cur.y + 1] = 'L';
                    vis[cur.x][cur.y + 1] = true;
                    l.add(new pair<>(cur.x, cur.y + 1));
                }
                if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                    ans[cur.x][cur.y - 1] = 'R';
                    vis[cur.x][cur.y - 1] = true;
                    l.add(new pair<>(cur.x, cur.y - 1));
                }
            }
        }

    }

    static class pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<pair<U, V>> {
        public U x;
        public V y;

        public pair(U x, V y) {
            this.x = x;
            this.y = y;
        }

        public int compareTo(pair<U, V> other) {
            int i = x.compareTo(other.x);
            if (i != 0) return i;
            return y.compareTo(other.y);
        }

        public String toString() {
            return x.toString() + " " + y.toString();
        }

        public boolean equals(Object obj) {
            if (this.getClass() != obj.getClass()) return false;
            pair<U, V> other = (pair<U, V>) obj;
            return x.equals(other.x) && y.equals(other.y);
        }

        public int hashCode() {
            return 31 * x.hashCode() + y.hashCode();
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 boolean isSpaceChar(int c) {

            if (filter != null)
                return filter.isSpaceChar(c);

            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


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

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

    static class DNashMatrix {
        pair<Integer, Integer> par;
        pair<Integer, Integer>[][] p;
        char[][] ans;
        boolean[][] vis;
        int n;

        public void solve(int testNumber, FastReader s, PrintWriter w) {
            n = s.nextInt();
            p = new pair[n][n];
            vis = new boolean[n][n];
            ans = new char[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) p[i][j] = new pair<>(s.nextInt() - 1, s.nextInt() - 1);
            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans[i][j] = 'a';
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                    if (vis[i][j]) continue;
                    if (p[i][j].x == i && p[i][j].y == j) {
                        par = p[i][j];
                        ans[i][j] = 'X';
                        dfs(p[i][j].x, p[i][j].y);
                    } else if (p[i][j].x == -2) {
                        pair<Integer, Integer> cur = new pair<>(i, j);
                        par = p[i][j];
                        if (cur.x + 1 < n && p[cur.x + 1][cur.y].equals(par)) {
                            ans[i][j] = 'D';
                            dfs(i, j);
                        } else if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                            ans[i][j] = 'U';
                            dfs(i, j);
                        } else if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                            ans[i][j] = 'R';
                            dfs(i, j);
                        } else if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                            ans[i][j] = 'L';
                            dfs(i, j);
                        } else {
                            w.println("INVALID");
                            return;
                        }
                    }
                }
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (ans[i][j] == 'a') {
                        w.println("INVALID");
                        return;
                    }
            w.println("VALID");
            for (char[] c : ans) w.println(c);
        }

        void dfs(int x, int y) {
            pair<Integer, Integer> cur = new pair<>(x, y);
            vis[cur.x][cur.y] = true;
            if (cur.x + 1 < n && !vis[cur.x + 1][cur.y] && p[cur.x + 1][cur.y].equals(par)) {
                ans[cur.x + 1][cur.y] = 'U';
                dfs(cur.x + 1, cur.y);
            }
            if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                ans[cur.x - 1][cur.y] = 'D';
                dfs(cur.x - 1, cur.y);
            }
            if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                ans[cur.x][cur.y + 1] = 'L';
                dfs(cur.x, cur.y + 1);
            }
            if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                ans[cur.x][cur.y - 1] = 'R';
                dfs(cur.x, cur.y - 1);
            }
        }

    }

    static class pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<pair<U, V>> {
        public U x;
        public V y;

        public pair(U x, V y) {
            this.x = x;
            this.y = y;
        }

        public int compareTo(pair<U, V> other) {
            int i = x.compareTo(other.x);
            if (i != 0) return i;
            return y.compareTo(other.y);
        }

        public String toString() {
            return x.toString() + " " + y.toString();
        }

        public boolean equals(Object obj) {
            if (this.getClass() != obj.getClass()) return false;
            pair<U, V> other = (pair<U, V>) obj;
            return x.equals(other.x) && y.equals(other.y);
        }

        public int hashCode() {
            return 31 * x.hashCode() + y.hashCode();
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 boolean isSpaceChar(int c) {

            if (filter != null)
                return filter.isSpaceChar(c);

            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


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

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

    static class DNashMatrix {
        pair par;
        pair[][] p;
        char[][] ans;
        boolean[][] vis;
        int n;

        public void solve(int testNumber, FastReader s, PrintWriter w) {
            n = s.nextInt();
            p = new pair[n][n];
            vis = new boolean[n][n];
            ans = new char[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) p[i][j] = new pair(s.nextInt() - 1, s.nextInt() - 1);
            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans[i][j] = 'a';
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                    if (vis[i][j]) continue;
                    if (p[i][j].x == i && p[i][j].y == j) {
                        par = p[i][j];
                        ans[i][j] = 'X';
                        dfs(p[i][j].x, p[i][j].y);
                    } else if (p[i][j].x == -2) {
                        pair cur = new pair(i, j);
                        par = p[i][j];
                        if (cur.x + 1 < n && p[cur.x + 1][cur.y].equals(par)) {
                            ans[i][j] = 'D';
                            dfs(i, j);
                        } else if (cur.x - 1 >= 0 && !vis[cur.x - 1][cur.y] && p[cur.x - 1][cur.y].equals(par)) {
                            ans[i][j] = 'U';
                            dfs(i, j);
                        } else if (cur.y + 1 < n && !vis[cur.x][cur.y + 1] && p[cur.x][cur.y + 1].equals(par)) {
                            ans[i][j] = 'R';
                            dfs(i, j);
                        } else if (cur.y - 1 >= 0 && !vis[cur.x][cur.y - 1] && p[cur.x][cur.y - 1].equals(par)) {
                            ans[i][j] = 'L';
                            dfs(i, j);
                        } else {
                            w.println("INVALID");
                            return;
                        }
                    }
                }
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    if (ans[i][j] == 'a') {
                        w.println("INVALID");
                        return;
                    }
            w.println("VALID");
            for (char[] c : ans) w.println(c);
        }

        void dfs(int x, int y) {
            vis[x][y] = true;
            if (x + 1 < n && !vis[x + 1][y] && p[x + 1][y].equals(par)) {
                ans[x + 1][y] = 'U';
                dfs(x + 1, y);
            }
            if (x - 1 >= 0 && !vis[x - 1][y] && p[x - 1][y].equals(par)) {
                ans[x - 1][y] = 'D';
                dfs(x - 1, y);
            }
            if (y + 1 < n && !vis[x][y + 1] && p[x][y + 1].equals(par)) {
                ans[x][y + 1] = 'L';
                dfs(x, y + 1);
            }
            if (y - 1 >= 0 && !vis[x][y - 1] && p[x][y - 1].equals(par)) {
                ans[x][y - 1] = 'R';
                dfs(x, y - 1);
            }
        }

        class pair {
            int x;
            int y;

            pair(int xx, int yy) {
                x = xx;
                y = yy;
            }

            boolean equals(pair other) {
                return x == other.x && y == other.y;
            }

        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 boolean isSpaceChar(int c) {

            if (filter != null)
                return filter.isSpaceChar(c);

            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


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

public class Main{
  static int repow(int b,int p){
    long a = b;
    long res=1;
    while(p>0){
      if(p%2==1){
        res*=a;
      }
      a*=a;
      p/=2;
    }
    return (int)res;
  }
  static int repow(int b,int p,int modder){
    long a = b%modder;
    long res=1;
    while(p>0){
      if(p%2==1){
        res=(res*a)%modder;
      }
      a=(a*a)%modder;
      p/=2;
    }
    return (int)res;
  }
  static long repow(long b,long p){
    long a = b;
    long res=1;
    while(p>0){
      if(p%2==1){
        res*=a;
      }
      a*=a;
      p/=2;
    }
    return res;
  }
  static long repow(long b,long p,long modder){
    long a = b%modder;
    long res=1;
    while(p>0){
      if(p%2==1){
        res=(res*a)%modder;
      }
      a=(a*a)%modder;
      p/=2;
    }
    return res;
  }
  static long gcd(long c,long d){
    while(true){
      long f=c%d;
      if(f==0){
        return d;
      }
      c=d;
      d=f;
    }
  }
  static long lcm(long c,long d){
    return c/gcd(c,d)*d;
  }
  static ArrayList<Integer> divList(int n){
    ArrayList<Integer> div=new ArrayList<Integer>();
    for(int i=1;i*i<=n;i++){
      if(n%i==0){
        div.add(i);
        if(i*i!=n){
          div.add((int)(n/i));
        }
      }
    }
    return div;
  }
  static HashSet<Integer> divSet(int n){
    HashSet<Integer> div=new HashSet<Integer>();
    for(int i=1;i*i<=n;i++){
      if(n%i==0){
        div.add(i);
        div.add((int)(n/i));
      }
    }
    return div;
  }
  static Map<Long,Integer> pFacMap(long x){
    Map<Long,Integer> mp=new HashMap<>();
    long t=x;
    for(long i=2;i*i<=x&&i<=t;i++){
      if(t%i==0){
        int num=0;
        while(t%i==0){
          t/=i;
          num++;
        }
        mp.put(i,num);
      }
    }
    if(t!=1){
      mp.put(t,1);
    }
    return mp;
  }
  static boolean iP(long n){
    if(n==2){
      return true;
    }
    if((n&1)==0||n==1){
      return false;
    }
//    if(n>3037007383L){
    if(n>Integer.MAX_VALUE){
      return tameshiwari(n);
    }
    long d=n-1;
    int s=0;
    while((d&1)==0){
      d/=2;
      s++;
    }
    int[] aa = {2,3,5,7,11,13,17};
    for(int i=0;i<7&&aa[i]<n;i++){
      int a = aa[i];
      long t = d;
      long y=repow(a,t,n);
      while(t!=n-1&&y!=1&&y!=n-1){
        y = (y*y)%n;
        t=t<<1;
      }
      if(y!=n-1&&(t&1)==0){
        return false;
      }
    }
    return true;
  }
  static boolean tameshiwari(long n){
    for(long i=2;i*i<=n;i++){
      if(n%i==0){
        return false;
      }
    }
    return true;
  }
  static class NCK{
    int max;
    int mod;
    long[] fac;
    long[] finv;
    long[] inv;
    NCK(){
      this(510000,1000000007);
    }
    NCK(int max,int mod){
      this.max=max;
      this.mod=mod;
      pre(max,mod);
    }
    void pre(int nmax,int nmod){
      fac = new long[nmax];
      finv = new long[nmax];
      inv = new long[nmax];
      fac[0]=fac[1]=1;
      finv[0]=finv[1]=1;
      inv[1]=1;
      for(int i=2;i<nmax;i++){
        fac[i]=fac[i-1]*i%nmod;
        inv[i]=nmod-inv[nmod%i]*(nmod/i)%nmod;
        finv[i]=finv[i-1]*inv[i]%nmod;
      }
    }
    long nCk(int n,int k){
      if(n<k){return 0;}
      if(n<0||k<0){return 0;}
      return fac[n]*(finv[k]*finv[n-k]%mod)%mod;
    }
  }
  static <T extends Comparable<T>> int BSA(List<T> l,T target){
    return BSA(l,target,0,l.size(),(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSA(List<T> l,T target,Comparator<T> c){
    return BSA(l,target,0,l.size(),c);
  }
  static <T extends Comparable<T>> int BSA(List<T> l,T target,int left,int right){
    return BSA(l,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSA(List<T> l,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=l.get(lt+(rt-lt)/2);
      if(c.compare(gaze,target)<0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>0){
        rt=lt+(rt-lt)/2-1;
      }else{
        return lt+(rt-lt)/2;
      }
    }
    return -1;
  }
  static <T extends Comparable<T>> int BSF(List<T> l,T target){
    return BSF(l,target,0,l.size(),(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSF(List<T> l,T target,Comparator<T> c){
    return BSF(l,target,0,l.size(),c);
  }
  static <T extends Comparable<T>> int BSF(List<T> l,T target,int left,int right){
    return BSF(l,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSF(List<T> l,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=l.get(lt+(rt-lt)/2);
      if(c.compare(gaze,target)<0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>=0){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static <T extends Comparable<T>> int BSL(List<T> l,T target){
    return BSL(l,target,0,l.size(),(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSL(List<T> l,T target,Comparator<T> c){
    return BSL(l,target,0,l.size(),c);
  }
  static <T extends Comparable<T>> int BSL(List<T> l,T target,int left,int right){
    return BSL(l,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSL(List<T> l,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=l.get(lt+(rt-lt)/2);
      if(c.compare(gaze,target)<=0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>0){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static <T extends Comparable<T>> int BSA(T[] a,T target){
    return BSA(a,target,0,a.length,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSA(T[] a,T target,Comparator<T> c){
    return BSA(a,target,0,a.length,c);
  }
  static <T extends Comparable<T>> int BSA(T[] a,T target,int left,int right){
    return BSA(a,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSA(T[] a,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=a[lt+(rt-lt)/2];
      if(c.compare(gaze,target)<0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>0){
        rt=lt+(rt-lt)/2-1;
      }else{
        return lt+(rt-lt)/2;
      }
    }
    return -1;
  }
  static <T extends Comparable<T>> int BSF(T[] a,T target){
    return BSF(a,target,0,a.length,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSF(T[] a,T target,Comparator<T> c){
    return BSF(a,target,0,a.length,c);
  }
  static <T extends Comparable<T>> int BSF(T[] a,T target,int left,int right){
    return BSF(a,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSF(T[] a,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=a[lt+(rt-lt)/2];
      if(c.compare(gaze,target)<0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>=0){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static <T extends Comparable<T>> int BSL(T[] a,T target){
    return BSL(a,target,0,a.length,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSL(T[] a,T target,Comparator<T> c){
    return BSL(a,target,0,a.length,c);
  }
  static <T extends Comparable<T>> int BSL(T[] a,T target,int left,int right){
    return BSL(a,target,left,right,(s1,s2)->s1.compareTo(s2));
  }
  static <T> int BSL(T[] a,T target,int left,int right,Comparator<T> c){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      T gaze=a[lt+(rt-lt)/2];
      if(c.compare(gaze,target)<=0){
        lt=lt+(rt-lt)/2+1;
      }else if(c.compare(gaze,target)>0){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static int BSA(int[] a,int target){
    return BSA(a,target,0,a.length,true);
  }
  static int BSA(int[] a,int target, boolean syojun){
    return BSA(a,target,0,a.length,syojun);
  }
  static int BSA(int[] a,int target,int left,int right){
    return BSA(a,target,left,right,true);
  }
  static int BSA(int[] a,int target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      int gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<target)||(!syojun&&gaze>target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze>target)||(!syojun&&gaze<target)){
        rt=lt+(rt-lt)/2-1;
      }else{
        return lt+(rt-lt)/2;
      }
    }
    return -1;
  }
  static int BSF(int[] a,int target){
    return BSF(a,target,0,a.length,true);
  }
  static int BSF(int[] a,int target,boolean syojun){
    return BSF(a,target,0,a.length,syojun);
  }
  static int BSF(int[] a,int target,int left,int right){
    return BSF(a,target,left,right,true);
  }
  static int BSF(int[] a,int target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      int gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<target)||(!syojun&&gaze>target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze<=target)||(!syojun&&gaze>=target)){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static int BSL(int[] a,int target){
    return BSL(a,target,0,a.length,true);
  }
  static int BSL(int[] a,int target,boolean syojun){
    return BSL(a,target,0,a.length,syojun);
  }
  static int BSL(int[] a,int target,int left,int right){
    return BSL(a,target,left,right,true);
  }
  static int BSL(int[] a,int target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      int gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<=target)||(!syojun&&gaze>=target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze>target)||(!syojun&&gaze<target)){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static int BSA(long[] a,long target){
    return BSA(a,target,0,a.length,true);
  }
  static int BSA(long[] a,long target, boolean syojun){
    return BSA(a,target,0,a.length,syojun);
  }
  static int BSA(long[] a,long target,int left,int right){
    return BSA(a,target,left,right,true);
  }
  static int BSA(long[] a,long target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      long gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<target)||(!syojun&&gaze>target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze>target)||(!syojun&&gaze<target)){
        rt=lt+(rt-lt)/2-1;
      }else{
        return lt+(rt-lt)/2;
      }
    }
    return -1;
  }
  static int BSF(long[] a,long target){
    return BSF(a,target,0,a.length,true);
  }
  static int BSF(long[] a,long target,boolean syojun){
    return BSF(a,target,0,a.length,syojun);
  }
  static int BSF(long[] a,long target,int left,int right){
    return BSF(a,target,left,right,true);
  }
  static int BSF(long[] a,long target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      long gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<target)||(!syojun&&gaze>target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze<=target)||(!syojun&&gaze>=target)){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static int BSL(long[] a,long target){
    return BSL(a,target,0,a.length,true);
  }
  static int BSL(long[] a,long target,boolean syojun){
    return BSL(a,target,0,a.length,syojun);
  }
  static int BSL(long[] a,long target,int left,int right){
    return BSL(a,target,left,right,true);
  }
  static int BSL(long[] a,long target,int left,int right,boolean syojun){
    int lt = left;
    int rt = right-1;
    while(lt<=rt){
      long gaze=a[lt+(rt-lt)/2];
      if((syojun&&gaze<=target)||(!syojun&&gaze>=target)){
        lt=lt+(rt-lt)/2+1;
      }else if((syojun&&gaze>target)||(!syojun&&gaze<target)){
        rt=lt+(rt-lt)/2-1;
      }
    }
    return lt;
  }
  static int kmp(String t,String p){
    int[] f=new int[p.length()+1];
    int i=0;
    int j=1;
    f[1]=0;
    while(j<p.length()){
      if(i==0||p.charAt(i-1)==p.charAt(j-1)){
        i++;
        j++;
        f[j]=i;
      }else{
        i=f[i];
      }
    }
    i=1;
    j=1;
    while(i<=p.length()&&j<=t.length()){
      if(i==0||p.charAt(i-1)==t.charAt(j-1)){
        i++;
        j++;
      }else{
        i=f[i];
      }
    }
    return i==(p.length()+1)?j-i:-1;
  }
  static String StSort(String s){
    StringBuilder sb = new StringBuilder(s);
    int lg = sb.length();
    int l;
    int r;
    int gaze;
    for(int i=1;i<lg;i++){
      l=0;
      r=i-1;
      while(l<=r){
        gaze=(l+r)/2;
        if(sb.charAt(gaze)<=sb.charAt(i)){
          l=gaze+1;
        }else if(sb.charAt(gaze)>sb.charAt(i)){
          r=gaze-1;
        }
      }
      sb.insert(l,sb.charAt(i));
      sb.deleteCharAt(i+1);
    }
    return sb.toString();
  }
  static class Xy{
    int x;
    int y;
    Xy(int x,int y){
      this.x=x;
      this.y=y;
    }
    public int manht(Xy o){
      return Math.abs(x-o.x)+Math.abs(y-o.y);
    }
    public String toString(){
      return "["+x+","+y+"]";
    }
    public double henkaku(){
      return Math.atan2(y,x);
    }
    public static int hencom(Xy s1,Xy s2){
      return (int)Math.signum(s1.henkaku()-s2.henkaku());
    }
    public boolean equals(Object o){
      return x==((Xy)o).x&&y==((Xy)o).y;
    }
  }
  static class Zip1{
    Map<Long,Integer> zip=new HashMap<>();
    long[] unzip;
    Zip1(long[] a){
      Arrays.sort(a);
      long mae=0;int zure=0;
      for(int i=0;i<a.length;i++){
        if(i==0||mae!=a[i]){
          zip.put(a[i],i-zure);
          mae=a[i];
        }else{
          zure++;
        }
      }
      unzip=new long[size()];
      for(Map.Entry<Long,Integer> me:zip.entrySet()){
        unzip[me.getValue()]=me.getKey();
      }
    }
    int zip(long t){
      return zip.get(t);
    }
    long unzip(int i){
      return unzip[i];
    }
    int size(){
      return zip.size();
    }
  }
  static class UnFd{
    int n;
    int[] a;
    int[] size;
    int forest;
    UnFd(int n){
      forest=this.n=n;
      a = new int[n];
      size = new int[n];
      for(int i=0;i<n;i++){
        a[i] = i;
        size[i]=1;
      }
    }
    boolean isRoot(int i){
      return a[i]==i;
    }
    int rootOf(int i){
      if(isRoot(i)){
        return i;
      }
      return a[i] = rootOf(a[i]);
    }
    boolean ud(int i,int j){
      return rootOf(i)==rootOf(j);
    }
    boolean marge(int i,int j){
      if(ud(i,j)){
        return false;
      }
      i=rootOf(i);
      j=rootOf(j);
      a[Integer.max(i,j)]=Integer.min(i,j);
      size[j]=size[i]=size[i]+size[j];
      forest-=1;
      return true;
    }
    int sizeOf(int i){
      return size[rootOf(i)];
    }
    int[] roots(){
      int[] rs = new int[forest];
      int p=0;
      for(int i=0;i<n;i++){
        if(isRoot(i)){
          rs[p]=i;
          p++;
        }
      }
      return rs;
    }
  }
  static class SegTree<T>{
    int n;
    int m;
    java.util.function.BinaryOperator<T> op;
    int[] l;
    int[] r;
    T[] a;
    T ident;
    SegTree(int n,java.util.function.BinaryOperator<T> op,T ident){
      this.n=n;
      this.op=op;
      this.ident=ident;
      int ii=n-1;
      int p=0;
      while(ii>0){
        ii/=2;
        p++;
      }
      m=repow(2,p+1)-1;
      @SuppressWarnings("unchecked")
      T[] b=(T[])(new Object[m]);
      a=b;
      Arrays.fill(a,ident);
      l=new int[m];
      r=new int[m];
      for(int i=0;i<=m/2;i++){
        l[m/2+i]=i;
        r[m/2+i]=i+1;
      }
      for(int i=m/2-1;i>=0;i--){
        l[i]=l[lch(i)];
        r[i]=r[rch(i)];
      }
    }
    SegTree(int n,java.util.function.BinaryOperator<T> op,T ident,T[] ary){
      this.n=n;
      this.op=op;
      this.ident=ident;
      int ii=n-1;
      int p=0;
      while(ii>0){
        ii/=2;
        p++;
      }
      m=repow(2,p+1)-1;
      @SuppressWarnings("unchecked")
      T[] b=(T[])(new Object[m]);
      a=b;
      for(int i=0;i<n;i++){
        a[m/2+i]=ary[i];
      }
      for(int i=m/2+n;i<m;i++){
        a[i]=ident;
      }
      for(int i=m/2-1;i>=0;i--){
        a[i]=op.apply(a[lch(i)],a[rch(i)]);
      }
      l=new int[m];
      r=new int[m];
      for(int i=0;i<=m/2;i++){
        l[m/2+i]=i;
        r[m/2+i]=i+1;
      }
      for(int i=m/2-1;i>=0;i--){
        l[i]=l[lch(i)];
        r[i]=r[rch(i)];
      }
    }
    public T getAll(){
      return a[0];
    }
    public T get(int from,int to){
      if(from<0||n<to||from>=to){
        throw new IllegalArgumentException(String.valueOf(from)+","+String.valueOf(to));
      }
      return get(from,to,0);
    }
    private T get(int from,int to,int node){
      if(from==l[node]&&to==r[node]){
        return a[node];
      }else{
        if(to<=l[node]+(r[node]-l[node])/2){
          return get(from,to,lch(node));
        }else if(l[node]+(r[node]-l[node])/2<=from){
          return get(from,to,rch(node));
        }else{
          return op.apply(get(from,l[node]+(r[node]-l[node])/2,lch(node)),get(l[node]+(r[node]-l[node])/2,to,rch(node)));
        }
      }
    }
    public void set(T ob,int i){
      if(i<0||n<=i){
        throw new IndexOutOfBoundsException(String.valueOf(i)+"isOutFromLength "+String.valueOf(n));
      }
      int j=m/2+i;
      a[j]=ob;
      while(true){
        if(j==0){
          break;
        }
        j=prt(j);
        a[j]=op.apply(a[lch(j)],a[rch(j)]);
      }
    }
    static private int prt(int node){
      return (node-1)/2;
    }
    static private int lch(int node){
      return 2*node+1;
    }
    static private int rch(int node){
      return 2*node+2;
    }
    public String toString(){
      return Arrays.toString(a);
    }
  }
  static boolean next_permutation(int[] per){
    if(per.length<2){
      return false;
    }
    int i;
    for(i=per.length-1;i>0;i--){
      if(per[i-1]<per[i]){
        break;
      }
    }
    if(0<i){
      i--;
      int tmp;
      int j;
      for(j=per.length-1;j>i;j--){
        if(per[j]>per[i]){
          break;
        }
      }
      //swap(i,j)
      tmp=per[i];
      per[i]=per[j];
      per[j]=tmp;
      for(int k=i+1;k<(i+1+per.length)/2;k++){
        //swap(k,per.length-k+i)
        tmp=per[k];
        per[k]=per[per.length-k+i];
        per[per.length-k+i]=tmp;
      }
      return true;
    }
    int tmp;
    for(int k=0;k<per.length;k++){
      //swap(k,per.length-k-1)
      tmp=per[k];
      per[k]=per[per.length-k-1];
      per[per.length-k-1]=tmp;
    }
    return false;
  }
  static boolean next_bits(boolean[] b){
    for(int i=0;i<b.length;i++){
      if(b[i]){
        b[i]=false;
      }else{
        b[i]=true;
        return true;
      }
    }
    return false;
  }
  static class Scnr{
    private final InputStream ins;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    Scnr(){
      this(System.in);
    }
    Scnr(InputStream in){
      ins = in;
    }
    private boolean hasNextByte(){
      if(ptr<buflen){
        return true;
      }else{
        ptr = 0;
        try{
          buflen = ins.read(buffer);
        }catch(IOException e){
          e.printStackTrace();
        }
        if(buflen<=0){
          return false;
        }
      }
      return true;
    }
    private int readByte(){
      if(hasNextByte()){
        return buffer[ptr++];
      }else{
        return -1;
      }
    }
    private static boolean isPrintableChar(int c){
      return 33<=c&&c<=126;
    }
    public boolean hasNext(){
      while(hasNextByte()&&!isPrintableChar(buffer[ptr])){
        ptr++;
      }
      return hasNextByte();
    }
    public String next(){
      return nextBuilder().toString();
    }
    public StringBuilder nextBuilder(){
      if(!hasNext()){
        throw new NoSuchElementException();
      }
      StringBuilder sb = new StringBuilder();
      int b = readByte();
      while(isPrintableChar(b)){
        sb.appendCodePoint(b);
        b = readByte();
      }
      return sb;
    }
    public double nextDouble(){
      return Double.parseDouble(next());
    }
    public long nextLong(){
      if(!hasNext()){
        throw new NoSuchElementException();
      }
      long n = 0;
      boolean minus = false;
      int b = readByte();
      if(b=='-'){
        minus=true;
        b=readByte();
      }
      if(b<'0'||'9'<b){
        throw new NumberFormatException();
      }
      while(true){
        if('0'<=b&&b<='9'){
          n*=10;
          n+=b-'0';
        }else if(b==-1||!isPrintableChar(b)){
          return minus?-n:n;
        }else{
          throw new NumberFormatException();
        }
        b=readByte();
      }
    }
    public int nextInt(){
      long nl=nextLong();
      if(nl<Integer.MIN_VALUE||Integer.MAX_VALUE<nl){
        throw new NumberFormatException();
      }
      return (int) nl;
    }
    public String[] nextA(int n){
      String[] a = new String[n];
      nextA(a,n);
      return a;
    }
    public void nextA(String[] a,int n){
      nextA(a,0,n);
    }
    public void nextA(String[] a,int off,int len){
      for(int i=off;i<off+len;i++){
        a[i]=next();
      }
    }
    public int[] nextAInt(int n){
      int[] a = new int[n];
      nextAInt(a,n);
      return a;
    }
    public void nextAInt(int[] a,int n){
      nextAInt(a,0,n);
    }
    public void nextAInt(int[] a,int off,int len){
      for(int i=off;i<off+len;i++){
        a[i] = nextInt();
      }
    }
    public long[] nextALong(int n){
      long[] a = new long[n];
      nextALong(a,n);
      return a;
    }
    public void nextALong(long[] a,int n){
      nextALong(a,0,n);
    }
    public void nextALong(long[] a,int off,int len){
      for(int i=off;i<off+len;i++){
        a[i] = nextLong();
      }
    }
    public double[] nextADouble(int n){
      double[] a = new double[n];
      nextADouble(a,n);
      return a;
    }
    public void nextADouble(double[] a,int n){
      nextADouble(a,0,n);
    }
    public void nextADouble(double[] a,int off,int len){
      for(int i=off;i<off+len;i++){
        a[i] = nextDouble();
      }
    }
    public List<Integer> nextLInt(int n){
      List<Integer> l = new ArrayList<>(n);
      for(int i=0;i<n;i++){
        l.add(sc.nextInt());
      }
      return l;
    }
    public List<Long> nextLLong(int n){
      List<Long> l = new ArrayList<>(n);
      for(int i=0;i<n;i++){
        l.add(sc.nextLong());
      }
      return l;
    }
    public List<Double> nextLDouble(int n){
      List<Double> l = new ArrayList<>(n);
      for(int i=0;i<n;i++){
        l.add(sc.nextDouble());
      }
      return l;
    }
  }

  static Scnr sc = new Scnr();
  static PrintWriter out = new PrintWriter(System.out);
  public static void main(String args[]){
    solve();
    out.flush();
  }
  static int[] dy={ 0, 1, 0,-1};
  static int[] dx={ 1, 0,-1, 0};
  static char[] dd={'L','U','R','D'};
  static char[] de={'R','D','L','U'};
  static void solve(){
    int n=sc.nextInt();
    final Xy inf=new Xy(-2,-2);
    Set<Xy> bst=new HashSet<>();
    Xy[][] xys=new Xy[n][n];
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        xys[i][j]=new Xy(sc.nextInt()-1,sc.nextInt()-1);
        if(xys[i][j].y==i&&xys[i][j].x==j){
          bst.add(xys[i][j]);
        }
      }
    }
    char[][] ans=new char[n][n];
System.err.println(ans[0][0]);
    for(Xy block:bst){
      Deque<Xy> dq=new ArrayDeque<>();
      Xy goal=block;
      ans[block.y][block.x]='X';
      dq.addFirst(block);
      while(!dq.isEmpty()){
        Xy here=dq.pollFirst();
        for(int i=0;i<4;i++){
          int x=here.x+dx[i];
          int y=here.y+dy[i];
          if(x<0||n<=x||y<0||n<=y){
            continue;
          }
          if(ans[y][x]==0&&goal.equals(xys[y][x])){
            ans[y][x]=dd[i];
            dq.add(xys[y][x]);
          }
        }
      }
    }
for(int i=0;i<n;i++){
  System.err.println(Arrays.toString(ans[i]));
}
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        if(ans[i][j]==0){
          if(xys[i][j].equals(inf)){
            for(int k=0;k<4;k++){
              int x=j+dx[k];
              int y=i+dy[k];
              if(x<0||n<=x||y<0||n<=y){
                continue;
              }
              if(xys[x][y].equals(inf)){
                ans[i][j]=de[k];
                break;
              }
            }
            if(ans[i][j]==0){
              out.println("INVALID");
              return;
            }
          }else{
            out.println("INVALID");
            return;
          }
        }
      }
    }
    out.println("VALID");
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
        out.print(ans[i][j]);
      }
      out.println();
    }
  }
}