#include <bits/stdc++.h>
using namespace std;
struct tcard {
  int r, m;
};
tcard f[20][20];
bool was[15][6];
int n, m;
string getcards(int rank, int m) {
  string ret;
  if (rank >= 2 && rank <= 9) {
    char tmps[3];
    tmps[0] = rank + '0';
    tmps[1] = 0;
    ret = string(tmps);
  } else if (rank == 10)
    ret = string("T");
  else if (rank == 11)
    ret = string("J");
  else if (rank == 12)
    ret = string("Q");
  else if (rank == 13)
    ret = string("K");
  else
    ret = "A";
  switch (m) {
    case 1:
      ret = ret + "C";
      break;
    case 2:
      ret = ret + "D";
      break;
    case 3:
      ret = ret + "H";
      break;
    case 4:
      ret = ret + "S";
      break;
  }
  return ret;
}
void readcard(tcard &ret) {
  char s[5];
  scanf(" %s  ", s);
  string str = string(s);
  if (str == "J1") {
    ret.r = 1;
    ret.m = 1;
    return;
  } else if (str == "J2") {
    ret.r = 1;
    ret.m = 2;
    return;
  } else if (s[0] >= '2' && s[0] <= '9') {
    ret.r = s[0] - '0';
  } else {
    switch (s[0]) {
      case 'T':
        ret.r = 10;
        break;
      case 'J':
        ret.r = 11;
        break;
      case 'Q':
        ret.r = 12;
        break;
      case 'K':
        ret.r = 13;
        break;
      case 'A':
        ret.r = 14;
        break;
    }
  }
  switch (s[1]) {
    case 'C':
      ret.m = 1;
      break;
    case 'D':
      ret.m = 2;
      break;
    case 'H':
      ret.m = 3;
      break;
    case 'S':
      ret.m = 4;
      break;
  }
}
bool sec(int x, int y, int xx, int yy) {
  if (xx + 2 < x || x + 2 < xx || yy + 2 < y || y + 2 < yy) return false;
  return true;
}
bool good(int x, int y) {
  bool matchm = true;
  for (int i = x; i <= x + 2 && matchm; i++)
    for (int j = y; j <= y + 2 && matchm; j++)
      if (f[i][j].m != f[x][y].m) {
        matchm = false;
      }
  if (matchm) return true;
  bool wasrank[16];
  memset(wasrank, 0, sizeof(wasrank));
  for (int i = x; i <= x + 2; i++)
    for (int j = y; j <= y + 2; j++)
      if (!wasrank[f[i][j].r]) {
        wasrank[f[i][j].r] = true;
      } else
        return false;
  return true;
}
bool getres(int &resx, int &resy, int &resx2, int &resy2) {
  for (int i = 0; i <= n - 3; i++)
    for (int j = 0; j <= m - 3; j++) {
      if (good(i, j)) {
        for (int ii = i; ii <= n - 3; ii++)
          for (int jj = 0; jj <= m - 3; jj++) {
            if (!sec(i, j, ii, jj)) {
              if (good(ii, jj)) {
                resx = i, resy = j, resx2 = ii, resy2 = jj;
                return true;
              }
            }
          }
      }
    }
  return false;
}
void init() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      tcard c;
      readcard(c);
      f[i][j] = c;
      if (c.r != 1) {
        was[c.r][c.m] = true;
      }
    }
  int x = -1, y, xx = -1, yy;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (f[i][j].r == 1) {
        if (x == -1)
          x = i, y = j;
        else
          xx = i, yy = j;
      }
  int resx1, resy1, resx2, resy2;
  if (x == -1) {
    if (getres(resx1, resy1, resx2, resy2)) {
      printf("Solution exists.\n");
      printf("There are no jokers.\n");
      printf("Put the first square to (%d, %d).\n", resx1 + 1, resy1 + 1);
      printf("Put the second square to (%d, %d).\n", resx2 + 1, resy2 + 1);
    } else
      printf("No solution.\n");
  } else if (xx == -1) {
    tcard tmp = f[x][y];
    for (int i = 2; i <= 14; i++)
      for (int j = 1; j <= 4; j++)
        if (!was[i][j]) {
          f[x][y].r = i;
          f[x][y].m = j;
          if (getres(resx1, resy1, resx2, resy2)) {
            printf("Solution exists.\n");
            string tmps = getcards(i, j);
            printf("Replace J%d with %s.\n", tmp.m, tmps.c_str());
            printf("Put the first square to (%d, %d).\n", resx1 + 1, resy1 + 1);
            printf("Put the second square to (%d, %d).\n", resx2 + 1,
                   resy2 + 1);
            return;
          }
        }
    printf("No solution.\n");
  } else {
    tcard tmp = f[x][y];
    tcard tmp2 = f[xx][yy];
    for (int i = 2; i <= 14; i++)
      for (int j = 1; j <= 4; j++)
        if (!was[i][j]) {
          f[x][y].r = i, f[x][y].m = j;
          for (int ii = 2; ii <= 14; ii++)
            for (int jj = 1; jj <= 4; jj++)
              if (!was[ii][jj] && (i != ii || j != jj)) {
                f[xx][yy].r = ii, f[xx][yy].m = jj;
                if (getres(resx1, resy1, resx2, resy2)) {
                  printf("Solution exists.\n");
                  string tmps1, tmps2;
                  if (tmp.m == 1)
                    tmps1 = getcards(i, j), tmps2 = getcards(ii, jj);
                  else
                    tmps1 = getcards(ii, jj), tmps2 = getcards(i, j);
                  printf("Replace J1 with %s and J2 with %s.\n", tmps1.c_str(),
                         tmps2.c_str());
                  printf("Put the first square to (%d, %d).\n", resx1 + 1,
                         resy1 + 1);
                  printf("Put the second square to (%d, %d).\n", resx2 + 1,
                         resy2 + 1);
                  return;
                }
              }
        }
    printf("No solution.\n");
  }
}
void solve() {}
int main() {
  init();
  solve();
  return 0;
}
