#include <bits/stdc++.h>
using namespace std;
typedef struct {
  char rank;
  char suit;
} T1;
T1 A[20][20];
bool B[300][300];
bool check1(int l, int r) {
  set<char> S;
  int cnt = 0;
  for (int i = l; i <= l + 2; i++)
    for (int j = r; j <= r + 2; j++) {
      if (A[i][j].suit != '1' && A[i][j].suit != '2') {
        S.insert(A[i][j].rank);
      } else
        cnt++;
    }
  return (S.size() + cnt) == 9;
}
bool check2(int l, int r) {
  set<char> S;
  for (int i = l; i <= l + 2; i++)
    for (int j = r; j <= r + 2; j++) {
      if (A[i][j].suit != '1' && A[i][j].suit != '2') {
        S.insert(A[i][j].suit);
      }
    }
  return S.size() == 1;
}
bool CHECK1(int l, int r) {
  set<char> S;
  for (int i = l; i <= l + 2; i++)
    for (int j = r; j <= r + 2; j++) S.insert(A[i][j].rank);
  return S.size() == 9;
}
bool CHECK2(int l, int r) {
  set<char> S;
  for (int i = l; i <= l + 2; i++)
    for (int j = r; j <= r + 2; j++) S.insert(A[i][j].suit);
  return S.size() == 1;
}
bool check3(int l1, int r1, int l2, int r2) {
  for (int i = l1; i <= l1 + 2; i++)
    for (int j = r1; j <= r1 + 2; j++)
      if (l2 <= i && i <= l2 + 2 && r2 <= j && j <= r2 + 2) {
        return false;
      }
  return true;
}
int main() {
  int n, m;
  cin >> n >> m;
  char tmp1[13] = {'2', '3', '4', '5', '6', '7', '8',
                   '9', 'T', 'J', 'Q', 'K', 'A'};
  char tmp2[4] = {'C', 'D', 'H', 'S'};
  set<string> SS;
  for (int i = 0; i < 13; i++)
    for (int j = 0; j < 4; j++) {
      string S = "";
      S += tmp1[i];
      S += tmp2[j];
      SS.insert(S);
    }
  bool hasJoker = false;
  int cntJoker = 0;
  bool J1 = false;
  int J1l;
  int J1r;
  bool J2 = false;
  int J2l;
  int J2r;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      cin >> A[i][j].rank >> A[i][j].suit;
      B[A[i][j].rank][A[i][j].suit] = true;
      if (A[i][j].rank == 'J' && (A[i][j].suit == '1' || A[i][j].suit == '2')) {
        hasJoker = true;
        cntJoker++;
        if (A[i][j].suit == '1') {
          J1 = true;
          J1l = i;
          J1r = j;
        }
        if (A[i][j].suit == '2') {
          J2 = true;
          J2l = i;
          J2r = j;
        }
      } else {
        string S = "";
        S += A[i][j].rank;
        S += A[i][j].suit;
        SS.erase(SS.find(S));
      }
    }
  vector<pair<int, int>> V1;
  vector<pair<int, int>> V2;
  for (int i = 1; i <= n - 2; i++)
    for (int j = 1; j <= m - 2; j++) {
      int l = i;
      int r = j;
      if (l == 1 && r == 3) cout << "";
      if (check1(l, r)) V1.push_back(make_pair(l, r));
      if (l == 4 && r == 1) cout << "";
      if (check2(l, r)) V2.push_back(make_pair(l, r));
    }
  for (int i = 0; i < V1.size(); i++)
    for (int j = 0; j < V1.size(); j++) {
      int l1 = V1[i].first;
      int r1 = V1[i].second;
      int l2 = V1[j].first;
      int r2 = V1[j].second;
      if (check3(l1, r1, l2, r2)) {
        if (cntJoker == 0) {
          cout << "Solution exists." << endl;
          cout << "There are no jokers." << endl;
          cout << "Put the first square to (" << l1 << ", " << r1 << ")."
               << endl;
          cout << "Put the second square to (" << l2 << ", " << r2 << ").";
          return 0;
        }
        if (cntJoker == 1) {
          for (set<string>::iterator it = SS.begin(); it != SS.end(); it++) {
            if (J1) {
              A[J1l][J1r].rank = (*it)[0];
              A[J1l][J1r].suit = (*it)[1];
              if (CHECK1(l1, r1) && CHECK1(l2, r2)) {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with " << (*it) << "." << endl;
                cout << "Put the first square to (" << l1 << ", " << r1 << ")."
                     << endl;
                cout << "Put the second square to (" << l2 << ", " << r2
                     << ").";
                return 0;
              }
              A[J1l][J1r].rank = 'J';
              A[J1l][J1r].suit = '1';
            }
            if (J2) {
              A[J2l][J2r].rank = (*it)[0];
              A[J2l][J2r].suit = (*it)[1];
              if (CHECK1(l1, r1) && CHECK1(l2, r2)) {
                cout << "Solution exists." << endl;
                cout << "Replace J2 with " << (*it) << "." << endl;
                cout << "Put the first square to (" << l1 << ", " << r1 << ")."
                     << endl;
                cout << "Put the second square to (" << l2 << ", " << r2
                     << ").";
                return 0;
              }
              A[J2l][J2r].rank = 'J';
              A[J2l][J2r].suit = '2';
            }
          }
        }
        if (cntJoker == 2) {
          for (set<string>::iterator it1 = SS.begin(); it1 != SS.end(); it1++) {
            for (set<string>::iterator it2 = SS.begin(); it2 != SS.end();
                 it2++) {
              if (it1 != it2) {
                A[J1l][J1r].rank = (*it1)[0];
                A[J1l][J1r].suit = (*it1)[1];
                A[J2l][J2r].rank = (*it2)[0];
                A[J2l][J2r].suit = (*it2)[1];
                if ((CHECK1(l1, r1) && CHECK1(l2, r2)) ||
                    (CHECK1(l1, r1) && CHECK2(l2, r2)) ||
                    (CHECK2(l1, r1) && CHECK1(l2, r2)) ||
                    (CHECK2(l1, r1) && CHECK2(l2, r2))) {
                  cout << "Solution exists." << endl;
                  cout << "Replace J1 with " << (*it1) << " and J2 with "
                       << (*it2) << "." << endl;
                  cout << "Put the first square to (" << l1 << ", " << r1
                       << ")." << endl;
                  cout << "Put the second square to (" << l2 << ", " << r2
                       << ").";
                  return 0;
                }
                A[J1l][J1r].rank = 'J';
                A[J1l][J1r].suit = '1';
                A[J2l][J2r].rank = 'J';
                A[J2l][J2r].suit = '2';
              }
            }
          }
        }
      }
    }
  cout << "No solution.";
  return 0;
}
