Problem: You are storing an integer array of length m in a database. To maintain internal integrity and protect data, the database stores n copies of this array.

Unfortunately, the recent incident may have altered the stored information in every copy in the database.

It's believed, that the incident altered at most two elements in every copy. You need to recover the original array based on the current state of the database.

In case there are multiple ways to restore the array, report any. If there is no array that differs from every copy in no more than two positions, report that as well.

Input

The first line contains integers n and m (2 ≤ n; 1 ≤ m; n ⋅ m ≤ 250 000) — the number of copies and the size of the array.

Each of the following n lines describes one of the currently stored copies in the database, it consists of m integers s_{i, 1}, s_{i, 2}, ..., s_{i, m} (1 ≤ s_{i, j} ≤ 10^9).

Output

If there is an array consistent with all given copies, print "Yes" and then the array itself. The array must have length m and contain integers between 1 and 10^9 only.

Otherwise, print "No".

If there are multiple possible arrays, print any of them.

Examples

Input


3 4
1 10 10 100
1 1 1 100
10 100 1 100


Output


Yes
1 10 1 100


Input


10 7
1 1 1 1 1 1 1
1 1 1 1 1 1 2
1 1 1 1 1 2 2
1 1 1 1 2 2 1
1 1 1 2 2 1 1
1 1 2 2 1 1 1
1 2 2 1 1 1 1
2 2 1 1 1 1 1
2 1 1 1 1 1 1
1 1 1 1 1 1 1


Output


Yes
1 1 1 1 1 1 1


Input


2 5
2 2 1 1 1
1 1 2 2 2


Output


No

Note

In the first example, the array [1, 10, 1, 100] differs from first and second copies in just one position, and from the third copy in two positions.

In the second example, array [1, 1, 1, 1, 1, 1, 1] is the same as the first copy and differs from all other copies in at most two positions.

In the third example, there is no array differing in at most two positions from every database's copy.

Solution (in JAVA):

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

public class Absent_Students {

	static double dist(triple a, triple b) {
		return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
	}

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();

