import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] A = sc.nextChars(N);

		char [][] B = new char [M][N];
		for (int i : rep(N))
			for (int j : rep(M))
				B[j][i] = A[i][j];

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == '<') {
				assert xu >= yv || v >= 0;
				if (xu >= yv)
					X[x] = xu;
				else if (A[x][v] == '=')
					X[x] = yv;
				else
					X[x] = yv + 1;
				X[x] = max(X[x], 1);
				++r;
			}
			else  {
				assert yv >= xu || u >= 0;
				if (yv >= xu)
					Y[y] = yv;
				else if (A[u][y] == '=')
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				Y[y] = max(Y[y], 1);
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == '=' ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[M-1];
			Y[y] = A[x][y] == '=' ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M))
				switch(A[i][j]) {
				case '<':
					if (X[i] >= Y[j])
						return "No";
					break;
				case '=':
					if (X[i] != Y[j])
						return "No";
				case '>':
					if (X[i] <= Y[j])
						return "No";
					break;
				}

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (char [][] A) {
		int N = A.length, M = A[0].length;
		int [] L = new int [N], R = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				if (A[i][j] == '>')
					++L[i];
				else if (A[i][j] == '<')
					++R[i];
		int [] res = rep(N);
		Comparator<Integer> cmp = (i, j) -> L[i] - L[j];
		cmp = cmp.thenComparing((i, j) -> R[j] - R[i]);
		res = sort(res, cmp);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] G = sc.nextChars(N);

		int [][] A = new int [N][M], B = new int [M][N];
		for (int i : rep(N))
			for (int j : rep(M)) {
				if (G[i][j] == '<')
					A[i][j] = -1;
				else if (G[i][j] == '=')
					A[i][j] = 0;
				else
					A[i][j] = 1;
				B[j][i] = -A[i][j];
			}

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == -1) {
				assert xu >= yv || v >= 0;
				if (xu >= yv)
					X[x] = xu;
				else if (A[x][v] == 0)
					X[x] = yv;
				else
					X[x] = yv + 1;
				X[x] = max(X[x], 1);
				++r;
			}
			else  {
				assert yv >= xu || u >= 0;
				if (yv >= xu)
					Y[y] = yv;
				else if (A[u][y] == 0)
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				Y[y] = max(Y[y], 1);
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == 0 ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[M-1];
			Y[y] = A[x][y] == 0 ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M)) {
				if (A[i][j] != 0 && A[i][j] * (X[i] - Y[j]) <= 0)
					return "No";
				else if (A[i][j] == 0 && X[i] != Y[j])
					return "No";
			}

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (int [][] A) {
		int N = A.length, M = A[0].length;
		int [] D = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				D[i] += A[i][j];

		int [] res = rep(N);
		res = sort(res, (i, j) -> D[i] - D[j]);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] G = sc.nextChars(N);

		int [][] A = new int [N][M], B = new int [M][N];
		for (int i : rep(N))
			for (int j : rep(M)) {
				if (G[i][j] == '<')
					A[i][j] = -1;
				else if (G[i][j] == '=')
					A[i][j] = 0;
				else
					A[i][j] = 1;
				B[j][i] = -A[i][j];
			}

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == -1) {
				assert xu >= yv || v >= 0;
				if (xu >= yv)
					X[x] = xu;
				else if (A[x][v] == 0)
					X[x] = yv;
				else
					X[x] = yv + 1;
				X[x] = max(X[x], 1);
				++r;
			}
			else  {
				assert yv >= xu || u >= 0;
				if (yv >= xu)
					Y[y] = yv;
				else if (A[u][y] == 0)
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				Y[y] = max(Y[y], 1);
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == 0 ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[N-1];
			Y[y] = A[x][y] == 0 ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M)) {
				if (A[i][j] != 0 && A[i][j] * (X[i] - Y[j]) <= 0)
					return "No";
				else if (A[i][j] == 0 && X[i] != Y[j])
					return "No";
			}

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (int [][] A) {
		int N = A.length, M = A[0].length;
		int [] D = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				D[i] += A[i][j];

		int [] res = rep(N);
		res = sort(res, (i, j) -> D[i] - D[j]);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt(), M = sc.nextInt();
		char [][] S = sc.nextChars(N);

		int [][] A = new int [N][M];
		for (int i : rep(N))
			for (int j : rep(M))
				A[i][j] = eval(S[i][j]);

		int [][] Z = new int [N+M][];

		for (int i : rep(N)) {
			int D = 0;
			for (int j : rep(M))
				D += A[i][j];
			Z[i] = new int [] { 0, i, D };
		}

		for (int j : rep(M)) {
			int D = 0;
			for (int i : rep(N))
				D -= A[i][j];
			Z[j+N] = new int [] { 1, j, D };
		}

		try {
			sort (Z, (x, y) -> compare(A, x, y));
		}
		catch (Throwable t) {
			return "No";
		}

		int [][] res = { new int [N], new int [M] };
		res[Z[0][0]][Z[0][1]] = 1;
		for (int i : rep(1, N+M)) {
			int [] z = Z[i], y = Z[i-1];
			int V = res[y[0]][y[1]];
			if (compare(A, z, y) > 0)
				++V;
			res[z[0]][z[1]] = V;
		}

		for (int i : rep(N))
			for (int j : rep(M))
				if (A[i][j] != Integer.signum(res[0][i] - res[1][j]))
					return "No";

		print("Yes");
		for (int i : rep(2))
			print(res[i]);
		return null;
	}

	int compare (int [][] A, int [] x, int [] y) {
		if (x[0] == 0 && y[0] == 1)
			return A[x[1]][y[1]];
		else if (x[0] == 1 && y[0] == 0)
			return -A[y[1]][x[1]];
		else return x[2] - y[2];
	}

	int eval (char c) {
		switch(c) {
		case '<': return -1;
		case '=': return 0;
		case '>': return 1;
		default: throw new Error();
		}
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static <T> T [] sort(T [] A, Comparator<T> C) { Arrays.sort(A, C); return A; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] A = sc.nextChars(N);

		char [][] B = new char [M][N];
		for (int i : rep(N))
			for (int j : rep(M))
				B[j][i] = A[i][j];

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == '<') {
				assert xu >= yv || v >= 0;
				if (xu >= yv)
					X[x] = xu;
				else if (A[x][v] == '=')
					X[x] = yv;
				else
					X[x] = yv + 1;
				X[x] = max(X[x], 1);
				++r;
			}
			else  {
				assert yv >= xu || u >= 0;
				if (yv >= xu)
					Y[y] = yv;
				else if (A[u][y] == '=')
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				Y[y] = max(Y[y], 1);
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == '=' ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[M-1];
			Y[y] = A[x][y] == '=' ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M)) {
				char d = A[i][j];
				if (d == '<' && X[i] >= Y[j])
					return "No";
				if (d == '=' && X[i] != Y[j])
					return "No";
				if (d == '>' && X[i] <= Y[j])
					return "No";
			}

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (char [][] A) {
		int N = A.length, M = A[0].length;
		int [] L = new int [N], R = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				if (A[i][j] == '>')
					++L[i];
				else if (A[i][j] == '<')
					++R[i];
		int [] res = rep(N);
		Comparator<Integer> cmp = (i, j) -> L[i] - L[j];
		cmp = cmp.thenComparing((i, j) -> R[j] - R[i]);
		res = sort(res, cmp);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] G = sc.nextChars(N);

		int [][] A = new int [N][M], B = new int [M][N];
		for (int i : rep(N))
			for (int j : rep(M)) {
				if (G[i][j] == '<')
					A[i][j] = -1;
				else if (G[i][j] == '=')
					A[i][j] = 0;
				else
					A[i][j] = 1;
				B[j][i] = -A[i][j];
			}

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == -1) {
				if (u == -1 && v == -1)
					X[x] = 1;
				else if (xu > yv)
					X[x] = xu;
				else if (A[x][v] == 0)
					X[x] = yv;
				else
					X[x] = yv + 1;
				++r;
			}
			else  {
				if (u == -1 && v == -1)
					Y[y] = 1;
				else if (yv > xu)
					Y[y] = yv;
				else if (A[u][y] == 0)
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == 0 ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[N-1];
			Y[y] = A[x][y] == 0 ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M))
				if (A[i][j] != 0 && A[i][j] * (X[i] - Y[j]) <= 0)
					return "No";
				else if (A[i][j] == 0 && X[i] != Y[j])
					return "No";

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (int [][] A) {
		int N = A.length, M = A[0].length;
		int [] D = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				D[i] += A[i][j];

		int [] res = rep(N);
		res = sort(res, (i, j) -> D[i] - D[j]);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;
import java.util.stream.*;

public class D {

	public Object solve () {
		int N = sc.nextInt();
		int M = sc.nextInt();
		char [][] G = sc.nextChars(N);

		int [][] A = new int [N][M], B = new int [M][N];
		for (int i : rep(N))
			for (int j : rep(M)) {
				if (G[i][j] == '<')
					A[i][j] = -1;
				else if (G[i][j] == '=')
					A[i][j] = 0;
				else
					A[i][j] = 1;
				B[j][i] = -A[i][j];
			}

		int [] R = calc(A);
		int [] C = calc(B);

		int [] X = new int [N], Y = new int [M];
		int r = 0, c = 0;
		while (r < N && c < M) {
			int x = R[r], y = C[c];
			int u = r > 0 ? R[r-1] : -1, xu = u >= 0 ? X[u] : 0;
			int v = c > 0 ? C[c-1] : -1, yv = v >= 0 ? Y[v] : 0;
			if (A[x][y] == -1) {
				assert xu > yv || v >= 0;
				if (xu > yv)
					X[x] = xu;
				else if (A[x][v] == 0)
					X[x] = yv;
				else
					X[x] = yv + 1;
				X[x] = max(X[x], 1);
				++r;
			}
			else  {
				assert yv >= xu || u >= 0;
				if (yv > xu)
					Y[y] = yv;
				else if (A[u][y] == 0)
					Y[y] = xu;
				else
					Y[y] = xu + 1;
				Y[y] = max(Y[y], 1);
				++c;
			}
		}

		while (r < N) {
			int x = R[r], y = C[M-1];
			X[x] = A[x][y] == 0 ? Y[y] : Y[y] + 1;
			++r;
		}

		while (c < M) {
			int y = C[c], x = R[N-1];
			Y[y] = A[x][y] == 0 ? X[x] : X[x] + 1;
			++c;
		}

		for (int i : rep(N))
			for (int j : rep(M)) {
				if (A[i][j] != 0 && A[i][j] * (X[i] - Y[j]) <= 0)
					return "No";
				else if (A[i][j] == 0 && X[i] != Y[j])
					return "No";
			}

		print("Yes");
		print(X);
		print(Y);
		return null;
	}

	int [] calc (int [][] A) {
		int N = A.length, M = A[0].length;
		int [] D = new int [N];
		for (int i : rep(N))
			for (int j : rep(M))
				D[i] += A[i][j];

		int [] res = rep(N);
		res = sort(res, (i, j) -> D[i] - D[j]);
		return res;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static Integer [] boxed (int ... A) { return stream(A).mapToObj(x -> x).toArray(Integer[]::new); }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sort (int [] A, Comparator<Integer> C) { Integer [] AA = boxed(A); Arrays.sort(AA, C); return unboxed(AA, A); }
	private static int [] unboxed (Integer [] A) { return stream(A).mapToInt(x -> x).toArray(); }
	private static int [] unboxed (Integer [] A, int [] a) { System.arraycopy(unboxed(A), 0, a, 0, A.length); return a; }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public char [] nextChars () { return next ().toCharArray (); }
			public char[][] nextChars (int N) { return IntStream.range(0, N).mapToObj(i -> nextChars()).toArray(char[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static final java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new D().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

public class D{

	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            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 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)
            {
                e.printStackTrace();
            }
            return str;
        }
    }
	static class Dsu
	{
		int n;
		int[] parent;
		int[] rank;

		public Dsu(int n)
		{
			this.n = n;
			parent = new int[n];
			rank = new int[n];
		}
		public void createSet()
		{
			for(int i = 0; i < n; i++)
			{
				parent[i] = i;
				rank[i] = 0;
			}
		}
		public int findParent(int x)
		{
			if(parent[x] == x)
				return x;
			parent[x] = findParent(parent[x]);
			return parent[x];
		}

		public void mergeSet(int a,int b)
		{
			int pa = findParent(a);
			int pb = findParent(b);

			if(pa == pb) return;

			if(rank[pa] > rank[pb])
			{
				parent[pb] = pa;
			}
			else if(rank[pa] < rank[pb])
			{
				parent[pa] = pb;
			}
			else
			{
				parent[pb] = pa;
				rank[pa]++;
			}
		}
	}
	public static int dfs(int s)
	{
		vis[s] = true;
		Iterator<Integer> itr = ar[s].iterator();
		int max = 0;
		while(itr.hasNext())
		{
			int n = itr.next();
			if(!vis[n])
			{
				max = Math.max(max,dfs(n));
			}
			else
			{
				max = Math.max(max,val[n]);
			}
		}

		val[s] = max+1;
		return val[s];

	}
	public static boolean isCyclic(int s)
	{
		if(recStack[s] == true)
			return true;

		if(vis[s] == true)
			return false;

		vis[s] = true;
		recStack[s] = true;
		Iterator<Integer> itr = ar[s].iterator();
		while(itr.hasNext())
		{
			int n = itr.next();
			if(isCyclic(n))
			{
				return true;
			}
		}
		recStack[s] = false;
		return false;

	}
	static char mat[][];
	static List<Integer> ar[];
	static int val[];
	static boolean vis[];
	static boolean recStack[];
	public static void main(String[] args)
	{
		OutputStream outputStream = System.out;
        FastReader sc = new FastReader();
        PrintWriter out = new PrintWriter(outputStream);
        int n = sc.nextInt();
        int m = sc.nextInt();
        ar = new List[n+m];

        for(int i = 0; i < n+m; i++)
        {
        	ar[i] = new ArrayList<>();
        }
        mat = new char[n][m];

        for(int i = 0; i < n; i++)
        {
        	mat[i] = sc.nextLine().toCharArray();
        }

        vis = new boolean[n+m];
        Arrays.fill(vis,false);

        recStack = new boolean[n+m];
        Arrays.fill(recStack,false);

        val = new int[n+m];

        Dsu d = new Dsu(n+m);
        //System.out.println("Next up finding equality");
        d.createSet();
        for(int i = 0; i < n; i++)
        {
        	for(int j = 0; j < m; j++)
        	{
        		if(mat[i][j] == '=')
        		{
        			d.mergeSet(i, n+j);
        		}
        	}
        }
        //System.out.println("Next up graph building");
        int pi = -1,pj = -1;
        for(int i = 0; i < n; i++)
        {
        	for(int j = 0; j < m; j++)
        	{
        		pi = d.findParent(i);
    			pj = d.findParent(n+j);
        		if(mat[i][j] == '>')
        		{
        			ar[pi].add(pj);
        		}
        		else if(mat[i][j] == '<')
        		{
        			ar[pj].add(pi);
        		}
        		else
        		{
        			continue;
        		}
        	}
        }
        //System.out.println("Next up cyclic nature");
        for(int i = 0; i < n+m; i++)
        {
        	if(!vis[d.findParent(i)])
        	{
        		if(isCyclic(d.findParent(i)))
                {
                	out.println("No");
                	out.close();
                	return;
                }
        	}
        }

        Arrays.fill(vis,false);
        //System.out.println("Next up dfs");
        for(int i = 0; i < n+m; i++)
        {
        	if(!vis[d.findParent(i)])
        	dfs(d.findParent(i));
        }
        out.println("Yes");
        for(int i = 0; i < n; i++)
        {
        	out.print(val[d.findParent(i)]+" ");
        }
        out.println();
        for(int i = n; i < n+m; i++)
        {
        	out.print(val[d.findParent(i)]+" ");
        }
        out.close();
	}

}


import java.util.*;
import java.io.*;
import java.math.BigInteger;
public class A{
    static PrintWriter out;
    static InputReader in;
    public static void main(String args[]){
        out = new PrintWriter(System.out);
        in = new InputReader();
        new A();
        out.flush(); out.close();
    }
    final int max = 2010;
    int n, m, p[], r[], tot;
    int from[] = new int[max * max], to[] = new int[max * max], e = 0;
    int ja[][], c[];
    char ch[][];
    boolean sp[];
    boolean rs = true;
    ArrayList<Integer> al[] = new ArrayList[max];
    int get(int u){
        return p[u] == u ? u : (p[u] = get(p[u]));
    }
    void merge(int u, int v){
        int pu = get(u), pv = get(v);
        if(r[pu] == r[pv])r[pu]++;
        if(r[pu] < r[pv]){
            pu ^= pv; pv ^= pu; pu ^= pv;
        }
        p[pv] = pu;
    }
    A(){
        n = in.nextInt(); m = in.nextInt();
        tot = n + m + 1;
        p = new int[tot]; r = new int[tot];
        for(int i = 1; i < tot; i++){
            p[i] = i;
        }
        ch = new char[n][];
        for(int i = 0; i < n; i++)ch[i] = in.next().trim().toCharArray();

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(ch[i][j] == '='){
                    merge(i + 1, n + j + 1);
                }
            }
        }
        for(int i = 0; i < max; i++)al[i] = new ArrayList<>();
        sp = new boolean[tot];
        for(int i = 1; i < tot; i++){
            p[i] = get(i);
            al[p[i]].add(i);
            sp[p[i]] = true;
        }

        o : for(int i = 0; i < max; i++){
            int sz = al[i].size();
            if(sz < 2)continue;
            // System.out.println(al[i]);
            for(int j = 0; j < sz; j++){
                int f = al[i].get(j);
                if(f > n)continue;
                for(int k = 0; k < sz; k++){
                    int s = al[i].get(k);
                    if(s <= n)continue;
                    s -= n;
                    if(ch[f - 1][s - 1] != '='){
                        rs = false;
                        break o;
                    }
                }
            }
        }

        for(int i = 1; i <= n; i++){
            if(sp[p[i]] == true){
                int sz = al[p[i]].size();
                for(int j = 0; j < sz; j++){
                    int t = al[p[i]].get(j);
                    if(t <= n){
                        for(int k = 1; k <= m; k++){
                            if(ch[t - 1][k - 1] == '=')continue;
                            if(ch[t - 1][k - 1] == '>'){
                                from[e] = p[k + n]; to[e++] = p[i];
                            }else{
                                from[e] = p[i]; to[e++] = p[k + n];
                            }
                        }
                    }else{
                        t -= n;
                        for(int k = 1; k <= n; k++){
                            if(ch[k - 1][t - 1] == '=')continue;
                            if(ch[k - 1][t - 1] == '>'){
                                from[e] = p[i]; to[e++] = p[k];
                            }else{
                                from[e] = p[k]; to[e++] = p[i];
                            }
                        }
                    }
                }
                sp[p[i]] = false;
            }
        }

        ja = new int[tot][]; c = new int[tot];
        for(int i = 0; i < e; i++){
            c[from[i]]++; cc[to[i]]++;
            // System.out.println(from[i] + " " + to[i]);
        }
        for(int i = 1; i < tot; i++){
            ja[i] = new int[c[i]]; c[i] = 0;
        }
        for(int i = 0; i < e; i++){
            ja[from[i]][c[from[i]]++] = to[i];
        }

        for(int i = 1; i < tot; i++){
            if(cc[p[i]] == 0 && !visit[p[i]]){
                int u = p[i];
                ad.add(u); order[u] = 1;
                visit[u] = true;
            }
        }

        while(!ad.isEmpty()){
            // System.out.println(ad);
            int u = ad.pollFirst();
            for(int v : ja[u]){
                if(--cc[v] == 0){
                    ad.addLast(v); order[v] = order[u] + 1;
                    visit[v] = true;
                }
            }
        }

        for(int i = 1; i < tot; i++){
            if(!visit[p[i]]){
                rs = false; break;
            }
        }

        if(!rs){
            out.print("No");
        }else{
            out.println("Yes");
            for(int i = 1; i <= n; i++){
                out.print(order[p[i]] + " ");
            }
            out.println();
            for(int i = 1; i <= m; i++){
                out.print(order[p[i + n]] + " ");
            }
        }

        // solve();
    }
    ArrayDeque<Integer> ad = new ArrayDeque<>();
    boolean visit[] = new boolean[max];
    int order[] = new int[max];
    int cc[] = new int[max];

    void solve(){
        int n = in.nextInt();
        long ans = 0;
        long ap = 0, bp = 0;
        for(int i = 0; i < n; i++){
            long a = in.nextLong(), b = in.nextLong();
            if(ap == a && bp == b && i != 0)continue;
            ans += Math.max(Math.min(a, b) - Math.max(ap, bp) + 1, 0);
            ap = a; bp = b;
        }out.print(ans);
    }
    public static class InputReader{
        BufferedReader br;
        StringTokenizer st;
        InputReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        public int nextInt(){
            return Integer.parseInt(next());
        }
        public long nextLong(){
            return Long.parseLong(next());
        }
        public double nextDouble(){
            return Double.parseDouble(next());
        }
        public String next(){
            while(st == null || !st.hasMoreTokens()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){}
            }
            return st.nextToken();
        }
    }
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;
public class A{
    static PrintWriter out;
    static InputReader in;
    public static void main(String args[]){
        out = new PrintWriter(System.out);
        in = new InputReader();
        new A();
        out.flush(); out.close();
    }
    int n, p[], s[], e[], pa[], r[], c[];
    int get(int u){
        return p[u] == u ? u : (p[u] = get(p[u]));
    }
    void merge(int u, int v){
        int pu = get(u), pv = get(v);
        if(r[pu] == r[pv])r[pu]++;
        if(r[pu] < r[pv]){
            pu ^= pv; pv ^= pu; pu ^= pv;
        }
        pa[e[pu]] = s[pv];
        c[s[pv]]++;
        e[pu] = e[pv];
        p[pv] = pu;
    }
    A(){
        n = in.nextInt();
        p = new int[n]; s = new int[n]; e = new int[n]; pa = new int[n]; r = new int[n]; c = new int[n];
        Arrays.fill(pa, -1);
        for(int i = 0; i < n; i++){
            p[i] = s[i] = e[i] = i;
        }
        for(int i = 0; i < n - 1; i++){
            int u = in.nextInt() - 1, v = in.nextInt() - 1;
            merge(u, v);
        }
        int b = -1;
        for(int i = 0; i < n; i++){
            if(c[i] == 0){
                b = i; break;
            }
        }
        for(int i = 0; i < n; i++){
            out.print((b + 1) + " ");
            b = pa[b];
        }
        // solve();
    }
    void solve(){
        int n = in.nextInt();
        long ans = 0;
        long ap = 0, bp = 0;
        for(int i = 0; i < n; i++){
            long a = in.nextLong(), b = in.nextLong();
            if(ap == a && bp == b && i != 0)continue;
            ans += Math.max(Math.min(a, b) - Math.max(ap, bp) + 1, 0);
            ap = a; bp = b;
        }out.print(ans);
    }
    public static class InputReader{
        BufferedReader br;
        StringTokenizer st;
        InputReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        public int nextInt(){
            return Integer.parseInt(next());
        }
        public long nextLong(){
            return Long.parseLong(next());
        }
        public double nextDouble(){
            return Double.parseDouble(next());
        }
        public String next(){
            while(st == null || !st.hasMoreTokens()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){}
            }
            return st.nextToken();
        }
    }
}


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

