Problem: Vasya has a pack of 54 cards (52 standard cards and 2 distinct jokers). That is all he has at the moment. Not to die from boredom, Vasya plays Solitaire with them.

Vasya lays out nm cards as a rectangle n × m. If there are jokers among them, then Vasya should change them with some of the rest of 54 - nm cards (which are not layed out) so that there were no jokers left. Vasya can pick the cards to replace the jokers arbitrarily. Remember, that each card presents in pack exactly once (i. e. in a single copy). Vasya tries to perform the replacements so that the solitaire was solved.

Vasya thinks that the solitaire is solved if after the jokers are replaced, there exist two non-overlapping squares 3 × 3, inside each of which all the cards either have the same suit, or pairwise different ranks.

Determine by the initial position whether the solitaire can be solved or not. If it can be solved, show the way in which it is possible.

Input

The first line contains integers n and m (3 ≤ n, m ≤ 17, n × m ≤ 52). Next n lines contain m words each. Each word consists of two letters. The jokers are defined as "J1" and "J2" correspondingly. For the rest of the cards, the first letter stands for the rank and the second one — for the suit. The possible ranks are: "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" and "A". The possible suits are: "C", "D", "H" and "S". All the cards are different.

Output

If the Solitaire can be solved, print on the first line "Solution exists." without the quotes. On the second line print in what way the jokers can be replaced. Three variants are possible:

  * "There are no jokers.", if there are no jokers in the input data.
  * "Replace Jx with y.", if there is one joker. x is its number, and y is the card it should be replaced with.
  * "Replace J1 with x and J2 with y.", if both jokers are present in the input data. x and y here represent distinct cards with which one should replace the first and the second jokers correspondingly.



On the third line print the coordinates of the upper left corner of the first square 3 × 3 in the format "Put the first square to (r, c).", where r and c are the row and the column correspondingly. In the same manner print on the fourth line the coordinates of the second square 3 × 3 in the format "Put the second square to (r, c).".

If there are several solutions to that problem, print any of them.

If there are no solutions, print of the single line "No solution." without the quotes.

See the samples to understand the output format better.

Examples

Input

4 6
2S 3S 4S 7S 8S AS
5H 6H 7H 5S TC AC
8H 9H TH 7C 8C 9C
2D 2C 3C 4C 5C 6C


Output

No solution.

Input

4 6
2S 3S 4S 7S 8S AS
5H 6H 7H J1 TC AC
8H 9H TH 7C 8C 9C
2D 2C 3C 4C 5C 6C


Output

Solution exists.
Replace J1 with 2H.
Put the first square to (1, 1).
Put the second square to (2, 4).


Input

4 6
2S 3S 4S 7S 8S AS
5H 6H 7H QC TC AC
8H 9H TH 7C 8C 9C
2D 2C 3C 4C 5C 6C


Output

Solution exists.
There are no jokers.
Put the first square to (1, 1).
Put the second square to (2, 4).

Note

