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<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

#define MAX_N 2005

#ifndef DEB_VAL
  #define DEB_VAL 0
#endif
#define DEB if(debug)

#define MP make_pair
#define PB push_back
#define FT first
#define SD second

int debug = DEB_VAL;

int n,m;
char input[MAX_N][MAX_N];
int in[2][MAX_N][30];
int kol[2][MAX_N];
int ruchy;
vector<pair<int, pair<int,int> > > res;

queue< pair<int, pair<int,int> > > qu;

int main() {
  scanf("%d %d", &n, &m);
  for(int i=0;i<n;i++) {
    scanf("%s", input[i]);
  }
  for(int i=0;i<n;i++) {
    for(int j=0;j<m;j++) {
      if(in[0][i][input[i][j]-'A']++==0){
        kol[0][i]++;
      }
      if(in[1][j][input[i][j]-'A']++==0){
        kol[1][j]++;
      }
    }
  }
  DEB {
    printf("Input - liczby kolorów:\n");
    printf("Wiersze:\n");
    for(int i=0;i<n;i++) {
      printf("%d, ",kol[0][i]);
    }
    printf("\nKolumny:\n");
    for(int j=0;j<m;j++) {
      printf("%d, ",kol[1][j]);
    }
    printf("\n");
  }
  //wrzucamy na kolejkę
  for(int i=0;i<n;i++) {
    if(kol[0][i]==1) qu.push(MP(-1*kol[0][i],MP(0,i)));
  }
  for(int j=0;j<m;j++) {
    if(kol[1][j]==1) qu.push(MP(-1*kol[1][j],MP(1,j)));
  }
  pair<int, pair<int,int> > akt;
  int kolor;
  while(!qu.empty()) {
    akt=qu.front();
    qu.pop();
    DEB { printf("wyciągam z kolejki: %d %d %d\n",akt.FT,akt.SD.FT,akt.SD.SD); }
    if(kol[akt.SD.FT][akt.SD.SD]!=-1*akt.FT) continue;
    if(kol[akt.SD.FT][akt.SD.SD]==0) break;
    DEB { printf("Dobry więc jadę dalej\n"); }
    //TODO - szybciej?
    int jakikolor;
    for(jakikolor=0;jakikolor<26;jakikolor++) {
      if(in[akt.SD.FT][akt.SD.SD][jakikolor]>0) break;
    }
    DEB { printf("Taki kolor tutaj jest ostatni -> %c\n",jakikolor+'A'); }
    res.PB(MP(akt.SD.FT,MP(akt.SD.SD,jakikolor)));
    //aktualizuj
    kol[akt.SD.FT][akt.SD.SD]--;
    in[akt.SD.FT][akt.SD.SD][jakikolor]--;
    //aktualizuje w poprzek
    if(akt.SD.FT==0) {
      //wiersz, czyli aktualizuj kolumne
      for(int j=0;j<m;j++) {
        if(in[1][j][jakikolor]>0) {
          in[1][j][jakikolor]--;
          if(in[1][j][jakikolor]==0) {
            //zmniejszyliśmy ten kolor do zera
            kol[1][j]--;
            if(kol[1][j]==1) qu.push(MP(-1*kol[1][j],MP(1,j)));
          }
        }
      }
    } else {
      //kolumna, czyli aktualizuj wiersz
      for(int i=0;i<n;i++) {
        if(in[0][i][jakikolor]>0) {
          in[0][i][jakikolor]--;
          if(in[0][i][jakikolor]==0) {
            //zmniejszyliśmy ten kolor do zera
            kol[0][i]--;
            if(kol[0][i]==1) qu.push(MP(-1*kol[0][i],MP(0,i)));
          }
        }
      }
    }
  }
  printf("%d\n", (int)res.size());
  for(int i=res.size()-1;i>=0;i--) {
    if(res[i].FT==0) {
      printf("R %d %c\n",res[i].SD.FT+1,res[i].SD.SD+'A');
    } else {
      printf("K %d %c\n",res[i].SD.FT+1,res[i].SD.SD+'A');
    }
  }
  return 0;
}