#include <bits/stdc++.h>
using namespace std;
long long MOD = 1000000007;
long double EPS = 1e-9;
int binpow(int b, int p, int mod) {
  int ans = 1;
  b %= mod;
  for (; p; p >>= 1) {
    if (p & 1) ans = ans * b % mod;
    b = b * b % mod;
  }
  return ans;
}
void pre() {}
vector<string> ss;
int n, m;
vector<vector<int> > g;
vector<int> dfsnum, low, st, vis, scc;
int num, num_scc, stack_sz;
int SCC(int x) {
  if (dfsnum[x] == -1)
    low[x] = dfsnum[x] = num++;
  else
    return low[x];
  st[stack_sz++] = x;
  for (int i = 0; i < (int)g[x].size(); ++i)
    if (scc[g[x][i]] == -1) low[x] = min(low[x], SCC(g[x][i]));
  if (low[x] == dfsnum[x]) {
    while (scc[x] != num_scc) scc[st[--stack_sz]] = num_scc;
    ++num_scc;
  }
  return low[x];
}
void initSCC(int n) {
  scc.assign(n + 1, -1);
  dfsnum.assign(n + 1, -1);
  low.assign(n + 1, -1);
  st.resize(n + 1);
  num_scc = num = stack_sz = 0;
  for (int i = 0; i < n; ++i) SCC(i + 1);
}
struct UnionFind {
  int n, set_size, *parent, *rank;
  UnionFind() {}
  UnionFind(int a) {
    n = set_size = a;
    parent = new int[n + 1];
    rank = new int[n + 1];
    for (int i = 1; i <= n; ++i) parent[i] = i, rank[i] = 1;
  }
  inline int find(int x) {
    if (x != parent[x]) return parent[x] = find(parent[x]);
    return x;
  }
  inline void merge(int x, int y) {
    int xroot = find(x), yroot = find(y);
    if (xroot != yroot) {
      if (rank[xroot] >= rank[yroot]) {
        parent[yroot] = xroot;
        rank[xroot] += rank[yroot];
      } else {
        parent[xroot] = yroot;
        rank[yroot] += rank[xroot];
      }
      set_size -= 1;
    }
  }
  void reset() {
    set_size = n;
    for (int i = 1; i <= n; i++) parent[i] = i, rank[i] = 1;
  }
  int size() { return set_size; }
};
int rname[100010];
int viss[100010];
vector<int> topo;
void mydfs(int nn, int pp) {
  for (auto v : g[nn]) {
    if (viss[v] == 0 && v != pp) {
      viss[v] = 1;
      mydfs(v, nn);
    }
  }
  topo.emplace_back(nn);
}
int dgval[100010];
void solve() {
  int n, m;
  cin >> n >> m;
  ss.resize(n);
  for (int i = 0; i < (n); ++i) {
    cin >> ss[i];
  }
  g.resize(n + m + 1);
  UnionFind uf(n + m + 1);
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      if (ss[i][j] == '=') {
        uf.merge(i + 1, n + j + 1);
      }
    }
  }
  int curn = 1;
  for (int i = 1; i <= n + m; ++i) {
    if (rname[uf.find(i)] == 0) {
      rname[uf.find(i)] = curn++;
    }
  }
  curn--;
  int pos = 1;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      if (ss[i][j] == '<') {
        if (uf.find(i + 1) == uf.find(n + j + 1)) {
          {};
          pos = 0;
        }
        g[rname[uf.find(n + j + 1)]].emplace_back(rname[uf.find(i + 1)]);
      } else if (ss[i][j] == '>') {
        if (uf.find(i + 1) == uf.find(n + j + 1)) {
          {};
          pos = 0;
        }
        g[rname[uf.find(i + 1)]].emplace_back(rname[uf.find(n + j + 1)]);
      }
    }
  }
  if (pos == 0) {
    cout << "No\n";
    return;
  }
  initSCC(curn);
  if (num_scc < curn) {
    cout << "No\n";
    return;
  }
  cout << "Yes\n";
  for (int i = 1; i <= curn; ++i) {
    if (!viss[i]) {
      viss[i] = 1;
      mydfs(i, -1);
    }
  }
  for (int i = 0; i < (topo.size()); ++i) {
    int nn = topo[i];
    dgval[nn] = 1;
    for (auto v : g[nn]) {
      (dgval[nn] = max((dgval[nn]), (dgval[v] + 1)));
    }
  }
  for (int i = 1; i <= n; ++i) {
    cout << dgval[rname[uf.find(i)]] << " ";
  }
  cout << '\n';
  for (int i = n + 1; i <= m + n; ++i) {
    cout << dgval[rname[uf.find(i)]] << " ";
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  pre();
  int t = 1;
  for (int i = 1; i <= t; i++) {
    solve();
  }
}