public class D {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int N = scanner.nextInt();
        int M = scanner.nextInt();
        char[][] rels = new char[N][M];
        DSU dsu = new DSU(N+M);
        for(int i= 0; i < N; i++) {
            char[] line = scanner.next().toCharArray();
            for(int j = 0; j < M; j++) {
                rels[i][j] = line[j];
                if (rels[i][j] == '=') dsu.union(i, j+N);
            }
        }
        int nextNode = 0;
        HashMap<Integer, Integer> mapping = new HashMap<>();
        for(int i= 0; i < N+M; i++) {
            if (!mapping.containsKey(dsu.find(i))) mapping.put(dsu.find(i), nextNode++);
        }
        ArrayList<Integer>[] graph = new ArrayList[nextNode];
        for(int i = 0; i <nextNode; i++) graph[i] = new ArrayList<>();
        int[] indeg = new int[nextNode];
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M; j++) {
                if (rels[i][j] == '=')continue;
                else if (rels[i][j] == '<') {
                    graph[mapping.get(dsu.find(i))].add(mapping.get(dsu.find(j + N)));
                    indeg[mapping.get(dsu.find(j+N))]++;
                }
                else {
                    graph[mapping.get(dsu.find(j+N))].add(mapping.get(dsu.find(i)));
                    indeg[mapping.get(dsu.find(i))]++;
                }
            }
        }
        int tot = 0;
        int[] ansList= new int[nextNode];
        ArrayDeque<Integer> queue = new ArrayDeque<>();
        for(int i = 0; i < nextNode; i++) if (indeg[i] == 0) {
            ansList[i] = 1;
            queue.offer(i);
        }
        while(!queue.isEmpty()) {
            int cur = queue.poll();
            tot++;
            for(int edge: graph[cur]) {
                indeg[edge]--;
                ansList[edge] = Math.max(ansList[cur] + 1, ansList[edge]);
                if (indeg[edge] == 0) queue.offer(edge);
            }
        }
        if (tot < nextNode) {
            out.println("No");
            out.flush();
            return;
        }
        out.println("Yes");
        for(int i = 0; i < N; i++) {
            out.print(ansList[mapping.get(dsu.find(i))] + " ");
        }
        out.println();
        for(int i = N; i < N+M; i++) {
            out.print(ansList[mapping.get(dsu.find(i))] + " ");
        }
        out.println();
        out.flush();
    }
