#include <bits/stdc++.h>
using namespace std;
int root(vector<int> &p, int i) {
  while (p[i] != i) {
    p[i] = p[p[i]];
    i = p[i];
  }
  return i;
}
void init(vector<int> &p, vector<int> &s) {
  for (int i = 0; i < p.size(); i++) {
    p[i] = i;
  }
  for (auto &i : s) {
    i = 1;
  }
}
void merge(int i, int j, vector<int> &p, vector<int> &s) {
  int root_i = root(p, i);
  int root_j = root(p, j);
  if (root_i != root_j) {
    if (s[root_i] > s[root_j]) {
      p[root_j] = p[root_i];
      s[root_i] += s[root_j];
    } else {
      p[root_i] = p[root_j];
      s[root_j] += s[root_i];
    }
  }
}
void nodeMerge(const vector<string> &r, vector<int> &p, vector<int> &s) {
  for (int i = 0; i < r.size(); i++) {
    for (int j = 0; j < r[0].size(); j++) {
      if (r[i][j] == '=') {
        merge(i, r.size() + j, p, s);
      }
    }
  }
}
vector<vector<int>> construct(const vector<string> &r, vector<int> &p,
                              vector<int> &s) {
  vector<vector<int>> res(p.size());
  int base = r.size();
  for (int i = 0; i < r.size(); i++) {
    for (int j = 0; j < r[0].size(); j++) {
      if (r[i][j] == '<') {
        res[root(p, i)].push_back(root(p, base + j));
      } else if (r[i][j] == '>') {
        res[root(p, base + j)].push_back(root(p, i));
      }
    }
  }
  return res;
}
bool DFS(vector<int> &state, const vector<vector<int>> &g, int i,
         stack<int> &order) {
  if (state[i] == 2) {
    return false;
  } else if (state[i] == 1) {
    return true;
  } else {
    state[i] = 1;
    for (auto n : g[i]) {
      if (DFS(state, g, n, order)) {
        return true;
      }
    }
    state[i] = 2;
    order.push(i);
  }
  return false;
}
bool findLoop(const vector<vector<int>> &g, stack<int> &order) {
  vector<int> state(g.size(), 0);
  for (int i = 0; i < state.size(); i++) {
    if (DFS(state, g, i, order)) {
      return true;
    }
  }
  return false;
}
int findRoot(vector<int> &p, stack<int> &order) {
  while (!order.empty()) {
    int topNode = order.top();
    if (root(p, topNode) == topNode) {
      return topNode;
    }
    order.pop();
  }
  cout << "no root";
}
vector<int> calGrade(const vector<vector<int>> &g, vector<int> &p,
                     stack<int> &order) {
  vector<vector<int>> rev(g.size());
  vector<int> grade(g.size(), 87);
  for (int i = 0; i < g.size(); i++) {
    for (auto n : g[i]) {
      rev[n].push_back(i);
    }
  }
  while (!order.empty()) {
    int maxVal = 0;
    int topNode = order.top();
    for (auto i : rev[topNode]) {
      maxVal = max(maxVal, grade[i]);
    }
    grade[topNode] = maxVal + 1;
    order.pop();
  }
  for (int i = 0; i < grade.size(); i++) {
    if (root(p, i) != i) {
      grade[i] = grade[root(p, i)];
    }
  }
  return grade;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<string> r;
  vector<int> p(n + m);
  vector<int> s(n + m);
  stack<int> order;
  init(p, s);
  string input;
  for (int i = 0; i < n; i++) {
    cin >> input;
    r.push_back(input);
  }
  nodeMerge(r, p, s);
  auto g = construct(r, p, s);
  if (findLoop(g, order)) {
    cout << "No";
  } else {
    cout << "Yes" << endl;
    int point = 1;
    vector<int> grade = calGrade(g, p, order);
    for (int i = 0; i < n; i++) {
      cout << grade[i] << ' ';
    }
    cout << endl;
    for (int i = 0; i < m; i++) {
      cout << grade[n + i] << ' ';
    }
  }
}
