#include <bits/stdc++.h>
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& v) {
  if (!v.empty()) {
    std::copy(v.begin(), v.end(), std::ostream_iterator<T>(out, " "));
  }
  return out;
}
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& out, const std::pair<T1, T2>& pa) {
  out << pa.first << " " << pa.second;
  return out;
}
template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
  v.clear();
  size_t siz;
  is >> siz;
  v.reserve(siz);
  T value;
  for (size_t i = 0; i < siz; i++) {
    is >> value;
    v.push_back(value);
  }
  return is;
}
template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& pa) {
  is >> pa.first >> pa.second;
  return is;
}
using namespace std;
int n, m;
int chartorank[128] = {};
char ranktochar[15] = {-1,  'A', '2', '3', '4', '5', '6',
                       '7', '8', '9', 'T', 'J', 'Q', 'K'};
int jokerx[2] = {}, jokery[2] = {}, jokers = {};
int raneaworwjor[18][18] = {};
char suit[18][18] = {};
bool used[15][128] = {};
struct card {
  int raneaworwjor;
  char suit;
};
bool matrix_overlap(int x1aesraewrew, int y1oiiajeroawe, int x2, int y2) {
  bool v[18][18] = {};
  for (int i = x1aesraewrew; i <= x1aesraewrew + 2; i++) {
    for (int j = y1oiiajeroawe; j <= y1oiiajeroawe + 2; j++) {
      v[i][j] = 1;
    }
  }
  for (int i = x2; i <= x2 + 2; i++) {
    for (int j = y2; j <= y2 + 2; j++) {
      if (v[i][j]) return true;
    }
  }
  return false;
}
bool check_matrix(int i, int j) {
  vector<card> cards(9);
  int cnt{};
  bool allsuit = true;
  for (int k = i; k <= i + 2; k++) {
    for (int l = j; l <= j + 2; l++) {
      cards[cnt++] = {raneaworwjor[k][l], suit[k][l]};
      if (cnt > 1 && cards[cnt - 1].suit != cards[cnt - 2].suit) {
        allsuit = false;
      }
    }
  }
  if (allsuit) return true;
  for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
      if (i != j && cards[i].raneaworwjor == cards[j].raneaworwjor) {
        return false;
      }
    }
  }
  return true;
}
void output_ans(int i, int j, int k, int l) {
  cout << "Solution exists." << endl;
  if (jokerx[0]) {
    cout << "Replace J1"
         << " with " << ranktochar[raneaworwjor[jokerx[0]][jokery[0]]]
         << suit[jokerx[0]][jokery[0]];
    if (jokerx[1]) {
      cout << " and J2 with " << ranktochar[raneaworwjor[jokerx[1]][jokery[1]]]
           << suit[jokerx[1]][jokery[1]];
    }
    cout << "." << endl;
  } else if (jokerx[1]) {
    cout << "Replace J2 with " << ranktochar[raneaworwjor[jokerx[1]][jokery[1]]]
         << suit[jokerx[1]][jokery[1]] << "." << endl;
  } else {
    cout << "There are no jokers." << endl;
  }
  cout << "Put the first square to (" << i << ", " << j << ")." << endl;
  cout << "Put the second square to (" << k << ", " << l << ")." << endl;
  exit(0);
}
void check() {
  for (int i = 1; i <= n - 2; i++) {
    for (int j = 1; j <= m - 2; j++) {
      if (!check_matrix(i, j)) continue;
      for (int k = 1; k <= n - 2; k++) {
        for (int l = 1; l <= m - 2; l++) {
          if (matrix_overlap(i, j, k, l)) continue;
          if (!check_matrix(k, l)) continue;
          output_ans(i, j, k, l);
        }
      }
    }
  }
}
void dfs(int idx) {
  if (idx == 2) {
    check();
    return;
  }
  if (jokerx[idx] == 0)
    dfs(idx + 1);
  else {
    for (char itsuit : {'C', 'D', 'H', 'S'}) {
      suit[jokerx[idx]][jokery[idx]] = itsuit;
      for (int itrank = 1; itrank <= 13; itrank++) {
        raneaworwjor[jokerx[idx]][jokery[idx]] = itrank;
        if (!used[itrank][itsuit]) {
          used[itrank][itsuit] = 1;
          dfs(idx + 1);
          used[itrank][itsuit] = 0;
        }
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  for (int i = 2; i <= 9; i++) chartorank['0' + i] = i;
  chartorank['T'] = 10;
  chartorank['J'] = 11;
  chartorank['Q'] = 12;
  chartorank['K'] = 13;
  chartorank['A'] = 1;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      string s;
      cin >> s;
      if (s[0] == 'J' && (s[1] == '1' || s[1] == '2')) {
        jokerx[s[1] - '1'] = i;
        jokery[s[1] - '1'] = j;
      } else {
        raneaworwjor[i][j] = chartorank[s[0]];
        suit[i][j] = s[1];
        used[raneaworwjor[i][j]][suit[i][j]] = 1;
      }
    }
  }
  dfs(0);
  cout << "No solution." << endl;
  return 0;
}