The pretests cover all the possible output formats.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
struct card {
  int value = -1;
  int suit = -1;
};
bool eqv(card c1, card c2) {
  return (c1.value == c2.value && c1.suit == c2.suit);
}
struct JOKER {
  bool is = false;
  int r;
  int c;
};
JOKER J1, J2;
struct sol {
  int r;
  int c;
  int type_;
  vector<card> repl1;
  vector<card> repl2;
};
bool if_J_in(int r, int c, int N) {
  if (N == 1 && J1.is && J1.r >= r && J1.r <= r + 2 && J1.c >= c &&
      J1.c <= c + 2)
    return true;
  if (N == 2 && J2.is && J2.r >= r && J2.r <= r + 2 && J2.c >= c &&
      J2.c <= c + 2)
    return true;
  return false;
}
bool ch_dif(int n, int m, vector<card> &On_Table, int r, int c) {
  for (int i = 0; i < 9; ++i) {
    int r1 = i / 3;
    int c1 = i - 3 * r1;
    r1 += r;
    c1 += c;
    int v1 = On_Table[r1 * m + c1].value;
    if (v1 < 0) continue;
    for (int j = i + 1; j < 9; ++j) {
      int r2 = j / 3;
      int c2 = j - 3 * r2;
      r2 += r;
      c2 += c;
      int v2 = On_Table[r2 * m + c2].value;
      if (v1 == v2 && v1 >= 0 && v2 >= 0) return false;
    }
  }
  return true;
}
void def_val(bool *values, int n, int m, vector<card> &On_Table, int r, int c) {
  for (int i = 0; i < 9; ++i) {
    int r1 = i / 3;
    int c1 = i - 3 * r1;
    r1 += r;
    c1 += c;
    int v1 = On_Table[r1 * m + c1].value;
    if (v1 >= 0) values[v1] = false;
  }
}
void if_sol(int r, int c, bool *cards, vector<card> &On_Table,
            vector<sol> &Solutions, int n, int m) {
  if (!if_J_in(r, c, 1) && !if_J_in(r, c, 2)) {
    if (ch_dif(n, m, On_Table, r, c)) {
      sol tmp;
      tmp.c = c;
      tmp.r = r;
      tmp.type_ = 0;
      Solutions.push_back(tmp);
    }
    return;
  }
  if (if_J_in(r, c, 1) || if_J_in(r, c, 2)) {
    if (ch_dif(n, m, On_Table, r, c)) {
      sol tmp;
      tmp.c = c;
      tmp.r = r;
      if (if_J_in(r, c, 1) && !if_J_in(r, c, 2)) tmp.type_ = 1;
      if (!if_J_in(r, c, 1) && if_J_in(r, c, 2)) tmp.type_ = 2;
      if (if_J_in(r, c, 1) && if_J_in(r, c, 2)) tmp.type_ = 3;
      bool values[13];
      for (int i = 0; i < 13; ++i) values[i] = true;
      def_val(values, n, m, On_Table, r, c);
      for (int v = 0; v < 13; ++v) {
        if (!values[v]) continue;
        for (int s = 0; s < 4; ++s) {
          if (cards[s * 13 + v]) {
            card tmp_;
            tmp_.suit = s;
            tmp_.value = v;
            tmp.repl1.push_back(tmp_);
            tmp.repl2.push_back(tmp_);
          }
        }
      }
      if (tmp.type_ == 1 && tmp.repl1.size() > 0) Solutions.push_back(tmp);
      if (tmp.type_ == 2 && tmp.repl2.size() > 0) Solutions.push_back(tmp);
      if (tmp.type_ == 3 && tmp.repl1.size() > 1) Solutions.push_back(tmp);
    }
    return;
  }
  return;
}
void print_card(card a) {
  if (a.value == -1) cout << "J" << a.suit;
  if (a.value >= 0) {
    switch (a.value) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
        cout << a.value + 2;
        break;
      case 8:
        cout << "T";
        break;
      case 9:
        cout << "J";
        break;
      case 10:
        cout << "Q";
        break;
      case 11:
        cout << "K";
        break;
      case 12:
        cout << "A";
        break;
    }
    switch (a.suit) {
      case 0:
        cout << "C";
        break;
      case 1:
        cout << "D";
        break;
      case 2:
        cout << "H";
        break;
      case 3:
        cout << "S";
        break;
    }
  }
}
void print_sols(vector<sol> &S) {
  for (int i = 0; i < S.size(); ++i) {
    cout << S[i].r << " " << S[i].c << " " << S[i].type_ << endl;
    if (S[i].type_ == 1 || S[i].type_ == 3) {
      for (int j = 0; j < S[i].repl1.size(); ++j) print_card(S[i].repl1[j]);
      cout << endl;
    }
    if (S[i].type_ == 2 || S[i].type_ == 3)
      for (int j = 0; j < S[i].repl2.size(); ++j) print_card(S[i].repl2[j]);
    cout << endl;
  }
  cout << endl;
}
bool both(sol s1, sol s2, bool *cards) {
  if (fabs(s1.r - s2.r) < 3 && fabs(s1.c - s2.c) < 3) return false;
  if (s1.type_ == 0 && s2.type_ == 0) {
    cout << "Solution exists." << endl;
    if (!J1.is && !J2.is) cout << "There are no jokers." << endl;
    if (J1.is && !J2.is) {
      int i = 0;
      for (i = 0; i < 13 * 4; ++i)
        if (cards[i]) break;
      if (i >= 13 * 4) return false;
      card tmp;
      tmp.suit = i / 13;
      tmp.value = i - tmp.suit * 13;
      cout << "Replace J1 with ";
      print_card(tmp);
      cout << "." << endl;
    }
    if (!J1.is && J2.is) {
      int i = 0;
      for (i = 0; i < 13 * 4; ++i)
        if (cards[i]) break;
      if (i >= 13 * 4) return false;
      card tmp;
      tmp.suit = i / 13;
      tmp.value = i - tmp.suit * 13;
      cout << "Replace J2 with ";
      print_card(tmp);
      cout << "." << endl;
    }
    if (J1.is && J2.is) {
      int i = 0;
      for (i = 0; i < 13 * 4; ++i)
        if (cards[i]) break;
      int j = 0;
      for (j = i + 1; j < 13 * 4; ++j)
        if (cards[j]) break;
      if (i >= 13 * 4 || j >= 13 * 4) return false;
      card tmp1;
      tmp1.suit = i / 13;
      tmp1.value = i - tmp1.suit * 13;
      card tmp2;
      tmp2.suit = j / 13;
      tmp2.value = j - tmp2.suit * 13;
      cout << "Replace J1 with ";
      print_card(tmp1);
      cout << " and J2 with ";
      print_card(tmp2);
      cout << "." << endl;
    }
    cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1 << ")."
         << endl;
    cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1 << ")."
         << endl;
    return true;
  }
  if (s1.type_ == 1 && s2.type_ == 2) {
    if (s1.repl1.size() > 1 || s2.repl2.size() > 1 ||
        !eqv(s1.repl1[0], s2.repl2[0])) {
      cout << "Solution exists." << endl;
      card tmp1 = s1.repl1[0];
      card tmp2 = s2.repl2[0];
      if (eqv(s1.repl1[0], s2.repl2[0])) {
        if (s1.repl1.size() > 1)
          tmp1 = s1.repl1[1];
        else
          tmp2 = s2.repl2[2];
      }
      cout << "Replace J1 with ";
      print_card(tmp1);
      cout << " and J2 with ";
      print_card(tmp2);
      cout << "." << endl;
      cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1
           << ")." << endl;
      cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1
           << ")." << endl;
      return true;
    } else
      return false;
  }
  if (s1.type_ == 2 && s2.type_ == 1) {
    if (s1.repl2.size() > 1 || s2.repl1.size() > 1 ||
        !eqv(s1.repl2[0], s2.repl1[0])) {
      cout << "Solution exists." << endl;
      card tmp2 = s1.repl2[0];
      card tmp1 = s2.repl1[0];
      if (eqv(tmp1, tmp2)) {
        if (s1.repl2.size() > 1)
          tmp2 = s1.repl2[1];
        else
          tmp1 = s2.repl1[2];
      }
      cout << "Replace J1 with ";
      print_card(tmp1);
      cout << " and J2 with ";
      print_card(tmp2);
      cout << "." << endl;
      cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1
           << ")." << endl;
      cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1
           << ")." << endl;
      return true;
    } else
      return false;
  }
  if (s1.type_ == 0 && s2.type_ == 1) {
    card tmp;
    if (J2.is) {
      int i;
      for (i = 0; i < 13 * 4; ++i) {
        tmp.suit = i / 13;
        tmp.value = i - tmp.suit * 13;
        if (cards[i] && !eqv(tmp, s2.repl1[0])) break;
      }
      if (i > 13 * 4) return false;
    }
    cout << "Solution exists." << endl;
    cout << "Replace J1 with ";
    print_card(s2.repl1[0]);
    if (J2.is) {
      cout << " and J2 with ";
      print_card(tmp);
    }
    cout << "." << endl;
    cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1 << ")."
         << endl;
    cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1 << ")."
         << endl;
    return true;
  }
  if (s1.type_ == 0 && s2.type_ == 2) {
    card tmp;
    if (J1.is) {
      int i;
      for (i = 0; i < 13 * 4; ++i) {
        tmp.suit = i / 13;
        tmp.value = i - tmp.suit * 13;
        if (cards[i] && !eqv(tmp, s2.repl2[0])) break;
      }
      if (i > 13 * 4) return false;
    }
    cout << "Solution exists." << endl;
    if (J1.is) {
      cout << "Replace J1 with ";
      print_card(tmp);
      cout << " and J2 with ";
    } else {
      cout << "Replace J2 with ";
    }
    print_card(s2.repl2[0]);
    cout << "." << endl;
    cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1 << ")."
         << endl;
    cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1 << ")."
         << endl;
    return true;
  }
  if (s1.type_ == 2 && s2.type_ == 0) {
    card tmp;
    if (J1.is) {
      int i;
      for (i = 0; i < 13 * 4; ++i) {
        tmp.suit = i / 13;
        tmp.value = i - tmp.suit * 13;
        if (cards[i] && !eqv(tmp, s1.repl2[0])) break;
      }
      if (i > 13 * 4) return false;
    }
    cout << "Solution exists." << endl;
    if (J1.is) {
      cout << "Replace J1 with ";
      print_card(tmp);
      cout << " and J2 with ";
    } else {
      cout << "Replace J2 with ";
    }
    print_card(s1.repl2[0]);
    cout << "." << endl;
    cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1 << ")."
         << endl;
    cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1 << ")."
         << endl;
    return true;
  }
  if (s1.type_ == 1 && s2.type_ == 0) {
    card tmp;
    if (J2.is) {
      int i;
      for (i = 0; i < 13 * 4; ++i) {
        tmp.suit = i / 13;
        tmp.value = i - tmp.suit * 13;
        if (cards[i] && !eqv(tmp, s1.repl1[0])) break;
      }
      if (i > 13 * 4) return false;
    }
    cout << "Solution exists." << endl;
    cout << "Replace J1 with ";
    print_card(s1.repl1[0]);
    if (J2.is) {
      cout << " and J2 with ";
      print_card(tmp);
    }
    cout << "." << endl;
    cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1 << ")."
         << endl;
    cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1 << ")."
         << endl;
    return true;
  }
  if (s1.type_ == 3) {
    if (s1.repl1.size() > 1) {
      card tmp1, tmp2;
      int i, j;
      bool ok = false;
      for (i = 0; i < s1.repl1.size() && !ok; ++i)
        for (j = i + 1; j < s1.repl1.size(); ++j) {
          if (s1.repl1[i].value != s1.repl1[j].value) {
            tmp1 = s1.repl1[i];
            tmp2 = s1.repl1[j];
            ok = true;
            break;
          }
        }
      if (!ok) return false;
      cout << "Solution exists." << endl;
      cout << "Replace J1 with ";
      print_card(tmp1);
      cout << " and J2 with ";
      print_card(tmp2);
      cout << "." << endl;
      cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1
           << ")." << endl;
      cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1
           << ")." << endl;
      return true;
    }
    return false;
  }
  if (s2.type_ == 3) {
    if (s2.repl1.size() > 1) {
      card tmp1, tmp2;
      int i, j;
      bool ok = false;
      for (i = 0; i < s2.repl1.size() && !ok; ++i)
        for (j = i + 1; j < s2.repl1.size(); ++j) {
          if (s2.repl1[i].value != s2.repl1[j].value) {
            tmp1 = s2.repl1[i];
            tmp2 = s2.repl1[j];
            ok = true;
            break;
          }
        }
      if (!ok) return false;
      cout << "Solution exists." << endl;
      cout << "Replace J1 with ";
      print_card(tmp1);
      cout << " and J2 with ";
      print_card(tmp2);
      cout << "." << endl;
      cout << "Put the first square to (" << s1.r + 1 << ", " << s1.c + 1
           << ")." << endl;
      cout << "Put the second square to (" << s2.r + 1 << ", " << s2.c + 1
           << ")." << endl;
      return true;
    }
    return false;
  }
  return false;
}
int main() {
  bool CARDS[13 * 4];
  for (int i = 0; i < 13; ++i)
    for (int j = 0; j < 4; ++j) CARDS[j * 13 + i] = true;
  int n, m;
  cin >> n >> m;
  vector<card> On_Table(n * m);
  vector<sol> Solutions;
  for (int i = 0; i < n * m; ++i) {
    string tmp;
    cin >> tmp;
    switch (tmp[0]) {
      case 'J':
        if (tmp[1] == '1' || tmp[1] == '2')
          On_Table[i].value = -1;
        else
          On_Table[i].value = 9;
        break;
      case '2':
        On_Table[i].value = 0;
        break;
      case '3':
        On_Table[i].value = 1;
        break;
      case '4':
        On_Table[i].value = 2;
        break;
      case '5':
        On_Table[i].value = 3;
        break;
      case '6':
        On_Table[i].value = 4;
        break;
      case '7':
        On_Table[i].value = 5;
        break;
      case '8':
        On_Table[i].value = 6;
        break;
      case '9':
        On_Table[i].value = 7;
        break;
      case 'T':
        On_Table[i].value = 8;
        break;
      case 'Q':
        On_Table[i].value = 10;
        break;
      case 'K':
        On_Table[i].value = 11;
        break;
      case 'A':
        On_Table[i].value = 12;
        break;
      default:
        cout << "ERROR" << endl;
        return 0;
        break;
    }
    switch (tmp[1]) {
      case '1':
        On_Table[i].suit = 1;
        J1.is = true;
        J1.r = i / m;
        J1.c = i - J1.r * m;
        break;
      case '2':
        On_Table[i].suit = 2;
        J2.is = true;
        J2.r = i / m;
        J2.c = i - J2.r * m;
        break;
      case 'C':
        On_Table[i].suit = 0;
        break;
      case 'D':
        On_Table[i].suit = 1;
        break;
      case 'H':
        On_Table[i].suit = 2;
        break;
      case 'S':
        On_Table[i].suit = 3;
        break;
      default:
        cout << "ERROR" << endl;
        return 0;
        break;
    }
  }
  for (int i = 0; i < n * m; ++i) {
    if (On_Table[i].suit >= 0)
      CARDS[On_Table[i].value + 13 * On_Table[i].suit] = false;
  }
  for (int r = 0; r < n - 2; ++r)
    for (int c = 0; c < m - 2; ++c)
      if_sol(r, c, CARDS, On_Table, Solutions, n, m);
  for (int i = 0; i < Solutions.size(); ++i)
    for (int j = i + 1; j < Solutions.size(); ++j)
      if (both(Solutions[i], Solutions[j], CARDS)) return 0;
  cout << "No solution." << endl;
  return 0;
}