1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstdint>

#include <algorithm>
#include <array>
#include <bit>
#include <numeric>
#include <vector>

struct seq_stat {
    uint64_t bitmap = 0;
    bool done = false;
    std::array<uint64_t, 'Z' - 'A' + 1> letter_counts;

    void inc_letter(char c) {
        c -= 'A';
        ++letter_counts[c];
        bitmap |= 1 << c;
    }

    void dec_letter(char c) {
        c -= 'A';
        if (letter_counts[c] > 0) {
            if (--letter_counts[c] == 0) {
                bitmap &= ~(1 << c);
            }
        }
    }

    bool can_be_filled() const {
        return !is_done() && std::popcount(bitmap) == 1;
    }

    char char_to_fill() const {
        return 'A' + std::countr_zero(bitmap);
    }

    void mark_as_done() {
        done = true;
    }

    bool is_done() const {
        return done;
    }
};

enum class op_type {
    del_row, del_col
};

struct operation {
    op_type typ;
    int position;
    char fill;
};

int main() {
    int h, w;
    scanf("%d %d", &h, &w);

    std::vector<seq_stat> cols, rows;

    cols.resize(w);
    rows.resize(h);

    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int c;
            while (std::isspace(c = getchar())) {}
            cols[x].inc_letter(c);
            rows[y].inc_letter(c);
        }
    }

    std::vector<operation> ops;
    for (int y = 0; y < h; y++) {
        if (rows[y].can_be_filled()) {
            ops.push_back({op_type::del_row, y, rows[y].char_to_fill()});
            rows[y].mark_as_done();
        }
    }
    for (int x = 0; x < w; x++) {
        if (cols[x].can_be_filled()) {
            ops.push_back({op_type::del_col, x, cols[x].char_to_fill()});
            cols[x].mark_as_done();
        }
    }

    size_t current_op = 0;
    while (current_op < ops.size()) {
        const auto [typ, which, letter] = ops[current_op++];
        switch (typ) {
        case op_type::del_col: {
            for (int y = 0; y < h; y++) {
                if (rows[y].is_done()) {
                    continue;
                }
                rows[y].dec_letter(letter);
                if (rows[y].can_be_filled()) {
                    ops.push_back({op_type::del_row, y, rows[y].char_to_fill()});
                    rows[y].mark_as_done(); 
                }
            }
        } break;
        case op_type::del_row: {
            for (int x = 0; x < w; x++) {
                if (cols[x].is_done()) {
                    continue;
                }
                cols[x].dec_letter(letter);
                if (cols[x].can_be_filled()) {
                    ops.push_back({op_type::del_col, x, cols[x].char_to_fill()});
                    cols[x].mark_as_done();
                }
            }
        } break;
        }
    }

    std::reverse(ops.begin(), ops.end());
    printf("%d\n", (int)ops.size());
    for (const auto& [typ, which, letter] : ops) {
        printf("%c %d %c\n", typ == op_type::del_col ? 'K' : 'R', which + 1, letter);
    }

    return 0;
}