Problem: Now Vasya is taking an exam in mathematics. In order to get a good mark, Vasya needs to guess the matrix that the teacher has constructed!

Vasya knows that the matrix consists of n rows and m columns. For each row, he knows the xor (bitwise excluding or) of the elements in this row. The sequence a1, a2, ..., an denotes the xor of elements in rows with indices 1, 2, ..., n, respectively. Similarly, for each column, he knows the xor of the elements in this column. The sequence b1, b2, ..., bm denotes the xor of elements in columns with indices 1, 2, ..., m, respectively.

Help Vasya! Find a matrix satisfying the given constraints or tell him that there is no suitable matrix.

Input

The first line contains two numbers n and m (2 ≤ n, m ≤ 100) — the dimensions of the matrix.

The second line contains n numbers a1, a2, ..., an (0 ≤ ai ≤ 109), where ai is the xor of all elements in row i.

The third line contains m numbers b1, b2, ..., bm (0 ≤ bi ≤ 109), where bi is the xor of all elements in column i.

Output

If there is no matrix satisfying the given constraints in the first line, output "NO".

Otherwise, on the first line output "YES", and then n rows of m numbers in each ci1, ci2, ... , cim (0 ≤ cij ≤ 2·109) — the description of the matrix.

If there are several suitable matrices, it is allowed to print any of them.

Examples

Input

2 3
2 9
5 3 13


Output

YES
3 4 5
6 7 8


Input

3 3
1 7 6
2 15 12


Output

NO

Solution (in JAVA):

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

// Solution

public class Main 
{    
  public static void main (String[] argv) 
  {
	  new Main();
  } 
     
  
  boolean test = false;  
  final int[][] dirs8 = {{0,1}, {0,-1}, {-1,0}, {1,0}, {1,1},{1,-1},{-1,1},{-1,-1}};
  final int MOD = 998244353;//1000000007;  
  int n_bit = 1;
  int[] bit;
  
  public Main()   {
	FastReader in = new FastReader(new BufferedReader(new InputStreamReader(System.in)));
	
     
    //FastReader in = new FastReader(new BufferedReader(new FileReader("Main.in")));   
    
    //int nt = in.nextInt();    
    int nt = 1;
    StringBuilder sb = new StringBuilder();
    
    
    for (int it = 0; it < nt; it++) 
    {
       int n = in.nextInt();
       int m = in.nextInt();
       
       int[] rsum = new int[n];
       int[] csum = new int[m];
       for (int i = 0; i < n; i++) rsum[i] = in.nextInt();
       for (int i = 0; i < m; i++) csum[i] = in.nextInt();
       
       int zero = 0;
       for (int v : rsum) zero ^= v;
       for (int v : csum) zero ^= v;
       if (zero != 0)
          System.out.println("NO");
       else {
          System.out.println("YES");
          int[][] a = new int[n][m];
          List<Integer> rones = new ArrayList<>();
          List<Integer> cones = new ArrayList<>();
          for (int digit = 0; digit < 32; digit ++)
          {
              int mask = 1 << digit;
              rones.clear();
              cones.clear();
              for (int i = 0; i < n; i++)
              {
                  if ((rsum[i] & mask) != 0)
                  {
                      rones.add(i);
                  }
              }
              
              for (int i = 0; i < m; i++)
              {
                  if ((csum[i] & mask) != 0)
                  {
                      cones.add(i);
                  }
              }
              if (rones.size() <= cones.size())
              {
                  int sz = rones.size();
                  for (int i = 0; i < sz; i++){
                      a[rones.get(i)][cones.get(i)] |= mask;                      
                  }
                  for (int i = sz; i < cones.size(); i++)
                      a[0][cones.get(i)] |= mask;     
              }else {
                  int sz = cones.size();
                  for (int i = 0; i < sz; i++){
                      a[rones.get(i)][cones.get(i)] |= mask;                      
                  }
                  for (int i = sz; i < rones.size(); i++)
                      a[rones.get(i)][0] |= mask; 
              }
          }
          
          for (int i = 0 ; i < n; i++){
              for (int j = 0; j < m; j++){
                  sb.append(a[i][j] + " ");
              }
              sb.append("\n");
          }
          System.out.print(sb);
          
          /*
          int[] myr = new int[n];
          int[] myc = new int[m];
          for (int i = 0; i < n; i++)
          {
              for (int j = 0; j < m; j++)
              {
                  myr[i] ^= a[i][j];
                  myc[j] ^= a[i][j];
              }             
              
          }
          
          System.out.println("my row sum : ");
          for (int i = 0 ; i < n; i++){
              System.out.print(myr[i] + " ");              
          }
          System.out.println();
          System.out.println("my col sum : ");
          for (int i = 0 ; i < m; i++){
              System.out.print(myc[i] + " ");              
          }
          System.out.println();
          */
       }
       //System.out.print(sb);
    }
    //System.out.print(sb);
  }
  