//    public static class Pair {
//        int x, y;
//        public Pair(int xx, int yy) {
//            x = xx;
//            y = yy;
//        }
//    }

    public static class DSU {
        int[] parent, rank;
        int nSets;
        public DSU (int ss) {
            nSets = ss;
            parent = new int[ss];
            rank = new int[ss];
            for(int i = 0; i < ss; i++) {
                rank[i] = 1;
                parent[i] = i;
            }
        }
        public int find(int t) {
            int prev = t;
            while(parent[t] != t) {
                t = parent[t];
            }
            compress(prev, t);
            return t;
        }
        public void compress(int s, int t) {
            while(parent[s]!=t) {
                int temp = parent[s];
                parent[s] = t;
                s = temp;
            }
        }
        public boolean union (int a, int b) {
            int pa = find(a);
            int pb = find(b);
            if (pa == pb) return false;
            nSets--;
            if(rank[pa]<=rank[pb]) {
                rank[pb]++;
                parent[pa] = pb;
            }
            else {
                rank[pa]++;
                parent[pb] = pa;
            }
            return true;
        }
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(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 nextInt() {
            return Integer.parseInt(next());
        }

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

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

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

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }
    }
}


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

public class Q3 {

    static int mod = (int) (1e9+7);
    static InputReader in;
    static PrintWriter out;
    static ArrayList<ArrayList<Integer>> list;

