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
#include <bits/stdc++.h>


using namespace std;


const int ALPH = 'Z' - 'A' + 1;

typedef unsigned long long hash_t;


struct op {
    bool row;
    int i, color;
};


vector <op> solve(int n, int m, vector <vector<int>> &tab) {
    vector <hash_t> hashColor(ALPH);
    for (int c = 0; c < ALPH; c++) {
        for (int w = 0; w < 8; w++) {
            hashColor[c] <<= 8;
            hashColor[c] ^= rand();
        }
    }

    vector <hash_t> hashRow(n, 0), hashCol(m, 0);
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) {
        hashRow[i] += hashColor[tab[i][j]];
        hashCol[j] += hashColor[tab[i][j]];
    }

    map <hash_t,vector<int>> hashToRow, hashToCol;

    for (int i = 0; i < n; i++) {
        hashToRow[hashRow[i]].push_back(i);
    }

    for (int j = 0; j < m; j++) {
        hashToCol[hashCol[j]].push_back(j);
    }

    set <int> rowsLeft, colsLeft;

    for (int i = 0; i < n; i++) {
        rowsLeft.insert(i);
    }

    for (int j = 0; j < m; j++) {
        colsLeft.insert(j);
    }

    vector <op> ops;
    hash_t hashRowDel = 0, hashColDel = 0;

    while (!rowsLeft.empty() && !colsLeft.empty()) {
        for (int c = 0; c < ALPH; c++) {
            hash_t hashRowFull = hashRowDel + colsLeft.size() * hashColor[c];
            hash_t hashColFull = hashColDel + rowsLeft.size() * hashColor[c];

            if (!hashToRow[hashRowFull].empty()) {
                int row = hashToRow[hashRowFull].back();
                hashToRow[hashRowFull].pop_back();

                ops.push_back({true, row, c});
                rowsLeft.erase(row);

                hashColDel += hashColor[c];
                break;
            } else if (!hashToCol[hashColFull].empty()) {
                int col = hashToCol[hashColFull].back();
                hashToCol[hashColFull].pop_back();

                ops.push_back({false, col, c});
                colsLeft.erase(col);

                hashRowDel += hashColor[c];
                break;
            }
        }
    }

    reverse(ops.begin(), ops.end());
    return ops;
}

int main() {
    ios_base::sync_with_stdio(false);
    srand(0xdead);

    int n, m;
    cin >> n >> m;

    vector <vector<int>> tab(n, vector <int> (m));
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;

        for (int j = 0; j < m; j++) {
            tab[i][j] = s[j] - 'A';
        }
    }

    auto ops = solve(n, m, tab);

    cout << ops.size() << '\n';
    for (auto &o : ops) {
        cout << (o.row ? 'R' : 'K') << ' ' << o.i + 1 << ' ' << (char) ('A' + o.color) << '\n';
    }

    return 0;
}