#include <bits/stdc++.h>
using namespace std;
string ranks = "23456789TJQKA";
string suits = "CDHS";
set<string> deck;
int H, W;
string cards[20][20];
bool sqr[20][20];
bool func(string J1, string J2) {
  int h, w, h2, w2, i, j, k;
  for ((h) = 0; (h) < (int)(H); (h)++)
    for ((w) = 0; (w) < (int)(W); (w)++) sqr[h][w] = false;
  for ((h) = 0; (h) < (int)(H - 2); (h)++)
    for ((w) = 0; (w) < (int)(W - 2); (w)++) {
      bool samesuit = true;
      for ((i) = 0; (i) < (int)(3); (i)++)
        for ((j) = 0; (j) < (int)(3); (j)++)
          if (cards[h][w][1] != cards[h + i][w + j][1]) samesuit = false;
      if (samesuit) sqr[h][w] = true;
      int mask = 0;
      for ((i) = 0; (i) < (int)(3); (i)++)
        for ((j) = 0; (j) < (int)(3); (j)++) {
          for ((k) = 0; (k) < (int)(13); (k)++)
            if (cards[h + i][w + j][0] == ranks[k]) break;
          mask |= (1 << k);
        }
      if (__builtin_popcount(mask) == 9) sqr[h][w] = true;
    }
  for ((h) = 0; (h) < (int)(H); (h)++)
    for ((w) = 0; (w) < (int)(W); (w)++)
      if (sqr[h][w])
        for ((h2) = 0; (h2) < (int)(H); (h2)++)
          for ((w2) = 0; (w2) < (int)(W); (w2)++)
            if (sqr[h2][w2])
              if (h2 - h >= 3 || w2 - w >= 3) {
                printf("Solution exists.\n");
                if (!J1.empty() && !J2.empty())
                  printf("Replace J1 with %s and J2 with %s.\n", J1.c_str(),
                         J2.c_str());
                if (!J1.empty() && J2.empty())
                  printf("Replace J1 with %s.\n", J1.c_str());
                if (J1.empty() && !J2.empty())
                  printf("Replace J2 with %s.\n", J2.c_str());
                if (J1.empty() && J2.empty()) printf("There are no jokers.\n");
                printf("Put the first square to (%d, %d).\n", h + 1, w + 1);
                printf("Put the second square to (%d, %d).\n", h2 + 1, w2 + 1);
                return true;
              }
  return false;
}
int main(void) {
  int i, j;
  cin >> H >> W;
  for ((i) = 0; (i) < (int)(H); (i)++)
    for ((j) = 0; (j) < (int)(W); (j)++) cin >> cards[i][j];
  for ((i) = 0; (i) < (int)(13); (i)++)
    for ((j) = 0; (j) < (int)(4); (j)++) {
      string tmp;
      tmp += ranks[i];
      tmp += suits[j];
      deck.insert(tmp);
    }
  for ((i) = 0; (i) < (int)(H); (i)++)
    for ((j) = 0; (j) < (int)(W); (j)++)
      if (cards[i][j] != "J1" && cards[i][j] != "J2") deck.erase(cards[i][j]);
  int j1x = -1, j1y = -1, j2x = -1, j2y = -1;
  for ((i) = 0; (i) < (int)(H); (i)++)
    for ((j) = 0; (j) < (int)(W); (j)++) {
      if (cards[i][j] == "J1") {
        j1x = i;
        j1y = j;
      }
      if (cards[i][j] == "J2") {
        j2x = i;
        j2y = j;
      }
    }
  bool exist1 = (j1x != -1);
  bool exist2 = (j2x != -1);
  if (exist1 && exist2)
    for (__typeof((deck).begin()) itr1 = (deck).begin(); itr1 != (deck).end();
         itr1++)
      for (__typeof((deck).begin()) itr2 = (deck).begin(); itr2 != (deck).end();
           itr2++) {
        string J1 = (*itr1), J2 = (*itr2);
        if (J1 == J2) continue;
        cards[j1x][j1y] = J1;
        cards[j2x][j2y] = J2;
        if (func(J1, J2)) return 0;
      }
  if (exist1 && !exist2)
    for (__typeof((deck).begin()) itr1 = (deck).begin(); itr1 != (deck).end();
         itr1++) {
      string J1 = (*itr1);
      cards[j1x][j1y] = J1;
      if (func(J1, "")) return 0;
    }
  if (!exist1 && exist2)
    for (__typeof((deck).begin()) itr2 = (deck).begin(); itr2 != (deck).end();
         itr2++) {
      string J2 = (*itr2);
      cards[j2x][j2y] = J2;
      if (func("", J2)) return 0;
    }
  if (!exist1 && !exist2) {
    if (func("", "")) return 0;
  }
  cout << "No solution." << endl;
  return 0;
}