    static int[] rt;
    static int[] size;

    static void initialize(int n){
        rt = new int[n + 1];
        size = new int[n + 1];
        for(int i = 0; i < rt.length; i++){
            rt[i] = i;
            size[i] = 1;
        }
    }

    static int root(int x){
        while(rt[x] != x){
            rt[x] = rt[rt[x]];
            x = rt[x];
        }
        return x;
    }

    static boolean union(int x,int y){
        int root_x = root(x);
        int root_y = root(y);
        if(root_x == root_y) return true;

        if(size[root_x]<size[root_y]){
            rt[root_x] = rt[root_y];
            size[root_y] += size[root_x];
        }
        else{
            rt[root_y] = rt[root_x];
            size[root_x] += size[root_y];
        }
        return false;
    }

    static boolean hasCycle(int u, boolean[] vis, boolean[] stack) {

    	if(!vis[u]) {
    		vis[u] = true;
    		stack[u] = true;
    		for(int v: list.get(u)) {
    			if(!vis[v] && hasCycle(v, vis, stack))
    				return true;
    			else if(stack[v])
    				return true;
    		}
    	}

    	stack[u] = false;
    	return false;
    }

    static boolean check()
    {
    	boolean[] vis = new boolean[list.size()];
    	boolean[] stack = new boolean[list.size()];

    	for(int i = 0; i < list.size(); i++)
    		if(hasCycle(i, vis, stack))
    			return true;
    	return false;
    }