  private int[] build_z_function(String s)
  {
      int n = s.length();
      int[] zfun = new int[n];
      
      int l = -1, r = -1;
      for (int i = 1; i < n; i++)
      {
         // Set the start value
         if (i <= r)
            zfun[i] = Math.min(zfun[i-l], r - i + 1);
         
         while (i + zfun[i] < n && s.charAt(i + zfun[i]) == s.charAt(zfun[i])) 
             zfun[i]++;             
         
         if (i + zfun[i] - 1> r){
             l = i;
             r = i + zfun[i] - 1;
         }
      }
      
      if (test)
      {
          System.out.println("Z-function of " + s);
          for (int i = 0; i < n; i++) System.out.print(zfun[i] + " ");
          System.out.println();
      }
      return zfun;
  }
  
  private int query(int p)
  {
      int sum = 0;
      for (; p > 0; p -= (p & (-p)))
      {
          sum += bit[p];
      }
      return sum;
  }
  
  private void add(int p, int val)
  {
      //System.out.println("add to BIT " + p);
      for (; p <= n_bit; p += (p & (-p)))
      {
          bit[p] += val;
      }
  }
  
  
  
  private List<Integer> getMinFactor(int sum)
  {
      List<Integer>  factors = new ArrayList<>();
      
               for (int sz = 2; sz <= sum / sz; sz++){
                   if (sum % sz == 0) {
                       factors.add(sz);
                       factors.add(sum / sz);
                   }
               }
               if (factors.size() == 0)
                   factors.add(sum);
          
      return factors;
  }
  
  /* Tree class */
  class Tree {
      int V = 0;
      int root = 0;
      List<Integer>[] nbs;
      int[][] timeRange;
      int[] subTreeSize;
      int t;
      boolean dump = false;
      
      public Tree(int V, int root)
      {
          if (dump) 
              System.out.println("build tree with size = " + V + ", root = " + root); 
          
          this.V = V;          
          this.root = root;
          nbs = new List[V];
          subTreeSize = new int[V];
          for (int i = 0; i < V; i++)
              nbs[i] = new ArrayList<>();
          
              
      }
      
      public void doneInput()
      {
          dfsEuler();
      }
      
      public void addEdge(int p, int q)
      {
          nbs[p].add(q);
          nbs[q].add(p);
      }
      
      private void dfsEuler()
      {
          timeRange = new int[V][2];          
          t = 1;
          dfs(root);           
      }
      
      private void dfs(int node)
      {
          if (dump)
              System.out.println("dfs on node " + node + ", at time " + t);
          timeRange[node][0] = t;
          
          for (int next : nbs[node]) {
              if (timeRange[next][0] == 0)
              {
                  ++t;
                  dfs(next);                  
              }
          }
          timeRange[node][1] = t;
          subTreeSize[node] = t - timeRange[node][0] + 1;
      }
      
      public List<Integer> getNeighbors(int p) {
          return nbs[p];
      }
      
      public int[] getSubTreeSize(){
          return subTreeSize;
      }
      
      public int[][] getTimeRange()
      {
          if (dump){
              for (int i = 0; i < V; i++){
                  System.out.println(i + ": " + timeRange[i][0] + " - " + timeRange[i][1]);
              }
          }
          return timeRange;
      }
      
  }
  
  /* segment tree */
  class SegTree {
      long[] tree;
      long[] lazy;
      int n;
      boolean dump = false;
      
      public SegTree(int n)
      {
          if (dump)
              System.out.println("create segTree with size " + n);
          this.n = n;
          tree = new long[n*4];
          lazy = new long[n*4];
      }
      
      public SegTree(int n, int[] a) {
          this(n);
          buildTree(1, 0, n-1, a);
      }
      
      private void buildTree(int node, int lo, int hi, int[] a)
      {
          if (lo == hi) {
              tree[node] = a[lo];
              return;
          }
          
          int m = (lo + hi) / 2;
          buildTree(node * 2, lo, m, a);
          buildTree(node * 2 + 1, m + 1, hi, a);
          pushUp(node, lo, hi);
      }
      
      
      private void pushUp(int node, int lo, int hi)
      {
          if (lo >= hi) return;
          
          // add combine fcn
      }
      
      private void pushDown(int node, int lo, int hi)
      {
          if (lo > hi || lazy[node] == 0) return;
          
          tree[node] += lazy[node];
          tree[node] %= MOD;
          
          if (lo < hi) {              
              lazy[node * 2] += lazy[node];
              lazy[node * 2 + 1] += lazy[node];
              lazy[node * 2] %= MOD;
              lazy[node * 2 + 1] %= MOD;
          }
          
          lazy[node] = 0;
      }
      
      public void rangeUpdate(int fr, int to, long val)
      {
          if (dump)
              System.out.println("rangeUpdate : " + fr + " - " + to + " delta = " + val);
          rangeUpdate(1, 0, n-1, fr, to, val);
      }
      
