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
130
131
132
133
134
135
136
137
138
139
140
141
#include <bits/stdc++.h>
using namespace std;

const string K = "K";
const string R = "R";

struct Line {
	map<char, int> colors;
	void add(char color) {
		colors[color]++;
	}

	void println() {
		for (auto color : colors) {
			cout << color.first << ":" << color.second << ", ";
		}
		cout << endl;
	}

	char getSingleColor() {
		return colors.begin()->first;
	}

	void removeColors(map<char, int> &colorToRemoveMap) {
		for (auto &entry : colorToRemoveMap) {
			colors[entry.first] -= entry.second;
			if (colors[entry.first] == 0) {
				colors.erase(entry.first);
			}
		}
	}
	void removeColor(char color) {
		colors[color]--;
		if (colors[color] == 0) {
			colors.erase(color);
		}
	}
};

void removeLines(map<int, Line> &lines, map<int, Line> &crossed,
		stack<string> &response, const string dir) {
	vector<int> linesToRemove;
	vector<int> linesToRemoveFromCrossed;
	map<char, int> colorToRemoveMap;
	for (auto &line : lines) {
		if (line.second.colors.size() == 1) {
			linesToRemove.push_back(line.first);
			char colorToRemove = line.second.getSingleColor();
			colorToRemoveMap[colorToRemove]++;
			response.push(
					dir + " " + to_string(line.first) + " " + colorToRemove);
//			for (auto &crossedLine : crossed) {
//				crossedLine.second.removeColor(colorToRemove);
//				if (crossedLine.second.colors.empty()) {
//					linesToRemoveFromCrossed.push_back(crossedLine.first);
//				}
//			}
		}
	}

	for (auto &crossedLine : crossed) {
		crossedLine.second.removeColors(colorToRemoveMap);
		if (crossedLine.second.colors.empty()) {
			linesToRemoveFromCrossed.push_back(crossedLine.first);
		}
	}

	for (int i : linesToRemove) {
		lines.erase(i);
	}
	for (int i : linesToRemoveFromCrossed) {
		crossed.erase(i);
	}

}

void printMap(map<int, Line> rows, string title) {
	cout << title << endl;
	for (auto line : rows) {
		cout << "\t" << line.first << " ";
		line.second.println();
	}
}
int main() {
//	ifstream cin("tests/0a.in");
//	ifstream cin("tests/0d.in");

	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);

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

	map<int, Line> rows;
	map<int, Line> columns;
	stack<string> response;

	string line;
	for (int row_i = 1; row_i <= n; row_i++) {
		cin >> line;
		for (int col_i = 1; col_i <= m; col_i++) {
			const char color = line[col_i - 1];
			rows[row_i].add(color);
			columns[col_i].add(color);
		}
	}
	int c = 0;

//	cout << c++ << ": rows.size=" << rows.size() << " columns.size="
//			<< columns.size() << endl;
//	printMap(rows, "rows");
//	printMap(columns, "columns");

	while (rows.size() > 0 || columns.size() > 0) {
		removeLines(rows, columns, response, R);

//		cout << c << ": rows.size=" << rows.size() << " columns.size=" << columns.size() << endl;
//		printMap(rows, "rows");
//		printMap(columns, "columns");

		removeLines(columns, rows, response, K);

//		cout << c << ": rows.size=" << rows.size() << " columns.size=" << columns.size() << endl;
//		printMap(rows, "rows");
//		printMap(columns, "columns");

		c++;
	}

//	cout << "c=" << c << endl;

	cout << response.size() << endl; // prints
	while (!response.empty()) {
		cout << response.top() << "\n";
		response.pop();
	}

	return 0;
}