#include <bits/stdc++.h>
using namespace std;
int N, M;
string grid[1000];
vector<vector<pair<int, char>>> startAdj;
vector<bool> visited;
vector<int> merged;
vector<vector<pair<int, char>>> adj;
vector<int> value;
vector<int> greaterCount;
void flood(int start, int pos) {
  if (visited[pos]) return;
  visited[pos] = true;
  merged[pos] = start;
  for (int i = 0; i < startAdj[pos].size(); i++) {
    if (startAdj[pos][i].second != '=') {
      adj[start].push_back(startAdj[pos][i]);
    }
  }
  for (int i = 0; i < startAdj[pos].size(); i++) {
    if (startAdj[pos][i].second == '=') {
      flood(start, startAdj[pos][i].first);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> N >> M;
  for (int i = 0; i < N; i++) cin >> grid[i];
  startAdj.assign(N + M + 1, vector<pair<int, char>>());
  for (int i = 0; i < N; i++)
    for (int j = 0; j < M; j++)
      startAdj[i + 1].push_back({j + 1 + N, grid[i][j]});
  for (int j = 0; j < M; j++) {
    for (int i = 0; i < N; i++) {
      char c = grid[i][j];
      if (c == '>')
        c = '<';
      else if (c == '<')
        c = '>';
      startAdj[j + 1 + N].push_back({i + 1, c});
    }
  }
  visited.assign(N + M + 1, false);
  merged.assign(N + M + 1, 0);
  adj.assign(N + M + 1, vector<pair<int, char>>());
  value.assign(N + M + 1, 0);
  greaterCount.assign(N + M + 1, 0);
  for (int i = 1; i <= N + M; i++) {
    if (!visited[i]) {
      flood(i, i);
    }
  }
  bool works = true;
  for (int i = 1; i <= N + M; i++) {
    for (int j = 0; j < adj[i].size(); j++) {
      if (adj[i][j].second == '>') greaterCount[i]++;
      if (merged[adj[i][j].first] == i) works = false;
    }
  }
  if (works) {
    vector<int> curr;
    for (int i = 1; i <= N + M; i++)
      if (merged[i] == i && greaterCount[i] == 0) curr.push_back(i);
    vector<int> next;
    int v = 1;
    while (curr.size() != 0) {
      for (int i = 0; i < curr.size(); i++) {
        value[curr[i]] = v;
        for (int j = 0; j < adj[curr[i]].size(); j++) {
          if (adj[curr[i]][j].second == '<') {
            greaterCount[merged[adj[curr[i]][j].first]]--;
            if (greaterCount[merged[adj[curr[i]][j].first]] == 0) {
              next.push_back(merged[adj[curr[i]][j].first]);
            }
          }
        }
      }
      curr = next;
      next.clear();
      v++;
    }
    for (int i = 1; i <= N + M; i++) {
      if (!value[i] && merged[i] == i) works = false;
    }
  }
  if (works) {
    cout << "Yes\n";
    for (int i = 0; i < N; i++) {
      if (i) cout << " ";
      cout << value[merged[i + 1]];
    }
    cout << "\n";
    for (int i = 0; i < M; i++) {
      if (i) cout << " ";
      cout << value[merged[i + 1 + N]];
    }
    cout << "\n";
  } else {
    cout << "No\n";
  }
  return 0;
}