      public long pointQuery(int p)
      {
          return pointQuery(1, 0, n-1, p);
      }
      
      
      private void rangeUpdate(int node, int lo, int hi, int fr, int to, long val)
      {
          if (dump)
              System.out.println("rangeUpdate : " + node + "[" + lo + " - " + hi + "]" + fr + " - " + to + " delta = " + val);
          
          pushDown(node, lo, hi);
          
          if (lo == fr && hi == to) {
              lazy[node] = val;              
              return;
          }
          
          int m = (lo + hi) / 2;
          if (to <=  m) 
              rangeUpdate(node * 2 , lo, m, fr, to, val);
          else if (fr > m)
              rangeUpdate(node * 2 + 1, m + 1, hi, fr, to, val);
          else {
              rangeUpdate(node * 2, lo, m, fr, m, val);
              rangeUpdate(node * 2 + 1, m + 1, hi, m + 1, to, val);
          }
          
          pushUp(node, lo, hi);          
      }
  
      /* pre-condition: lo <= p <= hi */
      private long pointQuery(int node, int lo, int hi, int p)
      {
          pushDown(node, lo, hi);
          
          if (lo == hi)
          {
              return tree[node];
          }
          
          int m = (lo + hi) / 2;
          if (p <= m) 
              return pointQuery(node * 2, lo, m, p);
          else
              return pointQuery(node * 2 + 1, m + 1, hi, p);
      }      
  
  }
  
  
  private long inv(long v)
  {
      return pow(v, MOD-2);
  }
  
  private long pow(long v, int p)
  {
      long ans = 1;
      while (p > 0)
      {
          if (p % 2 == 1)
              ans = ans * v % MOD;
          v = v * v % MOD;
          p = p / 2;
      }
      return ans;
  }
  
  private double dist(double x, double y, double xx, double yy)
  {
      return Math.sqrt((xx - x) * (xx - x) + (yy - y) * (yy - y));
  }
  

  
 
  private int mod_add(int a, int b) {
      int v = a + b;
      if (v >= MOD) v -= MOD;
      return v;
  }
  
  
  private long overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
      if (x1 > x3) return overlap(x3, y3, x4, y4, x1, y1, x2, y2);
      
      if (x3 > x2 || y4 < y1 || y3 > y2) return 0L;
      
      //(x3, ?, x2, ?)
      int yL = Math.max(y1, y3);
      int yH = Math.min(y2, y4); 
      int xH = Math.min(x2, x4);
      
      return f(x3, yL, xH, yH);
  }
  //return #black cells in rectangle
  private long f(int x1, int y1, int x2, int y2) {
      long dx = 1L + x2 - x1;
      long dy = 1L + y2 - y1;
      if (dx % 2 == 0 || dy % 2 == 0 || (x1 + y1) % 2 == 0) 
          return 1L * dx * dy / 2;
      return 1L * dx * dy / 2 + 1;
  }
  
  private int distM(int x, int y, int xx, int yy) {
      return abs(x - xx) + abs(y - yy);
  }
  
  private boolean less(int x, int y, int xx, int yy) {
      return x < xx || y > yy;
  }
  
  private int mul(int x, int y) {
      return (int)(1L * x * y % MOD);
  }
  
  
 
  
  private int nBit1(int v) {
      int v0 = v;
      int c = 0;
      while (v != 0) {
          ++c;
          v = v & (v - 1);
      }
      return c;
  }
  
  private long abs(long v) {
      return v > 0 ? v : -v;
  }
  
  private int abs(int v) {
      return v > 0 ? v : -v;
  }
  
  private int common(int v) {
      int c = 0;
      while (v != 1) {
          v = (v >>> 1);
          ++c;
      }
      
      return c;
  }
  
  private void reverse(char[] a, int i, int j) {
      while (i < j) {
          swap(a, i++, j--);
      }
  }
  
  private void swap(char[] a, int i, int j) {
      char t = a[i];
      a[i] = a[j];
      a[j] = t;
  }
  
  private int gcd(int x, int y) {
      if (y == 0) return x;
      return gcd(y, x % y);
  }
  private long gcd(long x, long y) {
      if (y == 0) return x;
      return gcd(y, x % y);
  }
  private int max(int a, int b) {
      return a >  b ? a : b;
  }
  
  private long max(long a, long b) {
      return a >  b ? a : b;
  }
  
  private int min(int a, int b) {
      return a >  b ? b : a;
  }
  
  private long min(long a, long b) {
      return a >  b ? b : a;
  }
  
  static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;
 
        public FastReader(BufferedReader in)
        {            
            br = in;
        }
 
        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    String line = br.readLine();
                    if (line == null || line.length() == 0) return "";
                    st = new StringTokenizer(line);
                }
                catch (IOException  e)
                {
                    return "";
                    //e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int nextInt()
        {
            return Integer.parseInt(next());
        }
 
        long nextLong()
        {
            return Long.parseLong(next());
        }
 
        double nextDouble()
        {
            return Double.parseDouble(next());
        }
 
        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                return null;
                //e.printStackTrace();
            }
            return str;
        }
    }
}