#include <bits/stdc++.h>
using namespace std;
int T;
int n, m;
int num[4001], ans[4001];
char c[2001][2001];
struct Edge {
  int to, next;
} edge[4000001];
int head[4001], sze;
int ru[4001], fa[4001];
bool vis[4001];
inline void add(int u, int v) {
  edge[++sze] = (Edge){v, head[u]}, head[u] = sze;
}
inline int find(int x) { return fa[x] == x ? fa[x] : fa[x] = find(fa[x]); }
inline void hb(int x, int y) {
  int fx = find(x), fy = find(y);
  if (fx != fy) fa[fx] = fy;
}
inline void init() {
  scanf("%d%d", &n, &m);
  sze = 0, memset(head, 0, sizeof head), memset(ru, 0, sizeof ru);
  int i, j;
  for (i = 1; i <= n + m; i++) {
    fa[i] = i;
  }
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= m; j++) {
      cin >> c[i][j];
      if (c[i][j] == '=') hb(i, j + n);
    }
  }
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= m; j++) {
      int fx = find(i), fy = find(j + n);
      if (c[i][j] == '>') add(fy, fx), ru[fx]++;
      if (c[i][j] == '<') add(fx, fy), ru[fy]++;
    }
  }
}
inline void solve() {
  memset(vis, false, sizeof vis);
  queue<int> q;
  int i;
  for (i = 1; i <= n + m; i++) {
    int p = find(i);
    if (!vis[p] && !ru[p]) q.push(p), vis[p] = true, num[p] = 1;
  }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (i = head[u]; i; i = edge[i].next) {
      int v = edge[i].to;
      ru[v]--;
      if (!ru[v] && !vis[v]) num[v] = num[u] + 1, q.push(v), vis[v] = true;
    }
  }
  int cnt = 0;
  for (i = 1; i <= n + m; i++) {
    if (vis[find(i)]) cnt++;
  }
  if (cnt != n + m)
    printf("No\n");
  else {
    printf("Yes\n");
    for (i = 1; i <= n; i++) {
      printf("%d ", num[find(i)]);
    }
    printf("\n");
    for (i = 1; i <= m; i++) {
      printf("%d ", num[find(i + n)]);
    }
    printf("\n");
  }
}
int main() {
  init();
  solve();
  return 0;
}
