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
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <vector>

using namespace std;

struct TestCase {
  int n, m;
  vector<vector<char>> board;
};

TestCase read_test_case() {
  TestCase tc;
  cin >> tc.n >> tc.m;
  tc.board.resize(tc.n);
  for (auto& row : tc.board) {
    row.resize(tc.m);
    for (auto& c : row) cin >> c;
  }

  return tc;
}

void solve_test_case(TestCase tc);

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  solve_test_case(read_test_case());
}

enum class Direction { Row, Column };

struct Action {
  Direction direction;
  int number;
  char c;
};

template <typename T, typename U>
T get_first_key(const map<T, U>& m) {
  for (const auto& [k, v] : m) return k;
  throw "map is empty";
}

void solve_test_case(TestCase tc) {
  vector<map<char, int>> colors_in_row(tc.n);
  vector<map<char, int>> colors_in_column(tc.m);

  for (int i = 0; i < tc.n; i++)
    for (int j = 0; j < tc.m; j++) {
      char c = tc.board[i][j];
      colors_in_row[i][c]++;
      colors_in_column[j][c]++;
    }

  vector<Action> result;

  queue<Action> q;

  for (int i = 0; i < tc.n; i++) {
    if (colors_in_row[i].size() == 1)
      q.push({Direction::Row, i, get_first_key(colors_in_row[i])});
  }

  for (int j = 0; j < tc.m; j++) {
    if (colors_in_column[j].size() == 1)
      q.push({Direction::Column, j, get_first_key(colors_in_column[j])});
  }

  while (!q.empty()) {
    Action a = q.front();
    q.pop();

    if (a.direction == Direction::Row) {
      if (colors_in_row[a.number].empty()) continue;

      colors_in_row[a.number].clear();

      for (int j = 0; j < tc.m; j++) {
        if (colors_in_column[j][a.c] == 0) continue;

        colors_in_column[j][a.c]--;
        if (colors_in_column[j][a.c] == 0) colors_in_column[j].erase(a.c);
        if (colors_in_column[j].size() == 1)
          q.push({Direction::Column, j, get_first_key(colors_in_column[j])});
      }
    } else if (a.direction == Direction::Column) {
      if (colors_in_column[a.number].empty()) continue;
      colors_in_column[a.number].clear();

      for (int i = 0; i < tc.n; i++) {
        if (colors_in_row[i][a.c] == 0) continue;

        colors_in_row[i][a.c]--;
        if (colors_in_row[i][a.c] == 0) colors_in_row[i].erase(a.c);
        if (colors_in_row[i].size() == 1)
          q.push({Direction::Row, i, get_first_key(colors_in_row[i])});
      }
    }
    result.push_back(a);
  }

  reverse(result.begin(), result.end());
  cout << result.size() << "\n";
  for (auto a : result) {
    switch (a.direction) {
      case Direction::Row:
        cout << "R " << a.number + 1 << " " << a.c << "\n";
        break;
      case Direction::Column:
        cout << "K " << a.number + 1 << " " << a.c << "\n";
        break;
    }
  }
}