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
// Zadanie Lamiglowka 3
// Rozwiazanie by Jakub Stepaniuk - wersja z wektorami zamiast setow

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int isReady(vector<int>& V) {
	int zlicz = -1;
	for (int i = 0; i < V.size(); i++) {
		if (V[i] != 0) {
			if (zlicz == -1) {
				zlicz = i;
			}
			else {
				return -1;
			}
		}
	}
	return zlicz;
}

struct Action {
	bool IsColumn;
	int Color;
	int Id;

	Action(bool iscol, int id, int clr) {
		IsColumn = iscol; Color = clr; Id = id;
	};
};

int main() {

	int h, w; cin >> h >> w;
	vector<vector<int>> rows(h, vector<int>(26, 0)), cols(w, vector<int>(26, 0)); char inp;
	vector<vector<int>> table(h, vector<int>(w));
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			cin >> inp;
			table[i][j] = inp - 'A';
			rows[i][inp - 'A']++; cols[j][inp - 'A']++;
		}
	}

	vector<Action> actions;
	vector<int> rowColor(h, -1), colColor(w, -1);
	queue<pair<bool, int>> toRemove;
	for (int i = 0; i < h; i++) {
		if (isReady(rows[i]) != -1) {
			toRemove.push({ false, i });
			rowColor[i] = isReady(rows[i]);
		}
	}
	for (int j = 0; j < w; j++) {
		if (isReady(cols[j]) != -1) {
			toRemove.push({ true, j });
			colColor[j] = isReady(cols[j]);
		}
	}

	pair<bool, int> curr;
	while (!toRemove.empty()) {
		curr = toRemove.front(); toRemove.pop();
		if (curr.first) {
			//cout << "Do usuniecia kolumna " << curr.second << endl;
			for (int i = 0; i < h; i++) {
				if (rowColor[i] == -1) {
					rows[i][table[i][curr.second]]--;
					if (isReady(rows[i]) != -1) {
						toRemove.push({ false, i });
						rowColor[i] = isReady(rows[i]);
					}
				}
			}
			actions.push_back(Action(curr.first, curr.second, colColor[curr.second]));
		}
		else {
			//cout << "Do usuniecia wiersz " << curr.second << endl;
			for (int i = 0; i < w; i++) {
				if (colColor[i] == -1) {
					cols[i][table[curr.second][i]]--;
					if (isReady(cols[i]) != -1) {
						toRemove.push({ true, i });
						colColor[i] = isReady(cols[i]);
					}
				}
			}
			actions.push_back(Action(curr.first, curr.second, rowColor[curr.second]));
		}
	}

	cout << actions.size() << endl;
	for (int i = actions.size() - 1; i >= 0; i--) {
		if (actions[i].IsColumn) {
			cout << "K ";
		}
		else {
			cout << "R ";
		}
		cout << actions[i].Id + 1 << ' ' << char(actions[i].Color + 'A') << endl;
	}

	return 0;
}