#include <bits/stdc++.h>
using namespace std;
class Graph {
 public:
  vector<vector<int> > adjList;
  vector<int> indegree;
  Graph(int v) {
    adjList.resize(v);
    indegree.resize(v, 0);
  }
  void add(int u, int v) {
    adjList[u].push_back(v);
    indegree[v]++;
  }
};
struct subset {
  int rank;
  int parent;
};
int find(subset subsets[], int i) {
  if (subsets[i].parent != i)
    subsets[i].parent = find(subsets, subsets[i].parent);
  return subsets[i].parent;
}
void Union(subset subsets[], int x, int y) {
  int xroot = find(subsets, x);
  int yroot = find(subsets, y);
  if (subsets[xroot].rank > subsets[yroot].rank) {
    subsets[yroot].parent = xroot;
  } else if (subsets[xroot].rank < subsets[yroot].rank) {
    subsets[xroot].parent = yroot;
  } else {
    subsets[yroot].parent = xroot;
    subsets[xroot].rank++;
  }
}
bool TopologicalSort(Graph const &graph, vector<int> &ans, int v,
                     subset subsets[]) {
  vector<int> indegree = graph.indegree;
  queue<int> S;
  for (int i = 0; i < v; i++) {
    if (!indegree[i]) {
      S.push(i);
      ans[find(subsets, i)] = 1;
    }
  }
  while (!S.empty()) {
    int n = S.front();
    S.pop();
    for (int m : graph.adjList[n]) {
      indegree[m] -= 1;
      ans[find(subsets, m)] = ans[find(subsets, n)] + 1;
      if (!indegree[m]) {
        S.push(m);
      }
    }
  }
  for (int i = 0; i < v; i++) {
    if (indegree[i]) {
      return false;
    }
  }
  return true;
}
int main() {
  int n, m;
  cin >> n >> m;
  subset *subsets = new subset[n + m];
  for (int v = 0; v < n + m; v++) {
    subsets[v].parent = v;
    subsets[v].rank = 0;
  }
  Graph graph(n + m);
  char input[n][m];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> input[i][j];
      if (input[i][j] == '=') {
        Union(subsets, i, j + n);
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      int x = find(subsets, i);
      int y = find(subsets, j + n);
      if (input[i][j] == '<') {
        graph.add(x, y);
      } else if (input[i][j] == '>') {
        graph.add(y, x);
      }
    }
  }
  vector<int> ans(n + m);
  if (TopologicalSort(graph, ans, n + m, subsets)) {
    cout << "YES" << endl;
    for (int i = 0; i < n; i++) {
      cout << ans[find(subsets, i)] << " ";
    }
    cout << endl;
    for (int i = n; i < m + n; i++) {
      cout << ans[find(subsets, i)] << " ";
    }
    cout << endl;
  } else {
    cout << "NO" << endl;
  }
}
