#include <bits/stdc++.h>
using namespace std;
const int N = (int)3e3;
int p[N], n, m, deg[N], d[N];
char a[N][N];
vector<int> adj[N];
queue<int> q;
bool visited[N];
int findSet(int u) { return p[u] == u ? p[u] : p[u] = findSet(p[u]); }
void unionSet(int u, int v) {
  int x = findSet(u), y = findSet(v);
  p[x] = y;
}
int main() {
  scanf("%d %d\n", &n, &m);
  for (int i = 1; i <= n; ++i) {
    scanf("%s\n", a[i] + 1);
    p[i] = i;
  }
  for (int i = 1; i <= m; ++i) p[n + i] = n + i;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      if (a[i][j] == '=') unionSet(i, n + j);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j) {
      if (a[i][j] == '>')
        adj[findSet(n + j)].push_back(findSet(i)), deg[findSet(i)]++;
      else if (a[i][j] == '<')
        adj[findSet(i)].push_back(findSet(n + j)), deg[findSet(n + j)]++;
    }
  bool ans = 1;
  for (int i = 1; i <= n + m; ++i)
    if (deg[findSet(i)] == 0 && !visited[findSet(i)]) {
      d[findSet(i)] = 1;
      visited[findSet(i)] = 1;
      q.push(findSet(i));
    }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int v : adj[u])
      if (!visited[v]) {
        d[v] = max(d[v], d[u] + 1);
        deg[v]--;
        if (deg[v] == 0) {
          q.push(v);
          visited[v] = 1;
        }
      }
  }
  for (int i = 1; i <= n + m; ++i)
    if (!visited[findSet(i)]) {
      ans = 0;
      break;
    }
  if (ans) {
    printf("Yes\n");
    for (int i = 1; i <= n; ++i) printf("%d ", d[findSet(i)]);
    printf("\n");
    for (int i = 1; i <= m; ++i) printf("%d ", d[findSet(n + i)]);
    printf("\n");
  } else
    printf("No\n");
  return 0;
}
