#include <bits/stdc++.h>
using namespace std;
string card[18][18];
set<string> used;
map<char, int> mp;
map<int, char> toc, tod;
int n, m;
struct state {
  int x, y;
  string ans[2];
  state() {}
  state(int _x, int _y, string _str1, string _str2) {
    x = _x;
    y = _y;
    ans[0] = _str1;
    ans[1] = _str2;
  }
};
vector<state> sol;
int num[15];
bool col[4];
bool jhas[2];
string str[2];
void addcolor(int x, int y, int j, int col) {
  if (j == 2) {
    sol.push_back(state(x, y, str[0], str[1]));
    return;
  }
  str[j].clear();
  if (jhas[j]) {
    for (int i = 2; i <= 14; i++) {
      str[j].push_back(tod[i]);
      str[j].push_back(toc[col]);
      if (used.find(str[j]) == used.end()) {
        used.insert(str[j]);
        addcolor(x, y, j + 1, col);
        used.erase(str[j]);
      }
      str[j].clear();
    }
  } else
    addcolor(x, y, j + 1, col);
}
void addnum(int x, int y, int j, int col) {
  if (j == 2) {
    sol.push_back(state(x, y, str[0], str[1]));
    return;
  }
  str[j].clear();
  if (jhas[j]) {
    for (int i = 2; i <= 14; i++) {
      if (num[i] != 0) continue;
      str[j].push_back(tod[i]);
      str[j].push_back(toc[col]);
      if (used.find(str[j]) == used.end()) {
        used.insert(str[j]);
        num[i]++;
        addnum(x, y, j + 1, col);
        num[i]--;
        used.erase(str[j]);
      }
      str[j].clear();
    }
  } else
    addnum(x, y, j + 1, col);
}
void check(int x, int y) {
  int i, j, dig, color, con;
  memset(num, 0, sizeof(num));
  memset(col, false, sizeof(col));
  memset(jhas, false, sizeof(jhas));
  for (i = x; i <= x + 2; i++)
    for (j = y; j <= y + 2; j++) {
      if (card[i][j][0] == 'J' && isdigit(card[i][j][1]))
        jhas[card[i][j][1] - '1'] = true;
      else {
        dig = mp[card[i][j][0]];
        color = mp[card[i][j][1]];
        num[dig]++;
        col[color] = true;
      }
    }
  for (i = 0, con = 0; i < 4; i++)
    if (col[i]) {
      con++;
      color = i;
    }
  if (con == 1) addcolor(x, y, 0, color);
  for (i = 2; i <= 14; i++)
    if (num[i] > 1) return;
  for (i = 0; i < 4; i++) addnum(x, y, 0, i);
}
int main() {
  int i, j, x, y;
  string joker[2];
  mp['2'] = 2;
  mp['3'] = 3;
  mp['4'] = 4;
  mp['5'] = 5;
  mp['6'] = 6;
  mp['7'] = 7;
  mp['8'] = 8;
  mp['9'] = 9;
  mp['T'] = 10;
  mp['J'] = 11;
  mp['Q'] = 12;
  mp['K'] = 13;
  mp['A'] = 14;
  mp['C'] = 0;
  mp['D'] = 1;
  mp['H'] = 2;
  mp['S'] = 3;
  toc[0] = 'C';
  toc[1] = 'D';
  toc[2] = 'H';
  toc[3] = 'S';
  tod[2] = '2';
  tod[3] = '3';
  tod[4] = '4';
  tod[5] = '5';
  tod[6] = '6';
  tod[7] = '7';
  tod[8] = '8';
  tod[9] = '9';
  tod[10] = 'T';
  tod[11] = 'J';
  tod[12] = 'Q';
  tod[13] = 'K';
  tod[14] = 'A';
  cin >> n >> m;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) {
      cin >> card[i][j];
      used.insert(card[i][j]);
    }
  for (i = 1; i <= n - 2; i++)
    for (j = 1; j <= m - 2; j++) check(i, j);
  for (i = 0; i < (int)sol.size(); i++) {
    for (j = i + 1; j < (int)sol.size(); j++) {
      if ((sol[i].x + 2 < sol[j].x || sol[i].y + 2 < sol[j].y) &&
          ((sol[i].ans[0].size() == 0u && sol[i].ans[1] != sol[j].ans[0]) ||
           (sol[i].ans[0] != sol[j].ans[1] && sol[i].ans[1].size() == 0u) ||
           (sol[i].ans[0].size() == 0u && sol[i].ans[1].size() == 0u) ||
           (sol[i].ans[0] != sol[j].ans[1] && sol[i].ans[1] != sol[j].ans[0])))
        break;
    }
    if (j < (int)sol.size()) break;
  }
  if (i >= (int)sol.size())
    printf("No solution.\n");
  else {
    printf("Solution exists.\n");
    for (x = 0; x < 2; x++)
      if (sol[i].ans[x].size() > 0u) joker[x] = sol[i].ans[x];
    for (x = 0; x < 2; x++)
      if (sol[j].ans[x].size() > 0u) joker[x] = sol[j].ans[x];
    int color, dig;
    for (x = 0; x < 2; x++)
      if (joker[x].size() > 0u) used.insert(joker[x]);
    string temp;
    for (x = 1; x <= n; x++)
      for (y = 1; y <= m; y++) {
        if (card[x][y][0] == 'J' && isdigit(card[x][y][1])) {
          if ((int)joker[card[x][y][1] - '1'].size() > 0) continue;
          for (color = 0; color < 4; color++) {
            for (dig = 2; dig <= 14; dig++) {
              temp.clear();
              temp.push_back(tod[dig]);
              temp.push_back(toc[color]);
              if (used.find(temp) == used.end()) break;
            }
            if (dig <= 14) break;
          }
          joker[card[x][y][1] - '1'] = temp;
          used.insert(temp);
        }
      }
    if (joker[0].size() == 0 && joker[1].size() == 0)
      printf("There are no jokers.\n");
    else if (joker[0].size() != 0 && joker[1].size() != 0)
      cout << "Replace J1 with " << joker[0] << " and J2 with " << joker[1]
           << ".\n";
    else if (joker[0].size() != 0)
      cout << "Replace J1 with " << joker[0] << ".\n";
    else
      cout << "Replace J2 with " << joker[1] << ".\n";
    printf("Put the first square to (%d, %d).\n", sol[i].x, sol[i].y);
    printf("Put the second square to (%d, %d).\n", sol[j].x, sol[j].y);
  }
  return 0;
}