    static void solve()
    {

        in = new InputReader(System.in);
        out = new PrintWriter(System.out);

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

        initialize(n + m);
        list = new ArrayList<ArrayList<Integer>>();
        for(int i = 0; i < n + m; i++)
        	list.add(new ArrayList<Integer>());

        char[][] c = new char[n][m];

        for(int i = 0; i < n; i++) {
        	c[i] = in.nextLine().toCharArray();
        	for(int j = 0; j < m; j++) {
        		if(c[i][j] == '=') {
        			union(i, n + j);
        		}
        	}
        }
        int[] size = new int[n + m];

        for(int i = 0; i < n; i++) {
        	int x = root(i);
        	for(int j = 0; j < m; j++) {
        		int y = root(n + j);
				if(c[i][j] == '>') {
					list.get(y).add(x);
					size[x]++;
				}
				else if(c[i][j] == '<') {
					list.get(x).add(y);
					size[y]++;
				}
        	}
        }

        if(check()) {
        	out.println("No");
        }
        else {
        	out.println("Yes");
        	Queue<Integer> queue = new LinkedList<Integer>();
        	int[] res = new int[n + m];

        	for(int i = 0; i < n + m; i++)
        		if(size[i] == 0) {
        			queue.add(i);
        			res[i] = 1;
        		}

        	while(!queue.isEmpty()) {
        		int u = queue.poll();
        		for(int v: list.get(u)) {
        			size[v]--;
        			res[v] = max(res[v], res[u] + 1);
        			if(size[v] == 0)
        				queue.add(v);
        		}
        	}

        	for(int i = 0; i < n; i++)
        		out.print(res[root(i)] + " ");
        	out.println();
        	for(int i = 0; i < m; i++)
        		out.print(res[root(n + i)] + " ");
        	out.println();
        }

        out.close();
    }

