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
#include<bits/stdc++.h>
using namespace std;
#ifdef DEBUG
auto&operator <<(auto& o, pair<auto, auto> p) {return o<<"("<<p.first<<", "<<p.second<<")";}
auto operator <<(auto& o, auto x)->decltype(x.end(), o) {o<<"{"; for(auto v : x) o<<v<<", "; return o<<"}";}
#define debug(X) cout<<"["#X"]"<<X<<endl;
#else
#define debug(X) {}
#endif
#define int long long
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin>>n>>m;
	vector<vector<pair<int, char> > > graph(n+m);
	vector<string> board(n);
	for(auto& v : board) cin>>v;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			auto v = board[i][j];
			graph[i].push_back({n+j, v});
		}
	}
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			auto v = board[j][i];
			graph[i+n].push_back({j, v});
		}
	}
	vector<char> col(n+m, -1);
	vector<int> touched;
	function<bool(int, char)> dfs = [&](int a, char c)
	{
		if(col[a] != -1 && col[a] != c) return false;
		if(col[a] == c) return true;
		touched.push_back(a);
		col[a] = c;
		for(auto v : graph[a])
			if(v.second != c)
				if(!dfs(v.first, v.second))
					return false;
		return true;
	};
	unordered_set<int> av;
	for(int i=0;i<n+m;i++)
	{
		if(col[i] != -1) continue;
		av.clear();
		vector<char> all;
		vector<int> cnt(30, 0);
		for(auto v : graph[i]) av.insert(v.second), cnt[v.second - 'A']++;
		if(i < n)
		cnt[board[i][0]-'A'] = 1e9+7;
		else
		cnt[board[0][i-n]-'A'] = 1e9+7; 
		for(auto v : av) all.push_back(v);
		sort(all.begin(), all.end(), [&](char a, char b){return cnt[a-'A'] > cnt[b-'A'];});
		for(char a : all)
		{
			debug(i);
			debug(a);
			touched.clear();
			if(dfs(i, a)) {break;}
			for(auto v : touched) col[v] = -1;
		}
	}
	vector<unordered_set<int> > toTop(n+m);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			if(board[i][j] == col[i] && board[i][j] != col[j+n]) toTop[i].insert(j+n);
			if(board[i][j] != col[i] && board[i][j] == col[j+n]) toTop[j+n].insert(i);
		}
	vector<unordered_set<int> > ingraph(n+m);
	auto toposort = [&]()
        {
                for(int i=0;i<n+m;i++) for(auto v : toTop[i]) ingraph[v].insert(i);
                queue<int> q;
                for(int i=0;i<n+m;i++) if(toTop[i].size() == 0) q.push(i);
                vector<int> result;
                while(!q.empty())
                {
                        auto a = q.front();
                        q.pop();
                        result.push_back(a);
                        for(auto v : ingraph[a])
                        {
                                toTop[v].erase(a);
                                if(toTop[v].size() == 0) q.push(v);
                        }
                }
                return result;
        };
	vector<int> d = toposort();
	cout<<d.size()<<"\n";
	for(auto v : d)
	{
		if(v < n) cout<<"R "<<v+1<<" "<<col[v]<<"\n";
		else cout<<"K "<<v-n+1<<" "<<col[v]<<"\n";
	}
}