#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 2005;
int pre[N];
int find(int x) { return (x == pre[x]) ? x : pre[x] = find(pre[x]); }
void join(int x, int y) {
  int rx = find(x), ry = find(y);
  if (rx == ry) return;
  pre[rx] = ry;
}
int in[N];
vector<int> G[N];
char mp[1005][1005];
int num[N];
bool vis[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= (int)(n + m); ++i) pre[i] = i;
  for (int i = 1; i <= (int)(n); ++i) {
    for (int j = 1; j <= (int)(m); ++j) {
      char tmp;
      cin >> tmp;
      mp[i][j] = tmp;
      if (tmp == '=') join(i, j + n);
    }
  }
  for (int i = 1; i <= (int)(n); ++i) {
    for (int j = 1; j <= (int)(m); ++j) {
      char tmp = mp[i][j];
      int ri = find(i);
      int rj = find(j + n);
      if (tmp == '<') {
        G[ri].push_back(rj);
        in[rj]++;
      } else if (tmp == '>') {
        G[rj].push_back(ri);
        in[ri]++;
      }
    }
  }
  queue<int> q;
  int curn = 1;
  for (int i = 1; i <= (int)(n + m); ++i) {
    if (in[i] == 0 && find(i) == i) {
      q.push(i);
      num[i] = curn;
    }
  }
  curn++;
  while (!q.empty()) {
    int x = q.front();
    int flag = 0;
    q.pop();
    if (vis[x]) continue;
    vis[x] = true;
    for (int i = 0; i < (int)(G[x].size()); ++i) {
      int end = G[x][i];
      in[end]--;
      if (in[end] == 0 && find(end) == end) {
        q.push(end);
        num[end] = curn;
        flag = 1;
      }
    }
    if (flag == 1) ++curn;
    flag = 0;
  }
  int flag = 0;
  for (int i = 1; i <= (int)(n + m); ++i) {
    if (!vis[pre[i]]) flag = 1;
  }
  if (flag) {
    cout << "NO";
    return 0;
  }
  cout << "YES" << endl;
  for (int i = 1; i <= (int)(n); ++i) {
    cout << num[find(i)] << ' ';
  }
  cout << endl;
  for (int i = (int)(n + 1); i <= (int)(n + m); ++i)
    cout << num[find(i)] << ' ';
}
