import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.exit;

public class D {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }

        Map<String, Set<String>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put("a" + i, new HashSet<>(Arrays.asList("a" + i)));
        for (int i = 0; i < m; i++) vToSet.put("b" + i, new HashSet<>(Arrays.asList("b" + i)));

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    if (!vToSet.get("a" + i).contains("b" + j)) {
                        HashSet<String> joined = new HashSet<>(vToSet.get("a" + i));
                        joined.addAll(vToSet.get("b" + j));
                        for (String v : joined) vToSet.put(v, joined);
                    }
                }
            }
        }

        Map<Set<String>, Set<Set<String>>> gt = new HashMap<>();
        for (Set<String> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<String> aSet = vToSet.get("a" + i);
                Set<String> bSet = vToSet.get("b" + j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        System.out.println("No");
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        System.out.println("No");
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        Map<String, Integer> rates = new HashMap<>();
        for (int i = 1; !gt.isEmpty(); ++i) {
            int next = i;
            List<Set<String>> minimal = gt.keySet().stream()
                    .filter(key -> gt.get(key).isEmpty())
                    .collect(Collectors.toList());
            if (minimal.isEmpty()) {
                System.out.println("No");
                exit(0);
            }
            for (Set<String> min : minimal) {
                gt.remove(min);
                for (Set<Set<String>> sets : gt.values()) {
                    sets.remove(min);
                }
                for (String v : min) {
                    rates.put(v, next);
                }
            }
        }
        System.out.println("Yes");
        for (int i = 0; i < n; i++) {
            System.out.print(rates.get("a" + i) + " ");
        }
        System.out.println();
        for (int j = 0; j < m; j++) {
            System.out.print(rates.get("b" + j) + " ");
        }
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;

public class D {
    public static void main(String[] args) throws IOException {
        long start = currentTimeMillis();
        Scanner s = new Scanner(new BufferedInputStream(System.in, 1<<20));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out), 1<<20);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, HashSet<Integer>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put(1024 + i, new HashSet<>(Arrays.asList(1024 + i)));
        for (int i = 0; i < m; i++) vToSet.put(i, new HashSet<>(Arrays.asList(i)));
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    int a = 1024 + i;
                    int b = j;
                    if (!vToSet.get(a).contains(b)) {
                        HashSet<Integer> joined;
                        if (vToSet.get(a).size() > vToSet.get(b).size()) {
                            joined = vToSet.get(a);
                            joined.addAll(vToSet.get(b));
                            for (Integer v : vToSet.get(b)) vToSet.put(v, joined);
                        } else {
                            joined = vToSet.get(b);
                            joined.addAll(vToSet.get(a));
                            for (Integer v : vToSet.get(a)) vToSet.put(v, joined);
                        }
                    }
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> gt = new HashMap<>();
        for (Set<Integer> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<Integer> aSet = vToSet.get(1024 + i);
                Set<Integer> bSet = vToSet.get(j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> lt = new HashMap<>();
        for (Map.Entry<Set<Integer>, Set<Set<Integer>>> gtEntry : gt.entrySet()) {
            for (Set<Integer> lesser : gtEntry.getValue()) {
                if (!lt.containsKey(lesser)) lt.put(lesser, new HashSet());
                lt.get(lesser).add(gtEntry.getKey());
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, Integer> rates = new HashMap<>();
        List<Set<Integer>> minSets = gt.keySet().stream()
                .filter(key -> gt.get(key).isEmpty())
                .collect(Collectors.toList());
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 1; !gt.isEmpty(); ++i) {
            if (minSets.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            List<Set<Integer>> nextMinSets = new ArrayList<>();
            for (Set<Integer> min : minSets) {
                gt.remove(min);
                for (Set<Integer> gtSet : lt.getOrDefault(min, new HashSet<>())) {
                    Set<Set<Integer>> gtSets = gt.get(gtSet);
                    gtSets.remove(min);
                    if (gtSets.isEmpty()) {
                        nextMinSets.add(gtSet);
                    }
                }
                for (Integer v : min) {
                    rates.put(v, i);
                }
            }
            if (nextMinSets.isEmpty() && !gt.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            minSets = nextMinSets;
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        out.write("Yes\n");
        for (int i = 0; i < n; i++) {
            out.write(rates.get(1024 + i) + " ");
        }
        out.write("\n");
        for (int j = 0; j < m; j++) {
            out.write(rates.get(j) + " ");
        }
        out.flush();

        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        ///
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;

public class D {
    public static void main(String[] args) throws IOException {
        long start = currentTimeMillis();
        Scanner s = new Scanner(new BufferedInputStream(System.in, 65536));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out), 65536);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }

        Map<String, HashSet<String>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put("a" + i, new HashSet<>(Arrays.asList("a" + i)));
        for (int i = 0; i < m; i++) vToSet.put("b" + i, new HashSet<>(Arrays.asList("b" + i)));

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    String a = "a" + i;
                    String b = "b" + j;
                    if (!vToSet.get(a).contains(b)) {
                        HashSet<String> joined;
                        if (vToSet.get(a).size() > vToSet.get(b).size()) {
                            joined = vToSet.get(a);
                            joined.addAll(vToSet.get(b));
                            for (String v : vToSet.get(b)) vToSet.put(v, joined);
                        } else {
                            joined = vToSet.get(b);
                            joined.addAll(vToSet.get(a));
                            for (String v : vToSet.get(a)) vToSet.put(v, joined);
                        }
                    }
                }
            }
        }
        if (n == 453) {
            out.write(">>: " + (System.currentTimeMillis() - start));
            out.flush();
        }

        Map<Set<String>, Set<Set<String>>> gt = new HashMap<>();
        for (Set<String> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<String> aSet = vToSet.get("a" + i);
                Set<String> bSet = vToSet.get("b" + j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        Map<Set<String>, Set<Set<String>>> lt = new HashMap<>();
        for (Map.Entry<Set<String>, Set<Set<String>>> gtEntry : gt.entrySet()) {
            for (Set<String> lesser : gtEntry.getValue()) {
                if (!lt.containsKey(lesser)) lt.put(lesser, new HashSet());
                lt.get(lesser).add(gtEntry.getKey());
            }
        }
        Map<String, Integer> rates = new HashMap<>();
        List<Set<String>> minSets = gt.keySet().stream()
                .filter(key -> gt.get(key).isEmpty())
                .collect(Collectors.toList());
        for (int i = 1; !gt.isEmpty(); ++i) {
            if (minSets.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            List<Set<String>> nextMinSets = new ArrayList<>();
            for (Set<String> min : minSets) {
                gt.remove(min);
                for (Set<String> gtSet : lt.getOrDefault(min, new HashSet<>())) {
                    Set<Set<String>> gtSets = gt.get(gtSet);
                    gtSets.remove(min);
                    if (gtSets.isEmpty()) {
                        nextMinSets.add(gtSet);
                    }
                }
                for (String v : min) {
                    rates.put(v, i);
                }
            }
            if (nextMinSets.isEmpty() && !gt.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            minSets = nextMinSets;
        }
        out.write("Yes\n");
        for (int i = 0; i < n; i++) {
            out.write(rates.get("a" + i) + " ");
        }
        out.write("\n");
        for (int j = 0; j < m; j++) {
            out.write(rates.get("b" + j) + " ");
        }
        out.flush();
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;

public class D {
    public static void main(String[] args) throws IOException {
        long start = currentTimeMillis();
        Scanner s = new Scanner(new BufferedInputStream(System.in, 1<<20));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out), 1<<20);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, HashSet<Integer>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put(1024 + i, new HashSet<>(Arrays.asList(1024 + i)));
        for (int i = 0; i < m; i++) vToSet.put(i, new HashSet<>(Arrays.asList(i)));
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    int a = 1024 + i;
                    int b = j;
                    if (!vToSet.get(a).contains(b)) {
                        HashSet<Integer> joined;
                        if (vToSet.get(a).size() > vToSet.get(b).size()) {
                            joined = vToSet.get(a);
                            joined.addAll(vToSet.get(b));
                            for (Integer v : vToSet.get(b)) vToSet.put(v, joined);
                        } else {
                            joined = vToSet.get(b);
                            joined.addAll(vToSet.get(a));
                            for (Integer v : vToSet.get(a)) vToSet.put(v, joined);
                        }
                    }
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> gt = new HashMap<>();
        for (Set<Integer> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<Integer> aSet = vToSet.get(1024 + i);
                Set<Integer> bSet = vToSet.get(j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> lt = new HashMap<>();
        for (Map.Entry<Set<Integer>, Set<Set<Integer>>> gtEntry : gt.entrySet()) {
            for (Set<Integer> lesser : gtEntry.getValue()) {
                if (!lt.containsKey(lesser)) lt.put(lesser, new HashSet());
                lt.get(lesser).add(gtEntry.getKey());
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, Integer> rates = new HashMap<>();
        List<Set<Integer>> minSets = gt.keySet().stream()
                .filter(key -> gt.get(key).isEmpty())
                .collect(Collectors.toList());
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 1; !gt.isEmpty(); ++i) {
            if (minSets.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            List<Set<Integer>> nextMinSets = new ArrayList<>();
            for (Set<Integer> min : minSets) {
                gt.remove(min);
                for (Set<Integer> gtSet : lt.getOrDefault(min, new HashSet<>())) {
                    Set<Set<Integer>> gtSets = gt.get(gtSet);
                    gtSets.remove(min);
                    if (gtSets.isEmpty()) {
                        nextMinSets.add(gtSet);
                    }
                }
                for (Integer v : min) {
                    rates.put(v, i);
                }
            }
            if (nextMinSets.isEmpty() && !gt.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            minSets = nextMinSets;
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        out.write("Yes\n");
        for (int i = 0; i < n; i++) {
            out.write(rates.get(1024 + i) + " ");
        }
        out.write("\n");
        for (int j = 0; j < m; j++) {
            out.write(rates.get(j) + " ");
        }
        out.flush();

        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        //
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;

public class D {
    public static void main(String[] args) throws IOException {
        long start = currentTimeMillis();
        Scanner s = new Scanner(new BufferedInputStream(System.in, 65536));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out), 65536);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }

        Map<String, HashSet<String>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put("a" + i, new HashSet<>(Arrays.asList("a" + i)));
        for (int i = 0; i < m; i++) vToSet.put("b" + i, new HashSet<>(Arrays.asList("b" + i)));

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    String a = "a" + i;
                    String b = "b" + j;
                    if (!vToSet.get(a).contains(b)) {
                        HashSet<String> joined;
                        if (vToSet.get(a).size() > vToSet.get(b).size()) {
                            joined = vToSet.get(a);
                            joined.addAll(vToSet.get(b));
                            for (String v : vToSet.get(b)) vToSet.put(v, joined);
                        } else {
                            joined = vToSet.get(b);
                            joined.addAll(vToSet.get(a));
                            for (String v : vToSet.get(a)) vToSet.put(v, joined);
                        }
                    }
                }
            }
        }

        Map<Set<String>, Set<Set<String>>> gt = new HashMap<>();
        for (Set<String> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<String> aSet = vToSet.get("a" + i);
                Set<String> bSet = vToSet.get("b" + j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        Map<Set<String>, Set<Set<String>>> lt = new HashMap<>();
        for (Map.Entry<Set<String>, Set<Set<String>>> gtEntry : gt.entrySet()) {
            for (Set<String> lesser : gtEntry.getValue()) {
                if (!lt.containsKey(lesser)) lt.put(lesser, new HashSet());
                lt.get(lesser).add(gtEntry.getKey());
            }
        }
        Map<String, Integer> rates = new HashMap<>();
        List<Set<String>> minSets = gt.keySet().stream()
                .filter(key -> gt.get(key).isEmpty())
                .collect(Collectors.toList());

        if (n == 453) {
            out.write(">>: " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 1; !gt.isEmpty(); ++i) {
            if (minSets.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            List<Set<String>> nextMinSets = new ArrayList<>();
            for (Set<String> min : minSets) {
                gt.remove(min);
                for (Set<String> gtSet : lt.getOrDefault(min, new HashSet<>())) {
                    Set<Set<String>> gtSets = gt.get(gtSet);
                    gtSets.remove(min);
                    if (gtSets.isEmpty()) {
                        nextMinSets.add(gtSet);
                    }
                }
                for (String v : min) {
                    rates.put(v, i);
                }
            }
            if (nextMinSets.isEmpty() && !gt.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            minSets = nextMinSets;
        }
        out.write("Yes\n");
        for (int i = 0; i < n; i++) {
            out.write(rates.get("a" + i) + " ");
        }
        out.write("\n");
        for (int j = 0; j < m; j++) {
            out.write(rates.get("b" + j) + " ");
        }
        out.flush();
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;

public class D {
    public static void main(String[] args) throws IOException {
        long start = currentTimeMillis();
        Scanner s = new Scanner(new BufferedInputStream(System.in, 1<<20));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out), 1<<20);
        int n = s.nextInt(), m = s.nextInt();
        char[][] rs = new char[n][];
        for (int i = 0; i < n; i++) {
            rs[i] = s.next().toCharArray();
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, HashSet<Integer>> vToSet = new HashMap<>();
        for (int i = 0; i < n; i++) vToSet.put(1024 + i, new HashSet<>(Arrays.asList(1024 + i)));
        for (int i = 0; i < m; i++) vToSet.put(i, new HashSet<>(Arrays.asList(i)));
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') {
                    int a = 1024 + i;
                    int b = j;
                    if (!vToSet.get(a).contains(b)) {
                        HashSet<Integer> joined;
                        if (vToSet.get(a).size() > vToSet.get(b).size()) {
                            joined = vToSet.get(a);
                            joined.addAll(vToSet.get(b));
                            for (Integer v : vToSet.get(b)) vToSet.put(v, joined);
                        } else {
                            joined = vToSet.get(b);
                            joined.addAll(vToSet.get(a));
                            for (Integer v : vToSet.get(a)) vToSet.put(v, joined);
                        }
                    }
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> gt = new HashMap<>();
        for (Set<Integer> set : vToSet.values()) {
            gt.put(set, new HashSet<>());
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (rs[i][j] == '=') continue;
                Set<Integer> aSet = vToSet.get(1024 + i);
                Set<Integer> bSet = vToSet.get(j);
                if (rs[i][j] == '>') {
                    if (gt.get(bSet).contains(aSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(aSet).add(bSet);
                }
                if (rs[i][j] == '<') {
                    if (gt.get(aSet).contains(bSet)) {
                        out.write("No");
                        out.flush();
                        exit(0);
                    }
                    gt.get(bSet).add(aSet);
                }
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Set<Integer>, Set<Set<Integer>>> lt = new HashMap<>();
        for (Map.Entry<Set<Integer>, Set<Set<Integer>>> gtEntry : gt.entrySet()) {
            for (Set<Integer> lesser : gtEntry.getValue()) {
                if (!lt.containsKey(lesser)) lt.put(lesser, new HashSet());
                lt.get(lesser).add(gtEntry.getKey());
            }
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        Map<Integer, Integer> rates = new HashMap<>();
        List<Set<Integer>> minSets = gt.keySet().stream()
                .filter(key -> gt.get(key).isEmpty())
                .collect(Collectors.toList());
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        for (int i = 1; !gt.isEmpty(); ++i) {
            if (minSets.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            List<Set<Integer>> nextMinSets = new ArrayList<>();
            for (Set<Integer> min : minSets) {
                gt.remove(min);
                for (Set<Integer> gtSet : lt.getOrDefault(min, new HashSet<>())) {
                    Set<Set<Integer>> gtSets = gt.get(gtSet);
                    gtSets.remove(min);
                    if (gtSets.isEmpty()) {
                        nextMinSets.add(gtSet);
                    }
                }
                for (Integer v : min) {
                    rates.put(v, i);
                }
            }
            if (nextMinSets.isEmpty() && !gt.isEmpty()) {
                out.write("No");
                out.flush();
                exit(0);
            }
            minSets = nextMinSets;
        }
        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }
        out.write("Yes\n");
        for (int i = 0; i < n; i++) {
            out.write(rates.get(1024 + i) + " ");
        }
        out.write("\n");
        for (int j = 0; j < m; j++) {
            out.write(rates.get(j) + " ");
        }
        out.flush();

        if (n == 1000 && m == 842) {
            out.write(">> " + (System.currentTimeMillis() - start));
            out.flush();
        }

    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        List<Integer> ls = new ArrayList<>();
        int gr = 0;
        List<Integer> eq = new ArrayList<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }

        boolean[] was = new boolean[sz];
        int wasCnt = 0;
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (wasCnt < sz && !bad) {
            boolean[] curMask = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!was[v] && nodes[v].gr == 0) {
                    curMask[v] = true;
                }
            }
            Queue<Integer> queue = new ArrayDeque<>(sz);
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!curMask[v]) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                curMask[v] = false;
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            List<Integer> cur = new ArrayList<>(sz);
            for (int v = 0; v < sz; v++) {
                if (curMask[v]) {
                    cur.add(v);
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                wasCnt++;
                was[v] = true;
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        Set<Integer> gr = new HashSet<>();
        Set<Integer> ls = new HashSet<>();
        Set<Integer> eq = new HashSet<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr.add(u);
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr.add(v);
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            Set<Integer> cur = new HashSet<>();
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr.size() == 0) {
                    cur.add(v);
                }
            }
            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr.remove(v);
                }
                for (int u: nodes[v].eq) {
                    if (!cur.contains(u)) {
                        bad = true;
                    }
                }
            }
            // eq
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        Set<Integer> gr = new HashSet<>();
        Set<Integer> ls = new HashSet<>();
        Set<Integer> eq = new HashSet<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr.add(u);
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr.add(v);
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            Set<Integer> cur = new HashSet<>();
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr.size() == 0) {
                    cur.add(v);
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            List<Integer> toRm = new ArrayList<>();
            for (int v = 0; v < sz; v++) {
                if (!cur.contains(v)) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                toRm.add(v);
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            cur.removeAll(toRm);

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr.remove(v);
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        List<Integer> ls = new ArrayList<>();
        int gr = 0;
        List<Integer> eq = new ArrayList<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }

        boolean[] was = new boolean[sz];
        int wasCnt = 0;
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (wasCnt < sz && !bad) {
            boolean[] curMask = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!was[v] && nodes[v].gr == 0) {
                    curMask[v] = true;
                }
            }
            Queue<Integer> queue = new ArrayDeque<>(sz);
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!curMask[v]) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                curMask[v] = false;
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            List<Integer> cur = new ArrayList<>(sz);
            for (int v = 0; v < sz; v++) {
                if (curMask[v]) {
                    cur.add(v);
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                wasCnt++;
                was[v] = true;
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.print(ans[i] + " ");
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        List<Integer> ls = new ArrayList<>();
        int gr = 0;
        List<Integer> eq = new ArrayList<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }

        boolean[] was = new boolean[sz];
        int wasCnt = 0;
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (wasCnt < sz && !bad) {
            boolean[] curMask = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!was[v] && nodes[v].gr == 0) {
                    curMask[v] = true;
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!curMask[v]) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                curMask[v] = false;
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            List<Integer> cur = new ArrayList<>();
            for (int v = 0; v < sz; v++) {
                if (curMask[v]) {
                    cur.add(v);
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                wasCnt++;
                was[v] = true;
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;
    int sz;

    class Node {
        List<Integer> ls = new ArrayList<>(sz);
        int gr = 0;
        List<Integer> eq = new ArrayList<>(sz);
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }

        boolean[] was = new boolean[sz];
        int wasCnt = 0;
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (wasCnt < sz && !bad) {
            boolean[] curMask = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!was[v] && nodes[v].gr == 0) {
                    curMask[v] = true;
                }
            }
            Queue<Integer> queue = new ArrayDeque<>(sz);
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!curMask[v]) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                curMask[v] = false;
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            List<Integer> cur = new ArrayList<>(sz);
            for (int v = 0; v < sz; v++) {
                if (curMask[v]) {
                    cur.add(v);
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                wasCnt++;
                was[v] = true;
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.print(ans[i] + " ");
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        List<Integer> ls = new ArrayList<>();
        int gr = 0;
        List<Integer> eq = new ArrayList<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            Set<Integer> cur = new HashSet<>();
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr == 0) {
                    cur.add(v);
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            List<Integer> toRm = new ArrayList<>();
            for (int v = 0; v < sz; v++) {
                if (!cur.contains(v)) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                toRm.add(v);
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            cur.removeAll(toRm);

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        List<Integer> ls = new ArrayList<>();
        int gr = 0;
        List<Integer> eq = new ArrayList<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr++;
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr++;
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            boolean[] curMask = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr == 0) {
                    curMask[v] = true;
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!curMask[v]) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                curMask[v] = false;
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }
            List<Integer> cur = new ArrayList<>();
            for (int v = 0; v < sz; v++) {
                if (curMask[v]) {
                    cur.add(v);
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr--;
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        Set<Integer> gr = new HashSet<>();
        Set<Integer> ls = new HashSet<>();
        Set<Integer> eq = new HashSet<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr.add(u);
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr.add(v);
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            Set<Integer> cur = new HashSet<>();
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr.size() == 0) {
                    cur.add(v);
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!cur.contains(v)) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                cur.remove(v);
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr.remove(v);
                }
            }
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        try (PrintWriter out = new PrintWriter(System.out)) {
            Solution solution = new Solution();
            solution.in = new InputReader(getInput());
            solution.out = out;
            solution.solve();
        }
    }

    static InputStream getInput() {
        String inputFile = getInputFileName();
        if (inputFile == null) {
            return System.in;
        }
        try {
            return new FileInputStream(Main.class.getClassLoader().getResource(inputFile).getFile());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    static String getInputFileName() {
        try {
            return System.getProperty("compet.input");
        } catch (Exception ex) {
            return null;
        }
    }
}

class Solution {
    InputReader in;
    PrintWriter out;

    int n;
    int m;

    class Node {
        Set<Integer> gr = new HashSet<>();
        Set<Integer> ls = new HashSet<>();
        Set<Integer> eq = new HashSet<>();
    }

    void solve() {
        n = in.nextInt();
        m = in.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.next();
        }
        int sz = n+m;
        Node[] nodes = IntStream.range(0, sz).mapToObj(i -> new Node()).toArray(Node[]::new);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int v = i;
                int u = n + j;
                switch (a[i].charAt(j)) {
                    case '>':
                        nodes[v].gr.add(u);
                        nodes[u].ls.add(v);
                        break;
                    case '<':
                        nodes[u].gr.add(v);
                        nodes[v].ls.add(u);
                        break;
                    case '=':
                        nodes[u].eq.add(v);
                        nodes[v].eq.add(u);
                        break;
                }
            }
        }
        Set<Integer> was = new HashSet<>();
        boolean bad = false;
        int num = 1;
        int[] ans = new int[sz];
        while (was.size() < sz && !bad) {
            Set<Integer> cur = new HashSet<>();
            for (int v = 0; v < sz; v++) {
                if (!was.contains(v) && nodes[v].gr.size() == 0) {
                    cur.add(v);
                }
            }
            Queue<Integer> queue = new ArrayDeque<>();
            boolean[] visited = new boolean[sz];
            for (int v = 0; v < sz; v++) {
                if (!cur.contains(v)) {
                    queue.add(v);
                    visited[v] = true;
                }
            }
            while (!queue.isEmpty()) {
                int v = queue.poll();
                cur.remove(v);
                for (int u: nodes[v].eq) {
                    if (!visited[u]) {
                        visited[u] = true;
                        queue.add(u);
                    }
                }
            }

            if (cur.size() == 0) {
                bad = true;
                break;
            }
            for (int v: cur) {
                was.add(v);
                ans[v] = num;
                for (int u: nodes[v].ls) {
                    nodes[u].gr.remove(v);
                }
                for (int u: nodes[v].eq) {
                    if (!cur.contains(u)) {
                        bad = true;
                    }
                }
            }
            // eq
            num++;
        }

        out.println(bad ? "No" : "Yes");
        if (!bad) {
            for (int i = 0; i < sz; i++) {
                if (i == n) {
                    out.println();
                }
                out.printf("%d ", ans[i]);
            }
        }
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        // DSU
        private int[] parent;
        private int[] rank;

        private void make(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int v = 0; v < n; v++) {
                parent[v] = v;
                rank[v] = 0;
            }
        }

        private int find(int v) {
            if (parent[v] == v) return v;
            return parent[v] = find(parent[v]);
        }

        private void unite(int v, int u) {
            v = find(v);
            u = find(u);
            if (v != u) {
                if (rank[v] < rank[u]) {
                    v ^= u; u ^= v; v ^= u; // swap
                }
                parent[u] = v;
                if (rank[v] == rank[u]) rank[v]++;
            }
        }
        //

        private List<Set<Integer>> g;
        private int[] vis;
        private int[] ans;

        private int max(int a, int b) {
            return a < b ? b : a;
        }

        private void dfs(int v) {
            vis[v] = ans[v] = 1;
            for (int u : g.get(v)) {
                if (vis[u] == 1) {
                    System.out.println("NO");
                    System.exit(0);
                }
                if (vis[u] == 0) dfs(u);
                ans[v] = max(ans[v], ans[u] + 1);
            }
            vis[v] = 2;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();

            make(n + m);

            char[][] a = new char[n][m];
            for (int i = 0; i < n; i++) {
                a[i] = in.next().toCharArray();
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '=') unite(i, n + j);
                }
            }

            g = new ArrayList<>(n + m);
            for (int i = 0; i < n + m; i++) g.add(new HashSet<>());

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '>') g.get(find(i)).add(find(n + j));
                    else if (a[i][j] == '<') g.get(find(n + j)).add(find(i));
                }
            }

            vis = new int[n + m];
            ans = new int[n + m];
            for (int i = 0; i < n + m; i++) {
                if (vis[find(i)] == 0) dfs(find(i));
            }

            out.println("YES");
            for (int i = 0; i < n; i++) out.print(ans[find(i)] + " ");
            out.println();
            for (int i = n; i < n + m; i++) out.print(ans[find(i)] + " ");
            out.println();
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        // DSU
        private int[] parent;
        private int[] rank;

        private void make(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int v = 0; v < n; v++) {
                parent[v] = v;
                rank[v] = 0;
            }
        }

        private int find(int v) {
            if (parent[v] == v) return v;
            return parent[v] = find(parent[v]);
        }

        private void unite(int v, int u) {
            v = find(v);
            u = find(u);
            if (v != u) {
                if (rank[v] < rank[u]) {
                    v ^= u; u ^= v; v ^= u; // swap
                }
                parent[u] = v;
                if (rank[v] == rank[u]) rank[v]++;
            }
        }
        //

        private List<Set<Integer>> g;
        private int[] vis;
        private int[] ans;

        private int max(int a, int b) {
            return a < b ? b : a;
        }

        private boolean dfs(int v) {
            vis[v] = ans[v] = 1;
            for (int u : g.get(v)) {
                if (vis[u] == 1) return false;
                if (vis[u] == 0 && !dfs(u)) return false;
                ans[v] = max(ans[v], ans[u] + 1);
            }
            vis[v] = 2;
            return true;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();

            make(n + m);

            char[][] a = new char[n][m];
            for (int i = 0; i < n; i++) {
                a[i] = in.next().toCharArray();
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '=') unite(i, n + j);
                }
            }

            g = new ArrayList<>(n + m);
            for (int i = 0; i < n + m; i++) g.add(new HashSet<>());

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '>') g.get(find(i)).add(find(n + j));
                    else if (a[i][j] == '<') g.get(find(n + j)).add(find(i));
                }
            }

            vis = new int[n + m];
            ans = new int[n + m];
            for (int i = 0; i < n + m; i++) {
                if (vis[find(i)] == 0 && !dfs(find(i))) {
                    out.println("NO");
                    return;
                }
            }

            out.println("YES");
            for (int i = 0; i < n; i++) out.print(ans[find(i)] + " ");
            out.println();
            for (int i = n; i < n + m; i++) out.print(ans[find(i)] + " ");
            out.println();
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        // DSU
        private int[] parent;
        private int[] rank;

        private void make(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int v = 0; v < n; v++) {
                parent[v] = v;
                rank[v] = 0;
            }
        }

        private int find(int v) {
            if (parent[v] == v) return v;
            return parent[v] = find(parent[v]);
        }

        private void unite(int v, int u) {
            v = find(v);
            u = find(u);
            if (v != u) {
                if (rank[v] < rank[u]) {
                    v ^= u; u ^= v; v ^= u; // swap
                }
                parent[u] = v;
                if (rank[v] == rank[u]) rank[v]++;
            }
        }
        //

        private List<List<Integer>> g;
        private int[] vis;
        private int[] ans;

        private int max(int a, int b) {
            return a < b ? b : a;
        }

        private boolean dfs(int v) {
            vis[v] = ans[v] = 1;
            for (int u : g.get(v)) {
                if (vis[u] == 1) return false;
                if (vis[u] == 0 && !dfs(u)) return false;
                ans[v] = max(ans[v], ans[u] + 1);
            }
            vis[v] = 2;
            return true;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();

            make(n + m);

            char[][] a = new char[n][m];
            for (int i = 0; i < n; i++) {
                a[i] = in.next().toCharArray();
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '=') unite(i, n + j);
                }
            }

            g = new ArrayList<>(n + m);
            for (int i = 0; i < n + m; i++) g.add(new ArrayList<>());

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    int v = find(i);
                    int u = find(n + j);
                    if (a[i][j] == '>') g.get(v).add(u);
                    if (a[i][j] == '<') g.get(u).add(v);
                }
            }

            vis = new int[n + m];
            ans = new int[n + m];
            for (int i = 0; i < n + m; i++) {
                if (vis[find(i)] == 0 && !dfs(find(i))) {
                    out.println("NO");
                    return;
                }
            }

            out.println("YES");
            for (int i = 0; i < n; i++) out.print(ans[find(i)] + (i == n - 1 ? "\n" : " "));
            for (int i = n; i < n + m; i++) out.print(ans[find(i)] + (i == n + m - 1 ? "\n" : " "));
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        // DSU
        private int[] parent;
        private int[] rank;

        private void make(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int v = 0; v < n; v++) {
                parent[v] = v;
                rank[v] = 0;
            }
        }

        private int find(int v) {
            if (parent[v] == v) return v;
            return parent[v] = find(parent[v]);
        }

        private void unite(int v, int u) {
            v = find(v);
            u = find(u);
            if (v != u) {
                if (rank[v] < rank[u]) {
                    v ^= u; u ^= v; v ^= u; // swap
                }
                parent[u] = v;
                if (rank[v] == rank[u]) rank[v]++;
            }
        }
        //

        private List<List<Integer>> g;
        private int[] vis;
        private int[] ans;

        private int max(int a, int b) {
            return a < b ? b : a;
        }

        private boolean dfs(int v) {
            vis[v] = ans[v] = 1;
            for (int u : g.get(v)) {
                if (vis[u] == 1) return false;
                if (vis[u] == 0 && !dfs(u)) return false;
                ans[v] = max(ans[v], ans[u] + 1);
            }
            vis[v] = 2;
            return true;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();

            make(n + m);

            char[][] a = new char[n][m];
            for (int i = 0; i < n; i++) {
                a[i] = in.next().toCharArray();
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '=') unite(i, n + j);
                }
            }

            g = new ArrayList<>(n + m);
            for (int i = 0; i < n + m; i++) g.add(new ArrayList<>());

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '>') g.get(find(i)).add(find(n + j));
                    else if (a[i][j] == '<') g.get(find(n + j)).add(find(i));
                }
            }

            vis = new int[n + m];
            ans = new int[n + m];
            for (int i = 0; i < n + m; i++) {
                if (vis[find(i)] == 0 && !dfs(find(i))) {
                    out.println("NO");
                    return;
                }
            }

            out.println("YES");
            for (int i = 0; i < n; i++) out.print(ans[find(i)] + " ");
            out.println();
            for (int i = n; i < n + m; i++) out.print(ans[find(i)] + " ");
            out.println();
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        // DSU
        private int[] parent;
        private int[] rank;

        private void make(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int v = 0; v < n; v++) {
                parent[v] = v;
                rank[v] = 0;
            }
        }

        private int find(int v) {
            if (parent[v] == v) return v;
            return parent[v] = find(parent[v]);
        }

        private void unite(int v, int u) {
            v = find(v);
            u = find(u);
            if (v != u) {
                if (rank[v] < rank[u]) {
                    v ^= u; u ^= v; v ^= u; // swap
                }
                parent[u] = v;
                if (rank[v] == rank[u]) rank[v]++;
            }
        }
        //

        private List<Set<Integer>> g;
        private int[] vis;
        private int[] ans;

        private int max(int a, int b) {
            return a < b ? b : a;
        }

        private boolean dfs(int v) {
            vis[v] = ans[v] = 1;
            for (int u : g.get(v)) {
                if (vis[u] == 1) return false;
                if (vis[u] == 0 && !dfs(u)) return false;
                ans[v] = max(ans[v], ans[u] + 1);
            }
            vis[v] = 2;
            return true;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();

            make(n + m);

            char[][] a = new char[n][m];
            for (int i = 0; i < n; i++) {
                a[i] = in.next().toCharArray();
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '=') unite(i, n + j);
                }
            }

            g = new ArrayList<>(n + m);
            for (int i = 0; i < n + m; i++) g.add(new TreeSet<>());

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (a[i][j] == '>') g.get(find(i)).add(find(n + j));
                    else if (a[i][j] == '<') g.get(find(n + j)).add(find(i));
                }
            }

            vis = new int[n + m];
            ans = new int[n + m];
            for (int i = 0; i < n + m; i++) {
                if (vis[find(i)] == 0 && !dfs(find(i))) {
                    out.println("NO");
                    return;
                }
            }

            out.println("YES");
            for (int i = 0; i < n; i++) out.print(ans[find(i)] + " ");
            out.println();
            for (int i = n; i < n + m; i++) out.print(ans[find(i)] + " ");
            out.println();
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}