    public static void main(String[] args) {
        new Thread(null ,new Runnable(){
            public void run()
            {
                try{
                    solve();
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
        },"1",1<<26).start();
    }

    static int[][] graph(int from[], int to[], int n)
    {
        int g[][] = new int[n][];
        int cnt[] = new int[n];
        for (int i = 0; i < from.length; i++) {
            cnt[from[i]]++;
            cnt[to[i]]++;
        }
        for (int i = 0; i < n; i++) {
            g[i] = new int[cnt[i]];
        }
        Arrays.fill(cnt, 0);
        for (int i = 0; i < from.length; i++) {
            g[from[i]][cnt[from[i]]++] = to[i];
            g[to[i]][cnt[to[i]]++] = from[i];
        }
        return g;
    }

    static class Pair implements Comparable<Pair>{

        int x,y,i;

		Pair (int x,int y,int i){
			this.x=x;
			this.y=y;
			this.i=i;
		}

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

		public int compareTo(Pair o) {
			if(this.x!=o.x)
	                    return Integer.compare(this.x,o.x);
			else
	                    return Integer.compare(this.y,o.y);
			//return 0;
		}

        public boolean equals(Object o) {
            if (o instanceof Pair) {
                Pair p = (Pair)o;
                return p.x == x && p.y == y && p.i==i;
            }
            return false;
        }
        public int hashCode() {
            return new Integer(x).hashCode() * 31 + new Integer(y).hashCode()+new Integer(i).hashCode()*37;
        }

    }

    static String rev(String s) {
        StringBuilder sb = new StringBuilder(s);
        sb.reverse();
        return sb.toString();
    }

    static long gcd(long x, long y) {
        if (y == 0) {
            return x;
        } else {
            return gcd(y, x % y);
        }
    }

    static int gcd(int x, int y) {
        if (y == 0) {
            return x;
        } else {
            return gcd(y, x % y);
        }
    }

    static int abs(int a, int b) {
        return (int) Math.abs(a - b);
    }

    static long abs(long a, long b) {
        return (long) Math.abs(a - b);
    }

    static int max(int a, int b) {
        if (a > b) {
            return a;
        } else {
            return b;
        }
    }

    static int min(int a, int b) {
        if (a > b) {
            return b;
        } else {
            return a;
        }
    }

    static long max(long a, long b) {
        if (a > b) {
            return a;
        } else {
            return b;
        }
    }

    static long min(long a, long b) {
        if (a > b) {
            return b;
        } else {
            return a;
        }
    }

    static long pow(long n, long p, long m) {
        long result = 1;
        if (p == 0) {
            return 1;
        }
        while (p != 0) {
            if (p % 2 == 1) {
                result *= n;
            }
            if (result >= m) {
                result %= m;
            }
            p >>= 1;
            n *= n;
            if (n >= m) {
                n %= m;
            }
        }
        return result;
    }

    static long pow(long n, long p) {
        long result = 1;
        if (p == 0) {
            return 1;
        }
        if (p == 1) {
            return n;
        }
        while (p != 0) {
            if (p % 2 == 1) {
                result *= n;
            }
            p >>= 1;
            n *= n;
        }
        return result;
    }

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

    static class InputReader
    {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

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

        public int snext()
        {
                if (snumChars == -1)
                        throw new InputMismatchException();
                if (curChar >= snumChars)
                {
                        curChar = 0;
                        try
                        {
                                snumChars = stream.read(buf);
                        } catch (IOException e)
                        {
                                throw new InputMismatchException();
                        }
                        if (snumChars <= 0)
                                return -1;
                }
                return buf[curChar++];
        }

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

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

        public int[] nextIntArray(int n)
        {
                int a[] = new int[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextInt();
                }
                return a;
        }

        public long[] nextLongArray(int n)
        {
                long a[] = new long[n];
                for (int i = 0; i < n; i++)
                {
                        a[i] = nextLong();
                }
                return a;
        }

        public String readString()
        {
                int c = snext();
                while (isSpaceChar(c))
                {
                        c = snext();
                }
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isSpaceChar(c));
                return res.toString();
        }

        public String nextLine()
        {
                int c = snext();
                while (isSpaceChar(c))
                        c = snext();
                StringBuilder res = new StringBuilder();
                do
                {
                        res.appendCodePoint(c);
                        c = snext();
                } while (!isEndOfLine(c));
                return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
                return c == '\n' || c == '\r' || c == -1;
        }

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

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class GourmetChoice {
    static int[] values = new int[2000];
    static color[] state = new color[2000];
    static DisjointSet dsu;
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        dsu = new DisjointSet(N+M);
        String[][] input = new String[N][M];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(f.readLine());
            String[] next = st.nextToken().split("");
            for (int j = 0; j < M; j++) {
                if (next[j].equals("=")) {
                    dsu.union(j + N, i);
                }
            }
            input[i] = next;
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (input[i][j].equals(">")) {
                    dsu.addEdge(dsu.find(i), dsu.find(j+N));
                }
                else if (input[i][j].equals("<")) {
                    dsu.addEdge(dsu.find(j+N), dsu.find(i));
                }
            }
        }
        for (int i = 0; i <2000; i++) {
            state[i] = color.blank;
        }
        for (int i = 0; i < N + M; i++) {
            int temp = dsu.find(i);
            if (state[temp] == color.blank) {
                dfs(temp);
            }
        }
        PrintWriter out = new PrintWriter(System.out);
        if (!ok) {
                System.out.println("NO");
                System.exit(0);
        }
        out.println("YES");
        for (int i = 0; i < N; i++) {
            out.print(values[dsu.find(i)] + " ");
        }
        out.println();
        for (int i = 0; i < M; i++) {
            out.print(values[dsu.find(N+i)] + " ");
        }
        out.println();
        out.close();
    }
    static boolean ok = true;
    public static void dfs(int i) {
        if (dsu.adjList[i].size() == 0) {
            state[i] = color.okay;
            values[i] = 1;
            return;
        }
        int mx = 0;
        state[i] = color.progress;
        for (int x = 0; x < dsu.adjList[i].size(); x++) {
            if (!ok) return;
            int j = dsu.adjList[i].get(x);
            if (state[j]==color.progress)ok=false;
            if (state[j] != color.okay) dfs(j);
            mx = Math.max(mx, values[j]+1);
        }
        state[i] = color.okay;
        values[i] = mx;
    }
    static class DisjointSet {
        int[] parent;
        ArrayList<Integer>[] adjList;
        int size;
        DisjointSet(int N) {
            size = N;
            parent = new int[size];
            adjList = new ArrayList[size];
            for (int i = 0; i < size; i++) {
                parent[i] = i;
                adjList[i] = new ArrayList<>();
            }
        }
        public int find(int x) {
            return (parent[x] == x ? x : (parent[x] = find(parent[x])));
        }
        public void addEdge(int x, int e) {
            adjList[x].add(e);
        }
        public void union(int x, int y) {
            int parX = find(x);
            int parY = find(y);
            if (parX != parY) {
                parent[parY] = parX;
            }
        }
        public ArrayList<Integer> getadjLists(int x) {
            return adjList[x];
        }
    }
    enum color {
        progress, okay, blank;
    };
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class GourmetChoice {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int[][] adjList = new int[N+M][N+M];
        int[] inDegree = new int[N+M];
        for (int i = 0; i < N; i++) {
            String[] next = f.readLine().split("");
            for (int j = 0; j < M; j++) {
                if (next[j].equals("<")) {
                    adjList[i][j+N] = 1;
                    inDegree[j+N]++;
                }
                else if (next[j].equals(">")) {
                    adjList[j+N][i] = 1;
                    inDegree[i]++;
                }
                else {
                    adjList[j+N][i] = 2;
                    adjList[i][j+N] = 2;
                }
            }
        }
        int[] values = new int[N+M];
        for (int i = 0; i < N+M; i++) {
            if (inDegree[i] == 0) {
                boolean[] visited = new boolean[N+M];
                visited[i] = true;
                values[i] = 1;
                Queue<Integer> bfs = new LinkedList<Integer>();
                bfs.add(i);
                while (!bfs.isEmpty()) {
                    int next = bfs.poll();
                    for (int j = 0; j < N+M; j++) {
                        if (adjList[next][j] == 1) {
                            if (values[next] + 1 > values[j]) {
                                if (visited[j]) {
                                    System.out.println("NO");
                                    System.exit(0);
                                }
                                values[j] = values[next]+1;
                                visited[j] = true;
                                bfs.add(j);
                            }
                        }
                        else if (adjList[next][j] == 2) {
                            if (values[next] > values[j]) {
                                if (visited[j]) {
                                    System.out.println("NO");
                                    System.exit(0);
                                }
                                values[j] = values[next];
                                visited[j] = true;
                                bfs.add(j);
                            }
                            else if (values[next] < values[j]) {
                                if (visited[j]) {
                                    System.out.println("NO");
                                    System.exit(0);
                                }
                                values[next] = values[j];
                                visited[j] = true;
                                bfs.add(next);
                            }
                        }
                    }
                }
            }
        }
        PrintWriter out = new PrintWriter(System.out);
        for (int i = 0; i < N; i++) {
            out.print(values[i]+" ");
        }
        out.println();
        for (int i = 0; i < M; i++) {
            out.print(values[N+i] + " ");
        }
        out.println();
        out.close();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class GourmetChoice {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        DisjointSet dsu = new DisjointSet(N+M);
        for (int i = 0; i < N; i++) {
            String[] next = f.readLine().split("");
            for (int j = 0; j < M; j++) {
                if (next[j].equals("<")) {
                    if (!dsu.addEdge(i, j+N)) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    dsu.addDegree(j+N);
                } else if (next[j].equals(">")) {
                    if (!dsu.addEdge(j+N, i)) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    dsu.addDegree(i);
                } else {
                    dsu.union(j+N, i);
                }
            }
        }
        int[] values = new int[N + M];
        boolean[] visited = new boolean[N+M];
        for (int i = 0; i < N + M; i++) {
            if (dsu.find(i) == i && dsu.inDegree[i] == 0) {
                Queue<Integer> bfs = new ArrayDeque<>();
                bfs.add(i);
                values[i] = 1;
                while (!bfs.isEmpty()) {
                    int next = bfs.poll();
                    if (values[next] > N + M) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    for (int j : dsu.getadjLists(next)) {
                        if (values[j] < values[next] + 1) {
                            values[j] = values[next] + 1;
                            bfs.add(j);
                        }
                    }
                }
            }
        }
        PrintWriter out = new PrintWriter(System.out);
        for (int i = 0; i < N+M; i++) {
            if (values[dsu.find(i)] == 0) {
                System.out.println("NO");
                System.exit(0);
            }
        }
        out.println("YES");
        for (int i = 0; i < N; i++) {
            out.print(values[dsu.find(i)] + " ");
        }
        out.println();
        for (int i = 0; i < M; i++) {
            out.print(values[dsu.find(N+i)] + " ");
        }
        out.println();
        out.close();
    }
    static class DisjointSet {
        int[] rank;
        int[] parent;
        int[] inDegree;
        HashSet<Integer>[] adjList;
        int size;
        static boolean[] madeParent = new boolean[2000];
        DisjointSet(int N) {
            size = N;
            rank = new int[size];
            parent = new int[size];
            adjList = new HashSet[size];
            inDegree = new int[N];
            for (int i = 0; i < size; i++) {
                parent[i] = i;
                rank[i] = 1;
                adjList[i] = new HashSet<>();
            }
        }
        public int find(int x) {
            if (parent[x] != x) {
                return parent[x] = find(parent[x]);
            }
            return x;
        }
        public boolean addEdge(int x, int e) {
            if (find(e) == find(x)) {
                return false;
            }
            adjList[find(x)].add(e);
            return true;
        }
        public void addDegree(int x) {
            inDegree[find(x)]++;
        }
        public void union(int x, int y) {
            int parX = find(x);
            int parY = find(y);
            if (parX != parY) {
                if (rank[parX] > rank[parY]) {
                    //parX tree is larger
                    parent[parY] = parX;
                    rank[parX] += rank[parY];
                    adjList[parX].addAll(adjList[parY]);
                    adjList[parY].clear();
                    inDegree[parX] += inDegree[parY];
                }
                else {
                    //parY tree is larger or they're the same
                    parent[parX] = parY;
                    rank[parY] += rank[parX];
                    adjList[parY].addAll(adjList[parX]);
                    adjList[parX].clear();
                    inDegree[parY] += inDegree[parX];
                }
            }
        }
        public HashSet<Integer> getadjLists(int x) {
            HashSet<Integer> parentAdjList = new HashSet<>();
            if (!madeParent[x]) {
                for (int e : adjList[x]) {
                    parentAdjList.add(find(e));
                }
                adjList[x] = parentAdjList;
            }
            return adjList[x];
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class GourmetChoice {
    static int[] values = new int[2000];
    static int[] state = new int[2000];
    static DisjointSet dsu;
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        dsu = new DisjointSet(N+M);
        String[][] input = new String[N][M];
        for (int i = 0; i < N; i++) {
            String[] next = f.readLine().split("");
            for (int j = 0; j < M; j++) {
                if (next[j].equals("=")) {
                    dsu.union(j + N, i);
                }
            }
            input[i] = next;
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (input[i][j].equals(">")) {
                    if (!dsu.addEdge(dsu.find(i), dsu.find(j+N))) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                }
                else if (input[i][j].equals("<")) {
                    if (!dsu.addEdge(dsu.find(j+N), dsu.find(i))) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                }
            }
        }
        for (int i = 0; i < N + M; i++) {
            int temp = dsu.find(i);
            if (state[temp] != 1) {
                dfs(temp);
            }
        }
        PrintWriter out = new PrintWriter(System.out);
        for (int i = 0; i < N+M; i++) {
            if (values[dsu.find(i)] == 0) {
                System.out.println("NO");
                System.exit(0);
            }
        }
        out.println("YES");
        for (int i = 0; i < N; i++) {
            out.print(values[dsu.find(i)] + " ");
        }
        out.println();
        for (int i = 0; i < M; i++) {
            out.print(values[dsu.find(N+i)] + " ");
        }
        out.println();
        out.close();
    }
    public static void dfs(int i) {
        if (dsu.getadjLists(i).size() == 0) {
            state[i] = 1;
            values[i] = 1;
        }
        int mx = values[i];
        state[i] = 1;
        for (int j : dsu.getadjLists(i)) {
            if (state[j] != 1) {
                dfs(j);
                mx = Math.max(values[j]+1, mx);
            }
            else {
                System.out.println("NO");
                System.exit(0);
            }
        }
        state[i] = 2;
        values[i] = mx;
        return;
    }
    static class DisjointSet {
        int[] parent;
        ArrayList<Integer>[] adjList;
        int size;
        DisjointSet(int N) {
            size = N;
            parent = new int[size];
            adjList = new ArrayList[size];
            for (int i = 0; i < size; i++) {
                parent[i] = i;
                adjList[i] = new ArrayList<>();
            }
        }
        public int find(int x) {
            return (parent[x] == x ? x : (parent[x] = find(parent[x])));
        }
        public boolean addEdge(int x, int e) {
            if (find(e) == find(x)) {
                return false;
            }
            adjList[find(x)].add(e);
            return true;
        }
        public void union(int x, int y) {
            int parX = find(x);
            int parY = find(y);
            if (parX != parY) {
                parent[parY] = parX;
            }
        }
        public ArrayList<Integer> getadjLists(int x) {
            return adjList[x];
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class GourmetChoice {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        DisjointSet dsu = new DisjointSet(N+M);
        for (int i = 0; i < N; i++) {
            String[] next = f.readLine().split("");
            for (int j = 0; j < M; j++) {
                if (next[j].equals("<")) {
                    if (!dsu.addEdge(i, j+N)) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    dsu.addDegree(j+N);
                } else if (next[j].equals(">")) {
                    if (!dsu.addEdge(j+N, i)) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    dsu.addDegree(i);
                } else {
                    dsu.union(j+N, i);
                }
            }
        }
        int[] values = new int[N + M];
        boolean[] visited = new boolean[N+M];
        for (int i = 0; i < N + M; i++) {
            if (dsu.find(i) == i && dsu.inDegree[dsu.find(i)] == 0) {
                Queue<Integer> bfs = new LinkedList<>();
                bfs.add(i);
                values[i] = 1;
                while (!bfs.isEmpty()) {
                    int next = bfs.poll();
                    if (values[next] > N + M) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    for (int j : dsu.getadjLists(next)) {
                        if (values[j] < values[next] + 1) {
                            values[j] = values[next] + 1;
                            bfs.add(j);
                        }
                    }
                }
            }
        }
        PrintWriter out = new PrintWriter(System.out);
        for (int i = 0; i < N+M; i++) {
            if (values[dsu.find(i)] == 0) {
                System.out.println("NO");
                System.exit(0);
            }
        }
        out.println("YES");
        for (int i = 0; i < N; i++) {
            out.print(values[dsu.find(i)] + " ");
        }
        out.println();
        for (int i = 0; i < M; i++) {
            out.print(values[dsu.find(N+i)] + " ");
        }
        out.println();
        out.close();
    }
    static class DisjointSet {
        int[] rank;
        int[] parent;
        int[] inDegree;
        HashSet<Integer>[] adjList;
        int size;
        static boolean[] madeParent = new boolean[2000];
        DisjointSet(int N) {
            size = N;
            rank = new int[size];
            parent = new int[size];
            adjList = new HashSet[size];
            inDegree = new int[N];
            for (int i = 0; i < size; i++) {
                parent[i] = i;
                rank[i] = 1;
                adjList[i] = new HashSet<>();
            }
        }
        public int find(int x) {
            if (parent[x] != x) {
                return parent[x] = find(parent[x]);
            }
            return x;
        }
        public boolean addEdge(int x, int e) {
            if (find(e) == find(x)) {
                return false;
            }
            adjList[find(x)].add(e);
            return true;
        }
        public void addDegree(int x) {
            inDegree[find(x)]++;
        }
        public void union(int x, int y) {
            int parX = find(x);
            int parY = find(y);
            if (parX != parY) {
                if (rank[parX] > rank[parY]) {
                    //parX tree is larger
                    parent[parY] = parX;
                    rank[parX] += rank[parY];
                    adjList[parX].addAll(adjList[parY]);
                    inDegree[parX] += inDegree[parY];
                }
                else {
                    //parY tree is larger or they're the same
                    parent[parX] = parY;
                    rank[parY] += rank[parX];
                    adjList[parY].addAll(adjList[parX]);
                    inDegree[parY] += inDegree[parX];
                }
            }
        }
        public HashSet<Integer> getadjLists(int x) {
            HashSet<Integer> parentAdjList = new HashSet<>();
            if (!madeParent[find(x)]) {
                for (int e : adjList[find(x)]) {
                    parentAdjList.add(find(e));
                }
                adjList[find(x)] = parentAdjList;
            }
            return adjList[find(x)];
        }
    }
}