#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
void qread(int &x) {
  int neg = 1;
  x = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') neg = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') x = 10 * x + c - '0', c = getchar();
  x *= neg;
}
const int maxn = 20;
const char suits[13] = {'2', '3', '4', '5', '6', '7', '8',
                        '9', 'T', 'J', 'Q', 'K', 'A'};
const char ranks[5] = {'C', 'D', 'H', 'S'};
int n, m, k;
int rs[256], rr[256], id[maxn], x[maxn], y[maxn];
pair<int, int> grid[maxn][maxn];
bool occ[maxn][maxn], app[maxn];
char ch[maxn];
void check() {
  vector<pair<int, int> > pos;
  for (int(i) = 0; (i) < n - 2; i++)
    for (int(j) = 0; (j) < m - 2; j++) {
      bool ok = true;
      for (int(ii) = 0; (ii) < 3; ii++)
        for (int(jj) = 0; (jj) < 3; jj++)
          if (grid[i + ii][j + jj].second != grid[i][j].second) ok = false;
      if (ok) {
        pos.push_back(make_pair(i, j));
        continue;
      }
      ok = true;
      for (int(ii) = 0; (ii) < 13; ii++) app[ii] = false;
      for (int(ii) = 0; (ii) < 3; ii++)
        for (int(jj) = 0; (jj) < 3; jj++) {
          if (app[grid[i + ii][j + jj].first]) ok = false;
          app[grid[i + ii][j + jj].first] = true;
        }
      if (ok) pos.push_back(make_pair(i, j));
    }
  for (int(i) = 0; (i) < pos.size(); i++)
    for (int j = i + 1; j < pos.size(); j++) {
      if (abs(pos[j].first - pos[i].first) >= 3 ||
          abs(pos[j].second - pos[i].second) >= 3) {
        puts("Solution exists.");
        if (!k)
          puts("There are no jokers.");
        else if (k == 1) {
          printf("Replace J%d with %c%c.\n", id[0],
                 suits[grid[x[0]][y[0]].first], ranks[grid[x[0]][y[0]].second]);
        } else {
          printf("Replace J1 with %c%c and J2 with %c%c.\n",
                 suits[grid[x[0]][y[0]].first], ranks[grid[x[0]][y[0]].second],
                 suits[grid[x[1]][y[1]].first], ranks[grid[x[1]][y[1]].second]);
        }
        printf("Put the first square to (%d, %d).\n", pos[i].first + 1,
               pos[i].second + 1);
        printf("Put the second square to (%d, %d).\n", pos[j].first + 1,
               pos[j].second + 1);
        exit(0);
      }
    }
}
void go(int cur) {
  if (cur == k) {
    check();
    return;
  }
  for (int(i) = 0; (i) < 13; i++)
    for (int(j) = 0; (j) < 4; j++) {
      if (!occ[i][j]) {
        occ[i][j] = true;
        grid[x[cur]][y[cur]] = make_pair(i, j);
        go(cur + 1);
        occ[i][j] = false;
      }
    }
}
int main() {
  for (int(i) = 0; (i) < 13; i++) rs[suits[i]] = i;
  for (int(i) = 0; (i) < 4; i++) rr[ranks[i]] = i;
  scanf("%d%d", &n, &m);
  for (int(i) = 0; (i) < n; i++)
    for (int(j) = 0; (j) < m; j++) {
      scanf("%s", ch);
      if (ch[0] == 'J' && isdigit(ch[1])) {
        x[k] = i;
        y[k] = j;
        id[k] = ch[1] - '0';
        k++;
      } else {
        grid[i][j] = make_pair(rs[ch[0]], rr[ch[1]]);
        occ[rs[ch[0]]][rr[ch[1]]] = true;
      }
    }
  if (k == 2 && id[0] == 2)
    swap(x[0], x[1]), swap(y[0], y[1]), swap(id[0], id[1]);
  go(0);
  puts("No solution.");
  return 0;
}