		a = new int[n][m];
		int[] diff = new int[n];
		int max = 0;
		for (int i = 0; i < n; i++) {
			int c = 0;
			for (int j = 0; j < m; j++) {
				a[i][j] = sc.nextInt();
				if (a[i][j] != a[0][j])
					c++;
			}
			diff[i] = c;
			max = Math.max(c, max);
		}
//		System.out.println(Arrays.toString(diff));
		boolean f = false;
		if (max >= 5)
			;
		else if (max == 4) {
			out: for (int i = 1; i < diff.length; i++) {
				if (diff[i] == 4) {
					int[] diffpos = new int[4];
					int idx = 0;
					for (int j = 0; j < m; j++) {
						if (a[0][j] != a[i][j]) {
							diffpos[idx++] = j;
						}
					}
					f = helper4(i, diffpos);
					if (f)
						break out;
				}
			}
		} else if (max == 3) {
			out: for (int i = 1; i < diff.length; i++) {
				if (diff[i] == 3) {
					int[] diffpos = new int[3];
					int idx = 0;
					for (int j = 0; j < m; j++) {
						if (a[0][j] != a[i][j]) {
							diffpos[idx++] = j;
						}
					}
//					System.out.println(i);
//					System.out.println(Arrays.toString(diffpos));
					f = helper3(i, diffpos);
					if (f)
						break out;
				}
			}
		} else {
			f = true;
			ans = a[0].clone();
		}
		if (f) {
			pw.println("Yes");
			for (int i = 0; i < ans.length; i++) {
				pw.print(ans[i] + " ");
			}
		} else {
			pw.println("No");
		}
		pw.flush();
	}

	static int a[][];
	static int[] ans;

	static boolean helper4(int cur, int[] diffpos) {
		for (int i = 0; i < diffpos.length - 1; i++) {
			for (int j = i + 1; j < diffpos.length; j++) {
				int[] temp = a[0].clone();
				temp[diffpos[i]] = a[cur][diffpos[i]];
				temp[diffpos[j]] = a[cur][diffpos[j]];
				boolean f = check(temp, 2);
				if (f) {
					ans = temp.clone();
					return true;
				}
			}
		}
		return false;
	}

	static boolean helper3(int cur, int[] diffpos) {
		for (int i = 0; i < diffpos.length; i++) {
			int[] temp = a[0].clone();
			temp[diffpos[i]] = a[cur][diffpos[i]];
//			System.out.println(Arrays.toString(temp)+" this the first one");
			boolean f = check(temp, 1);
//			System.out.println(Arrays.toString(temp));
			if (f) {
				ans = temp.clone();
				return true;
			}
		}
		return false;
	}

	static boolean check(int[] temp, int changes) {
		for (int i = 0; i < a.length; i++) {
			ArrayList<Integer> diff = new ArrayList<>();
			for (int j = 0; j < temp.length; j++) {
				if (a[i][j] != temp[j]) {
					diff.add(j);
				}
			}
//			System.out.println(diff);
			if (diff.size() > 2) {
				if (changes == 2 || diff.size() > 3)
					return false;
				for (int x : diff) {
					int[] tt = temp.clone();
					tt[x] = a[i][x];
					boolean f = check(tt, 2);
					if (f) {
						temp[x] = a[i][x];
						return true;
					}
				}
				return false;
			}
		}
		return true;
	}

	static final int INF = (int) 1e9;
	static int V, s, t, res[][]; // input
	static ArrayList<Integer>[] adjList; // input
	static int[] ptr, dist;

	static long dinic() // O(V^2E)
	{
		long mf = 0;
		while (bfs()) {
			ptr = new int[V];
			int f;
			while ((f = dfs(s, INF)) != 0)
				mf += f;
		}
		return mf;
	}

	static boolean bfs() {
		dist = new int[V];
		Arrays.fill(dist, -1);
		dist[s] = 0;
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(s);
		while (!q.isEmpty()) {
			int u = q.remove();
			if (u == t)
				return true;
			for (int v : adjList[u])
				if (dist[v] == -1 && res[u][v] > 0) {
					dist[v] = dist[u] + 1;
					q.add(v);
				}
		}
		return false;
	}

	static int dfs(int u, int flow) {
		if (u == t)
			return flow;
		for (int i = ptr[u]; i < adjList[u].size(); i = ++ptr[u]) {
			int v = adjList[u].get(i);
			if (dist[v] == dist[u] + 1 && res[u][v] > 0) {
				int f = dfs(v, Math.min(flow, res[u][v]));
				if (f > 0) {
					res[u][v] -= f;
					res[v][u] += f;
					return f;
				}
			}
		}
		return 0;

	}

	static class triple implements Comparable<triple> {
		double x;
		double y;
		int z;
		int idx;

		public triple(double a, double b, int c, int d) {
			x = a;
			y = b;
			z = c;
			idx = d;
		}

		@Override
		public int compareTo(triple o) {
			// TODO Auto-generated method stub
			return 0;
		}
	}

	static int[] isComposite;

	static void sieve(int N) // O(N log log N)
	{
		isComposite = new int[N + 1];
		isComposite[0] = isComposite[1] = 1; // 0 indicates a prime number
//		primes = new ArrayList<Integer>();

		for (int i = 2; i <= N; ++i) // can loop till i*i <= N if primes array is not needed O(N log log sqrt(N))
			if (isComposite[i] == 0) // can loop in 2 and odd integers for slightly better performance
			{
//				primes.add(i);
				if (1l * i * i <= N)
					for (int j = i * i; j <= N; j += i) // j = i * 2 will not affect performance too much, may alter in
														// modified sieve
						isComposite[j] = 1;
			}
	}

	static class pair implements Comparable<pair> {
		int x, y;
		int w;

		pair(int s, int d) {
			x = s;
			y = d;
		}

		pair(int s, int d, int c) {
			x = s;
			y = d;
			w = c;
		}

		@Override
		public int compareTo(pair p) {
			return (x == p.x && y == p.y) ? 0 : 1;
		}

		@Override
		public String toString() {
			return x + " " + y;

		}

	}

	static long mod(long ans, int mod) {
		return (ans % mod + mod) % mod;
	}

	static long gcd(long a, long b) {
		if (a == 0)
			return b;
		return gcd(b % a, a);
	}

	static long lcm(long a, long b) {
		return (a * b) / gcd(a, b);
	}

	public static int log(int n, int base) {
		int ans = 0;
		while (n + 1 > base) {
			ans++;
			n /= base;
		}
		return ans;
	}

	static long pow(long b, long e) {
		long ans = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				ans = ((ans * 1l * b));
			e >>= 1;
			{

			}
			b = ((b * 1l * b));
		}
		return ans;
	}

	static int powmod(int b, long e, int mod) {
		int ans = 1;
		b %= mod;
		while (e > 0) {
			if ((e & 1) == 1)
				ans = (int) ((ans * 1l * b) % mod);
			e >>= 1;
			b = (int) ((b * 1l * b) % mod);
		}
		return ans;
	}

	static int ceil(int a, int b) {
		int ans = a / b;
		return a % b == 0 ? ans : ans + 1;
	}

	static long ceil(long a, long b) {
		long ans = a / b;
		return a % b == 0 ? ans : ans + 1;
	}

	static HashMap<Integer, Integer> compress(int a[]) {
		TreeSet<Integer> ts = new TreeSet<>();
		HashMap<Integer, Integer> hm = new HashMap<>();
		for (int x : a)
			ts.add(x);
		for (int x : ts) {
			hm.put(x, hm.size() + 1);
		}
		return hm;
	}

	// Returns nCr % p
	static int C[];

	static int nCrModp(int n, int r, int p) {
		if (r > n - r)
			r = n - r;
		if (C[r] != 0)
			return C[r];
		// The array C is going to store last
		// row of pascal triangle at the end.
		// And last entry of last row is nCr

		C[0] = 1; // Top row of Pascal Triangle

		// One by constructs remaining rows of Pascal
		// Triangle from top to bottom
		for (int i = 1; i <= n; i++) {

			// Fill entries of current row using previous
			// row values
			for (int j = Math.min(i, r); j > 0; j--)

				// nCj = (n-1)Cj + (n-1)C(j-1);
				C[j] = (C[j] + C[j - 1]) % p;
		}
		return C[r];
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public int[] intArr(int n) throws IOException {
			int a[] = new int[n];
			for (int i = 0; i < a.length; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		public long[] longArr(int n) throws IOException {
			long a[] = new long[n];
			for (int i = 0; i < a.length; i++) {
				a[i] = nextLong();
			}
			return a;
		}

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

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

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

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}

	public static void shuffle(Integer[] x2) {
		int n = x2.length;
		for (int i = 0; i < n; i++) {
			int r = i + (int) (Math.random() * (n - i));
			int tmp = x2[i];
			x2[i] = x2[r];
			x2[r] = tmp;
		}
	}

}