Problem: Let's define logical OR as an operation on two logical values (i. e. values that belong to the set {0, 1}) that is equal to 1 if either or both of the logical values is set to 1, otherwise it is 0. We can define logical OR of three or more logical values in the same manner:

<image> where <image> is equal to 1 if some ai = 1, otherwise it is equal to 0.

Nam has a matrix A consisting of m rows and n columns. The rows are numbered from 1 to m, columns are numbered from 1 to n. Element at row i (1 ≤ i ≤ m) and column j (1 ≤ j ≤ n) is denoted as Aij. All elements of A are either 0 or 1. From matrix A, Nam creates another matrix B of the same size using formula:

<image>.

(Bij is OR of all elements in row i and column j of matrix A)

Nam gives you matrix B and challenges you to guess matrix A. Although Nam is smart, he could probably make a mistake while calculating matrix B, since size of A can be large.

Input

The first line contains two integer m and n (1 ≤ m, n ≤ 100), number of rows and number of columns of matrices respectively.

The next m lines each contain n integers separated by spaces describing rows of matrix B (each element of B is either 0 or 1).

Output

In the first line, print "NO" if Nam has made a mistake when calculating B, otherwise print "YES". If the first line is "YES", then also print m rows consisting of n integers representing matrix A that can produce given matrix B. If there are several solutions print any one.

Examples

Input

2 2
1 0
0 0


Output

NO


Input

2 3
1 1 1
1 1 1


Output

YES
1 1 1
1 1 1


Input

2 3
0 1 0
1 1 1


Output

YES
0 0 0
0 1 0

Solution (in JAVA):

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

   public class GFG{
      public static void main (String[] args)  throws Exception
   	 {
         FastScanner sc=new FastScanner(System.in);
         PrintWriter out=new PrintWriter(System.out);
         

         int n=sc.nextInt();
         int m =sc.nextInt();

         int dp[][]=new int [n][m];
         int ans[][]=new int [n][m];

         for(int i =0 ;i<n;i++){
            Arrays.fill(ans[i],1);
         }
         for(int i=0;i<n;i++){
          for (int j=0;j<m;j++){
            dp[i][j]=sc.nextInt();
            if(dp[i][j]==0){
              for(int k=0;k<m;k++){
                ans[i][k]=0;
              }
              for(int k=0;k<n;k++){
                ans[k][j]=0;
              }
            }
          }
         }
         // for(int i=0;i<n;i++){
         //  out.println(Arrays.toString(ans[i]));
         // }
         int flag=0;
         for(int i=0;i<n;i++){
          for(int j=0;j<m;j++){
            if(dp[i][j]==1){
              
              flag=0;
              for(int k=0;k<m;k++){
                
                if(ans[i][k]==1) {flag=1;break;}
              }
              for(int k=0;k<n;k++){

                if(ans[k][j]==1) {flag=1;break;}
              }
              if(flag==0){
                flag=-1;
                break;
              } 
            }
          }
          if(flag==-1){
              flag=-1;
              break;
          }
         }

         if(flag==-1){
          out.println("NO");
         }
         else{
          out.println("YES");
          for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
              out.print(ans[i][j]+" ");
            }
            out.println();
          }
         }
         

         



         




         out.close();
         
      }

   }	
   class FastScanner
   {
      
      final private int BUFFER_SIZE = 1 << 17;
      private DataInputStream din;
      private byte[] buffer;
      private int bufferPointer, bytesRead;
    
      public FastScanner(InputStream in)
      {
         din = new DataInputStream(in);
         buffer = new byte[BUFFER_SIZE];
         bufferPointer = bytesRead = 0;
      }
      public String nextLine() throws Exception
      {
   	   StringBuffer sb=new StringBuffer("");
   	   byte c = read();
   	   while (c <= ' ') c = read();
   	   do
   	   {
   		   sb.append((char)c);
   		   c=read();
   	   }while(c>' ');
   	   return sb.toString();
      }

      public char nextChar() throws Exception
      {
   	   byte c=read();
   	   while(c<=' ') c= read();
   	   return (char)c;
      }

      public int nextInt() throws Exception
      {
         int ret = 0;
         byte c = read();
         while (c <= ' ') c = read();
         boolean neg = c == '-';
         if (neg) c = read();
         do
         {
       	  ret = ret * 10 + c - '0';
            c = read();
         } while (c > ' ');
         if (neg) return -ret;
         return ret;
      }

      public long nextLong() throws Exception
      {
         long ret = 0;
         byte c = read();
         while (c <= ' ') c = read();
         boolean neg = c == '-';
         if (neg) c = read();
         do
         {
       	   ret = ret * 10 + c - '0';
            c = read();
         } while (c > ' ');
         if (neg) return -ret;
         return ret;
      }

      private void fillBuffer() throws Exception
      {
         bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
         if (bytesRead == -1) buffer[0] = -1;
      }
    
      private byte read() throws Exception
      {
         if (bufferPointer == bytesRead) fillBuffer();
         return buffer[bufferPointer++];
      }
      public double nextDouble() throws Exception 
        { 
            double ret = 0, div = 1; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
  
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
  
            if (c == '.') 
            { 
                while ((c = read()) >= '0' && c <= '9') 
                { 
                    ret += (c - '0') / (div *= 10); 
                } 
            } 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
        private static int binarySearchPM(int[] arr, int key){
           int n = arr.length;
           int mid = -1;
           int begin = 0,end=n;
           while(begin <= end){
               mid = (begin+end) / 2;
               if(mid == n){
                   return n;
               }
               if(key < arr[mid]){
                   end = mid-1;
               } else if(key > arr[mid]){
                   begin = mid+1;
               } else {
                   return mid;
               }
           }
           //System.out.println(begin+" "+end);
           return -begin; //expected Index
      }
      // function to find last index <= y 
      static int upperIndex(int arr[], int n, int y) { 
           int l = 0, h = n - 1; 
           while (l <= h)  
           { 
               int mid = (l + h) / 2; 
               if (arr[mid] <= y) 
                   l = mid + 1; 
               else
                   h = mid - 1; 
           } 
           return h; 
       }
      static int lowerIndex(int arr[], int n, int x) { 
        int l = 0, h = n - 1; 
        while (l <= h)  
        { 
            int mid = (l + h) / 2; 
            if (arr[mid] >= x) 
                h = mid - 1; 
            else
                l = mid + 1; 
        } 
        return l; 
      } 
   }