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.

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.

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.

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

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

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

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

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

NoteThe pretests cover all the possible output formats.

#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;

int n, m, jcnt;
string a[20][20];
set<pair<int,int>>ans;
map<pair<int,int>,vector<pair<int,int>>> ma;
pair<int,int> _j1,j2;
set<string> present,cards;
string suit[]={"C", "D", "H", "S"};
string rnk[] ={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};

bool valid(int r, int c)
{

	set<char> suits;
	set<char> rnks;
	for(int i=r; i <= r+2; i++)
		for(int j=c; j <= c+2; j++)
		{
			suits.insert(a[i][j][1]);
			rnks.insert(a[i][j][0]);
		}
	return (rnks.size() == 9 || suits.size() == 1);
}

int main()
{
	cin >> n >> m;
	for(int i=0; i < 13; i++)
		for(int j=0; j < 4; j++)
			cards.insert(rnk[i]+suit[j]);
	for(int i=1; i <= n; i++)
		for(int j=1; j <= m; j++)
		{
			cin >> a[i][j];
			if (a[i][j] == "J1")	_j1=make_pair(i, j), jcnt++;
			if (a[i][j] == "J2")	j2=make_pair(i, j), jcnt++;
			cards.erase(a[i][j]);
		}
	if ( jcnt == 0 )
	{
		for(int i=1; i <= n-2; i++)
			for(int j=1; j <= m-2; j++)
				if (valid(i, j))	ans.insert(make_pair(i, j));

		for(auto i : ans)
			for(auto j : ans)
				if (! (abs(i.first-j.first) < 3 && abs(i.second-j.second) < 3) )
				{
					cout << "Solution exists." << endl;
					cout << "There are no jokers." << endl;
					cout << "Put the first square to (" << i.first << ", " << i.second << ")." << endl;
					cout << "Put the second square to ("<< j.first << ", " << j.second << ")." << endl;
					return 0;
				}
	}
	else if (jcnt == 1)
	{
		for(auto i : cards)
		{
			bool p1=false;
			if (_j1.first != 0)		a[_j1.first][_j1.second]=i, p1=true;
			else a[j2.first][j2.second]=i;
			ans.clear();
			for(int i=1; i <= n-2; i++)
				for(int j=1; j <= m-2; j++)
				{
					if (valid(i, j))
					{
						ans.insert(make_pair(i, j));
					}
				}

			for(auto i : ans)
				for(auto j : ans)
					if (! (abs(i.first-j.first) < 3 && abs(i.second-j.second) < 3) )
					{
						cout << "Solution exists." << endl;
						if (p1)	cout << "Replace J1 with " << a[_j1.first][_j1.second] << "." << endl;
						else 	cout << "Replace J2 with " << a[j2.first][j2.second]   << "." << endl;
						cout << "Put the first square to (" << i.first << ", " << i.second << ")." << endl;
						cout << "Put the second square to ("<< j.first << ", " << j.second << ")." << endl;
						return 0;
					}
		}
	}
	else if (jcnt==2)
	{
		for(auto i : cards)
			for(auto j : cards)
				if (i!=j)
				{
					a[_j1.first][_j1.second]=i;
					a[j2.first][j2.second]=j;
					ans.clear();
					for(int i=1; i<=n-2; i++)
						for(int j=1; j<=m-2; j++)
							if (valid(i, j))	ans.insert(make_pair(i, j));

					for(auto i : ans)
						for(auto j : ans)
							if (! (abs(i.first-j.first)<3 && abs(i.second-j.second)<3) )
							{
								cout<<"Solution exists."<<endl;
								cout<<"Replace J1 with "<<a[_j1.first][_j1.second]<<" and J2 with "<<a[j2.first][j2.second]<<"."<<endl;
								cout<<"Put the first square to ("<<i.first<<", "<<i.second<<")."<<endl;
								cout<<"Put the second square to ("<< j.first<<", "<<j.second<<")."<<endl;
								return 0;
							}
				}
	}
	cout<<"No solution."<<endl;
	return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
#include <queue>
#include <deque>
#include <set>
#define ll long long
#define MP make_pair
#define PII pair<int, int>
#define F first
#define S second
#define SHN 1e9
#define lSHN 1e18
using namespace std;
int n,m;
string s[20][20];
set<string> st;
string ran="23456789TJQKA";
string sui="CDHS";
int j1x=-1,j1y=-1,j2x=-1,j2y=-1;
int x1,y1,x2,y2;
bool isres=0;
bool ok[20][20];
inline bool go(int x,int y)
{
	bool su=1;
	int ra=0;
	for (int i=x;i<x+3;i++)
	{
		for (int j=y;j<y+3;j++)
		{
			if (s[x][y][1]!=s[i][j][1]) su=0;
			ra|=(1<<(ran.find(s[i][j][0])));
		}
	}
	//if (!x && !y) cout <<su<<" "<<__builtin_popcount(ra)<<" ##\n";
	return su || __builtin_popcount(ra)==9;
}
void check(string x,string y)
{
	if (x!="") s[j1x][j1y]=x;
	if (y!="") s[j2x][j2y]=y;
	for (int i=0;i<n-2;i++)
	{
		for (int j=0;j<m-2;j++)
		    ok[i][j]=go(i,j);
	}
	for (int i1=0;i1<n-2;i1++)
	{
		for (int j1=0;j1<m-2;j1++)
		{
			if (!ok[i1][j1]) continue;
			for (int i2=0;i2<n-2;i2++)
			{
				for (int j2=0;j2<m-2;j2++)
				{
					if (!ok[i2][j2]) continue;
					if (abs(i1-i2)>=3 || abs(j1-j2)>=3)
					{
						isres=1;
						x1=i1+1,y1=j1+1,x2=i2+1,y2=j2+1;
						return;
					}
				}
			}
		}
	}
}
int main()
{
	cin >>n>>m;
	for (int i=0;i<13;i++)
	{
		for (int j=0;j<4;j++)
		{
			string ss="  ";
			ss[0]=ran[i];
			ss[1]=sui[j];
			st.insert(ss);
		}
	}
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			cin >>s[i][j];
			if (s[i][j]!="J1" && s[i][j]!="J2")
			{
				st.erase(s[i][j]);
				continue;
			}
			if (s[i][j]=="J1") j1x=i,j1y=j;
			if (s[i][j]=="J2") j2x=i,j2y=j;
		}
	}
	if (j1x==-1 && j2x==-1)
	{
		check("","");
		if (isres)
		{
			cout <<"Solution exists.\n";
			cout <<"There are no jokers.\n";
			cout <<"Put the first square to ("<<x1<<", "<<y1<<").\n";
			cout <<"Put the second square to ("<<x2<<", "<<y2<<").";
			return 0;
		}
	}
	else if (j1x!=-1 && j2x==-1)
	{
		for (set<string>::iterator it=st.begin();it!=st.end();it++)
		{
			check((*it),"");
			if (isres)
			{
				cout <<"Solution exists.\n";
				cout <<"Replace J1 with "<<(*it)<<".\n";
				cout <<"Put the first square to ("<<x1<<", "<<y1<<").\n";
				cout <<"Put the second square to ("<<x2<<", "<<y2<<").";
				return 0;
			}
		}
	}
	else if (j1x==-1 && j2x!=-1)
	{
		for (set<string>::iterator it=st.begin();it!=st.end();it++)
		{
			check("",(*it));
			if (isres)
			{
				cout <<"Solution exists.\n";
				cout <<"Replace J2 with "<<(*it)<<".\n";
				cout <<"Put the first square to ("<<x1<<", "<<y1<<").\n";
				cout <<"Put the second square to ("<<x2<<", "<<y2<<").";
				return 0;
			}
		}
	}
	else
	{
		for (set<string>::iterator it1=st.begin();it1!=st.end();it1++)
		{
			for (set<string>::iterator it2=st.begin();it2!=st.end();it2++)
			{
				if (it1==it2) continue;
				check((*it1),(*it2));
				if (isres)
				{
					cout <<"Solution exists.\n";
					cout <<"Replace J1 with "<<(*it1)<<" and J2 with "<<(*it2)<<".\n";
					cout <<"Put the first square to ("<<x1<<", "<<y1<<").\n";
					cout <<"Put the second square to ("<<x2<<", "<<y2<<").";
					return 0;
				}
			}
		}
	}
	cout <<"No solution.";
	return 0;
}

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define f first
#define s second
#define mp make_pair
using namespace std;

int n, m;
string crank = "A23456789TJQK";
string suit = "CDHS";
vector<vector<bool> > inDeck(13, vector<bool>(4, true));
vector<int> crankCount(13, 4);
vector<vector<string> > card;

pair<int, int> cardData(string card) {
	if(card[0] == 'J' && card[1] >= '1' && card[1] <= '2')
		return mp(-1, card[1] - '1');
	return mp(crank.find(card[0]), suit.find(card[1]));
}

//------------------------------------------------------
//placement function

vector<vector<pair<int, int> > > jreplace(2);
vector<int> placeJokers;

bool place(int y, int x) {
	vector<bool> used(13, false);
	vector<int> jokers;

	for(int dy = 0; dy < 3; dy++)
		for(int dx = 0; dx < 3; dx++) {
			int cy = y + dy, cx = x + dx;

			auto data = cardData(card[cy][cx]);
			if(data.f == -1)
				jokers.push_back(data.s);
			else {
				if(used[data.f])
					return false;
				used[data.f] = true;
			}

		}

	placeJokers.insert(placeJokers.end(), jokers.begin(), jokers.end() );

	for(int i=0;i<13;i++)
		if(!used[i]) {
			for(int j=0;j<4;j++)
				if(inDeck[i][j] && jokers.size() > 0) {
					jreplace[jokers.back()].push_back(mp(i, j) );

					if(jokers.size() > 1) {
						jokers.pop_back();
						break;
					}
				}
		}
	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	card.resize(n, vector<string>(m));
	vector<int> jokers;

	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++) {
			cin >> card[i][j];

			auto data = cardData(card[i][j]);
			if(data.f != -1) {
				inDeck[data.f][data.s] = false;
				crankCount[data.f]--;
			}
			else
				jokers.push_back(data.s);
		}

	for(int y1 = 0; y1+3 <= n; y1++)
		for(int x1 = 0; x1+3 <= m; x1++)
			for(int y2 = 0; y2+3 <= n; y2++)
				for(int x2 = 0; x2+3 <= m; x2++)
					if(y2+3 <= y1 || y1+3 <= y2 || x1+3 <= x2 || x2+3 <= x1) {
						placeJokers.clear();
						jreplace.clear();
						jreplace.resize(2);
						if(!place(y1, x1))
							continue;
						if(!place(y2, x2))
							continue;

						pair<int, int> card[2];

						if(placeJokers.size() == 1) {
							if(jreplace[placeJokers[0]].size() == 0)
								continue;
							card[placeJokers[0]] = jreplace[placeJokers[0]][0];
						}
						if(placeJokers.size() == 2) {
							if(jreplace[0].size() == 0 || jreplace[1].size() == 0)
								continue;
							if(jreplace[0].size() == 1 && jreplace[1].size() == 1 && jreplace[0][0] == jreplace[1][0])
								continue;
							card[0] = jreplace[0][0];
							card[1] = jreplace[1][0];
							if(card[0] == card[1] && jreplace[0].size() > 1)
								card[0] = jreplace[0][1];
							if(card[0] == card[1] && jreplace[1].size() > 1)
								card[1] = jreplace[1][1];
						}

						if(jokers.size() > placeJokers.size()) {
							if(placeJokers.size() == 1) {
								for(int i=0;i<13;i++)
									for(int j=0;j<4;j++)
										if(inDeck[i][j] && mp(i, j) != card[placeJokers[0]])
											card[1-placeJokers[0]] = mp(i, j);
							}
							else {
								int cnt = 0;

								for(int i=0;i<13;i++)
									for(int j=0;j<4;j++)
										if(inDeck[i][j]) {
											card[cnt] = mp(i, j);
											cnt = (cnt+1)%2;
										}
							}
						}

						if(jokers.size() == 1) {
							cout << "Solution exists.\n";
							cout << "Replace J" << jokers[0] + 1 << " with " << crank[card[jokers[0]].f] << suit[card[jokers[0]].s] << ".\n";
						}

						else if(jokers.size() == 2) {
							cout << "Solution exists.\n";
							cout << "Replace J1 with " << crank[card[0].f] << suit[card[0].s];
							cout << " and J2 with " << crank[card[1].f] << suit[card[1].s] << ".\n";
						}
						else
							cout << "Solution exists.\nThere are no jokers.\n";

						cout << "Put the first square to (" << y1+1 << ", " << x1+1 << ").\n";
						cout << "Put the second square to (" << y2+1 << ", " << x2+1 << ").\n";

						return 0;
					}

	cout << "No solution.\n";
	return 0;
}

#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <array>
#include <bitset>
#include <unordered_map>

using namespace std;
typedef long long LL;
typedef pair<int,int> P;

char table[18][18][3];
bool used[128][128];
bool ok(int p, int q, int x, int y){
	return p<=x&&x<=p+2&&q<=y&&y<=q+2;
}
bool cross(int a,int b,int c,int d){
	return max(a,c)<=min(a+2,c+2)&&max(b,d)<=min(b+2,d+2);
}
int toInt(char c){
	switch(c){
		case 'T':return 10;
		case 'J':return 11;
		case 'Q':return 12;
		case 'K':return 0;
		case 'A':return 1;
	}
	return c-'0';
}
int toInt2(char c){
	switch(c){
		case 'C':return 0;
		case 'D':return 1;
		case 'H':return 2;
		case 'S':return 3;
	}
	return 0;
}
bool check(int p,int q, bool debug=false){
	int done[13]={};
	bool ok1=true;
	bool ok2=true;
	for(int i=p;i<=p+2;i++){
		for(int j=q;j<=q+2;j++){
			ok1&=(table[i][j][1]==table[p][q][1]);
			ok2&=(done[toInt(table[i][j][0])]++==0);
			if(debug){
				cerr << table[i][j] << " ";
			}
		}
		if(debug){
			cerr << endl;
		}
	}
	if(debug){
		cerr << ok1 << ", " << ok2 << endl;
	}
	return ok1||ok2;
}
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	int j1x=0,j1y=0,j2x=0,j2y=0;
	string j1="J1";
	string j2="J2";
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%s",table[i][j]);
			if(table[i][j]==j1){
				j1x=i;
				j1y=j;
			}
			else if(table[i][j]==j2){
				j2x=i;
				j2y=j;
			}
			else{
				used[toInt(table[i][j][0])][toInt2(table[i][j][1])]=true;
			}
		}
	}
	vector<P> rem;
	rem.push_back(P(-1,-1));
	for(int i=0;i<13;i++){
		for(int j=0;j<4;j++){
			if(!used[i][j]){
				rem.push_back(P(i,j));
			}
		}
	}

	auto s1="KA23456789TJQ";
	auto s2="CDHS";
	for(int p=1;p+2<=n;p++){
		for(int q=1;q+2<=m;q++){
			for(int r=1;r+2<=n;r++){
				for(int s=1;s+2<=m;s++){
					if(P(p,q)>=P(r,s))continue;
					if(cross(p,q,r,s))continue;
					for(auto a:rem){
						if(a.first>=0){
							table[j1x][j1y][0]=s1[a.first];
							table[j1x][j1y][1]=s2[a.second];
						}
						else if(j1x){
							continue;
						}
						for(auto b:rem){
							if(b.first>=0){
								if(a==b)continue;
								table[j2x][j2y][0]=s1[b.first];
								table[j2x][j2y][1]=s2[b.second];
							}
							else if(j2x){
								continue;
							}
#if 0
							if(a==P(2,2)&&p==1&&q==1&&r==2&&s==4){
								cerr << "aaa ";
								check(p,q,true);
								check(r,s,true);
							}
#endif
							if(check(p,q)&&check(r,s)){
								puts("Solution exists.");
								if(j1x&&j2x){
									printf("Replace J1 with %s and J2 with %s.\n",table[j1x][j1y], table[j2x][j2y]);
								}
								else if(j1x){
									printf("Replace J1 with %s.\n",table[j1x][j1y]);
								}
								else if(j2x){
									printf("Replace J2 with %s.\n",table[j2x][j2y]);
								}
								else{
									puts("There are no jokers.");
								}
								printf("Put the first square to (%d, %d).\n",p,q);
								printf("Put the second square to (%d, %d).\n",r,s);
								return 0;
							}
							if(!ok(p,q,j2x,j2y)&&!ok(r,s,j2x,j2y)){
								break;
							}
						}
						if(!ok(p,q,j1x,j1y)&&!ok(r,s,j1x,j1y)){
							break;
						}
					}

				}
			}
		}
	}

	puts("No solution.");

	return 0;
}

#include<bits/stdc++.h>
#define ll  long long
#define pb push_back
#define mkp make_pair
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define pi 3.14159265359
#define zer(dp) memset(dp,0,sizeof dp)
#define all(x) x.begin(),x.end()
//PLEASE DON'T HACK I AM POOR :(
using namespace std;
int main()
{
	fastio
	ll n,i,j,k,m;
    cin>>n>>m;
    vector<string> ar={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K","A" };
    vector<string> ho={ "C", "D", "H","S"};
    vector<string>all;
    for(i=0;i<ar.size();i++){for(j=0;j<ho.size();j++)all.pb(ar[i]+ho[j]);}
//    for(i=0;i<all.size();i++)cout<<all[i]<<"\n";
    string arr[n+1][m+1],temp[n+1][m+1];
    map<string,ll>pr;
    ll i1=-1,j1=-1,i2=-1,j2=-1;
    for(i=1;i<=n;i++)
    {
    	for(j=1;j<=m;j++)
    	{
    		cin>>arr[i][j];
    		pr[arr[i][j]]=1;
    		temp[i][j]=arr[i][j];
    		if(arr[i][j]=="J1")
    		{
    			i1=i;j1=j;
			}
			if(arr[i][j]=="J2")
    		{
    			i2=i;j2=j;
			}

		}
	}
	vector<string>avail;
	for(i=0;i<all.size();i++)
	{
		if(!pr[all[i]])
		{
		avail.pb(all[i]);
//		cout<<"ha  "<<all[i]<<"\n";
		}
	}
	ll rep=0;
	ll fl=0;
	for(i=0;i<avail.size()&&!fl;i++)
	{
		for(j=0;j<avail.size()&&!fl;j++)
		{
			if(i!=j)
			{
				if(i1!=-1&&i2!=-1)
			{
				rep=2;
				temp[i1][j1]=avail[i];
				temp[i2][j2]=avail[j];
			}
			else if((i1==-1&&i2!=-1)||(i1!=-1&&i2==-1))
			{
				rep=1;
				if(i1!=-1)
				temp[i1][j1]=avail[i];
				if(i2!=-1)
				temp[i2][j2]=avail[i];
			}
			else rep=0;
//			if(i1!=-1)cout<<"j1 "<<temp[i1][j1]<<" \n";if(i2!=-1)cout<<"j2 "<<temp[i2][j2]<<" opop\n";
			vector<pair<ll,ll> >prf;
			ll p,q,r,s;
			for(p=1;p<=n;p++)
			{
				for(q=1;q<=m;q++)
				{
					vector<string>ne;
					for(r=p;r<=n&&r<=p+2;r++)
					{
						for(s=q;s<=m&&s<=q+2;s++)
						{
						  ne.pb(temp[r][s]);
						}
					}
					ll poss=0;
					if(ne.size()==9)
					{
						map<string,ll>fi,se;
						for(r=0;r<ne.size();r++)
						{
							string sa,sb;
							for(ll g=0;g<1;g++)sa.pb(ne[r][g]);
							for(ll g=1;g<2;g++)sb.pb(ne[r][g]);
//							cout<<sa<<" ye h equa "<<sb<<"\n";
							fi[sa]++;
							se[sb]++;
						}
						ll f1=1,f2=0;
						for(s=0;s<ar.size();s++)
						{
//							cout<<fi[ar[s]]<<" ooooo\n";
							if(fi[ar[s]]>1)f1=0;
						}
						for(s=0;s<ho.size();s++)
						{
							if(se[ho[s]]==9)f2=1;
						}
						if(f1||f2)
						poss=1;
//					if(p==1&&q==1)cout<<"   ###### YE RAHA  "<<f1<<" "<<f2<<"\n";
					}
					if(poss)prf.pb(mkp(p,q));
//					if(poss)cout<<"HAAAA       "<<p<<"   "<<q<<"\n";
				}
			}
			for(p=0;p<prf.size()&&!fl;p++)
			{
				for(q=p+1;q<prf.size()&&!fl;q++)
				{
					ll r1,c1,r2,c2;
					r1=prf[p].first;c1=prf[p].second;
					r2=prf[q].first;c2=prf[q].second;
//					cout<<r1<<"   TUTUU  "<<c1<<" "<<r2<<" "<<c2<<"\n";
					if(r2>r1+2||c2>c1+2)
					{
					  fl=1;
					  cout<<"Solution exists.\n";
					  if(rep==2)
					  {
					  	cout<<"Replace J1 with "<<temp[i1][j1]<<" and ";
					  	cout<<"J2 with "<<temp[i2][j2]<<".\n";
					  }
					  else if(rep==1)
					  {
					  	if(i1!=-1)
					  	cout<<"Replace J1 with "<<temp[i1][j1]<<".\n";
					  	if(i2!=-1)
					  	cout<<"Replace J2 with "<<temp[i2][j2]<<".\n";
					  }
					  else
					  {
					  	cout<<"There are no jokers.\n";
					  }
					  cout<<"Put the first square to ("<<r1<<", "<<c1<<").\n";
					  cout<<"Put the second square to ("<<r2<<", "<<c2<<").\n";
					}
				}
			}
			}
		}
	}
	if(!fl)
	cout<<"No solution.\n";
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int OO = 0x3f3f3f3f ,N = 1e2 ,mod = 1e9+9 ;
#define read(FILE)  freopen(FILE, "r", stdin);
#define write(FILE) freopen(FILE, "w", stdout);
#define BeatMeIFUCAN ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

int n ,m ,r1=-1 ,c1=-1 ,r2=-1 ,c2=-1 ,R1 ,C1 ,R2 ,C2 ;
string str[N][N] ,ranks="23456789TJQKA" ,suits="CDHS";
set<string> st ;
bool can(int i1,int j1,int i2,int j2){
    int vis[N][N]={};
    for(int i=i1;i<=i1+2;++i)for(int j=j1;j<=j1+2;++j) ++vis[i][j];
    for(int i=i2;i<=i2+2;++i)for(int j=j2;j<=j2+2;++j) if(++vis[i][j]==2) return 0;
    return 1;
}
bool ck(int r,int c){
    for(int i1=r;i1<=r+2;++i1)for(int j1=c;j1<=c+2;++j1)for(int i2=r;i2<=r+2;++i2)for(int j2=c;j2<=c+2;++j2)
    if(str[i1][j1][1]!=str[i2][j2][1]&&str[i1][j1][0]==str[i2][j2][0]) return 0;
    return 1;
}
bool valid(){
    for(int i1=1;i1<=n-2;++i1)for(int j1=1;j1<=m-2;++j1)if(ck(i1,j1))
    for(int i2=1;i2<=n-2;++i2)for(int j2=1;j2<=m-2;++j2)if(can(i1,j1,i2,j2)&&ck(i2,j2)){
        R1=i1 ,R2=i2 ,C1=j1 ,C2=j2 ;
        return 1;
    }
    return 0;
}
int main(){
    for(char a:ranks)for(char b:suits){
        string tmp="";
        tmp+=a;
        tmp+=b;
        st.insert(tmp);
    }
    cin>>n>>m;
    for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){
        cin>>str[i][j];
        if(str[i][j]=="J1") r1=i ,c1=j ;
        else if(str[i][j]=="J2") r2=i ,c2=j ;
        else st.erase(str[i][j]);
    }
    if(~r1&&~r2)for(string j1:st)for(string j2:st){
        if(j1==j2) continue ;
        str[r1][c1]=j1 ,str[r2][c2]=j2 ;
        if(valid()){
            cout<<"Solution exists.\nReplace J1 with "<<j1<<" and J2 with "<<j2<<".\nPut the first square to ("<<R1<<", "<<C1<<
            ").\nPut the second square to ("<<R2<<", "<<C2<<").";
            return 0;
        }
    }
    else if(~r1)for(string j1:st){
        str[r1][c1]=j1;
        if(valid()){
            cout<<"Solution exists.\nReplace J1 with "<<j1<<".\nPut the first square to ("<<R1<<", "<<C1<<
            ").\nPut the second square to ("<<R2<<", "<<C2<<").";
            return 0;
        }
    }
    else if(~r2)for(string j2:st){
        str[r2][c2]=j2;
        if(valid()){
            cout<<"Solution exists.\nReplace J2 with "<<j2<<".\nPut the first square to ("<<R1<<", "<<C1<<
            ").\nPut the second square to ("<<R2<<", "<<C2<<").";
            return 0;
        }
    }
    else{
        if(valid()){
            cout<<"Solution exists.\nThere are no jokers.\nPut the first square to ("<<R1<<", "<<C1<<
            ").\nPut the second square to ("<<R2<<", "<<C2<<").";
            return 0;
        }
    }
    cout<<"No solution.";
    return 0 ;
}

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <iterator>
#include <functional>
#include <algorithm>
#include <numeric>
#include <sstream>

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>

using namespace std;

const string kSuites = "JCDHS";
const string kRanks = "123456789TJQKA";

int GetSuite(char ch) {
	return kSuites.find_first_of(ch);
}

int GetRank(char ch) {
	return kRanks.find_first_of(ch);
}

struct Card {
	int suite, rank;

	Card(const string& str) {
		if (isdigit(str[1])) {
			suite = GetSuite(str[0]);
			rank = GetRank(str[1]);
		} else {
			suite = GetSuite(str[1]);
			rank = GetRank(str[0]);
		}
	}

	Card(int s, int r) : suite(s), rank(r) { }

	bool operator < (const Card& c) const {
		if (suite != c.suite) return suite < c.suite;
		return rank < c.rank;
	}

	bool operator == (const Card& c) const {
		return suite == c.suite && rank == c.rank;
	}

	bool IsJoker() const { return suite == GetSuite('J'); }

	string ToString() const {
		string ret(1, kRanks[rank]);
		ret += kSuites[suite];
		return ret;
	}
};

bool inside(int row, int col, int x, int y) {
	return x >= row && x < row + 3 && y >= col && y < col + 3;
}
// 0 0 1 4
bool overlaps(int r1, int c1, int r2, int c2) {
	for (int p = 0; p < 3; ++p)
		for (int q = 0; q < 3; ++q)
			if (inside(r1, c1, r2 + p, c2 + q) || inside(r2, c2, r1 + p, r1 + q))
				return true;
	return false;
}

bool good(const vector< vector<Card> >& board, int x, int y) {
	vector<int> suite_counts(kSuites.length()), ranks_seen(kRanks.length());
	for (int i = 0; i < 3; ++i) {
		if (x + i >= board.size()) return false;

		for (int j = 0; j < 3; ++j) {
			if (y + j >= board[x].size()) return false;

			++suite_counts[board[x + i][y + j].suite];
			++ranks_seen[board[x + i][y + j].rank];
		}
	}

	if (find(suite_counts.begin(), suite_counts.end(), 9) != suite_counts.end()) {
		return true;
	}

	for (int i = 0; i < ranks_seen.size(); ++i)
		if (ranks_seen[i] > 1) {
			return false;
		}

	return true;
}

bool check(const vector< vector<Card> >& board, pair<int, int>& p1, pair<int, int>& p2) {
	for (int x1 = 0; x1 < board.size(); ++x1) {
		for (int y1 = 0; y1 < board[x1].size(); ++y1) {
			for (int x2 = 0; x2 < board.size(); ++x2) {
				for (int y2 = 0; y2 < board[x2].size(); ++y2) {
					if (overlaps(x1, y1, x2, y2)) continue;

					if (good(board, x1, y1) && good(board, x2, y2)) {
						p1 = make_pair(x1, y1);
						p2 = make_pair(x2, y2);
						return true;
					}
				}
			}
		}
	}

	return false;
}

void PrintResult(int joker_index1, const Card& rep1, int joker_index2, const Card& rep2, const pair<int, int>& p1, const pair<int, int>& p2) {
	cout << "Solution exists." << endl;
	if (joker_index1 == -1 && joker_index2 == -1) {
		cout << "There are no jokers";
	}

	if (joker_index1 != -1) {
		cout << "Replace J" << joker_index1 << " with " << rep1.ToString();
	}
	if (joker_index2 != -1) {
		cout << " and J" << joker_index2 << " with " << rep2.ToString();
	}
	cout << "." << endl;

	cout << "Put the first square to (" << (p1.first + 1) << ", " << (p1.second + 1) << ")." << endl;
	cout << "Put the second square to (" << (p2.first + 1) << ", " << (p2.second + 1) << ")." << endl;
}

int main() {
	int N, M;
	cin >> N >> M;

	vector< vector<Card> > board(N);
	vector< pair<int, int> > joker_pos;
	set<Card> used;
	for (int i = 0; i < board.size(); ++i) {
		for (int j = 0; j < M; ++j) {
			string str;
			cin >> str;
			board[i].push_back(Card(str));

			if (board[i][j].IsJoker()) {
				joker_pos.push_back(make_pair(i, j));
			} else {
				used.insert(board[i][j]);
			}
		}
	}

	if (joker_pos.empty()) {
		pair<int, int> p1, p2;
		if (check(board, p1, p2)) {
			Card c(0, 0);
			PrintResult(-1, c, -1, c, p1, p2);
		} else {
			cout << "No solution." << endl;
		}
		return 0;
	}

	if (joker_pos.size() == 2 && board[joker_pos[0].first][joker_pos[0].second].rank != 0) {
		swap(joker_pos[0], joker_pos[1]);
	}

	for (int suite1 = 1; suite1 < kSuites.length(); ++suite1) {
		for (int rank1 = 1; rank1 < kRanks.length(); ++rank1) {
			Card rep1(suite1, rank1);
			if (used.find(rep1) != used.end()) continue;

			Card joker1_backup = board[joker_pos[0].first][joker_pos[0].second];
			board[joker_pos[0].first][joker_pos[0].second] = rep1;

			if (joker_pos.size() == 1) {
				pair<int, int> p1, p2;
				if (check(board, p1, p2)) {
					PrintResult(joker1_backup.rank + 1, rep1, -1, Card(0, 0), p1, p2);
					return 0;
				} else {
					board[joker_pos[0].first][joker_pos[0].second] = joker1_backup;
					continue;
				}
			} else {
				for (int suite2 = 1; suite2 < kSuites.length(); ++suite2) {
					for (int rank2 = 1; rank2 < kRanks.length(); ++rank2) {
						Card rep2(suite2, rank2);
						if (rep2 == rep1 || used.find(rep2) != used.end()) continue;

						Card joker2_backup = board[joker_pos[1].first][joker_pos[1].second];
						board[joker_pos[1].first][joker_pos[1].second] = rep2;
						pair<int, int> p1, p2;
						if (check(board, p1, p2)) {
							PrintResult(joker1_backup.rank + 1, rep1, joker2_backup.rank + 1, rep2, p1, p2);
							return 0;
						} else {
							board[joker_pos[1].first][joker_pos[1].second] = joker2_backup;
							continue;
						}
					}
				}
			}
			board[joker_pos[0].first][joker_pos[0].second] = joker1_backup;
		}
	}

	cout << "No solution." << endl;
}

#include <iostream>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

#define ll long long

map <string, bool> used;
vector <string> vs[60];
vector <string> sp;

int jx1, jy1, jx2, jy2;
int px1, py1, px2, py2;
int n, m, cnt = 0;

string make_str(char a, char b) {
	string s;
	s.push_back(a);
	s.push_back(b);
	return s;
}

void init() {
	char q[] = {'T', 'Q', 'K', 'A', 'J'};
	for(int i = 2; i <= 9; i ++) {
		char ch = i + '0';
		sp.push_back(make_str(ch, 'C'));
		sp.push_back(make_str(ch, 'D'));
		sp.push_back(make_str(ch, 'H'));
		sp.push_back(make_str(ch, 'S'));
	}
	for(int i = 0; i < 5; i ++) {
		char ch = q[i];
		sp.push_back(make_str(ch, 'C'));
		sp.push_back(make_str(ch, 'D'));
		sp.push_back(make_str(ch, 'H'));
		sp.push_back(make_str(ch, 'S'));
	}
}

bool is_clear(int x, int y) {
	map <char, int> mp1;
	map <char, int> mp2;
	for(int i = x; i < x + 3; i ++)
		for(int j = y; j < y + 3; j ++) {
			string s = vs[i][j];
			char ch = s[0];
			if (!mp1.count(ch))
				mp1[ch] = 1;
			else mp1[ch] ++;
			ch = s[1];
			if (!mp2.count(ch))
				mp2[ch] = 1;
			else mp2[ch] ++;
		}
	int k1 = 0, k2 = 0;
	map <char, int> :: iterator it;
	for(it = mp1.begin(); it != mp1.end(); it ++)
		if ((*it).second > 1)
			k1 ++;
	for(it = mp2.begin(); it != mp2.end(); it ++)
		if ((*it).second != 9)
			k2 ++;
	return (k1 == 0 || k2 == 0);
}

bool is_all_clear() {
	bool f = true;
	for(int x1 = 0; n - x1 >= 3; x1 ++) {
		for(int y1 = 0; m - y1 >= 3; y1 ++) {
			for(int x2 = 0; n - x2 >= 3; x2 ++) {
				for(int y2 = 0; m - y2 >= 3; y2 ++) {
					if (abs(x1 - x2) < 3 && abs(y1 - y2) < 3)
						continue;
					if (is_clear(x1, y1) && is_clear(x2, y2)) {
						px1 = x1;
						py1 = y1;
						px2 = x2;
						py2 = y2;
						return true;
					}
				}
			}
		}
	}
	return false;
}

void my_print(int w) {
		if (!w && is_all_clear()) {
			cout << "Solution exists.\n";
			cout << "There are no jokers.\n";
			cout << "Put the first square to (" << px1+1 << ", " << py1+1 << ")." << endl;
			cout << "Put the second square to (" << px2+1 << ", " << py2+1 << ")." << endl;
		}
		else if (w) {
			if (w == 1) {
				if (jx1 == -1) {
					swap(jx1, jx2);
					swap(jy1, jy2);
				}
				string s = vs[jx1][jy1];
				for(int i = 0; i < sp.size(); i ++) {
					if (used.count(sp[i]))
						continue;
					vs[jx1][jy1] = sp[i];
					if (is_all_clear()) {
						cout << "Solution exists.\n";
						cout << "Replace " << s << " with " << sp[i] << ".\n";
						cout << "Put the first square to (" << px1+1 << ", " << py1+1 << ")." << endl;
						cout << "Put the second square to (" << px2+1 << ", " << py2+1 << ")." << endl;
						return;
					}
				}
				cout << "No solution.";
			}
			else {
				string s1 = vs[jx1][jy1];
				string s2 = vs[jx2][jy2];
				for(int i = 0; i < sp.size(); i ++) {
					for(int j = 0; j < sp.size(); j ++) {
						if (sp[i] == sp[j] || used.count(sp[i]) || used.count(sp[j]))
							continue;
						vs[jx1][jy1] = sp[i];
						vs[jx2][jy2] = sp[j];
						if (is_all_clear()) {
							cout << "Solution exists.\n";
							cout << "Replace J1 with " << sp[i] << " and J2 with " << sp[j] << ".\n";
							/*cout << "Replace " << s1 << " with " << sp[i] << ".\n";
							cout << "Replace " << s2 << " with " << sp[j] << ".\n";*/
							cout << "Put the first square to (" << px1+1 << ", " << py1+1 << ")." << endl;
							cout << "Put the second square to (" << px2+1 << ", " << py2+1 << ")." << endl;
							return;
						}
					}
				}
				cout << "No solution.";
			}
		}
		else cout << "No solution.";
}

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	cin >> n >> m;
	jx1 = jy1 = jx2= jy2 = -1;
	px1 = py1 = px2 = py2 = -1;
	init();
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < m; j ++) {
			string s;
			cin >> s;
			vs[i].push_back(s);
			used[s] = true;
			if (s == "J1") {
				jx1 = i;
				jy1 = j;
				cnt ++;
			}
			if (s == "J2"){
				jx2 = i;
				jy2 = j;
				cnt ++;
			}
		}
	my_print(cnt);

}

#include<bits/stdc++.h>
//#include<ctime>
//#include <stdlib.h>
using namespace std;
#define time ios_base::sync_with_stdio(0);cin.tie(0);
#define dpp(arr,val) memset(arr,val,sizeof (arr))
#define ll long long
#define ull unsigned long long
#define ld long double
#define PQ priority_queue
#define pii pair<int,int>
#define pll pair<ll,ll>
#define S second
#define F first
//const int oo=0x3f3f3f3f ;

double eps= 0.0000001;
double pi=acos(-1);
//bool isprime(ll value){int cnt=0;for (ll i=1; i*i<=value; i++){if (value%i==0){cnt++;if (i*i!=value){cnt++;}}}if (cnt==2){return true;}else{return false;}}
ll fastpower(ll b,ll p)
{
    ll ans=1;
    while(p)
    {
        if (p%2)
        {
            ans=(ans*b);
        }
        b=b*b;
        p/=2;
    }
    return ans;
}
ll fastpowermod(ll b,ll p,ll m)
{
    ll ans=1;
    while(p)
    {
        if (p%2)
        {
            ans=((ans%m)*(b%m))%m;
        }
        b=((b%m)*(b%m))%m;
        p/=2;
    }
    return ans%m;
}
string  makeitstring(ll n)
{
    string ans;
    bool ch=0;
    if (n<0)
    {
        n*=-1;
        ch=1;
    }
    if (n==0)
    {
        ans="0";
    };
    while (n)
    {
        ll mo=n%10;
        mo+=48;
        char m=mo;
        ans=m+ans;
        n/=10;
    }
    if (ch)
    {
        ans='-'+ans;
    }
    return ans;
}
// gold bach (using induction)theory any number can be expressed as the sum of three prime numbers
// if num>2 and any even number greater than two can be expressed as the sum of two prime numbers
//ll ny[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
//ll ly[12]= {31,29,31,30,31,30,31,31,30,31,30,31};
//bool valid(int x,int y,int n,int m){return (x>=0&&y<m&&x<n&&y>=0);}
//ll ncr(ll n,ll r){ll ans=1;r=min(r,n-r);for (int i=1;i<=r;i++){ans*=(n-r+i);ans/=i;}return ans;}
//bool checksqrt(double f){return (sqrt(f)*sqrt(f)==f);}
//struct element{ll l,r,index;};
//bool cmp(element a,element b){if (a.l==b.l){return a.r>b.r;}else {return a.l<b.l ;}}
//bool isPowerOfTwo(ll x){return (x && !(x & (x - 1)));}
//bool checkpower(long double n){long double f=sqrt(n);return !(f-floor(f));}
//string multiply(string one,string two){string s;int cnt=0;if (one[0]=='-'){reverse(one.begin(),one.end());one.pop_back();reverse(one.begin(),one.end());cnt++;}if (two[0]=='-'){reverse(two.begin(),two.end());two.pop_back();reverse(two.begin(),two.end());cnt++;}int n1=one.size();int n2=two.size();vector<int>ans(n1+n2,0);int pos1=0;int pos2=0;for (int i=n1-1; i>=0; i--){int carry=0;int digit1=one[i]-'0';pos2=0;for (int j=n2-1; j>=0; j--){int digit2=two[j]-'0';int sum=(digit1*digit2)+ans[pos1+pos2]+carry;carry=sum/10;ans[pos1+pos2]=sum%10;pos2++;}if (carry>0){ans[pos1+pos2]+=carry;}pos1++;}bool check=0;for (int i=ans.size()-1; i>=0; i--){if (ans[i]){check=true;}if (check){s+=makeitstring(ans[i]);}}if(!check){s+='0';}if (cnt%2){s='-'+s;}return s;}
//double eps =1e-9;
//void comparing_doubles(double f,double s){if (f-s>eps){cout<<">"<<endl;}else if (f-s<-eps){cout<<"<"<<endl;}else{// if (abs(f-s)<eps)cout<<"=";}}
bool compare(double f,double s)
{
    return  (abs(f-s)<eps);
}
ll gcd(ll a,ll b)
{
    while(b!=0)
    {
        ll a2=a;
        a=b;
        b=a2%b;
    }
    return a;
}
//ll solve(ll n){return (n*(n+1))/2;}
//ll cumsumrule(ll l,ll r,vector<ll>&cum){if (!l){return cum[r];}else {return cum[r]-cum[l-1];}}
/*
struct point{
    ll x,y;
};
bool eq(point p1,point p2){return (p1.x==p2.x&&p1.y==p2.y);}
ll distance(point p1,point p2){ll dis=0;dis+=((p1.x-p2.x)*(p1.x-p2.x));dis+=((p1.y-p2.y)*(p1.y-p2.y));return dis;}
bool sq(point p1,point p2,point p3,point p4)
{
    if ((eq(p1,p2)||eq(p1,p3)||eq(p1,p4))||(eq(p2,p3)||eq(p2,p4))||eq(p3,p4))
    {
        return 0;
    }

    ll d2=distance(p1,p2);
    ll d3=distance(p1,p3);
    ll d4=distance(p1,p4);
    if (d2==d3&&2*d2==d4&&2*d2==distance(p2,p3)) {
    ll d=distance(p2,p4);return (d==distance(p3,p4)&&d==d2);
    }
    if (d3==d4&&2*d3==d2&&2*d3==distance(p3, p4)) {
        ll d=distance(p2, p3);
        return (d==distance(p2,p4)&&d==d3);
    }
    if (d2==d4&&2*d2==d3&&2*d2==distance(p2,p4)){
        ll d = distance(p2, p3);
        return (d==distance(p3, p4)&&d==d2);
    }

    return 0;
}

void rot(ll &x1,ll &y1,ll x2, ll y2)
{
 ll xf=x2-(y1-y2);
 ll yf=y2+(x1-x2);
 x1=xf;
 y1=yf;

}
*/
/*
int memo[MAX][MAX];

struct state {
	int i, j;
	bool isProcessed;
	state(int i, int j) : i(i), j(j), isProcessed(0) {}
};

int best(int i, int j) {
	stack<state> st;
	state cur = state(i, j);
	st.push(cur);

	while(!st.empty()) {
		cur = st.top(), i = cur.i, j = cur.j, st.pop();
		//base case handling
		if(memo[i][j] == -1) {
			if(i >= j)
				memo[i][j] = 0;
			else if(!cur.isProcessed) {
				//push me again to be processed later
				cur.isProcessed = 1;
				st.push(cur);
				//push my sub-states
				st.push(state(i+1, j-1));
				st.push(state(i+1, j));
				st.push(state(i, j-1));
			} else // Evaluate
				memo[i][j] = min(memo[i+1][j-1] + (A[i] != A[j]), min(memo[i][j-1]+1, memo[i+1][j]+1));
		}
	}

	return memo[cur.i][cur.j];
}*/

/*void unionrule(int i,ll l,ll cnt)
{
    if (i==m){if (cnt%2==0){ans+=(n/l);}else {ans-=(n/l);}return ;}
    // add 1 set elements
    // subtract 2 set elements
    // add 3 set elements subtract 4 set elements etc.
    unionrule(i+1,(l*a[i])/gcd(l,a[i]),cnt+1);
    unionrule(i+1,l,cnt);
}
*/
//priority_queue<int,vector<int>,greater<int> >pqmin;
//priority_queue<pair<pii,pii>,vector<pair<pii,pii>>,greater<pair<pii,pii>>>pqmin;
//int dx[]={1,0,-1,0};
//int dy[]={0,1,0,-1};
/*

// C++ program for implementation of KMP pattern searching
// algorithm
#include <bits/stdc++.h>

void computeLPSArray(char* pat, int M, int* lps);

// Prints occurrences of txt[] in pat[]
void KMPSearch(char* pat, char* txt)
{
    int M = strlen(pat);
    int N = strlen(txt);

    // create lps[] that will hold the longest prefix suffix
    // values for pattern
    int lps[M];

    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps);

    int i = 0; // index for txt[]
    int j = 0; // index for pat[]
    while (i < N) {
        if (pat[j] == txt[i]) {
            j++;
            i++;
        }

        if (j == M) {
            printf("Found pattern at index %d ", i - j);
            j = lps[j - 1];
        }

        // mismatch after j matches
        else if (i < N && pat[j] != txt[i]) {
            // Do not match lps[0..lps[j-1]] characters,
            // they will match anyway
            if (j != 0)
                j = lps[j - 1];
            else
                i = i + 1;
        }
    }
}

// Fills lps[] for given patttern pat[0..M-1]
void computeLPSArray(char* pat, int M, int* lps)
{
    // length of the previous longest prefix suffix
    int len = 0;

    lps[0] = 0; // lps[0] is always 0

    // the loop calculates lps[i] for i = 1 to M-1
    int i = 1;
    while (i < M) {
        if (pat[i] == pat[len]) {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            // This is tricky. Consider the example.
            // AAACAAAA and i = 7. The idea is similar
            // to search step.
            if (len != 0) {
                len = lps[len - 1];

                // Also, note that we do not increment
                // i here
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}

// Driver program to test above function
int main()
{
    char txt[] = "ABABDABACDABABCABAB";
    char pat[] = "ABABCABAB";
    KMPSearch(pat, txt);
    return 0;
}

*/
/*
// A C++ program to find articulation points in an undirected graph
#include<iostream>
#include <list>
#define NIL -1
using namespace std;

// A class that represents an undirected graph
class Graph
{
    int V;    // No. of vertices
    list<int> *adj;    // A dynamic array of adjacency lists
    void APUtil(int v, bool visited[], int disc[], int low[],
                int parent[], bool ap[]);
public:
    Graph(int V);   // Constructor
    void addEdge(int v, int w);   // function to add an edge to graph
    void AP();    // prints articulation points
};

Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w);
    adj[w].push_back(v);  // Note: the graph is undirected
}

// A recursive function that find articulation points using DFS traversal
// u --> The vertex to be visited next
// visited[] --> keeps tract of visited vertices
// disc[] --> Stores discovery times of visited vertices
// parent[] --> Stores parent vertices in DFS tree
// ap[] --> Store articulation points
void Graph::APUtil(int u, bool visited[], int disc[],
                                      int low[], int parent[], bool ap[])
{
    // A static variable is used for simplicity, we can avoid use of static
    // variable by passing a pointer.
    static int time = 0;

    // Count of children in DFS Tree
    int children = 0;

    // Mark the current node as visited
    visited[u] = true;

    // Initialize discovery time and low value
    disc[u] = low[u] = ++time;

    // Go through all vertices aadjacent to this
    list<int>::iterator i;
    for (i = adj[u].begin(); i != adj[u].end(); ++i)
    {
        int v = *i;  // v is current adjacent of u

        // If v is not visited yet, then make it a child of u
        // in DFS tree and recur for it
        if (!visited[v])
        {
            children++;
            parent[v] = u;
            APUtil(v, visited, disc, low, parent, ap);

            // Check if the subtree rooted with v has a connection to
            // one of the ancestors of u
            low[u]  = min(low[u], low[v]);

            // u is an articulation point in following cases

            // (1) u is root of DFS tree and has two or more chilren.
            if (parent[u] == NIL && children > 1)
               ap[u] = true;

            // (2) If u is not root and low value of one of its child is more
            // than discovery value of u.
            if (parent[u] != NIL && low[v] >= disc[u])
               ap[u] = true;
        }

        // Update low value of u for parent function calls.
        else if (v != parent[u])
            low[u]  = min(low[u], disc[v]);
    }
}

// The function to do DFS traversal. It uses recursive function APUtil()
void Graph::AP()
{
    // Mark all the vertices as not visited
    bool *visited = new bool[V];
    int *disc = new int[V];
    int *low = new int[V];
    int *parent = new int[V];
    bool *ap = new bool[V]; // To store articulation points

    // Initialize parent and visited, and ap(articulation point) arrays
    for (int i = 0; i < V; i++)
    {
        parent[i] = NIL;
        visited[i] = false;
        ap[i] = false;
    }

    // Call the recursive helper function to find articulation points
    // in DFS tree rooted with vertex 'i'
    for (int i = 0; i < V; i++)
        if (visited[i] == false)
            APUtil(i, visited, disc, low, parent, ap);

    // Now ap[] contains articulation points, print them
    for (int i = 0; i < V; i++)
        if (ap[i] == true)
            cout << i << " ";
}
*/
/*
int parent[N];
int sz[N];
ll cnt[N];
void st()
{

   for (int i=0;i<N;i++)
   {
       parent[i]=i;
       sz[i]=1;

   }
}
int findp(int node)
{
    if (parent[node]==node)
    {
        return node;
    }
    return parent[node]=findp(parent[node]);
}
void unionnodes(int a,int b,int val)
{
    int pa=findp(a);
    int pb=findp(b);
    if (pa==pb)
    {
     return ;
    }
    if (sz[pa]>=sz[pb])
    {
        sz[pa]+=sz[pb];
        parent[pb]=pa;
    }
    else {
        sz[pb]+=sz[pa];
        parent[pa]=pb;
    }
    return ;
}*/
//int pal[N];
/*string findSum(string str1, string str2)
{
    // Before proceeding further, make sure length
    // of str2 is larger.
    if (str1.length() > str2.length())
        swap(str1, str2);

    // Take an empty string for storing result
    string str = "";

    // Calculate lenght of both string
    int n1 = str1.length(), n2 = str2.length();

    // Reverse both of strings
    reverse(str1.begin(), str1.end());
    reverse(str2.begin(), str2.end());

    int carry = 0;
    for (int i=0; i<n1; i++)
    {
        // Do school mathematics, compute sum of
        // current digits and carry
        int sum = ((str1[i]-'0')+(str2[i]-'0')+carry);
        str.push_back(sum%10 + '0');

        // Calculate carry for next step
        carry = sum/10;
    }

    // Add remaining digits of larger number
    for (int i=n1; i<n2; i++)
    {
        int sum = ((str2[i]-'0')+carry);
        str.push_back(sum%10 + '0');
        carry = sum/10;
    }

    // Add remaining carry
    if (carry)
        str.push_back(carry+'0');

    // reverse resultant string
    reverse(str.begin(), str.end());

    return str;
}*/
/*const int N=1e3+1;
int n,m;
int dp[N][N];
bool vis[N][N];
string arr[N][N];
int col(string c)
{
    int sz=c.size();
    int cur=1;
    int ans=0;
    for (int i=sz-1;i>=0;i--)
    {
     ans+=(c[i]-'A'+1)*cur;
     cur*=26;
    }
    return ans;
}
void vecki(string s,vector<pii>&inde)
{

    string r="";
    string c="";
    for (int i=1;i<s.size();)
    {
    if (s[i]=='+'){inde.push_back({atoi(r.c_str())-1,col(c)-1});r=c="";i++;}
    if (isalpha(s[i])){c+=s[i];i++;}
    else if (isdigit(s[i])){r+=s[i];i++;}

    }
    if(r!=""&&c!=""){inde.push_back({atoi(r.c_str())-1,col(c)-1});}
}
int conv(char c)
{
    if (isalpha(c))
    {
       c-='A';
       return (int)c;
    }
    else if(isdigit(c)){c-='0';return (int)c-1;}

}

int solve(int i,int j)
{

    if (vis[i][j]){return dp[i][j];}
    string s=arr[i][j];
    vector<pii>inde;
    vecki(s,inde);
    int sum=0;
    for (int i=0;i<inde.size();i++)
    {
        sum+=solve(inde[i].first,inde[i].second);

    }
    vis[i][j]=1;
    return dp[i][j]=sum;

}*/

/*ll countbit(ll n)
{
    int ans=0;
    while(n)
    {
        if (n%2){ans++;}
        n/=2;
    }
    return ans;
}
*/
/*const int N=1e6+10;
int parent[N];
vector<pll>adj[N];
ll dist[N];
void printpath(int node)
{
    if (parent[node]==-1){cout<<node<<" ";return ;}
    else {
    printpath(parent[node]);
    cout<<node<<" ";
    }
}
void init()
{

    for (int i=0;i<N;i++)
    {
        parent[i]=-1;
        dist[i]=LLONG_MAX;
    }
}
void dijkestra(ll src)
{
	priority_queue<pll>pq;
	pq.push({0,src});
    dist[src]=0;
    while(!pq.empty())
    {

        ll p=pq.top().second;
        ll w=-1*pq.top().first;
        pq.pop();
        for (auto ch:adj[p])
        {
            if (ch.first+w<dist[ch.second])
            {
             parent[ch.second]=p;
             dist[ch.second]=ch.first+w;
             pq.push({dist[ch.second]*-1,ch.second});
            }
        }
    }
}*/
/*ll fact[N];
ll invfact[N];
ll modInverse(ll a,ll m)
{
    int m0 = m;
    int y = 0, x = 1;

    if (m == 1)
      return 0;

    while (a > 1)
    {
        // q is quotient
        int q = a / m;
        int t = m;

        // m is remainder now, process same as
        // Euclid's algo
        m = a % m, a = t;
        t = y;

        // Update y and x
        y = x - q * y;
        x = t;
    }

    // Make x positive
    if (x < 0)
       x += m0;

    return x;
}
void initfact()
{
    fact[0]=1;
    for (int i=1;i<N;i++)
    {
        fact[i]=fact[i-1]*i;
        fact[i]%=M;
    }
    for (int i=0;i<N;i++)
    {
        invfact[i]=modInverse(fact[i],M)%M;

    }
}
ll npr(ll n,ll r)
{
    return (fact[n]*invfact[n-r])%M;
}*/
int f=-1,s=-1,s2=-1,f2=-1;
int n,m;
char rnk[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};//13
char suit[]={'C','D','H','S'};//4
string arr[18][18];
bool checksuit(int x,int y)
{
    map<char,int>cnt;
    for (int i=0;i<3;i++)
    {
        for (int j=0;j<3;j++)
        {
            cnt[arr[i+x][j+y][1]]++;
        }
    }
    for (int i=0;i<4;i++)
    {
        if (cnt[suit[i]]==9){return 1;}
    }
    return 0;
}
bool checkrank(int x,int y)
{

    map<char,int>cnt;
    for (int i=0;i<3;i++)
    {
        for (int j=0;j<3;j++)
        {
            cnt[arr[i+x][j+y][0]]++;
        }
    }
    for (int i=0;i<13;i++)
    {
        if (cnt[rnk[i]]>1){return 0;}
    }
    return 1;

}
bool checkrepeat()
{
    map<string,int>cnt;
    for (int i=0;i<n;i++)
    {
        for (int j=0;j<m;j++)
        {
            cnt[arr[i][j]]++;
            if (cnt[arr[i][j]]==2){return 0;}
        }
    }
    return 1;
}
bool checkrnksuit(int i,int j,int k,int l)
{
    return (checkrank(k,l)||checksuit(k,l))&&(checkrank(i,j)||checksuit(i,j));
}

bool checksoliter()
{
    for (int i=0;i<n-2;i++)
    {
        for (int j=0;j<m-2;j++)
        {
            for (int k=0;k<n-2;k++)
            {
                for (int l=0;l<m-2;l++)
                {
                    if (abs(k-i)<3&&abs(l-j)<3){continue;}

                    if (checkrnksuit(i,j,k,l)){

                        cout<<"Solution exists."<<endl;
                       if (f!=-1&&f2!=-1){cout<<"Replace J1 with "<<arr[f][s]<<" and J2 with " <<arr[f2][s2]<<"."<<endl;}
                       else if(f!=-1){
                        cout<<"Replace J1 with "<<arr[f][s]<<"."<< endl;
                       }
                       else if(f2!=-1){cout<<"Replace J2 with "<<arr[f2][s2]<< "." << endl;}
                       else{cout<<"There are no jokers."<<endl;}
                     cout<<"Put the first square to ("<<i+1<<", "<<j+1<<")." << endl;
                    cout<<"Put the second square to ("<<k+1<<", "<<l+1<< ")." << endl;
                    return 1;
                    }
                }
            }
        }
    }
    return 0;
}
int main()
{

    //myf.open("file.txt");
    //freopen("fractions.in", "r", stdin);
    //freopen("output.txt", "w", stdout);
    time;
    cin>>n>>m;
    for (int i=0;i<n;i++)
    {

        for (int j=0;j<m;j++)
        {
            cin>>arr[i][j];
            if (arr[i][j]=="J1")
            {
                f=i,s=j;
            }
            if(arr[i][j]=="J2"){
                f2=i;
                s2=j;
            }
        }
    }
    for (int i=0;i<13;i++)
    {
        for (int j=0;j<4;j++)
        {
            string sch;
            sch+=rnk[i];
            sch+=suit[j];
           if (f!=-1&&s!=-1){arr[f][s]=sch;}

    for (int i=0;i<13;i++)
    {
        for (int j=0;j<4;j++)
        {
            string sch2;
            sch2+=rnk[i];
            sch2+=suit[j];
           if (f2!=-1&&s2!=-1)
           {
               arr[f2][s2]=sch2;
            if (checkrepeat()&&checksoliter()){return 0;}

           }
           else if (checkrepeat()&&checksoliter()){return 0;}

        }

    }
    }
}
 cout<<"No solution.";

    return 0;

}

#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

char buf[10099];

pair<char, char> s[18][18];

char num[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char suit[] = {'C', 'D', 'H', 'S'};

int abs(int x) {
	return x > 0 ? x : -x;
}

bool gao(int x, int y, pair<char, char> s[][18]) {
	set<char> num, suit;
	for (int i = x; i < x + 3; ++i) {
		for (int j = y; j < y + 3; ++j) {
			num.insert(s[i][j].first);
			suit.insert(s[i][j].second);
		}
	}

//	printf("%d %d %d %d\n", x, y, num.size(), suit.size());

	return (int)num.size() == 9 || (int)suit.size() == 1;
}

int main() {
	int n, m;

	scanf("%d%d", &n, &m);

	pair<int, int> J1(-1, -1), J2(-1, -1);

	set<pair<char, char> > rest;

	for (int i = 0; i < 13; ++i) {
		for (int j = 0; j < 4; ++j) {
			rest.insert(make_pair(num[i], suit[j]));
		}
	}

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			scanf(" %c%c", &s[i][j].first, &s[i][j].second);
			if (s[i][j].first == 'J' && (s[i][j].second == '1' || s[i][j].second == '2')) {
				if (s[i][j].second == '1') {
					J1.first = i;
					J1.second = j;
				} else {
					J2.first = i;
					J2.second = j;
				}
			} else {
				rest.erase(s[i][j]);
			}
		}
	}

//	printf("%d %d %d %d\n", J1.first, J1.second, J2.first, J2.second);

	if (J1.first != -1 || J2.first != -1) {
		if (J1.first == -1 || J2.first == -1) {
			int jd;
			if (J1.first != -1) {
				jd = 1;
			} else {
				jd = 2;
				J1 = J2;
			}

			for (set<pair<char, char> >::iterator si = rest.begin(); si != rest.end(); ++si) {
				pair<char, char> card = *si;
				s[J1.first][J1.second] = card;
//				printf("%c%c\n", card.first, card.second);
				vector<pair<int, int> > ans;
				for (int i = 0; i < n - 2; ++i) {
					for (int j = 0; j < m - 2; ++j) {
						if (gao(i, j, s)) {
							ans.push_back(make_pair(i, j));
						}
					}
				}

				for (int i = 0; i < ans.size(); ++i) {
					for (int j = i + 1; j < ans.size(); ++j) {
						if (abs(ans[i].first - ans[j].first) >= 3 || abs(ans[i].second - ans[j].second) >= 3) {
							printf("Solution exists.\n");
							printf("Replace J%d with %c%c.\n", jd, card.first, card.second);
							printf("Put the first square to (%d, %d).\n", ans[i].first + 1, ans[i].second + 1);
							printf("Put the second square to (%d, %d).\n", ans[j].first + 1, ans[j].second + 1);
							return 0;
						}
					}
				}
			}
		} else {
			for (set<pair<char, char> >::iterator si = rest.begin(); si != rest.end(); ++si) {
				pair<char, char> card = *si;
				s[J1.first][J1.second] = card;
				for (set<pair<char, char> >::iterator sj = rest.begin(); sj != rest.end(); ++sj) {
					if (sj == si) {
						continue;
					}
					s[J2.first][J2.second] = *sj;
					vector<pair<int, int> > ans;
					for (int i = 0; i <= n - 3; ++i) {
						for (int j = 0; j <= m - 3; ++j) {
							if (gao(i, j, s)) {
								ans.push_back(make_pair(i, j));
							}
						}
					}

					for (int i = 0; i < ans.size(); ++i) {
						for (int j = i + 1; j < ans.size(); ++j) {
							if (abs(ans[i].first - ans[j].first) >= 3 || abs(ans[i].second - ans[j].second) >= 3) {
								printf("Solution exists.\n");
								printf("Replace J1 with %c%c and J2 with %c%c.\n", card.first, card.second, sj->first, sj->second);
								printf("Put the first square to (%d, %d).\n", ans[i].first + 1, ans[i].second + 1);
								printf("Put the second square to (%d, %d).\n", ans[j].first + 1, ans[j].second + 1);
								return 0;
							}
						}
					}
				}
			}
		}
	} else {
		vector<pair<int, int> > ans;
		for (int i = 0; i <= n - 3; ++i) {
			for (int j = 0; j <= m - 3; ++j) {
				if (gao(i, j, s)) {
					ans.push_back(make_pair(i, j));
				}
			}
		}
		for (int i = 0; i < ans.size(); ++i) {
			for (int j = i + 1; j < ans.size(); ++j) {
				if (abs(ans[i].first - ans[j].first) >= 3 || abs(ans[i].second - ans[j].second) >= 3) {
					printf("Solution exists.\n");
					printf("There are no jokers.\n");
					printf("Put the first square to (%d, %d).\n", ans[i].first + 1, ans[i].second + 1);
					printf("Put the second square to (%d, %d).\n", ans[j].first + 1, ans[j].second + 1);
					return 0;
				}
			}
		}
	}

	puts("No solution.");
	return 0;
}

#include <cctype>
#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <list>
#include <deque>
#include <stack>
#include <map>
#include <utility>
#include <cstring>
#include <sstream>
#include <bitset>
#include <assert.h>
#include <iomanip>
#include <climits>
#include <cstdio>

#define DEBUG_FLAG 1
#if DEBUG_FLAG
#define DBG(z) cout << #z << " : " << (z) << "\n";
#define DBY(x,y) cout << #x << " : " << (x) <<" , "<< #y << " : "<< (y) << "\n";
#define DBZ(x,y,z) cout << #x << " : " << (x) <<" , "<< #y << " : "<< (y) << " , " << #z << " : " << (z) << "\n";
#else
#define DBG(z)
#define DBY(x,y)
#define DBZ(x,y,z)
#endif

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset((x),(y),sizeof((x)))
#define all(c) c.begin(),c.end()

#define PI 3.1415926535
#define d(i,j) sqrt((a[(i)].x-a[(j)].x)*(a[(i)].x-a[(j)].x)+(a[(i)].y-a[(j)].y)*(a[(i)].y-a[(j)].y))
#define kv(i) i*i

using namespace std;
using namespace __gnu_cxx;

int n,m,x,x2,y,y2;
string s[20][20];
bool vis[20][20];
int starti,startj,start1i,start1j;
string card[]={"2S","2C","2D","2H","3S","3C","3D","3H","4S","4C","4D","4H","5S","5C","5D","5H","6S","6C","6D","6H","7S","7C","7D","7H","8S","8C","8D","8H","9S","9C","9D","9H","TS","TC","TD","TH","AS","AC","AD","AH","JS","JC","JD","JH","QS","QC","QD","QH","KS","KC","KD","KH"};
vector<int> ans,ans1;

int get(string c)//A - 1, T- 10 , J-11, Q-12, K-13
{
    if(c[0]>='2' && c[0]<='9')
        return c[0]-'0';
    if(c[0]=='A')   return 1;
    if(c[0]=='T')   return 10;
    if(c[0]=='J')   return 11;
    if(c[0]=='Q')   return 12;
    if(c[0]=='K')   return 13;
}

bool samesuit(int beginx, int beginy)
{
    char suit=s[beginx][beginy][1];
    for(int i=beginx;i<beginx+3;i++)
        for(int j=beginy;j<beginy+3;j++)
            if(s[i][j][1]!=suit)// || vis[i][j])
                return false;
    return true;
}

bool rank(int beginx, int beginy)
{
    bool r[15];
    ms(r,0);
    for(int i=beginx;i<beginx+3;i++)
        for(int j=beginy;j<beginy+3;j++){
            if(r[get(s[i][j])])
                return false;
            r[get(s[i][j])]=1;
        }
    return true;
}

bool test1()
{
    for(int i=0;i<ans.size();i++)
        for(int j=i+1;j<ans.size();j++)
            if(max(ans[i],ans[j])>=min(ans[i],ans[j])+3 || max(ans1[i],ans1[j])>=min(ans1[i],ans1[j])+3)
            {
                starti=ans[i],startj=ans1[i],start1i=ans[j],start1j=ans1[j];
                return true;
            }
    return false;
}

bool test()
{
    ms(vis,0);

    int cnt=0;
    ans.clear(),ans1.clear();
    for(int i=0;i<n-2;i++)
        for(int j=0;j<m-2;j++)
        {
          /*  if(s[x][y]=="QC" && s[x2][y2]=="TC"){
                cout<<i<<" "<<j<<" "<<samesuit(i,j)<<" "<<rank(i,j)<<"\n";
                if(samesuit(i,j) || rank(i,j))
                    DBY(i+1,j+1);
            }*/
            if(samesuit(i,j)){
                cnt++;
                ans.pb(i+1),ans1.pb(j+1);
            }
            else if(rank(i,j)){
                cnt++;
                ans.pb(i+1),ans1.pb(j+1);
            }
        }
    if(cnt<2)
        return false;
    return test1();
}

void output()
{
    cout<<"Put the first square to ("<<starti<<", "<<startj<<").\n";
    cout<<"Put the second square to ("<<start1i<<", "<<start1j<<").\n";
}

int main()
{
    int i,j,k;
    bool ima[52];
    ms(ima,0);

    x=x2=y=y2=-1;
    cin>>n>>m;
    for(i=0;i<n;i++)
        for(j=0;j<m;j++){
            cin>>s[i][j];
            if(s[i][j]=="J1")
                x=i,y=j;
            else if(s[i][j]=="J2")
                x2=i,y2=j;
            else
                for(k=0;k<52;k++)
                    if(card[k]==s[i][j])
                    {
                        ima[k]=1;
                        break;
                    }
        }
   // for(i=0;i<52;i++)
     //   DBZ(i,card[i],ima[i]);
    if(x==-1 && x2==-1){
        if(test()){
            cout<<"Solution exists.\n";
            cout<<"There are no jokers.\n";
            output();
        }
        else
            cout<<"No solution.\n";
        return 0;
    }
    if(x==-1 && x2!=-1){
        for(i=0;i<52;i++)    if(!ima[i]){
            s[x2][y2]=card[i];
            if(test()){
                cout<<"Solution exists.\n";
                cout<<"Replace J2 with "<<card[i]<<".\n";
                output();
                return 0;
            }
        }
        cout<<"No solution.\n";
        return 0;
    }
    if(x2==-1 && x!=-1){
        for(i=0;i<52;i++)    if(!ima[i]){
            s[x][y]=card[i];
            if(test()){
                cout<<"Solution exists.\n";
                cout<<"Replace J1 with "<<card[i]<<".\n";
                output();
                return 0;
            }
        }
        cout<<"No solution.\n";
        return 0;
    }
    if(x!=-1 && x2!=-1){
        for(i=0;i<52;i++)    if(!ima[i])
            for(j=0;j<52;j++)    if(!ima[j] && i!=j){
                s[x][y]=card[i],s[x2][y2]=card[j];
                if(test()){
                    cout<<"Solution exists.\n";
                    cout<<"Replace J1 with "<<card[i]<<" and J2 with "<<card[j]<<".\n";
                    output();
                    return 0;
                }
            }
        cout<<"No solution.\n";
        return 0;
    }

    return 0;
}

#include <bits/stdc++.h>
#define assem99 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define ld long double
#define endll '\n'
#define sz(a) (int)(a).size()
#define RWFile freopen("string.in.txt","r",stdin); freopen("string.out.txt","w",stdout);
int dx[] = { 0, -1, 0, 1, -1, 1, -1, 1 };
int dy[] = { -1, 0, 1, 0, 1, -1, -1, 1 };
const int MOD = 1e9 + 7, N = 4e7 + 5, oo = 1e9;
const double pi = acos(-1);
using namespace std;

string s1 = "23456789AKQJT", s2 = "CDHS", arr[60][60];
bool vis[60][60];
set<string> st;
int n, m;
pair<int, int> J1, J2, ans1, ans2;

void init()
{
    for(int i = 0; i < sz(s1); i++)
    {
        for(int j = 0; j < sz(s2); j++)
        {
            string t = "";
            t += s1[i], t += s2[j];
            st.insert(t);
        }
    }
    J1 = {59, 59};
    J2 = {59, 59};
}

bool check(int i, int j, bool again)
{
    set<char> st1, st2;
    if(i + 2 >= n and j + 2 >= m) return false;
    if(!again) memset(vis, 0, sizeof vis);
    for(int ii = i; ii < i + 3; ii++)
    {
        for(int jj = j; jj < j + 3; jj++)
        {
            if(again and vis[ii][jj]) return false;
            vis[ii][jj] = !again;
            st1.insert(arr[ii][jj][0]);
            st2.insert(arr[ii][jj][1]);
        }
    }
    return (sz(st1) == 9 or sz(st2) == 1);
}

bool valid()
{
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(check(i, j, 0))
            {
                for(int ii = 0; ii < n; ii++)
                {
                    for(int jj = 0; jj < m; jj++)
                    {
                        if(check(ii, jj, 1))
                        {
                            ans1 = {i, j};
                            ans2 = {ii, jj};
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false;
}

int main()
{
    //assem99
    cin>>n>>m;
    init();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            cin>>arr[i][j];
            if(arr[i][j] == "J1") J1 = {i, j};
            else if(arr[i][j] == "J2") J2 = {i, j};
            else st.erase(st.find(arr[i][j]));
        }
    }
    for(auto ii : st)
    {
        for(auto jj : st)
        {
            if(ii != jj)
            {
                arr[J1.first][J1.second] = ii;
                arr[J2.first][J2.second] = jj;
                if(valid())
                {
                    cout<<"Solution exists."<<endll;
                    if(J1.first == 59 and J2.first == 59) cout<<"There are no jokers."<<endll;
                    else if(J1.first != 59 and J2.first != 59) cout<<"Replace J1 with "<<ii<<" and J2 with "<<jj<<'.'<<endll;
                    else if(J1.first == 59) cout<<"Replace J2 with "<<jj<<'.'<<endll;
                    else if(J2.second == 59) cout<<"Replace J1 with "<<ii<<'.'<<endll;
                    cout<<"Put the first square to ("<<ans1.first + 1<<", "<< ans1.second + 1<<")."<<endll;
                    cout<<"Put the second square to ("<<ans2.first + 1<<", "<< ans2.second + 1<<")."<<endll;
                    return 0;
                }
            }
        }
    }
    cout<<"No solution.";

    return 0;
}

/*
 * Author: blackBird
 * Email: saketbharamberocks@gmail.com
 */
#include <cstdio>
#include <sstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cassert>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <cmath>
#include <utility>
#include <climits>

using namespace std ;

typedef long long ll ;
typedef pair<int,int> ii ;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FOR0(i,a) for(int i=0;i<(a);i++)
#define FOR1(i,a) for(int i=1;i<(a);i++)
#define REP(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define TRAVERSE(it,s) for(typeof(s.begin()) it=s.begin();it!=s.end();++it)
#define ENDL putchar(10)
#define PB push_back
#define MP make_pair
#define SZ size

#define FILL(a,x) memset(a,x,sizeof a)
#define ALL(c) (c).begin(),(c).end()
#define PRESENT(c,x) (find(ALL(c),x) != (c).end())

#define ABS(a) ((a)<0?-(a):(a))
#define SQ(x) (x)*(x)
#define INF 0xffffff00
#define ESP 1e-6

#define MIN(a,b) (a)<(b)?(a):(b)
#define MAX(a,b) (a)>(b)?(a):(b)
#define MININ(a) *min_element(a.begin(), a.end())
#define MININ_A(a,n) *min_element(a, a+n)
#define MAXIN(a) *max_element(a.begin(), a.end())
#define MAXIN_A(a,n) *max_element(a, a+n)

#define P(x) cout << x
#define PE(x) cout << x << endl
#define SI ({int _x; scanf("%d",&_x); _x;})
#define SLL ({long long _x; scanf("%lld",&_x); _x;})
#define SLF ({double _x; scanf("%lld",&_x); _x;})
#define SC getchar()
#define SS(n) scanf("%s",n)

char rank[55][55] ;
char suit[55][55] ;

char R[]  = {  '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' , 'A'  } ;
char C[] = { 'C' , 'D', 'H', 'S' } ;

int j1x, j1y, j2x, j2y, j1num, j2;
int ans1x, ans1y, ans2x, ans2y;

bool check ( int n, int m ) {
	vector<ii> vii ;
	set<char> set1, set2;
	for ( int i = 1 ; i+2 <= n ; i ++ ) {
		for ( int j = 1 ; j+2 <= m ; j ++ ) {
			set1.clear();
			set2.clear();
			for (int a = 0 ; a < 3 ; a ++ ) {
				for ( int b = 0 ; b < 3 ; b ++ ) {
					set1.insert(rank[i+a][j+b]);
					set2.insert(suit[i+a][j+b]);
				}
			}
			if ( set1.SZ() == 9 || set2.SZ() == 1 ) {
				vii.PB(MP(i,j));
			}
		}
	}
	for ( int i = 0 ; i < vii.SZ() ; i ++ ) {
		for ( int j = i + 1 ; j < vii.SZ() ; j ++ ) {
			int xdiff = vii[i].first - vii[j].first ;
			int ydiff = vii[i].second - vii[j].second ;
			if ( abs(xdiff) >= 3 || abs(ydiff) >= 3 ) {
				ans1x = vii[i].first ;
				ans1y = vii[i].second ;
				ans2x = vii[j].first ;
				ans2y = vii[j].second ;
				return true ;
			}
		}
	}
	return false ;
}

int main () {
	int n = SI ;
	int m = SI ;
	int jokers = 0 ;
	set<string> cards;
	FOR0(i,13) {
		FOR0(j,4) {
			string s;
			s.PB(R[i]);
			s.PB(C[j]);
			cards.insert(s);
		}
	}

	FOR0(i,n) {
		FOR0(j,m) {
			string s ;
			cin >> s ;
			rank[i+1][j+1] = s[0] ;
			suit[i+1][j+1] = s[1] ;
			if (s[0] == 'J' && (s[1] == '1' || s[1] == '2'))  {
				jokers ++ ;
				if ( jokers == 1 ) {
					j1x = i+1;
					j1y = j+1;
					j1num = s[1] - '0' ;
				} else {
					j2x = i+1;
					j2y = j+1;
					j2 = s[1] - '0' ;
				}
			} else {
				cards.erase(s);
			}
		}
	}

//	cout << jokers << endl ;

	if ( jokers == 2 ) {
		set<string> :: iterator it1, it2;
		for ( it1 = cards.begin() ; it1 != cards.end() ; it1 ++ ) {
			for ( it2 = cards.begin() ; it2 != cards.end() ; it2 ++ ) {
				if ( *it1 != *it2 ) {
					rank[j1x][j1y] = (*it1)[0] ;
					suit[j1x][j1y] = (*it1)[1] ;
					rank[j2x][j2y] = (*it2)[0] ;
					suit[j2x][j2y] = (*it2)[1] ;

//					cout << *it1 << " " << *it2 << endl ;

					if (check(n,m)) {
						cout << "Solution exists." << endl ;
						if ( j1num == 1 ) {
							cout << "Replace J1 with " << *it1  << " and J2 with " << *it2 << "." << endl ;
						} else {
							cout << "Replace J1 with " << *it2  << " and J2 with " << *it1 << "." << endl ;
						}
						cout << "Put the first square to (" << ans1x << ", " << ans1y << ")." << endl ;
						cout << "Put the second square to (" << ans2x << ", " << ans2y << ")." << endl ;
						return 0 ;
					}
				}
			}
		}
	} else if ( jokers == 1 ) {
		set<string> :: iterator it ;
		for ( it = cards.begin() ; it != cards.end() ; it ++ ) {
			rank[j1x][j1y] = (*it)[0] ;
			suit[j1x][j1y] = (*it)[1] ;
			if (check(n,m)) {
				cout << "Solution exists." << endl ;
				cout << "Replace J" << j1num << " with " << *it  << "." << endl ;
				cout << "Put the first square to (" << ans1x << ", " << ans1y << ")." << endl ;
				cout << "Put the second square to (" << ans2x << ", " << ans2y << ")." << endl ;
				return 0 ;
			}
		}
	} else if ( check(n,m) ) {
				cout << "Solution exists." << endl ;
				cout << "There are no jokers." << endl ;
				cout << "Put the first square to (" << ans1x << ", " << ans1y << ")." << endl ;
				cout << "Put the second square to (" << ans2x << ", " << ans2y << ")." << endl ;
		return 0 ;
	}
	cout << "No solution." << endl ;
	return 0 ;
}

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
#define inf 1073741824
#define llinf 4611686018285162540LL
#define eps 1e-8
#define mod 9223372034707292160LL
#define pi acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i--)
#define mset(x,val) memset(x,val,sizeof(x))
#define mcpy(x,y) memcpy(x,y,sizeof(y))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define fuck puts("FUCK!")
#define mpii(a,b) make_pair(a,b);
#define NN 101010
#define MM 202020
using namespace std;
typedef unsigned long long ll;
typedef long double lb;
typedef pair<int,int> pii;
int n,m,joker;
set<char> rank,suit;
set<char>::iterator it;
int jx[3],jy[3];
int ax[3],ay[3];
int ans[3],cot,pd;
int vis[22][22],vj[3];
char s[22][22][3];
char bj[55][3]={
"ZY",
"2C","2D","2H","2S","3C","3D","3H","3S","4C","4D","4H","4S",
"5C","5D","5H","5S","6C","6D","6H","6S","7C","7D","7H","7S",
"8C","8D","8H","8S","9C","9D","9H","9S","TC","TD","TH","TS",
"QC","QD","QH","QS","KC","KD","KH","KS","AC","AD","AH","AS",
"JC","JD","JH","JS"
};
bool ppd(int x,int y){
    int flag=1;
    rep(i,x,x+2) rep(j,y,y+2) if(vis[i][j]==1) return 0;
    rank.clear();
    suit.clear();
    rep(i,x,x+2){
        rep(j,y,y+2){
            rank.insert(s[i][j][0]);
            suit.insert(s[i][j][1]);
        }
    }
  /*  if(s[jx[1]][jy[1]][0]=='2'&&s[jx[2]][jy[2]][0]=='A'){
    rep(i,x,x+2){
        rep(j,y,y+2){
            printf("%s ",s[i][j]);
        }
        printf("\n");
    }
        printf("=====%d %d  %d\n",x,y,cot);
        printf("Rank : ");for(it=rank.begin();it!=rank.end();it++) printf("%c ",*it); printf("\n");
        printf("Suit : ");for(it=suit.begin();it!=suit.end();it++) printf("%c ",*it); printf("\n");
    }*/
    if(rank.size()==9||suit.size()==1) return 1;
    return 0;
}

void find(){
    rep(i,1,n-2){
        rep(j,1,m-2){
            if(ppd(i,j)){
                cot++;
                ax[2]=i;
                ay[2]=j;
                return ;
            }
        }
    }
}

int check(){
    cot=0;
    mset(vis,0);
    rep(i,1,n-2){
        rep(j,1,m-2){
            if(ppd(i,j)){
                cot++;
                ax[1]=i,ay[1]=j;
                rep(ii,i,i+2) rep(jj,j,j+2) vis[ii][jj]=1;
       //         printf("-1-  %d %d\n",i,j);
                find();
                if(cot==2) break;
                rep(ii,i,i+2) rep(jj,j,j+2) vis[ii][jj]=0;
                cot--;

            }
        }
        if(cot==2) break;
    }
    return cot;
}

bool can(int pos){
    rep(i,1,n){
        rep(j,1,m){
            if(strcmp(bj[pos],s[i][j])==0) return 0;
        }
    }
    return 1;
}

int main(){

  /*  rep(i,1,48){
        printf("%s ",bj[i]);
        if(i%12==0)     printf("\n");
    }*/

    while(scanf("%d%d",&n,&m)!=EOF){
        joker=pd=0;
        vj[1]=vj[2]=0;
        rep(i,1,n) {
            rep(j,1,m) {
                scanf("%s",s[i][j]);
                if(strcmp(s[i][j],"J1")==0) joker++,jx[1]=i,jy[1]=j,vj[1]=1;
                if(strcmp(s[i][j],"J2")==0) joker++,jx[2]=i,jy[2]=j,vj[2]=1;
            }
        }
      //  printf("joker=%d \n",joker);
     //  printf("%d %d %d %d\n",jx[1],jy[1],jx[2],jy[2]);
        if(!joker){
            if(check()==2) pd=1;
        }

        else if(joker==1){
            int pos;
            if(vj[1]) pos=1;
            else pos=2;
            rep(i,1,52){
                int x=jx[pos],y=jy[pos];
                if(!can(i)) continue;
                strcpy(s[x][y],bj[i]);
                ans[pos]=i;
                if(check()==2) {pd=1;break; }
            }
        }

        else{
            rep(i,1,52){
                rep(j,1,52){
                    if(can(i)){
                        strcpy(s[jx[1]][jy[1]],bj[i]);
                        if(can(j)){
                            strcpy(s[jx[2]][jy[2]],bj[j]);
                            ans[1]=i;
                            ans[2]=j;
                            if(check()==2){pd=1;break;}
                        }
                        strcpy(s[jx[1]][jy[1]],"J1");
                        strcpy(s[jx[2]][jy[2]],"J2");
                    }
                }
                if(pd==1) break;
            }
        }

        if(!pd) printf("No solution.\n");
        else{
            printf("Solution exists.\n");
            if(joker==0) printf("There are no jokers.\n");
            else if(joker==1) {
                if(vj[1]) printf("Replace J1 with %s.\n",bj[ans[1]]);
                else printf("Replace J2 with %s.\n",bj[ans[2]]);
            }
            else printf("Replace J1 with %s and J2 with %s.\n",bj[ans[1]],bj[ans[2]]);
            printf("Put the first square to (%d, %d).\n",ax[1],ay[1]);
            printf("Put the second square to (%d, %d).\n",ax[2],ay[2]);
        }
    }
    return 0;
}

//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//#pragma GCC target("avx,tune=native")
#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
const int inf=0x3f3f3f3f;
const double eps=1e-6;
const int mod=1000000007;
typedef long long ll;
int calc1(char c){
	if(c=='C')return 1;
	if(c=='D')return 2;
	if(c=='H')return 3;
	if(c=='S')return 4;
}
inline calc2(char c){
	if(isdigit(c))return c-'0';
	if(c=='T')return 10;
	if(c=='J')return 11;
	if(c=='Q')return 12;
	if(c=='K')return 13;
	if(c=='A')return 1;
}
inline char get1(int x){
	if(x==1)return 'C';
	if(x==2)return 'D';
	if(x==3)return 'H';
	if(x==4)return 'S';
}
inline char get2(int x){
	if(2<=x&&x<10)return '0'+x;
	if(x==10)return 'T';
	if(x==11)return 'J';
	if(x==12)return 'Q';
	if(x==13)return 'K';
	if(x==1)return 'A';
}
bool cross(int i1,int j1,int i2,int j2){
	vector<int>s1,s2;
	for(int i=i1;i<i1+3;i++){
		for(int j=j1;j<j1+3;j++){
			s1.push_back(i*100+j);
		}
	}
	for(int i=i2;i<i2+3;i++){
		for(int j=j2;j<j2+3;j++){
			s2.push_back(i*100+j);
		}
	}
	for(auto p:s1)for(auto q:s2)if(p==q)return true;
	return false;
}
bool ok(int x,int y,vector<vector<pair<int,int> > >&mat){
	bool samecolor=true;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(mat[i][j].first!=mat[x][y].first)samecolor=false;
		}
	}
	bool difranks=true;
	set<int>all;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(all.count(mat[i][j].second))difranks=false;
			all.insert(mat[i][j].second);
		}
	}
	return samecolor|difranks;
}
pair<pair<int,int>,pair<int,int> >check(vector<vector<pair<int,int> > >mat){
	int n=mat.size(),m=mat[0].size();
	for(int i1=0;i1<=n-3;i1++){
		for(int j1=0;j1<=m-3;j1++){
			for(int i2=0;i2<=n-3;i2++){
				for(int j2=0;j2<=m-3;j2++){
					if(!cross(i1,j1,i2,j2)&&ok(i1,j1,mat)&&ok(i2,j2,mat)){
						return make_pair(make_pair(i1+1,j1+1),make_pair(i2+1,j2+1));
					}
				}
			}
		}
	}
	return make_pair(make_pair(-1,-1),make_pair(-1,-1));
}
int n,m;
int main(){
	cin>>n>>m;
	vector<vector<pair<int,int> > >card(n,vector<pair<int,int> >(m,make_pair(0,0)));
	int cntj=0;
	vector<pair<int,int> >jokers;
	vector<string>vs;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			string s;
			cin>>s;
			if(s[0]=='J'&&isdigit(s[1])){
				cntj++;
				jokers.push_back(make_pair(i,j));
				vs.push_back(s);
				card[i][j]=make_pair(-1,-1);
				continue;
			}
			card[i][j]=make_pair(calc1(s[1]),calc2(s[0]));
			//color rank
		}
	}
	set<pair<int,int> >S;
	for(int i=1;i<=4;i++)for(int j=1;j<=13;j++)S.insert(make_pair(i,j));
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(card[i][j].first!=-1){
				S.erase(S.find(card[i][j]));
			}
		}
	}
	vector<pair<int,int> >restcards(S.begin(),S.end());
	if(cntj==0){
		auto p=check(card);
		if(p.first.first!=-1){
			puts("Solution exists.");
			puts("There are no jokers.");
			printf("Put the first square to (%d, %d).\n",p.first.first,p.first.second);
			printf("Put the second square to (%d, %d).\n",p.second.first,p.second.second);
			return 0;
		}else{
			puts("No solution.");
			return 0;
		}
	}else if(cntj==1){
		int x=jokers[0].first,y=jokers[0].second;
		for(auto p:restcards){
			card[x][y]=p;
			auto _p=check(card);
			if(_p.first.first!=-1){
				puts("Solution exists.");
				printf("Replace %s with %c%c.\n",vs[0].c_str(),get2(p.second),get1(p.first));
				printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
				printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
				return 0;
			}
			card[x][y]=make_pair(-1,-1);
		}
	}else{
		int x[2]={jokers[0].first,jokers[1].first},y[2]={jokers[0].second,jokers[1].second};
		for(auto p:restcards){
			for(auto q:restcards){
				if(p!=q){
					card[x[0]][y[0]]=p;
					card[x[1]][y[1]]=q;
					auto _p=check(card);
					if(_p.first.first!=-1){
						puts("Solution exists.");
						pair<char,char>c1,c2;
						if(vs[0]=="J1"){
							c1=make_pair(get2(p.second),get1(p.first));
							c2=make_pair(get2(q.second),get1(q.first));
						}else{
							c2=make_pair(get2(p.second),get1(p.first));
							c1=make_pair(get2(q.second),get1(q.first));
						}
						printf("Replace J1 with %c%c and J2 with %c%c.\n",c1.first,c1.second,c2.first,c2.second);
						printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
						printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
						return 0;
					}
					card[x[0]][y[0]]=make_pair(-1,-1);
					card[x[1]][y[1]]=make_pair(-1,-1);
				}
			}
		}
	}
	puts("No solution.");
	return 0;
}

/**
 *
 */
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef long long LL;

template<typename T> inline int sz(const T& x) { return (int)x.size(); }

pair<ii,ii> solve( vector<vector<string> > tab ) {
	int n = sz(tab); int m = sz(tab[0]);
	for(int i1 = 0; i1 < n-2; ++i1) {
		for(int j1 = 0; j1 < m-2; ++j1) {
			for(int i2 = 0; i2 < n-2; ++i2) {
				for(int j2 = 0; j2 < m-2; ++j2) {

					if( abs(i1-i2) < 3 && abs(j1-j2) < 3 )
						continue;

					set<char> sa, sb;
					for(int i = 0; i < 3; ++i) {
						for(int j = 0; j < 3; ++j) {
							sa.insert( tab[i1+i][j1+j][0] );
							sb.insert( tab[i1+i][j1+j][1] );
						}
					}

					if( sz(sa) != 9 && sz(sb) != 1 )
						continue;
//					int q = sz(sa), w = sz(sb);

					sa.clear(); sb.clear();
					for(int i = 0; i < 3; ++i) {
						for(int j = 0; j < 3; ++j) {
							sa.insert( tab[i2+i][j2+j][0] );
							sb.insert( tab[i2+i][j2+j][1] );
						}
					}

					if( sz(sa) != 9 && sz(sb) != 1 )
						continue;
//					if((q == 9 && sz(sa) == 9) || (w == 1 && sz(sb) == 1) )

					return make_pair( ii(i1,j1), ii(i2,j2) );
				}
			}
		}
	}

	return make_pair(ii(-1,0), ii(0,0));
}

void out_sol( pair<ii,ii> res ) {
	cout << "Put the first square to (" << (res.first.first+1) << ", " << (res.first.second+1) << ").\n";
	cout << "Put the second square to (" << (res.second.first+1) << ", " << (res.second.second+1) << ").\n";
}

int main() {
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);

	char a[13] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
	char b[4] = {'C','D','H','S'};

	set<string> cards;

	for(int i = 0; i < 13; ++i) {
		for(int j = 0; j < 4; ++j) {
			string s("  ");
			s[0] = a[i];
			s[1] = b[j];
			cards.insert( s );
		}
	}

	int n,m;
	cin >> n >> m;

	vector<vector<string> > table(n, vector<string>(m));
	int jokers = 0;
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < m; ++j) {
			string s;
			cin >> s;
			table[i][j] = s;
			cards.erase(s);
			if( s == "J1" || s == "J2" )
				++jokers;
		}
	}

	if( jokers == 0 ) {
		pair<ii,ii> res = solve(table);
		if( res.first.first == -1 )
			cout << "No solution.\n";
		else {
			cout << "Solution exists.\nThere are no jokers.\n";
			out_sol(res);
		}
		return 0;
	}

	vector<string> free;
	for(set<string>::iterator it = cards.begin(); it != cards.end(); ++it) {
		free.push_back( *it );
	}

	if( jokers == 1 ) {
		int i,j;
		for(i = 0; i < n; ++i) {
			for(j = 0; j < m; ++j) {
				if( table[i][j] == "J1" || table[i][j] == "J2" )
					goto BB;
			}
		}
		BB:
		string t = table[i][j];
		for(int k = 0; k < sz(free); ++k) {
			table[i][j] = free[k];
			pair<ii,ii> res = solve(table);
			if( res.first.first >= 0 ) {
				cout << "Solution exists.\n";
				cout << "Replace " << t << " with " << table[i][j] << ".\n";
				out_sol(res);
				return 0;
			}
		}

		cout << "No solution.\n";
		return 0;
	}

	if( jokers == 2 ) {
		int i1=-1,i2=-1,j1,j2;
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < m; ++j) {
				if( table[i][j] == "J1" || table[i][j] == "J2" ) {
					if( i1 < 0 ) {
						i1 = i; j1 = j;
					} else {
						i2 = i; j2 = j;
					}
				}
			}
		}

		string x = table[i1][j1];
		string y = table[i2][j2];
		if( x[1] == '2') {
			swap(x,y);
			swap(i1,i2);
			swap(j1,j2);
		}
		for(int i = 0; i < sz(free); ++i) {
			for(int j = 0; j < sz(free); ++j) {
				if( i == j ) continue;

				table[i1][j1] = free[i];
				table[i2][j2] = free[j];

				pair<ii,ii> res = solve(table);
				if( res.first.first >= 0 ) {
					cout << "Solution exists.\n";
					//cout << "Replace " << x << " with " << table[i1][j1] << ".\n";
					//cout << "Replace " << y << " with " << table[i2][j2] << ".\n";
					cout << "Replace " << x << " with " << table[i1][j1] << " and " << y << " with " << table[i2][j2] << ".\n";
					out_sol(res);
					return 0;
				}
			}
		}
	}
	cout << "No solution.\n";

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

string suit = "CDHS";
string ranks = "23456789TJQKA";

set <string> all;
string a[20][20];
int px1, px2, py1, py2;
int can[20][20];
int n, m;

bool check(string s, string t){
	if (s != "") a[px1][py1] = s;
	if (t != "") a[px2][py2] = t;
	memset(can, 0, sizeof(can));
	for (int x = 0; x <= n - 3; x++){
		for (int y = 0; y <= m - 3; y++){
			int flag = 1;
			for (int i = 0; i < 3; i++){
				for (int j = 0; j < 3; j++){
					flag &= a[x + i][y + j][1] == a[x][y][1];
				}
			}
			if (flag) can[x][y] = 1;
			set <char> s;
			for (int i = 0; i < 3; i++){
				for (int j = 0; j < 3; j++){
					s.insert(a[x + i][y + j][0]);
				}
			}
			if (s.size() == 9) can[x][y] = 1;
		}
	}
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			for (int k = 0; k < n; k++){
				for (int l = 0; l < m; l++){
					if (!can[i][j] || !can[k][l]) continue;
					if (k - i >= 3 || l - j >= 3){
						printf("Solution exists.\n");
						if (px1 == -1 && px2 == -1) printf("There are no jokers.\n");
						else if (px1 == -1) printf("Replace J2 with %s.\n", t.c_str());
						else if (px2 == -1) printf("Replace J1 with %s.\n", s.c_str());
						else printf("Replace J1 with %s and J2 with %s.\n", s.c_str(), t.c_str());
						printf("Put the first square to (%d, %d).\n", i + 1, j + 1);
						printf("Put the second square to (%d, %d).\n", k + 1, l + 1);
						return 1;
					}
				}
			}
		}
	}
	return 0;
}

int main(){
	for (int i = 0; i < 4; i++){
		for (int j = 0; j < 13; j++){
			string tmp; tmp += ranks[j], tmp += suit[i];
			all.insert(tmp);
		}
	}
	cin >> n >> m;
	px1 = px2 = py1 = py2 = -1;
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			cin >> a[i][j];
			if (a[i][j] == "J1") px1 = i, py1 = j;
			else if (a[i][j] == "J2") px2 = i, py2 = j;
			else all.erase(a[i][j]);
		}
	}
	if (px1 == -1 && px2 == -1){
		if (!check("", "")) printf("No solution.\n");
		return 0;
	}
	if (px1 == -1){
		for (set <string> :: iterator it = all.begin(); it != all.end(); it++){
			if (check("", *it)) return 0;
		}
		printf("No solution.\n");
		return 0;
	}
	if (px2 == -1){
		for (auto it = all.begin(); it != all.end(); it++){
			if (check(*it, "")) return 0;
		}
		printf("No solution.\n");
		return 0;
	}
	for (auto it1 = all.begin(); it1 != all.end(); it1++){
		for (auto it2 = all.begin(); it2 != all.end(); it2++){
			if (it1 == it2) continue;
			if (check(*it1, *it2)) return 0;
		}
	}
	printf("No solution.\n");
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const string ssuit[4]={"C","D","H","S"};
const string rrank[13]={"2","3","4","5","6","7","8","9","T","J","Q","K","A"};
#define st first
#define nd second
#define l(s) s.size()//ppp
#define mp make_pair
#define pb push_back
string a[105][105];
set<string>sst;
bool gao(int x,int y)
{
	set<char>s,r;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			r.insert(a[x+i][y+j][0]),s.insert(a[x+i][y+j][1]);
	return l(s)==1||l(r)==9;
}
char buf[105];
int r,c,cj1,rj1,cj2,rj2;
int main()
{
	cin>>r>>c;
	rj1=cj1=rj2=cj2=-1;
	for(int i=0;i<4;i++)
		for(int j=0;j<13;j++)
			sst.insert(rrank[j]+ssuit[i]);
	for(int i=0;i<r;i++)
		for(int j=0;j<c;j++)
		{
			cin>>buf;
			a[i][j]=buf;
			sst.erase(a[i][j]);
			if(a[i][j]=="J1")
			{
				rj1=i;
				cj1=j;
			}
			else if(a[i][j]=="J2")
			{
				rj2=i;
				cj2=j;
			}
		}
	sst.insert("@1");
	sst.insert("@2");
	for(set<string>::const_iterator j1=sst.begin();j1!=sst.end();j1++)
	{
		if(rj1!=-1)
		{
			if((*j1)[0]=='@')
				continue;
			a[rj1][cj1]=*j1;
		}
		for(set<string>::const_iterator j2=sst.begin();j2!=sst.end();j2++)
		{
			if(j1==j2)
				continue;
			if(rj2!=-1)
			{
				if((*j2)[0]=='@')
					continue;
				a[rj2][cj2]=*j2;
			}
			vector<pair<int,int> >ok;
			for(int i=0;i+3<=r;i++)
				for(int j=0;j+3<=c;j++)
					if(gao(i,j))
						ok.pb(mp(i,j));
			for(vector<pair<int,int> >::const_iterator i1=ok.begin();i1!=ok.end();i1++)
				for(vector<pair<int,int> >::const_iterator i2=ok.begin();i2!=i1;i2++)
				{
					if(i1->st+3<=i2->st||i2->st+3<=i1->st||i1->nd+3<=i2->nd||i2->nd+3<=i1->nd)
					{
						puts("Solution exists.");
						if(rj1!=-1&&rj2!=-1)
							printf("Replace J1 with %s and J2 with %s.\n",j1->c_str(),j2->c_str());
						else if(rj1!=-1)
							printf("Replace J1 with %s.\n",j1->c_str());
						else if(rj2!=-1)
							printf("Replace J2 with %s.\n",j2->c_str());
						else
							puts("There are no jokers.");
						printf("Put the first square to (%d, %d).\n",i2->st+1,i2->nd+1);
						printf("Put the second square to (%d, %d).\n",i1->st+1,i1->nd+1);
						return 0;
					}
				}
		}

	}
	puts("No solution.");
	return 0;
}

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <string>

#define Forn(i, n) for(i = 0; i < (int)(n); ++i)
#define forn(i, n) for(int i = 0; i < (int)(n); ++i)
#define ford(i, n) for(int i = (int)(n-1); i >= 0; --i)

#define mp make_pair

using namespace std;

int n, m;

string map[17][17], repJ[2];
vector<string> allCard;
string FR = "23456789TJQKA", SD = "CDHS";
int SQ[2][2];
int Bmap[17][17];

bool check2(){
    forn(num, 2){
        bool f2 = 1;
        forn(di, 3)
            forn(dj, 3)
                f2 &= (map[SQ[num][0]+di][SQ[num][1]+dj][1] == map[SQ[num][0]][SQ[num][1]][1]);
        string tmp;
        forn(di, 3)
            forn(dj, 3)
                tmp += map[SQ[num][0]+di][SQ[num][1]+dj][0];
        sort(tmp.begin(), tmp.end());
        if(unique(tmp.begin(), tmp.end()) != tmp.end() && !f2)
            return 0;
    }
    return 1;
}

bool check(){
    Forn(SQ[0][0], n - 2)
        Forn(SQ[0][1], m - 2)
            Forn(SQ[1][0], n - 2)
                Forn(SQ[1][1], m - 2){
                    bool ok = 1;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                if(++Bmap[SQ[num][0]+di][SQ[num][1]+dj] == 2)
                                    ok = 0;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                --Bmap[SQ[num][0]+di][SQ[num][1]+dj];
                    if(ok){
                        if(check2())
                            return 1;
                    }
                }
    return 0;

}

void f(int r, int c){
    if(r < n){
        if(c == m)
            f(r + 1, 0);
        else if(isdigit(map[r][c][1])){
            string J = map[r][c];
            forn(i, allCard.size()){
                if(allCard[i] == repJ[0] || allCard[i] == repJ[1])
                    continue;
                map[r][c] = allCard[i];
                repJ[J[1]-'1'] = map[r][c];
                f(r, c + 1);
                repJ[J[1]-'1'] = "";
            }
            map[r][c] = J;
        }else
            f(r, c + 1);
    }else{
        if(check()){
            cout << "Solution exists." << endl;
            if(repJ[0].length() == 0 && repJ[1].length() == 0 )
                cout << "There are no jokers." << endl;
            else if(repJ[0].length() == 0 || repJ[1].length() == 0 ){
                if(repJ[0].length() == 0)
                    cout << "Replace J2 with " << repJ[1] << "." << endl;
                else
                    cout << "Replace J1 with " << repJ[0] << "." << endl;
            }else{
                cout << "Replace J1 with " << repJ[0] << " and J2 with " << repJ[1] << "." << endl;
            }
            cout << "Put the first square to (" << SQ[0][0] + 1 << ", " << SQ[0][1] + 1 << ")." << endl;
            cout << "Put the second square to (" << SQ[1][0] + 1<< ", " << SQ[1][1] + 1 << ")." << endl;
            exit(0);
        }
    }
}

int main()
{
    forn(i, FR.length())
        forn(j, SD.length())
            allCard.push_back(string(1, FR[i]) + SD[j]);
    cin >> n >> m;
    int tmp = 0;
    forn(i, n)
        forn(j, m){
            cin >> map[i][j];
            if(!isdigit(map[i][j][1]))
                allCard.erase(find(allCard.begin(), allCard.end(), map[i][j]));
            else ++tmp;
        }
    f(0, 0);
    cout << "No solution." << endl;
    return 0;
}

#include <bits/stdc++.h>

#define all(v) (v).begin(), (v).end()
#define upmax(a, b) a = ((b > a) ? b : a)

using namespace std;
using ll = long long;

vector <string> cards;
string a[20][20];
int n, m;

vector <pair<int, int>> check() {
    vector <pair<int, int>> norm;
    for (int i = 0; i + 2 < n; ++i) {
        for (int j = 0; j + 2 < m; ++j) {
            set <char> dst;
            set <char> fi;
            for (int k = i; k < i + 3; ++k) {
                for (int c = j; c < j + 3; ++c) {
                    dst.insert(a[k][c][1]);
                    fi.insert(a[k][c][0]);
                }
            }
            if (dst.size() == 9 || fi.size() == 1) {
                norm.push_back({i, j});
            }
        }
    }
    vector <pair<int, int>> ret;
    for (int i = 0; i < norm.size(); ++i) {
        for (int j = i + 1; j < norm.size(); ++j) {
            set <pair<int, int>> cl1, cl2;
            for (int k = norm[i].first; k < norm[i].first + 3; ++k)
                for (int c = norm[i].second; c < norm[i].second + 3; ++c)
                    cl1.insert({k, c});
            for (int k = norm[j].first; k < norm[j].first + 3; ++k)
                for (int c = norm[j].second; c < norm[j].second + 3; ++c)
                    cl2.insert({k, c});
            bool ans = 1;
            for (auto i : cl1) {
                ans &= cl2.count(i) == 0;
            }
            if (ans) {
                ret.push_back(norm[i]);
                ret.push_back(norm[j]);
                return ret;
            }
        }
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    for (char m : "CDHS") {
        for (char c : "23456789TJQKA") {
            if (c == '\0' || m == '\0')
                continue;
            string put;
            put += m;
            put += c;
            cards.push_back(put);
        }
    }
    cin >> n >> m;
    vector <pair<pair<int, int>,int>> crs;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> a[i][j];
            swap(a[i][j][0], a[i][j][1]);
            if (a[i][j][1] == 'J' && (a[i][j][0] == '1' || a[i][j][0] == '2')) {
                crs.push_back({{i, j}, a[i][j][0] - '0'});
            }
            for (int k = 0; k < cards.size(); ++k) {
                if (cards[k] == a[i][j]) {
                    cards.erase(cards.begin() + k);
                    break;
                }
            }
        }
    }
    if (crs.size() == 0) {
        auto z = check();
        if (z.size() == 0) {
            cout << "No solution.\n";
        }
        else {
            cout << "Solution exists.\nThere are no jokers.\n";
            cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
            cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
        }
    }
    else if (crs.size() == 1) {
        for (int i = 0; i < cards.size(); ++i) {
            a[crs[0].first.first][crs[0].first.first] = cards[i];
            auto z = check();
            if (z.size() == 2) {
                cout << "Solution exists.\n";
                cout << "Replace J" << crs[0].second << " with " << cards[i][1] << cards[i][0] << ".\n";
                cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
                cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
                return 0;
            }
        }
        cout << "No solution.\n";
    }
    else {
        if (crs[1].second == 1) swap(crs[1], crs[0]);
        for (int i = 0; i < cards.size(); ++i) {
            for (int j = 0; j < cards.size(); ++j) {
                if (i == j) continue;
                a[crs[0].first.first][crs[0].first.second] = cards[i];
                a[crs[1].first.first][crs[1].first.second] = cards[j];
                auto z = check();
                if (z.size() == 2) {
                    cout << "Solution exists.\n";
                    cout << "Replace J" << crs[0].second << " with " << cards[i][1] << cards[i][0] << " and J" <<crs[1].second <<" with " <<cards[j][1] << cards[j][0] << ".\n";
                    cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
                    cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
                    return 0;
                }
            }
        }
        cout << "No solution.\n";
    }
    return 0;
}

#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
struct card {
    int num , hua;
    card () {}
    card (int n,int h) {
        num = n;
        hua = h;
    }
    string getName() {
        string ret;
        ret.clear();
        if (num == 1) {
            ret += "A";
        }
        else if (num < 10 && num > 1) {
            ret += num + '0';
        }
        else if (num == 10) {
            ret += 'T';
        }
        else if (num == 11) {
            ret += 'J';
        }
        else if (num == 12) {
            ret += 'Q';
        }
        else if (num == 13) {
            ret += 'K';
        }
        else {
            ret += 'J';//"C", "D", "H" and "S
        }

        if (hua == 0) {
            ret += 'C';
        }
        else if (hua == 1 && num != 0) {
            ret += 'D';
        }
        else if (hua == 2 && num != 0) {
            ret += 'H';
        }
        else if (hua == 3) {
            ret += 'S';
        }
        else ret += '0' + hua;
        return ret;
    }
    void check(
        string &str
        ) {
        if (str[0] == 'T') {
            num = 10;
        }
        else if (str[0] == 'J' && !(str[1] >= '1' && str[1] <= '2')) {
            num = 11;
        }
        else if (str[0] == 'Q') {
            num = 12;
        }
        else if (str[0] == 'K') {
            num = 13;
        }
        else if (str[0] == 'A') {
            num = 1;
        }
        else if (str[0] == 'J') {
            num = 0;
        }
        else {
            num = str[0]  - '0'; //"C", "D", "H" and "S
        }

        if (str[1] == 'C')
            hua = 0;
        else if (str[1] == 'D')
            hua = 1;
        else if (str[1] == 'H')
            hua = 2;
        else if (str[1] == 'S')
            hua = 3;
        else hua = str[1] - '0';
    }
};

card list[60][60];

bool Hash[4][20];

vector<card> canUse;

int xx1 , yy1;
int xx2 , yy2;
int Cnt = 0;

bool mark[100];

bool success;

string first , second , third , forth;

int ansx1 , ansy1, ansx2 ,ansy2;

card joker1 , joker2;

int n , m;

void check() {
    for (int i = 1;i <= n - 2;i ++) {
        for (int j = 1;j <= m - 2;j ++) {

            bool flag = false;
            if (list[i][j].hua == list[i][j + 1].hua &&
                list[i][j].hua == list[i][j + 2].hua &&
                list[i][j].hua == list[i + 1][j].hua &&
                list[i][j].hua == list[i + 1][j + 1].hua &&
                list[i][j].hua == list[i + 1][j + 2].hua &&
                list[i][j].hua == list[i + 2][j].hua &&
                list[i][j].hua == list[i + 2][j + 1].hua &&
                list[i][j].hua == list[i + 2][j + 2].hua) {
                    flag = true;
            }
            bool mark[20] = {false};

            if (flag == false) {
                flag = true;
                for (int h = 0;h < 3;h ++) {
                    for (int k = 0;k < 3;k ++) {
                        if (mark[ list[i + h][j + k].num]) {
                            flag = false;
                            h = 1000;
                            break;
                        }
                        else {
                            mark[ list[i + h][j + k].num ] = true;
                        }
                    }
                }
            }

            if (flag) {
                for (int h = 1;h <= n - 2;h ++) {
                    for (int k = 1;k <= m - 2;k ++) {
                        if ( (h - i < 3 && h - i > -3) && (k - j < 3 && k - j > -3) ) {
                            continue;
                        }

                        bool flag = false;
                        if (list[h][k].hua == list[h][k + 1].hua &&
                            list[h][k].hua == list[h][k + 2].hua &&
                            list[h][k].hua == list[h + 1][k].hua &&
                            list[h][k].hua == list[h + 1][k + 1].hua &&
                            list[h][k].hua == list[h + 1][k + 2].hua &&
                            list[h][k].hua == list[h + 2][k].hua &&
                            list[h][k].hua == list[h + 2][k + 1].hua &&
                            list[h][k].hua == list[h + 2][k + 2].hua) {
                                flag = true;
                        }
                        bool mark[20] = {false};

                        if (flag == false) {
                            flag = true;
                            for (int hh = 0;hh < 3;hh ++) {
                                for (int kk = 0;kk < 3;kk ++) {
                                    if (mark[ list[h + hh][k + kk].num]) {
                                        flag = false;
                                        hh = 1000;
                                        break;
                                    }
                                    else {
                                        mark[ list[h + hh][k + kk].num ] = true;
                                    }
                                }
                            }
                        }

                        if (flag == true) {
                            success = true;
                            ansx1 = i;
                            ansy1 = j;
                            ansx2 = h;
                            ansy2 = k;
                            return;
                        }

                    }
                }
            }

        }
    }
}
card replace1 , replace2;
void DFS(int cnt) {
    if (cnt == 0) {
        check();
        if (success) {
            first += "Solution exists.";
            if (Cnt == 0) {
                second += "There are no jokers.";
            }
            else {
                second += "Replace ";
                second += joker1.getName();
                second += " with ";
                second += replace1.getName();
            }
            if (Cnt == 2) {
                second += " and J2 with ";
                second += replace2.getName();
            }
            if (Cnt != 0)
                second += ".";
            third += "Put the first square to (";
            char tempx[20],tempy[20];
            itoa(ansx1,tempx,10);
            itoa(ansy1,tempy,10);
            third += tempx;
            third += ", ";
            third += tempy;
            third += ").";

            forth += "Put the second square to (";
            itoa(ansx2,tempx,10);
            itoa(ansy2,tempy,10);
            forth += tempx;
            forth += ", ";
            forth += tempy;
            forth += ").";
        }
        else {
            return;
        }
    }
    else {
        for (int i = 0;i < canUse.size();i ++) {
            if (mark[i]) continue;

            if (cnt == 2) {
                list[xx2][yy2] = canUse[i];
                mark[i] = true;
                replace2 = canUse[i];
                DFS(cnt - 1);
                if (success) return;
                mark[i] = false;
            }
            else {
                list[xx1][yy1] = canUse[i];
                replace1 = canUse[i];
                mark[i] = true;
                DFS(cnt - 1);
                if (success) return;
                mark[i] = false;
            }
        }
    }
}
int main () {
    scanf ("%d%d",&n,&m);
    for (int i = 1;i <= n;i ++) {
        for (int j = 1;j <= m;j ++) {
            if (i == 3 && j == 1) {
                i = i;
            }
            char temp[1010];
            scanf ("%s",temp);
            string str(temp);
            list[i][j].check(str);
        }
    }
    memset (Hash,false,sizeof(Hash));

    for (int i = 1;i <= n;i ++) {
        for (int j = 1;j <= m;j ++) {
            if (list[i][j].num != 0) {
                Hash[ list[i][j].hua ][ list[i][j].num ] = true;
            }
            else {
                Cnt ++;
                if (Cnt == 1) {
                    xx1 = i;yy1 = j;
                    joker1 = list[i][j];
                }
                else {
                    xx2 = i;yy2 = j;
                    joker2 = list[i][j];
                }
            }
        }
    }
    if (Cnt == 2 && joker1.hua > joker2.hua) {
        swap(joker1,joker2);
        swap(xx1 , xx2);
        swap(yy1 , yy2);
    }
    canUse.clear();
    for (int i = 0;i <= 3;i ++) {
        for (int j = 1;j <= 13;j ++) {
            if (Hash[i][j] == false) {
                canUse.push_back(card(j,i));
            }
        }
    }
    memset (mark,false,sizeof(mark));
    success = false;
    first.clear();
    second.clear();
    third.clear();
    forth.clear();
    DFS(Cnt);
    if (success == false) {
        puts("No solution.");
    }
    else {
        puts(first.c_str());
        puts(second.c_str());
        puts(third.c_str());
        puts(forth.c_str());
    }
    return 0;
}

/*
3 6
AC 2C 3C 4C 5C 6C
J2 J1 7C 8C 9C TC
JC KC QC AH 2H 3H
*/

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

int SI(const char* s){
    int ret=0;
    if(s[1]<='2') ret+=42+s[1]-'1';
    if(s[1]=='H') ret+=13;
    if(s[1]=='D') ret+=26;
    if(s[1]=='C') ret+=39;
    if(s[0]<='9') ret+=s[0]-'1';
    if(s[0]=='T') ret+=9;
    if(s[0]=='J') ret+=10;
    if(s[0]=='Q') ret+=11;
    if(s[0]=='K') ret+=12;
    return ret;
}

string IS(int x){
    string ret;
    if(x<52){
        if(x%13==0) ret+='A';
        if(x%13>=1 && x%13<=8) ret+=x%13+'1';
        if(x%13==9) ret+='T';
        if(x%13==10) ret+='J';
        if(x%13==11) ret+='Q';
        if(x%13==12) ret+='K';
        if(x/13==0) ret+='S';
        if(x/13==1) ret+='H';
        if(x/13==2) ret+='D';
        if(x/13==3) ret+='C';
    }else{
        if(x==52) ret="J1";
        if(x==53) ret="J2";
    }
    return ret;
}

int n,m,flag[54],a[17][17];
vector<pair<int,int>> u,ans;

bool check(size_t o){
    if(o==2) return true;
    for(int r=0;r<n-2;r++) for(int c=0;c<m-2;c++){
        if(o && abs(r-ans[0].first)<=2 && abs(c-ans[0].second)<=2) continue;
        int cnt[4]={},tag[13]={};
        for(int i=0;i<3;i++) for(int j=0;j<3;j++){
            cnt[a[r+i][c+j]/13]++;
            tag[a[r+i][c+j]%13]++;
        }
        if(*max_element(tag,tag+13)<=1 || count(cnt,cnt+4,0)==3){
            ans.push_back({r,c});
            if(check(o+1)) return true;
            ans.pop_back();
        }
    }
    return false;
}

bool gao(size_t o){
    if(o==u.size()){
        if(check(0)) return true;
    }else{
        int r=u[o].first;
        int c=u[o].second;
        int t=a[r][c];
        for(int i=0;i<52;i++) if(!flag[i]){
            a[r][c]=i;
            flag[i]=t;
            if(gao(o+1)) return true;
            flag[i]=0;
        }
        a[r][c]=t;
    }
    return false;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) for(int j=0;j<m;j++){
        char str[5];
        scanf("%s",str);
        a[i][j]=SI(str);
        if(a[i][j]>=52) u.push_back({i,j});
        flag[a[i][j]]=1;
    }
    if(u.size()==2 && a[u[0].first][u[0].second]==53) swap(u[0],u[1]);
    if(!gao(0)) return puts("No solution.");
    puts("Solution exists.");
    if(u.size()==0) printf("There are no jokers");
    if(u.size()>=1) printf("Replace %s with %s",
                    IS(flag[a[u[0].first][u[0].second]]).c_str(),
                    IS(a[u[0].first][u[0].second]).c_str());
    if(u.size()==2) printf(" and %s with %s",
                    IS(flag[a[u[1].first][u[1].second]]).c_str(),
                    IS(a[u[1].first][u[1].second]).c_str());
    puts(".");
    printf("Put the first square to (%d, %d).\n",ans[0].first+1,ans[0].second+1);
    printf("Put the second square to (%d, %d).\n",ans[1].first+1,ans[1].second+1);
}

    #include <bits/stdc++.h>

    using namespace std;
    #define ll long long
    #define pb push_back
    #define F first
    #define S second
    const int mod = 1e9 + 7, A = 1e3 + 2;
    int n, m;
    bool taken[52];
    vector<string> all(52);
    vector<pair<int, int>> jokers;
    vector<vector<string>> in, tmp;
    void input() {
     cin >> n >> m;
     in.resize(n, vector<string>(m));
     tmp.resize(n, vector<string>(m));
     for (int i = 0; i < n; i++) {
     for (int j = 0; j < m; j++)
     cin >> in[i][j];
     }
    }
    void pre() {
     string rank = "23456789TJQKA", type = "CDHS";
     int ptr = 0;
     for (int i = 0; i < 13; i++) {
     for (int j = 0; j < 4; j++, ptr++) {
     all[ptr].pb(rank[i]);
     all[ptr].pb(type[j]);
     }
     }
     for (int i = 0; i < n; i++) {
     for (int j = 0; j < m; j++) {
     tmp[i][j] = in[i][j];
     if (in[i][j] == "J1" || in[i][j] == "J2")
     jokers.pb({i, j});
     else {
     for (int ind = 0; ind < 52; ind++) {
     if (in[i][j] == all[ind])
     taken[ind] = 1;
     }
     }
     }
     }
    }
    bool validate(vector<vector<string>> &v, pair<int, int> &x1, pair<int, int> &x2) {
     vector<pair<int, int>> valid;
     for (int i = 0; i < n - 2; i++) {
     for (int j = 0; j < m - 2; j++) {
     set<char> ranks;
     for (int r = i; r < i + 3; r++) {
     for (int c = j; c < j + 3; c++)
     ranks.insert(v[r][c][0]);
     }
     if (ranks.size() == 9)
     valid.pb({i, j});
     }
     }
     if (valid.empty())
     return 0;
     pair<int, int> mni = {1e2, 0}, mnj = {0, 1e2};
     pair<int, int> mxi = {-1, 0}, mxj = {0, -1};
     for (auto x : valid) {
     if (mni.F > x.F) mni = x;
     if (mnj.S > x.S) mnj = x;
     if (mxi.F < x.F) mxi = x;
     if (mxj.S < x.S) mxj = x;
     }
     if (mxi.F - mni.F >= 3) {
     x1 = mxi, x2 = mni;
     return 1;
     }
     if (mxj.S - mnj.S >= 3) {
     x1 = mxj, x2 = mnj;
     return 1;
     }
     return 0;
    }

    void solved(pair<int, int> &p1, pair<int, int> &p2) {
     cout << "Solution exists.\n";
     if (jokers.size() == 0)
     cout << "There are no jokers.\n";
     if (jokers.size() == 1)
     cout << "Replace " << in[jokers[0].F][jokers[0].S] << " with " << tmp[jokers[0].F][jokers[0].S] << ".\n";
     if (jokers.size() == 2) {
     if (in[jokers[0].F][jokers[0].S] == "J2") {
     swap(in[jokers[0].F][jokers[0].S], in[jokers[1].F][jokers[1].S]);
     swap(tmp[jokers[0].F][jokers[0].S], tmp[jokers[1].F][jokers[1].S]);
     }
     cout << "Replace " << in[jokers[0].F][jokers[0].S] << " with " << tmp[jokers[0].F][jokers[0].S]
     << " and " << in[jokers[1].F][jokers[1].S] << " with " << tmp[jokers[1].F][jokers[1].S] << ".\n";
     }
     cout << "Put the first square to (" << p1.F + 1 << ", " << p1.S + 1 << ").\n";
     cout << "Put the second square to (" << p2.F + 1 << ", " << p2.S + 1 << ").\n";
     exit(0);
    }
    void generate(int ind) {
     if (ind == (int)jokers.size()) {
     pair<int , int> p1, p2;
     if (validate(tmp, p1, p2))
     solved(p1, p2);
     return;
     }
     for (int i = 0; i < 52; i++) {
     if (!taken[i]) {
     taken[i] = 1;
     tmp[jokers[ind].F][jokers[ind].S] = all[i];
     generate(ind + 1);
     taken[i] = 0;
     }
     }
    }
    int main() {
     ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
     input();
     pre();
     generate(0);
     cout << "No solution.\n";
     return 0;
     }

#include <iostream>
#include <fstream>
#include <sstream>
#include <functional>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <complex>
#include <cassert>
using namespace std;
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define EACH(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define FOR(i,k,n) for (int i=(k);i<(int)(n);i++)
#define FEQ(i,k,n) for(int i=(k);i<=(int)(n);i++)
typedef long long ll;
typedef complex<double> P;

int n,m;
pair<char,char> cards[17][17];
map<char,map<char,bool> > used;
string rank = "23456789TJQKA";
string suit = "CDHS";
pair<int,int> ans[2];

bool check()
{
  vector<pair<int,int> > ok;

  REP(i,n - 2) REP(j,m - 2){
    set<char> ranks,suits;
    REP(k,3) REP(l,3) {
      ranks.insert(cards[i+k][j+l].first);
      suits.insert(cards[i+k][j+l].second);
    }
    if (ranks.size() == 9 || suits.size() == 1)
      ok.push_back(make_pair(i,j));
  }

  if (ok.size() >= 2){
    REP(i,ok.size()) FOR(j,i+1,ok.size()){
      if (ok[i].first + 3 <= ok[j].first || ok[j].first + 3 <= ok[i].first ||
          ok[i].second + 3 <= ok[j].second || ok[j].second + 3 <= ok[i].second){
        ans[0] = ok[i];
        ans[1] = ok[j];
        return true;
      }
    }
  }

  return false;
}

int main()
{
  while(cin>>n>>m){
    vector<pair<int,int> > joker;
    vector<char> numj;
    REP(i,13) REP(j,4) used[rank[i]][suit[j]] = true;
    REP(i,n) REP(j,m) {
      string s;cin>>s;
      cards[i][j].first = s[0];
      cards[i][j].second = s[1];
      if (s[0] == 'J' && (s[1] == '1' || s[1] == '2')){
        joker.push_back(make_pair(i,j));
        numj.push_back(s[1]);
      }
      else used[s[0]][s[1]] = false;
    }

    vector<pair<int,int> > rest;
    EACH(it,used) EACH(jt,it->second)
      if (jt->second) rest.push_back(make_pair(it->first,jt->first));

    if (joker.size() == 0){
      if (check()){
        puts("Solution exists.");
        puts("There are no jokers.");
        printf("Put the first square to (%d, %d).\n",ans[0].first+1,ans[0].second+1);
        printf("Put the second square to (%d, %d).\n",ans[1].first+1,ans[1].second+1);
      }
      else
        puts("No solution.");
    }
    else if (joker.size() == 1){
      REP(i,rest.size()){
        cards[joker[0].first][joker[0].second] = rest[i];
        if (check()){
          puts("Solution exists.");
          printf("Replace J%c with %c%c.\n",numj[0],rest[i].first,rest[i].second);
          printf("Put the first square to (%d, %d).\n",ans[0].first+1,ans[0].second+1);
          printf("Put the second square to (%d, %d).\n",ans[1].first+1,ans[1].second+1);
          goto NEXT;
        }
      }
      puts("No solution.");
    }
    else if (joker.size() == 2){
      REP(i,rest.size()) REP(j,rest.size()){
        if (i == j) continue;
        cards[joker[0].first][joker[0].second] = rest[i];
        cards[joker[1].first][joker[1].second] = rest[j];
        if (check()){
          puts("Solution exists.");
          if (numj[0] == '1')
            printf("Replace J1 with %c%c and J2 with %c%c.\n",rest[i].first,rest[i].second,rest[j].first,rest[j].second);
          else
            printf("Replace J1 with %c%c and J2 with %c%c.\n",rest[j].first,rest[j].second,rest[i].first,rest[i].second);
          printf("Put the first square to (%d, %d).\n",ans[0].first+1,ans[0].second+1);
          printf("Put the second square to (%d, %d).\n",ans[1].first+1,ans[1].second+1);
          goto NEXT;
        }
      }
      puts("No solution.");
    }

  NEXT:;
  }

  return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <string>
#define PQ priority_queue
#define OO 2147483647
#define Max(a, b) ((FASTBUFFER = ((a) - (b)) >> 31), ((b) & FASTBUFFER | (a) & ~FASTBUFFER))
#define Min(a, b) ((FASTBUFFER = ((a) - (b)) >> 31), ((a) & FASTBUFFER | (b) & ~FASTBUFFER))
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)

int FASTBUFFER;

using namespace std;

string suit = "CDHS", J1 = "J1", J2 = "J2";
string rank = "23456789TJQKA";
string card[105], cc[105][105];
int tot, n, m, ansa, ansb, ansc, ansd;
map <string, pair <int, int> > s;

int check();
void print();

int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			char str[16];
			scanf("%s", str + 1);
			string snow = str + 1;
			s[snow] = make_pair(i, j);
			cc[i][j] = snow;
		}
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 13; j++)
		{
			string snow = "";
			snow += rank[j];
			snow += suit[i];
			if (s.find(snow) == s.end())
				card[++tot] = snow;
		}
	if (s.find(J1) != s.end())
	{
		if (s.find(J2) != s.end())
		{
			for (int k = 1; k <= tot; k++)
				for (int l = 1; l <= tot; l++)
				{
					if (l == k)
						continue;
					cc[s[J1].first][s[J1].second] = card[k];
					cc[s[J2].first][s[J2].second] = card[l];
					if (check())
					{
						printf("Solution exists.\n");
						printf("Replace J1 with %s and J2 with %s.\n", card[k].c_str(), card[l].c_str());
						print();
						return 0;
					}
				}
		}

		else
		{
			for (int k = 1; k <= tot; k++)
			{
				cc[s[J1].first][s[J1].second] = card[k];
				if (check())
				{
					printf("Solution exists.\n");
					printf("Replace J1 with %s.\n", card[k].c_str());
					print();
					return 0;
				}
			}
		}
	}

	else
	{
		if (s.find(J2) != s.end())
		{
			for (int k = 1; k <= tot; k++)
			{
				cc[s[J2].first][s[J2].second] = card[k];
				if (check())
				{
					printf("Solution exists.\n");
					printf("Replace J2 with %s.\n", card[k].c_str());
					print();
					return 0;
				}
			}
		}

		else
		{
			if (check())
			{
				printf("Solution exists.\n");
				printf("There are no jokers.\n");
				print();
				return 0;
			}
		}
	}

	printf("No solution.\n");
	return 0;
}

int check()
{
	set <string> ss;
	set <char> s1, s2, s3, s4;
	for (int a = 1; a + 2 <= n; a++)
		for (int b = 1; b + 2 <= m; b++)
			for (int c = 1; c + 2 <= n; c++)
				for (int d = 1; d + 2 <= m; d++)
				{
					ss.clear(), s1.clear(), s2.clear(), s3.clear(), s4.clear();
					for (int i = 0; i < 3; i++)
						for (int j = 0; j < 3; j++)
						{
							string str1 = cc[a + i][b + j], str2 = cc[c + i][d + j];
							ss.insert(str1), ss.insert(str2);
							s1.insert(str1[0]), s2.insert(str1[1]);
							s3.insert(str2[0]), s4.insert(str2[1]);
						}
					if (ss.size() == 18 && (s1.size() == 9 || s2.size() == 1) && (s3.size() == 9 || s4.size() == 1))
					{
						ansa = a, ansb = b, ansc = c, ansd = d;
						return 1;
					}
				}
	return 0;
}

void print()
{
	printf("Put the first square to (%d, %d).\n", ansa, ansb);
	printf("Put the second square to (%d, %d).\n", ansc, ansd);
}

#include<bits/stdc++.h>
using namespace std;
const string rk[13]={"2","3","4","5","6","7","8","9","T","J","Q","K","A"};
const string su[4]={"C","D","H","S"};
string a[111][111];
set<string>st;
int n,m,i1=-1,i2=-1,j11=-1,j2=-1;
bool gao(int x,int y)
{
	set<char>s,r;
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			r.insert(a[x+i][y+j][0]);
			s.insert(a[x+i][y+j][1]);
		}
	}
	return s.size()==1 || r.size()==9;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<13;j++)
		{
			st.insert(rk[j]+su[i]);
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			string s;
			cin>>s;
			a[i][j]=s;
			st.erase(s);
			if(s=="J1")
			{
				i1=i;
				j11=j;
			}
			else if(s=="J2")
			{
				i2=i;
				j2=j;
			}
		}
	}
	st.insert("@1");
	st.insert("@2");
	for(set<string>::iterator it1=st.begin();it1!=st.end();it1++)
	{
		if(i1!=-1)
		{
			if((*it1)[0]=='@')
			{
				continue;
			}
			a[i1][j11]=*it1;
		}
		for(set<string>::iterator it2=st.begin();it2!=st.end();it2++)
		{
			if(it1==it2)
			{
				continue;
			}
			if(i2!=-1)
			{
				if((*it2)[0]=='@')
				{
					continue;
				}
				a[i2][j2]=*it2;
			}
			vector<pair<int,int> >ok;
			for(int i=0;i+3<=n;i++)
			{
				for(int j=0;j+3<=m;j++)
				{
					if(gao(i,j))
					{
						ok.push_back(make_pair(i,j));
					}
				}
			}
			for(vector<pair<int,int> >::iterator ii=ok.begin();ii!=ok.end();ii++)
			{
				for(vector<pair<int,int> >::iterator jj=ok.begin();jj!=ok.end();jj++)
				{
					if(ii->first+3<=jj->first || jj->first+3<=ii->first || ii->second+3<=jj->second || jj->second+3<=ii->second)
					{
						cout<<"Solution exists."<<endl;
						if(i1!=-1 && i2!=-1)
						{
							cout<<"Replace J1 with "<<*it1<<" and J2 with "<<*it2<<"."<<endl;
						}
						else if(i1!=-1)
						{
							cout<<"Replace J1 with "<<*it1<<"."<<endl;
						}
						else if(i2!=-1)
						{
							cout<<"Replace J2 with "<<*it2<<"."<<endl;
						}
						else
						{
							cout<<"There are no jokers."<<endl;
						}
						cout<<"Put the first square to ("<<ii->first+1<<", "<<ii->second+1<<")."<< endl;
						cout<<"Put the second square to ("<<jj->first+1<<", "<<jj->second+1<<")."<< endl;
						return 0;
					}
				}
			}
		}
	}
	cout<<"No solution."<<endl;
	return 0;
}

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

#define maxn (60)

bool flag[maxn][maxn], vis[maxn], pool[15];
int g[maxn][maxn];
int m, n;
string s[maxn][maxn];
int jokers[2];

bool HALT = false;

int calc(string x) {
    int ret = 0;

    switch (x[1]) {
        case 'C' : ret += 0; break;
        case 'D' : ret += 13; break;
        case 'H' : ret += 26; break;
        case 'S' : ret += 39; break;
        default : ret += x[1] - '1'; break;
    }

    switch (x[0]) {
        case 'J' : {
            if (isdigit(x[1])) ret += 52;
            else ret += 10;
            break;
        }
        case 'A' : ret += 0; break;
        case 'T' : ret += 9; break;
        case 'Q' : ret += 11; break;
        case 'K' : ret += 12; break;
        default : ret += x[0] - '1'; break;
    }

    return ret;
}

string i2c(int x) {
    if (x == 52) return "J1";
    if (x == 53) return "J2";

    string str = "";

    switch (x % 13) {
        case 0 : str.push_back('A'); break;
        case 9 : str.push_back('T'); break;
        case 10 : str.push_back('J'); break;
        case 11 : str.push_back('Q'); break;
        case 12 : str.push_back('K'); break;
        default : str.push_back(x % 13 + '1');
    }

    switch (x / 13) {
        case 0 : str.push_back('C'); break;
        case 1 : str.push_back('D'); break;
        case 2 : str.push_back('H'); break;
        case 3 : str.push_back('S'); break;
    }

    return str;
}

bool suit(int x, int y) {
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            if (g[i + x][j + y] / 13 != g[x][y] / 13) return false;

    //cout << "Suit! " << x << "  " << y << endl;

    return true;
}

bool pairwise(int x, int y) {
    memset(pool, 0, sizeof(pool));

    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j) {
            int k = g[i + x][j + y] % 13;
            if (pool[k]) return false;
            pool[k] = true;
        }

    //cout << "Pairwise! " << x << "  " << y << endl;

    return true;
}

void outit(int a, int b, int c, int d) {
    HALT = true;
    cout << "Solution exists." << endl;
    if (jokers[0] == -1) {
        if (jokers[1] == -1) cout << "There are no jokers." << endl;
        else cout << "Replace J2 with " + i2c(jokers[1]) + "." << endl;
    }
    else {
        if (jokers[1] == -1) cout << "Replace J1 with " + i2c(jokers[0]) + "." << endl;
        else cout << "Replace J1 with " + i2c(jokers[0]) + " and J2 with " + i2c(jokers[1]) + "." << endl;
    }

    cout << "Put the first square to (" << a + 1 << ", " << b + 1 << ")." << endl;
    cout << "Put the second square to (" << c + 1 << ", " << d + 1 << ")." << endl;
}

void check() {
/*
    cout << "Gotit..." << endl;
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) cout << g[i][j] << " ";
        cout << endl;
    }
*/
    memset(flag, 0, sizeof(flag));
    for (int i = 0; i < m - 2; ++i)
        for (int j = 0; j < n - 2; ++j)
            if (suit(i, j)) flag[i][j] = true;

    for (int i = 0; i < m - 2; ++i)
        for (int j = 0; j < n - 2; ++j)
            if (pairwise(i, j)) flag[i][j] = true;

    for (int i = 0; i < m - 2; ++i)
        for (int j = 0; j < n - 2; ++j) {
            if (!flag[i][j]) continue;

            for (int a = i + 3; a < m - 2; ++a)
                for (int b = 0; b < n - 2; ++b) {
                    if (!flag[a][b]) continue;
                    outit(i, j, a, b); return ;
                }

            for (int a = 0; a < i + 3; ++a)
                for (int b = j + 3; b < n - 2; ++b) {
                    if (!flag[a][b]) continue;
                    outit(i, j, a, b); return ;
                }
        }
}

void dfs(int x) {
    if (HALT) return ;

    if (x >= 54) {
        check(); return ;
    }

    bool MARK = false;
    for (int i = 0; i < m; ++i)
        for (int j = 0; j < n; ++j) if (g[i][j] == x) {
            MARK = true;
            for (int k = 0; k < 52; ++k) if (!vis[k]) {
                vis[k] = true, g[i][j] = k;
                jokers[x - 52] = k;

                dfs(x + 1);

                vis[k] = false, g[i][j] = x;
            }
        }

    if (!MARK) dfs(x + 1);
}

int main() {
    cin >> m >> n;

    for (int i = 0; i < m; ++i)
        for (int j = 0; j < n; ++j) {
            cin >> s[i][j];

            g[i][j] = calc(s[i][j]);
            vis[g[i][j]] = true;
        }

    jokers[0] = jokers[1] = -1;
    dfs(52);

    if (!HALT) cout << "No solution." << endl;

    return 0;
}

#include <iostream>
#include <string>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;

string rank[15] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
string suit[5] = {"C", "D", "H", "S"};

int ans1i, ans1j, ans2i, ans2j;

int check(string str[100][100], int m, int n)
{
	int ret[100][100];
	int used[500];
	char st;
	int flag = 0;
	int i, j, k, l;
	int ok = 0;

	memset(ret, 0, sizeof(ret));
	for(i = 2;i < m;i++)
		for(j = 2;j < n;j++)
		{
			flag = 1;
			st = str[i - 2][j - 2][1];
			memset(used, 0, sizeof(used));
			for(k = i - 2;k <= i;k++)
			{
				for(l = j - 2;l <= j;l++)
					if (used[str[k][l][0]] > 0)
					{
						flag = 0;
						break;
					}
					else
						used[str[k][l][0]]++;
				if (flag == 0)
					break;
			}
			if (flag == 1)
			{
				ret[i][j] = 1;
				continue;
			}
			flag = 1;
			for(k = i - 2;k <= i;k++)
			{
				for(l = j - 2;l <= j;l++)
					if (str[k][l][1] > st)
					{
						flag = 0;
						break;
					}
				if (flag == 0)
					break;
			}
		}

//	if (str[4][2] == "JD" && str[2][7] == "7H")
//		printf("%d %d\n", ret[4][2], ret[4][7]);
	for(i = 2;i < m;i++)
	{
		for(j = 2;j < n;j++)
		{
			if (ret[i][j])
			{
				for(k = i + 3;k < m;k++)
				{
					for(l = 2;l < n;l++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				if (ok)
					break;
			//	if (str[4][2] == "JD" && str[2][7] == "7H" && i == 4 && j == 2)
			//		printf("ok %d %d %d\n", 2, j + 3, ret[4][7]);
				for(l = j + 3;l < n;l++)
				{
					for(k = 2;k < m;k++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				if (ok)
					break;
			}
			if (ok)
				break;
		}
		if (ok)
			break;
	}

	return ok;
}

int main()
{
	int m, n;
	int rk, st, rk2, st2;
	int pi1, pj1, pi2, pj2;
	int i, j;
	int flag;
	string arr[100][100];
	set <string> used;
	cin>>m>>n;

	pi1 = pj1 = pi2 = pj2 = -1;
	for(i = 0;i < m;i++)
		for(j = 0;j < n;j++)
		{
			cin>>arr[i][j];
			if (arr[i][j] != "J1" && arr[i][j] != "J2")
				used.insert(arr[i][j]);
			if (arr[i][j] == "J1")
			{
				pi1 = i;
				pj1 = j;
			}
			if (arr[i][j] == "J2")
			{
				pi2 = i;
				pj2 = j;
			}
		}

	flag = 0;
	for(rk = 0;rk < 13;rk++)
	{
		for(st = 0;st < 4;st++)
		{
			if (pi1 != -1)
			{
				arr[pi1][pj1] = rank[rk] + suit[st];
				if (used.find(arr[pi1][pj1]) != used.end())
					continue;
			}

			for(rk2 = 0;rk2 < 13;rk2++)
			{
				for(st2 = 0;st2 < 4;st2++)
				{
					if (pi1 != -1 && rk == rk2 && st == st2)
						continue;
					if (pi2 != -1)
					{
						arr[pi2][pj2] = rank[rk2] + suit[st2];
						if (used.find(arr[pi2][pj2]) != used.end())
							continue;
					}

			//		if (arr[pi1][pj1] == "JD" && arr[pi2][pj2] == "7H")
			//			printf("%d\n", check(arr, m, n));
					if (check(arr, m, n))
					{
						flag = 1;
						break;
					}
				}
				if (flag == 1)
					break;
			}
			if (flag == 1)
				break;
		}
		if (flag)
			break;
	}

	if (flag)
	{
		printf("Solution exists.\n");
		if (pi1 == -1 && pi2 == -1)
			printf("There are no jokers.\n");
		else if (pi1 != -1 && pi2 != -1)
			printf("Replace J1 with %s and J2 with %s.\n", arr[pi1][pj1].c_str(), arr[pi2][pj2].c_str());
		else if (pi2 != -1)
			printf("Replace J2 with %s.\n", arr[pi2][pj2].c_str());
		else if (pi1 != -1)
			printf("Replace J1 with %s.\n", arr[pi1][pj1].c_str());

		printf("Put the first square to (%d, %d).\n", ans1i, ans1j);
		printf("Put the second square to (%d, %d).\n", ans2i, ans2j);
	}
	else
		printf("No solution.\n");

	return 0;
}

#include <bits/stdc++.h>

#define MOD (int)(1e9 + 7)
using namespace std;

vector<string> v[105];
set<char> s;
pair<int, int> jok[4];
string jokers[4];
set<string> ax;
map<string, bool> mp;
map<pair<int, int>, bool> mp1;

char suit[] = {'C', 'D', 'H', 'S'};
char extra[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
int n, m, nr;

struct chestie
{
    int i, j;
} dr1, dr2;

bool dif()
{
    vector<chestie> vec;
    for(int i = 3; i <= n; ++i)
        for(int j = 3; j <= m; ++j)
        {
            mp.clear();
            bool ok = 1;
            for(int ki = i - 2; ki <= i; ++ki)
                for(int kj = j - 2; kj <= j; ++kj)
                    if(mp.find(string(1, v[ki][kj][0])) != mp.end())
                    {
                        ok = 0;
                        break;
                    }
                    else mp[string(1, v[ki][kj][0])] = 1;
            if(ok)
                vec.push_back({i - 2, j - 2});
        }

    bool ok = 0;
    for(int i = 0; i < vec.size() && !ok; ++i)
        for(int j = i + 1; j < vec.size() && !ok; ++j)
        {
            mp1.clear();
            bool ok2 = 1;
            for(int ki = vec[i].i; ki <= vec[i].i + 2; ++ki)
                for(int kj = vec[i].j; kj <= vec[i].j + 2; ++kj)
                    mp1[{ki, kj}] = 1;
            for(int ki = vec[j].i; ki <= vec[j].i + 2; ++ki)
                for(int kj = vec[j].j; kj <= vec[j].j + 2; ++kj)
                    if(mp1.find(make_pair(ki, kj)) != mp1.end())
                    {
                        ok2 = 0;
                        break;
                    }
            if(ok2)
            {
                dr1 = vec[i];
                dr2 = vec[j];
                ok = 1;
            }
        }
    if(ok)
        return 1;
    return 0;
}

bool testSuit(char which)
{
    vector<chestie> vec;
    string t = string(1, which);
    for(int i = 3; i <= n; ++i)
        for(int j = 3; j <= m; ++j)
        {
            bool ok = 1;
            for(int ki = i - 2; ki <= i; ++ki)
                for(int kj = j - 2; kj <= j; ++kj)
                    if(string(1, v[ki][kj][1]) != t)
                    {
                        ok = 0;
                        break;
                    }
            if(ok)
                vec.push_back({i - 2, j - 2});
        }

    bool ok = 0;
    for(int i = 0; i < vec.size() && !ok; ++i)
        for(int j = i + 1; j < vec.size() && !ok; ++j)
        {
            mp1.clear();
            bool ok2 = 1;
            for(int ki = vec[i].i; ki <= vec[i].i + 2; ++ki)
                for(int kj = vec[i].j; kj <= vec[i].j + 2; ++kj)
                    mp1[{ki, kj}] = 1;
            for(int ki = vec[j].i; ki <= vec[j].i + 2; ++ki)
                for(int kj = vec[j].j; kj <= vec[j].j + 2; ++kj)
                    if(mp1.find(make_pair(ki, kj)) != mp1.end())
                    {
                        ok2 = 0;
                        break;
                    }
            if(ok2)
            {
                dr1 = vec[i];
                dr2 = vec[j];
                ok = 1;
            }
        }
    if(ok)
        return 1;
    return 0;
}

bool solve()
{
    if(dif())
        return 1;
    for(int i = 0; i < 4; ++i)
        if(testSuit(suit[i]))
            return 1;
    return 0;
}

void putSq()
{
    cout << "Put the first square to (" << dr1.i << ", " << dr1.j << ").\n";
    cout << "Put the second square to (" << dr2.i << ", " << dr2.j << ").\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    for(int i = 0; i < 4; ++i)
    {
        for(int j = 0; j < 13; ++j)
        {
            string au1 = string(1, extra[j]);
            string au2 = string(1, suit[i]);
            string rez = au1 + au2;
            ax.insert(rez);
        }
    }

    cin >> n >> m;

    nr = 0;
    for(int i = 1; i <= n; ++i)
    {
        v[i].push_back("a");
        for(int j = 1; j <= m; ++j)
        {
            string aux;
            cin >> aux;

            v[i].push_back(aux);
            if(aux[0] == 'J' && (aux[1] == '1' || aux[1] == '2'))
            {
                jok[++nr] = {i, j};
                jokers[nr] = aux;
            }
            ax.erase(aux);
        }
    }

    if(nr == 0)
    {
        if(solve())
        {
            cout << "Solution exists.\n";
            cout << "There are no jokers.\n";
            putSq();
        }
        else cout << "No solution.\n";
    }
    else
    {
        bool ok = 0;
        if(nr == 1)
        {
            for(auto it: ax)
            {
                v[jok[1].first][jok[1].second] = it;
                if(solve())
                {
                    cout << "Solution exists.\n";
                    cout << "Replace " << jokers[1] << " with " << it << ".\n";
                    putSq();
                    ok = 1;
                    break;
                }
            }
        }
        else
        {
            for(auto it1: ax)
            {
                if(ok)
                    break;
                for(auto it2 : ax)
                {
                    if(it1 != it2)
                    {
                        v[jok[1].first][jok[1].second] = it1;
                        v[jok[2].first][jok[2].second] = it2;
                        if(solve())
                        {
                            cout << "Solution exists.\n";
                            if(jokers[1] == "J1")
                                cout << "Replace " << jokers[1] << " with " << it1 << " and " << jokers[2] << " with " << it2 << ".\n";
                            else cout << "Replace " << jokers[2] << " with " << it2 << " and " << jokers[1] << " with " << it1 << ".\n";
                            putSq();
                            ok = 1;
                            break;
                        }
                    }
                }
            }
        }

        if(!ok)
            cout << "No solution.\n";
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

vector<string>rnk= {"2","3","4","5","6","7","8","9","T","J","Q","K","A"};
vector<string>suit= {"C","D","H","S"};
set<string>c;
string card[18][18];

bool valid(int x,int y)
{
    set<char>s;
    for(int i=x; i<x+3; i++)
        for(int j=y; j<y+3; j++)
            s.insert(card[i][j][0]);
    return s.size()==9;
}

int main()
{
    for(string s:rnk)
        for(string t:suit)
            c.emplace(s+t);
    int n,m,jx1=-1,jx2=-1,jy1,jy2;
    cin>>n>>m;
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
        {
            cin>>card[i][j];
            if(card[i][j]=="J1")
            {
                jx1=i;
                jy1=j;
            }
            else if(card[i][j]=="J2")
            {
                jx2=i;
                jy2=j;
            }
            else
                c.erase(card[i][j]);
        }
    for(string a:c)
    {
        //cout<<a<<endl;
        for(string b:c)
        {
            if(a==b)
                continue;
            if(jx1!=-1)
                card[jx1][jy1]=a;
            if(jx2!=-1)
                card[jx2][jy2]=b;
            for(int i=0; i<n-2; i++)
                for(int j=0; j<m-2; j++)
                    for(int k=0; k<n-2; k++)
                        for(int l=0; l<m-2; l++)
                        {
                            if((i-k)>=3||(j-l)>=3)
                            {
                                if(valid(i,j)&&valid(k,l))
                                {
                                    cout<<"Solution exists."<<endl;
                                    if(jx1!=-1&&jx2!=-1)
                                        cout<<"Replace J1 with "<<a<<" and J2 with "<<b<<"."<<endl;
                                    else if(jx1!=-1)
                                        cout<<"Replace J1 with "<<a<<"."<<endl;
                                    else if(jx2!=-1)
                                        cout<<"Replace J2 with "<<b<<"."<<endl;
                                    else
                                        cout<<"There are no jokers."<<endl;
                                    cout<<"Put the first square to ("<<i+1<<", "<<j+1<<")."<<endl;
                                    cout<<"Put the second square to ("<<k+1<<", "<<l+1<<")."<<endl;
                                    return 0;
                                }
                            }
                        }
        }
    }
    cout<<"No solution."<<endl;
    return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define SZ size()
using namespace std;
typedef long long ll;
int in(){int a; scanf("%d", &a); return a;}
const int MAX = 55;

string board[MAX][MAX];
set <string> allowed, ranks, suits;

pair <int,int> J1, J2, sq1, sq2;

int n, m;

stringstream ss;

bool isValid(int r, int c){
    set <char> _suits;
    set <char> _ranks;
    for(int i = r; i <= r + 2; i++) {
        for(int j = c; j <= c + 2; j++) {
            _ranks.insert(board[i][j][0]);
            _suits.insert(board[i][j][1]);
        }
    }

    return _suits.SZ == 1 || _ranks.SZ == 9;
}

bool check(){

    for(int i = 1; i <= n - 2; i++) {
        for(int j = 1; j <= m - 2; j++) {
            for(int u = 1; u <= n - 2; u++) {
                for(int v = 1; v <= m - 2; v++) {

                    if(abs(u - i) >= 3 ||  abs(v - j) >= 3){
                        if(isValid(i, j) && isValid(u, v)) {
                            sq1 = {i, j};
                            sq2 = {u, v};
                            return true;
                        }
                    }

                }
            }
        }
    }

    return false;
}

int main(){

    for(char _rank = '2'; _rank <= '9'; _rank++){
        ranks.insert(string(1, _rank));
    }
    ranks.insert("T");
    ranks.insert("J");
    ranks.insert("Q");
    ranks.insert("K");
    ranks.insert("A");

    suits.insert("C");
    suits.insert("D");
    suits.insert("H");
    suits.insert("S");

    for(string _rank : ranks) {
        for(string _suit : suits) {
            allowed.insert(_rank + _suit);
        }
    }

    n = in(), m = in();

    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            cin >> board[i][j];
            if(board[i][j] == "J1") J1 = {i, j};
            if(board[i][j] == "J2") J2 = {i, j};
            allowed.erase(board[i][j]);
        }
    }

    if(J1.F && J2.F) {
        for(string card1 : allowed) {
            for(string card2 : allowed) {
                if(card1 != card2 ){
                    board[J1.F][J1.S] = card1;
                    board[J2.F][J2.S] = card2;

                    if(check()) {
                        printf("Solution exists.\n");
                        printf("Replace J1 with %s and J2 with %s.\n", card1.c_str(), card2.c_str());
                        printf("Put the first square to (%d, %d).\n", sq1.F, sq1.S);
                        printf("Put the second square to (%d, %d).\n", sq2.F, sq2.S);
                        return 0;
                    }
                }
            }
        }

        printf("No solution.\n");
    }

    else if(J1.F) {

        for(string card1 : allowed) {
            board[J1.F][J1.S] = card1;
            if(check()) {
                printf("Solution exists.\n");
                printf("Replace J1 with %s.\n", card1.c_str());
                printf("Put the first square to (%d, %d).\n", sq1.F, sq1.S);
                printf("Put the second square to (%d, %d).\n", sq2.F, sq2.S);
                return 0;
            }
        }

        printf("No solution.\n");
    }

    else if(J2.F) {

        for(string card2 : allowed) {
            board[J2.F][J2.S] = card2;
            if(check()) {
                printf("Solution exists.\n");
                printf("Replace J2 with %s.\n", card2.c_str());
                printf("Put the first square to (%d, %d).\n", sq1.F, sq1.S);
                printf("Put the second square to (%d, %d).\n", sq2.F, sq2.S);
                return 0;
            }
        }

        printf("No solution.\n");
    }

    else {

        if(check()) {
            printf("Solution exists.\n");
            printf("There are no jokers.\n");
            printf("Put the first square to (%d, %d).\n", sq1.F, sq1.S);
            printf("Put the second square to (%d, %d).\n", sq2.F, sq2.S);
            return 0;
        }

        printf("No solution.\n");

    }
}

#include <iostream>
#include <set>

using namespace std;

#define REP(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,n) REP(i,0,n)
#define foreach(i,c) for(__typeof__((c).end()) i=(c).begin(); i!=(c).end(); i++ )

int n, m, u, v, x, y;
set<string> unused, aset, bset;
set<char> cur_rank, cur_suit;
string cards[17][17], rank[] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" }, suit[] = { "C", "D", "H", "S" };
bool j1, j2, found;

bool okay( int a, int b, string j1str, string j2str )
{
	cur_rank.clear();
	cur_suit.clear();
	rep(p,3) rep(q,3)
	{
		string cur = cards[a+p][b+q];
		if(cur=="J1") cur = j1str;
		if(cur=="J2") cur = j2str;
		cur_rank.insert(cur[0]);
		cur_suit.insert(cur[1]);
	}
	return cur_rank.size()==9 || cur_suit.size()==1;
}

bool find( string j1str, string j2str )
{
	for( u = 0; u < n-2; u++ ) for( v = 0; v < m-2; v++ )
	if(okay(u,v,j1str,j2str))
	for( x = 0; x < n-2; x++ ) for( y = 0; y < m-2; y++ )
	if( ( x>=u+3 || x<=u-3 || y>=v+3 || y<=v-3 ) && okay(x,y,j1str,j2str) )
		return true;
	return false;
}

int main()
{
	rep(i,13) rep(j,4) unused.insert( rank[i] + suit[j] );
	aset.insert("a");
	bset.insert("b");
	cin >> n >> m;
	rep(i,n) rep(j,m)
	{
		cin >> cards[i][j];
		if( cards[i][j] == "J1" ) j1 = true;
		if( cards[i][j] == "J2" ) j2 = true;
		unused.erase( cards[i][j] );
	}
	if(j1) aset = unused;
	if(j2) bset = unused;
	foreach(a,aset) foreach(b,bset) if( *a!=*b && find(*a,*b) )
	{
		cout << "Solution exists." << endl;
		if(j1&&j2) cout << "Replace J1 with " << *a << " and J2 with " << *b << "." << endl;
		else if(j1) cout << "Replace J1 with " << *a << "." << endl;
		else if(j2) cout << "Replace J2 with " << *b << "." << endl;
		else cout << "There are no jokers." << endl;
		cout << "Put the first square to (" << u+1 << ", " << v+1 << ")." << endl;
		cout << "Put the second square to (" << x+1 << ", " << y+1 << ")." << endl;
		return 0;
	}
	cout << "No solution." << endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define loop(i,b,e) for(int i=b;i<=e;i++)
#define loop2(i,e,b) for(int i=e;i>=b;i--)
#define io ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define X real()
#define Y imag()
#define cp(a,b)    ( (conj(a)*(b)).imag() )
#define length(a) (hypot((a).imag(), (a).real()))
typedef complex<double> point;
typedef long long ll;
typedef unsigned long long ull;
double PI = 3.141592653589793;
const double EPS = 1e-9;
const int N = 1e6 + 5;
const ll mod = 1e9 + 7;
const int oo = 1e9;
int dx[] = { 0, 0, 1, -1, 1, -1, 1, -1 };
int dy[] = { 1, -1, 0, 0, -1, 1, 1, -1 };

int n, m;
char ranks[] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' ,'A' };
char suits[] = { 'C', 'D', 'H' ,'S' };
map<string, bool> mp;
bool sol;
vector<pair<int, int> > v;
string g[20][20];
vector<pair<int, int> > cords;
vector<string> rep;
vector<char> jk;

bool can(int i, int j, int xx, int yy) {
	if (i + 2 >= n || j + 2 >= m) return 0;
	map<char, bool> vis_ranks;
	bool rank = 1, suit = 1;
	char s = g[i][j][1];
	loop(x, i, i + 2) {
		loop(y, j, j + 2) {
			if (x >= xx && x <= xx + 2 && y >= yy && y <= yy + 2) return 0;
			if (vis_ranks[g[x][y][0]]) rank = 0;
			vis_ranks[g[x][y][0]] = 1;
			if (s != g[x][y][1]) suit = 0;
		}
	}
	return suit | rank;
}

void check(int x,int y) {
	if (cords.size() == 2) {
		sol = 1;
		return;
	}
	loop(i, 0, n - 1) {
		loop(j, 0, m - 1) {
			if (i >= x && i <= x + 2 && j >= y && j <= y + 2) continue;
			if (can(i, j,x,y)) {
				cords.push_back({ i,j });
				check(i, j);
				if (sol) return;
				cords.pop_back();
			}
		}
	}
}

void backtrack(int idx) {
	if (idx == v.size()) {
		check(999,999);
		return;
	}
	loop(i,0,12)
		loop(j, 0, 3) {
			string s = "";
			s += ranks[i];
			s += suits[j];
			if (mp[s]) continue;
			mp[s] = 1;
			g[v[idx].first][v[idx].second] = s;
			backtrack(idx + 1);
			if (sol) {
				rep.push_back(s);
				return;
			}
			mp[s] = 0;
	}
}

int main() {
	cin >> n >> m;
	loop(i,0,n-1){
		loop(j, 0, m - 1) {
			cin >> g[i][j];
			mp[g[i][j]] = 1;
			if (g[i][j][0] == 'J' && (g[i][j][1] == '1' || g[i][j][1] == '2')) {
				v.push_back({ i,j });
				jk.push_back(g[i][j][1]);
			}
		}
	}
	if (jk.size() == 2) {
		if (jk[0] == '2') swap(jk[0], jk[1]), swap(v[0], v[1]);
	}
	backtrack(0);
	if (!sol) {
		printf("No solution.");
		return 0;
	}
	printf("Solution exists.\n");
	if (!v.size()) printf("There are no jokers.\n");
	else if (v.size() == 1) cout << "Replace J"<< jk[0]<<" with " << rep[0] << "." << endl;
	else cout << "Replace J" << jk[0] << " with " << rep[1] << " and J"<< jk[1] <<" with " << rep[0] << "." << endl;
	printf("Put the first square to (%d, %d).\n", cords[0].first + 1, cords[0].second + 1);
	printf("Put the second square to (%d, %d).", cords[1].first + 1, cords[1].second + 1);
}

//be name khoda

#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;

string c[20]={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K","A"},c2[10]={"C", "D", "H" ,"S"};
int cl=13,c2l=4,n,m,x[4],y[4],l=0;
char seenf;
bool ch[40][10],J[4];
string s[20][20];

bool checkgood(int i,int j)
{
	bool ch2=1,ch=1,ch3[40]={};
	char suit=s[i][j][0];
	for(int g=i;g<i+3;g++)
		for(int h=j;h<j+3;h++)
		{
			string t=s[g][h];
			char t1=t[0];
			int k;
			for(int g=0;g<cl;g++)
				if(t1==c[g][0])
				{
					k=g;
					g=cl;
				}
			if(ch3[k])
				ch2=0;
			ch3[k]=1;
			if(t[1]!=suit)
				ch=0;
		}
	return (ch|ch2);
}

void mark(string t)
{
	char a=t[0];
	char suit=t[1];
	int aa,sa;
	for(int i=0;i<cl;i++)
		if(a==c[i][0])
			aa=i;
	for(int j=0;j<c2l;j++)
		if(suit==c2[j][0])
			sa=j;
	ch[aa][sa]=1;
}

bool checkedgham(int i,int j,int h,int g)
{
	bool ch[50][50]={};
	for(int g=i;g<i+3;g++)
		for(int h=j;h<j+3;h++)
			ch[g][h]=1;
	for(int i=h;i<h+3;i++)
		for(int j=g;j<g+3;j++)
		{
			if(ch[i][j])
				return 0;
			ch[i][j]=1;
		}
	return 1;
}

bool check()
{
	for(int i=0;i<n-2;i++)
		for(int j=0;j<m-2;j++)
			for(int h=0;h<n-2;h++)
				for(int g=0;g<m-2;g++)
				{
					if(!checkedgham(i,j,h,g))
						continue;
					if(checkgood(i,j) && checkgood(h,g))
					{
						cout<<"Solution exists."<<endl;
						if(l==0)
							cout<<"There are no jokers."<<endl;
						else
						{
							if(l==1)
							{
								cout<<"Replace ";
								if(J[1])
									cout<<"J1";
								else
									cout<<"J2";
								cout<<" with "<<s[x[0]][y[0]]<<'.'<<endl;
							}
							if(l==2)
							{
								if(seenf=='2')
								{
									swap(x[0],x[1]);
									swap(y[0],y[1]);
								}
								cout<<"Replace J1 with "<<s[x[0]][y[0]]<<" and J2 with "<<s[x[1]][y[1]]<<'.'<<endl;
							}
						}
						cout<<"Put the first square to ("<<i+1<<", "<<j+1<<")."<<endl;
						cout<<"Put the second square to ("<<h+1<<", "<<g+1<<")."<<endl;
						exit(0);
						return 1;
					}
				}
	return 0;
}

void replaceJ(int k,int g,int o)
{
	if(o==0)
	{
		check();
		return;
	}
	for(int i=0;i<cl;i++)
		for(int j=0;j<c2l;j++)
			if(!ch[i][j] && !(i==k && j==g))
			{
				s[x[o-1]][y[o-1]]=c[i]+c2[j];
				replaceJ(i,j,o-1);
			}
}

int main()
{

	cin>>n>>m;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			cin>>s[i][j];
			bool k=1;
			if(s[i][j][0]=='J' && (s[i][j][1]=='1' || s[i][j][1]=='2'))
			{
				if(!seenf)
					seenf=s[i][j][1];
				k=0;
				if(s[i][j][1]=='1')
					J[1]=1;
				else
					J[2]=1;
				x[l]=i;
				y[l++]=j;
			}
			if(k)
				mark(s[i][j]);
		}
	//cout<<l<<endl;
	replaceJ(-1,-1,l);
	cout<<"No solution."<<endl;
	return 0;
}

#if 1
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <stack>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <functional>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <list>
#include <ctime>
using namespace std;

typedef long long LL;
typedef long double LD;
const LD eps = 1e-9;

typedef pair<int, int> pii;
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define iss istringstream
#define oss ostringstream
#define dbg(x) cerr << #x << " = " << x << endl;
#define dbgv(x) { cerr << #x << ": {"; for(int i = 0; i < x.size(); ++i) { if(i) cerr << ", "; cerr << x[i]; } cerr << "}" << endl; }

char p[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char q[] = {'C', 'D', 'H', 'S'};

bool intersect(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy)
{
	return ax <= dx && cx <= bx && ay <= dy && cy <= by;
}
int px, py, qx, qy;
bool check(vector< vector<string> > &a)
{
	int n = a.size(), m = a[0].size();
	vector< vector<bool> > c(n, vector<bool>(m));
	for(int x1 = 0; x1 <= n - 3; ++x1)
	for(int y1 = 0; y1 <= m - 3; ++y1)
	{
		set<char> e1, e2;
		for(int i = 0; i < 3; ++i)
			for(int j = 0; j < 3; ++j)
				e1.insert(a[x1 + i][y1 + j][0]),
				e2.insert(a[x1 + i][y1 + j][1]);
		if(e1.size() == 9 || e2.size() == 1)
			c[x1][y1] = true;
	}
	for(int x1 = 0; x1 <= n - 3; ++x1)
	for(int y1 = 0; y1 <= m - 3; ++y1) if(c[x1][y1])
		for(int x2 = 0; x2 <= n - 3; ++x2)
		for(int y2 = 0; y2 <= m - 3; ++y2) if(c[x2][y2])
			if(!intersect(x1, y1, x1 + 2, y1 + 2, x2, y2, x2 + 2, y2 + 2))
			{
				px = x1;
				py = y1;
				qx = x2;
				qy = y2;
				return true;
			}
	return false;
}
int main()
{
	// freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	int n, m;
	cin >> n >> m;
	vector< vector<string> > a(n, vector<string>(m));
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < m; ++j)
			cin >> a[i][j];

	vector<string> all;
	for(int i = 0; i < 13; ++i)
		for(int j = 0; j < 4; ++j)
			all.pb(string(1, p[i]) + string(1, q[j]));
	set< string > ex;
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < m; ++j)
			ex.insert(a[i][j]);
	int jx1 = -1, jy1 = -1, jx2 = -1, jy2 = -1;
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < m; ++j)
			if(a[i][j] == "J1")
				jx1 = i,
				jy1 = j;
			else if(a[i][j] == "J2")
				jx2 = i,
				jy2 = j;

	if(jx1 == -1 && jx2 == -1)
	{
		if(check(a))
		{
			cout << "Solution exists." << endl;
			cout << "There are no jokers." << endl;
			cout << "Put the first square to (" << px + 1 << ", " << py + 1 << ")." << endl;
			cout << "Put the second square to (" << qx + 1 << ", " << qy + 1 << ")." << endl;
			return 0;
		} else
		{
			cout << "No solution." << endl;
			return 0;
		}
	}

	if(jx1 != -1 && jx2 != -1)
	{
		for(int i = 0; i < all.size(); ++i) if(!ex.count(all[i]))
		{
			a[jx1][jy1] = all[i];
			for(int j = 0; j < all.size(); ++j) if(!ex.count(all[j]) && i != j)
			{
				a[jx2][jy2] = all[j];
				if(check(a))
				{
					cout << "Solution exists." << endl;
					//cout << "Replace J1 with " << all[i] << "." << endl;
					//cout << "Replace J2 with " << all[j] << "." << endl;
					cout << "Replace J1 with " << all[i] << " and J2 with " << all[j] << "." << endl;
					cout << "Put the first square to (" << px + 1 << ", " << py + 1 << ")." << endl;
					cout << "Put the second square to (" << qx + 1 << ", " << qy + 1 << ")." << endl;
					return 0;
				}
			}
		}
	} else
	{
		string jok;
		int jx, jy;
		if(jx1 != -1)
			jx = jx1, jy = jy1, jok = "J1";
		else
			jx = jx2, jy = jy2, jok = "J2";
		for(int i = 0; i < all.size(); ++i) if(!ex.count(all[i]))
		{
			a[jx][jy] = all[i];

			if(check(a))
			{
				cout << "Solution exists." << endl;
				cout << "Replace " << jok << " with " << all[i] << "." << endl;
				cout << "Put the first square to (" << px + 1 << ", " << py + 1 << ")." << endl;
				cout << "Put the second square to (" << qx + 1 << ", " << qy + 1 << ")." << endl;
				return 0;
			}

		}

	}

	cout << "No solution." << endl;
	return 0;
}
#endif

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

#include<bits/stdc++.h>
using namespace std;
#define j1 sidkfhwe
#define j2 sidkfhwf
#define p1 sidkfhwg
#define p2 sidkfhwh
int n,m;
int joker_sum;
pair<int,int> j1,j2,p1,p2;
string board[52][52];
bool used[52];
string sole="Solution exists.";
string nojo="There are no jokers.";
string noso="No solution.";
bool vis[52][52];
void pt(){
	cout<<"Put the first square to ("<<p1.first<<", "<<p1.second<<")."<<endl;
	cout<<"Put the second square to ("<<p2.first<<", "<<p2.second<<")."<<endl;
}
bool in_grid(int a,int b,int c,int d){
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			for(int k=0;k<3;k++){
				for(int l=0;l<3;l++)
				{
					if(a+i==c+k&&b+j==d+l)
						return 1;
				}
			}
		}
	}
	return 0;
}
bool chk(int x,int y){
	if(in_grid(x,y,p1.first,p1.second))
		return false;
	if(in_grid(x,y,p2.first,p2.second))
		return false;
	string a1,a2,a3,b1,b2,b3,c1,c2,c3;
	a1=board[x+0][y+0];a2=board[x+0][y+1];a3=board[x+0][y+2];
	b1=board[x+1][y+0];b2=board[x+1][y+1];b3=board[x+1][y+2];
	c1=board[x+2][y+0];c2=board[x+2][y+1];c3=board[x+2][y+2];
	set<char> s;
	s.insert(a1[0]);
	s.insert(a2[0]);
	s.insert(a3[0]);
	s.insert(b1[0]);
	s.insert(b2[0]);
	s.insert(b3[0]);
	s.insert(c1[0]);
	s.insert(c2[0]);
	s.insert(c3[0]);
	if(s.size()==9)
		return true;
	return false;
}
bool tst(){
	int tot=0;
	p1=make_pair(-2,-2);
	p2=make_pair(-2,-2);
	for(int i=1;i<=n-2;i++){
		for(int j=1;j<=m-2;j++){
			if(chk(i,j)){
				tot++;
				if(tot==1)
					p1=make_pair(i,j);
				else if(tot==2){
					p2=make_pair(i,j);
					break;
				}
			}
		}
		if(tot==2)
			break;
	}
	if(tot==2)
		return true;
	return false;
}
map<string,int> st;
map<string,int> st2;
map<int,string> ts;
map<int,string> ts2;
//st:suit->id
//ts:id->suit
//st2:rank->id
//ts2:id->rank
int main(){
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin>>n>>m;
	j1=make_pair(-1,-1);
	j2=make_pair(-1,-1);
	st["C"]=0;st["D"]=1;st["H"]=2;st["S"]=3;
	for(__typeof(st.begin()) it=st.begin();it!=st.end();it++)
		ts[it->second]=it->first;
	st2["A"]=1;st2["2"]=2;st2["3"]=3;st2["4"]=4;st2["5"]=5;
	st2["6"]=6;st2["7"]=7;st2["8"]=8;st2["9"]=9;st2["T"]=10;
	st2["J"]=11;st2["Q"]=12;st2["K"]=13;
	for(__typeof(st2.begin()) it=st2.begin();it!=st2.end();it++)
		ts2[it->second]=it->first;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>board[i][j];
			if(board[i][j]=="J1"){//joker1
				joker_sum++;
				j1=make_pair(i,j);
			}
			else if(board[i][j]=="J2"){//joker2
				joker_sum++;
				j2=make_pair(i,j);
			}
			else{
				used[st[board[i][j].substr(1)]*13+st2[board[i][j].substr(0,1)]-1]=true;
			}
		}
	}
	if(joker_sum==0){
		if(tst()){
			cout<<sole<<endl<<nojo<<endl;
			pt();
			return 0;
		}
		else{
			cout<<noso<<endl;
			return 0;
		}
	}
	else if(joker_sum==1){
		if(j1.first!=-1){
			for(int i=0;i<52;i++){
				if(!used[i]){
					string add=(ts2[i%13+1]+ts[i/13]);
					board[j1.first][j1.second]=add;
					if(tst()){
						cout<<sole<<endl<<"Replace J1 with "<<add<<"."<<endl;
						pt();
						return 0;
					}
					board[j1.first][j1.second]="";
				}
			}
			cout<<noso<<endl;
			return 0;
		}
		if(j2.first!=-1){
			for(int i=0;i<52;i++){
				if(!used[i]){
					string add=(ts2[i%13+1]+ts[i/13]);
					board[j2.first][j2.second]=add;
					if(tst()){
						cout<<sole<<endl<<"Replace J2 with "<<add<<"."<<endl;
						pt();
						return 0;
					}
					board[j2.first][j2.second]="";
				}
			}
			cout<<noso<<endl;
			return 0;
		}
	}
	else{
		for(int i=0;i<52;i++)if(!used[i]){
			for(int j=0;j<52;j++)if(!used[j]&&i!=j){
				string add=ts2[i%13+1]+ts[i/13];
				board[j1.first][j1.second]=add;
				string add2=ts2[j%13+1]+ts[j/13];
				board[j2.first][j2.second]=add2;
				if(tst()){
					cout<<sole<<endl<<"Replace J1 with "<<add<<" and J2 with "<<add2<<"."<<endl;
					pt();
					return 0;
				}
				board[j1.first][j1.second]="";
				board[j2.first][j2.second]="";
			}
		}
		cout<<noso<<endl;
		return 0;
	}
	return 0;
}

#include <bits/stdc++.h>
#define loop(n) for(ll  i= 0 ; i< (n) ; i++)
#define ll long long
#define vi vector<ll>
#define ii pair<ll,ll>
#define inf 1000000000000000
#define MAXNODE 250009
#define all(x) x.begin(),x.end()
#define pii pair<ll,ll>
#define vii vector<pii>
#define OO (0x7fffffffffffffff)
#define md 1000000007
#define LCM(a,b) (a)*(b) / ( __gcd( a , b) )
#define pi (3.141592653589793)
#define tRed(x) (x)*(pi)/(180.0)
#define tDeg(x) (x)*(180.0)/(pi)

using namespace std;

int n , m  ;
vector<vector<string>> gr ;

pair<ii,ii> sol(){

    loop(n){

        int x1 = i ;
        if(x1+3>n)break ;
        loop(m){
            int y1 = i ;
            if(y1+3>m)break ;

            loop(n){
                int x2 = i ;
                if(x2+3>n)break ;
                loop(m){
                    int y2 = i ;
                    if(y2+3>m)break ;
                    if(abs(x1-x2)<3 && abs(y1-y2)<3)continue ;
                    bool dn = 1 ;
                    bool ss = 1  ;
                    char la = gr[x1][y1][1] ;
                    char lb = gr[x2][y2][1] ;
                    vi r1(300) ;

                    vi r2(300) ;

                    loop(3){
                        int nx1 = x1+i ;
                        int nx2 = x2+i ;
                        loop(3){
                            int ny1 = y1+i ;
                            int ny2 = y2+i ;

                            string a = gr[nx1][ny1] ;
                            string b = gr[nx2][ny2] ;
                            char R1 = a[0] ; char S1 = a[1] ;
                            char R2 = b[0] ; char S2 = b[1] ;
                            if(r1[R1] || r2[R2]){
                                dn = 0 ;
                            }
                            r1[R1] =1 ;
                            r2[R2] = 1;
                            if(S1!=la || S2!=lb)ss = 0 ;
                        }
                    }
                    if(ss ||dn){
                        //cout << ss << " " << dn << '\n' ;
                        return {make_pair(x1+1 , y1+1) , make_pair(x2+1 , y2+1)} ;
                    }

                }
            }
        }
    }
    return {make_pair(-1 , -1) , make_pair(-1 , -1)} ;
}

int main(){

    //cout << tDeg(atan2(1,0)) ;
   // cout << __gcd(48 , 72) ;
    // freopen("small.in" , "r" , stdin) ;
   // freopen("1.txt" , "w" , stdout) ;

    cin.tie(0);
    cin.sync_with_stdio(0);

    cin >> n >> m ;
    gr.assign(n , vector<string>(m,"")) ;

    vector<string> v(52) ;
    int o  = 0 ;

    vector<char> vvv ;
    for(char  i ='2' ; i<='9' ; i++){
        vvv.push_back(i) ;
    }
    vvv.push_back('T') ;
    vvv.push_back('J') ;
    vvv.push_back('Q') ;
    vvv.push_back('K') ;
    vvv.push_back('A') ;

    loop(vvv.size()){
        char x = vvv[i] ;
        v[o] = x ; v[o]+='C' ; o++ ;
        v[o] = x ; v[o]+='D' ; o++ ;
        v[o] = x ; v[o]+='H' ; o++ ;
        v[o] = x ; v[o]+='S' ; o++ ;
    }

    map<string,int> M ;

    vector<pair<ii,string>> jo ;

    loop(n){
        int I = i ;
        loop(m){
            cin >> gr[I][i] ;
            if(gr[I][i][0]=='J' && (gr[I][i][1]=='1' || gr[I][i][1]=='2')){
                jo.push_back({make_pair(I,i),gr[I][i]}) ;
            }
            else{
                M[gr[I][i]] =1 ;
            }
        }
    }

    if(jo.size()==0){
        pair<ii,ii> p = sol() ;
        if(p.first.first==-1){
            cout << "No solution." ;
            return 0 ;
        }
        else{
            cout << "Solution exists.\n" ;
            cout << "There are no jokers.\n" ;
            cout << "Put the first square to (" << p.first.first<<", " << p.first.second << ").\n" ;
            cout << "Put the second square to (" << p.second.first<<", " << p.second.second << ").\n" ;
            return 0 ;
        }
    }
    else if(jo.size()==1){
        loop(v.size()){
            if(M[v[i]])continue ;
            gr[jo[0].first.first][jo[0].first.second] = v[i] ;
            pair<ii,ii> p = sol() ;
            if(p.first.first==-1){
                continue ;
            }
            else{
                cout << "Solution exists.\n" ;
                cout << "Replace "<<jo[0].second <<" with " << v[i]<<".\n" ;
                cout << "Put the first square to (" << p.first.first<<", " << p.first.second << ").\n" ;
                cout << "Put the second square to (" << p.second.first<<", " << p.second.second << ").\n" ;
                return 0 ;
            }
        }
        cout << "No solution." ;
        return 0  ;
    }
    else{
        if(jo[1].second=="J1"){
            swap(jo[0],jo[1]) ;
        }
        loop(v.size()){
            if(M[v[i]])continue ;
            M[v[i]] = 1 ;
            gr[jo[0].first.first][jo[0].first.second] = v[i] ;
            int I = i ;
            loop(v.size()){
                if(M[v[i]])continue ;
                gr[jo[1].first.first][jo[1].first.second] = v[i] ;
                pair<ii,ii> p = sol() ;
                if(p.first.first==-1){
                    continue ;
                }
                else{
                    cout << "Solution exists.\n" ;
                    cout << "Replace "<<jo[0].second<<" with " << v[I]<<" and "<<jo[1].second<<" with " << v[i] <<".\n" ;
                    cout << "Put the first square to (" << p.first.first<<", " << p.first.second << ").\n" ;
                    cout << "Put the second square to (" << p.second.first<<", " << p.second.second << ").\n" ;
                    return 0 ;
                }
                M[v[i]]=0 ;
            }
            M[v[i]]= 0 ;
        }
        cout << "No solution." ;
        return 0  ;

    }

    return 0 ;
}

#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_DEPRECATE

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#pragma comment(linker, "/STACK:64000000")

template<class T> inline T sqr (T x) {return x * x;}

typedef long long int64;
typedef unsigned long long uint64;
typedef pair<int, int> pii;
typedef pair<int, pii> pip;
typedef pair<pii, int> ppi;
typedef pair<int64, int64> pii64;
typedef pair<double, double> pdd;
typedef pair<string, int> psi;
typedef pair<int, string> pis;
#define FAIL ++*(int*)0
#define eps  1e-9
#define inf  0x7f7f7f7f
#define MP make_pair
#define sz(C) (int)((C).size())
#define all(C) (C).begin(), (C).end()
#define TASK "test"
#define RR 151

int dx[] = {0, 0, 2, 2};
int dy[] = {0, 2, 2, 0};

int n, m;
string a[32][32];
vector<pii> jk;
vector<string> jokers;
set<string> cards;
vector<string> c;
vector<pii> put;
vector<string> rep;
int id[128];
char used[64] = {0};

void precalc () {
    static char cost[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    static char suit[] = {'C', 'D', 'H', 'S'};
    for (int i = 0; i < 13; ++i)
        for (int j = 0; j < 4; ++j)
            cards.insert(string(1, cost[i]) + string(1, suit[j]));
    for (int i = 0; i < 13; ++i)
        id[cost[i]] = i;
}

inline bool in (int l, int m, int r) {
    return l <= m && m <= r;
}

inline bool intersect (int x1, int y1, int x2, int y2) {
    for (int i = 0; i < 4; ++i) {
        if (in(x1, x2 + dx[i], x1 + 2) && in(y1, y2 + dy[i], y1 + 2))
            return true;
    }
    return false;
}

inline bool same_suit (int x, int y) {
    char suit = a[x][y][1];
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            if (a[x + i][y + j][1] != suit)
                return false;
        }
    }
    return true;
}

inline bool diff_cost (int x, int y) {
    int used = 0;
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            char ch = a[x + i][y + j][0];
            if (used & (1 << id[ch])) return false;
            used |= 1 << id[ch];
        }
    }
    return true;
}

inline bool check () {
    for (int i = 0; i + 2 < n; ++i) {
        for (int j = 0; j + 2 < m; ++j) {
            for (int x = 0; x + 2 < n; ++x) {
                for (int y = 0; y + 2 < m; ++y) {
                    if (intersect(i, j, x, y)) continue;
                    if ((same_suit(i, j) || diff_cost(i, j)) && (same_suit(x, y) || diff_cost(x, y))) {
                        put.push_back(MP(i, j));
                        put.push_back(MP(x, y));
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

bool rec (int x) {
    if (x == sz(jk)) {
        return check();
    }
    int jx = jk[x].first;
    int jy = jk[x].second;
    for (int i = 0; i < sz(c); ++i) {
        if (used[i]) continue;
        string save = a[jx][jy];
        a[jx][jy] = c[i];
        rep.push_back(c[i]);
        used[i] = true;
        if (rec(x + 1)) return true;
        used[i] = false;
        rep.pop_back();
        a[jx][jy] = save;
    }
    return false;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n >> m;
    precalc();
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            string s;
            cin >> s;
            a[i][j] = s;
            cards.erase(s);
            if (s == "J1" || s == "J2")
                jk.push_back(MP(i, j)), jokers.push_back(s);
        }
    }
    if (sz(jk) == 2 && jokers[0] == "J2")
        swap(jk[0], jk[1]), swap(jokers[0], jokers[1]);
    c.assign(all(cards));
    if (rec(0)) {
        puts("Solution exists.");
        switch (sz(jk)) {
            case 0:
                puts("There are no jokers.");
                break;
            case 1:
                printf("Replace %s with %s.\n", jokers[0].c_str(), rep[0].c_str());
                break;
            case 2:
                printf("Replace J1 with %s and J2 with %s.\n", rep[0].c_str(), rep[1].c_str());
                break;
        }
        printf("Put the first square to (%d, %d).\n", put[0].first + 1, put[0].second + 1);
        printf("Put the second square to (%d, %d).\n", put[1].first + 1, put[1].second + 1);
    } else {
        puts("No solution.");
    }

    return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
#define REP(i,a,b) for (int i = a ; i <= b ; i++)
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;

const int OO = 1e9+7;
const int MOD = 1e9+7;
const int N = 52+7;

pair<char,char> a[N][N];
map<pair<char,char> ,int> c;
int n,m;
pi w1,w2;
bool check()
{
    vector<pi> vec;
    REP(i,0,n-3) REP(j,0,m-3)
    {
        set<char> st;
        bool oks = 1;
        char suit = a[i][j].S;
        REP(ki,0,2) REP(kj,0,2)
        {
            st.insert( a[i+ki][j+kj].F );
            if (suit != a[i+ki][j+kj].S) oks = 0;
        }
        if (oks || st.size() == 9) vec.PB({i,j});
    }

    int sz = vec.size();
    REP(i,0,sz-1) REP(j,0,sz-1)
    {
        if (i==j)continue;
        if (vec[j].F+2 < vec[i].F || vec[j].S+2 < vec[i].S) {w1 = vec[i];w2 = vec[j];return 1;}
        else if (vec[j].F > vec[i].F+2 || vec[j].S > vec[i].S+2) {w1 = vec[i];w2 = vec[j];return 1;}
    }

    return 0;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    string r = "23456789JTKA";
    string s = "CDHS";

    cin >> n >> m;
    int J1i = -1,J1j = -1,J2i = -1,J2j = -1;

    REP(i,0,n-1) REP(j,0,m-1)
    {
        cin >> a[i][j].F >> a[i][j].S;
        if (a[i][j].F == 'J')
        {
            if (a[i][j].S == '1') {J1i = i;J1j = j;}
            else if (a[i][j].S == '2') {J2i = i;J2j = j;}
        }
        c[a[i][j]]++;
    }

    //cout << J2i << endl;
    if (J1i != -1 && J2i != -1)
    {
        REP(i1,0,11) REP(j1,0,3)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            REP(i2,0,11) REP(j2,0,3)
            {
                if (c[{r[i2],s[j2]}] > 0) continue;
                c[{r[i2],s[j2]}]++;
                a[J2i][J2j] = {r[i2],s[j2]};
                //cout << J2i << ' ' << J2j << endl;
                if (check())
                {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with "<< r[i1]<<s[j1] <<" and J2 with " << r[i2]<<s[j2] << "." << endl;
                    cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                    cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                    return 0;
                }
                a[J2i][J2j] = {'J','2'};
                c[{r[i2],s[j2]}]--;
            }
            a[J1i][J1j] = {'J','1'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J1i != -1)
    {
        REP(i1,0,11) REP(j1,0,3)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with "<< r[i1]<<s[j1] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J1i][J1j] = {'J','2'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J2i != -1)
    {
        REP(i2,0,11) REP(j2,0,3)
        {
            if (c[{r[i2],s[j2]}] > 0) continue;
            c[{r[i2],s[j2]}]++;
            a[J2i][J2j] = {r[i2],s[j2]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J2 with " << r[i2]<<s[j2] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J2i][J2j] = {'J','2'};
            c[{r[i2],s[j2]}]--;
        }
    }
    else if (check())
    {
        cout << "Solution exists." << endl;
        cout << "There are no jokers." << endl;
        cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
        cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
        return 0;
    }

    cout << "No solution." << endl;

    return 0;
}

#pragma comment(linker, "/STACK:16777216")

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cfloat>
#include <climits>
#include <cctype>
#include <cmath>
#include <cassert>
#include <ctime>

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <complex>
#include <functional>
#include <numeric>

using namespace std;

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }

typedef long long ll;

#define eps 1e-10
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL

#define rep(x,y,z) for(int(x)=(y);(x)<(z);(x)++)
#define cast(x,t) *({stringstream ss;static t __ret;ss<<x,ss>>__ret;&__ret;})

#define dbg(x) cout << #x << " == " << x << endl
#define print(x) cout << x << endl

// var
string tab[20][20];
int n, m, _1, _2;
int jx[20], jy[20];

string a[] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" };
string b[] = { "C", "D", "H" , "S" };
map<int,string> mapa;
set<string> mesa;

int vis[20][20], passo;
int X1, Y1, X2, Y2;

set<char> rank, suit;

int test(int x, int y) {
	rank.clear(); suit.clear();
	rep(i,0,3) rep(j,0,3) {
		if(x + i >= n || y + j >= m || vis[x+i][y+j] == passo) return 0; else vis[x+i][y+j] = passo;
		if(tab[x+i][y+j] == string("J1") || tab[x+i][y+j] == string("J2")) return 0;
		rank.insert( tab[x+i][y+j][0] );
		suit.insert( tab[x+i][y+j][1] );
	}
	return rank.size() == 9 || suit.size() == 1;
}

int test(int x1, int y1, int x2, int y2) {
	++passo;
	return test(x1,y1) && test(x2,y2);
}

int ok() {
	rep(x1,0,n) rep(y1,0,m) rep(x2,0,n) rep(y2,0,m) if( test(x1,y1,x2,y2) ) {
		X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;
		return 1;
	}
	return 0;
}

int main() {

	// solve
	for(int i = 0, k = 0; i < 13; i++) {
		for(int j = 0; j < 4; j++) {
			mapa[k++] = a[i] + b[j];
		}
	}

	cin >> n >> m;

	for(int i = 0; i < n; i++)
		for(int j = 0; j < m; j++) {
			cin >> tab[i][j];
			mesa.insert( tab[i][j] );
			if(tab[i][j][0] == 'J' && !isalpha(tab[i][j][1])) {
				jx[ tab[i][j][1]-'1' ] = i; jy[ tab[i][j][1]-'1' ] = j;
				if(tab[i][j][1] == '1') _1 = 1; else _2 = 1;
			}
		}

	if(!_1 && !_2) {
		if(ok()) {
			puts("Solution exists.\nThere are no jokers.");
			printf("Put the first square to (%d, %d).\nPut the second square to (%d, %d).\n",X1+1,Y1+1,X2+1,Y2+1);
		}
		else {
			puts("No solution.");
		}
	}
	else if(_1 & !_2 ) {
		for(int i = 0; i < 52; i++) if(mesa.count(mapa[i]) == 0) {
			tab[jx[0]][jy[0]] = mapa[i];
			if(ok()) {
				puts("Solution exists.");
				printf("Replace J1 with %s.\n", mapa[i].c_str());
				printf("Put the first square to (%d, %d).\nPut the second square to (%d, %d).\n",X1+1,Y1+1,X2+1,Y2+1);
				return 0;
			}
		}
		puts("No solution.");
	}
	else if(!_1 & _2 ) {
		for(int i = 0; i < 52; i++) if(mesa.count(mapa[i]) == 0) {
			tab[jx[1]][jy[1]] = mapa[i];
			if(ok()) {
				puts("Solution exists.");
				printf("Replace J2 with %s.\n", mapa[i].c_str());
				printf("Put the first square to (%d, %d).\nPut the second square to (%d, %d).\n",X1+1,Y1+1,X2+1,Y2+1);
				return 0;
			}
		}
		puts("No solution.");
	}
	else {
		for(int i = 0; i < 52; i++) if(mesa.count(mapa[i]) == 0) for(int j = 0; j < 52; j++) if(j != i && mesa.count(mapa[j]) == 0) {
			tab[jx[0]][jy[0]] = mapa[i];
			tab[jx[1]][jy[1]] = mapa[j];
			if(ok()) {
				puts("Solution exists.");
				printf("Replace J1 with %s and J2 with %s.\n", mapa[i].c_str(), mapa[j].c_str());
				printf("Put the first square to (%d, %d).\nPut the second square to (%d, %d).\n",X1+1,Y1+1,X2+1,Y2+1);
				return 0;
			}
		}
		puts("No solution.");
	}

	return 0;
}

//I love natalia

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>

using namespace std;

string A[20][20];

bool check1(int r, int c) {
    set <char> S;

    int cnt = 0;

    for (int i = r; i <= r+2; i++)
        for (int j = c; j <= c+2; j++)
            if (A[i][j] == "J1" ||
                A[i][j] == "J2") {

                    cnt++;
            }
            else
                S.insert(A[i][j][0]);

    return ( (S.size() + cnt) == 9 );
}

bool check2(int r1, int c1, int r2, int c2) {
    for (int i = r1; i <= r1+2; i++)
        for (int j = c1; j <= c1+2; j++)
            if (r2 <= i && i <= r2+2 &&
                c2 <= j && j <= c2+2) {

                    return false;
            }

    return true;
}

bool check3(int r, int c) {
    set <char> S;

    for (int i = r; i <= r+2; i++)
        for (int j = c; j <= c+2; j++)
            S.insert(A[i][j][0]);

    return ( S.size() == 9 );
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int n, m;
    cin >> n >> m;

    string tmpRank[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
    string tmpSuit[4]  = {"C", "D", "H", "S"};
    set <string> Pack;
    for (int i = 0; i < 13; i++)
        for (int j = 0; j < 4; j++)
            Pack.insert(tmpRank[i] + tmpSuit[j]);

    bool isThereJ1 = false;
    int         J1r;
    int         J1c;

    bool isThereJ2 = false;
    int         J2r;
    int         J2c;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            cin >> A[i][j];

            if (A[i][j] == "J1") {
                isThereJ1  = true;
                       J1r = i;
                       J1c = j;

                continue;
            }

            if (A[i][j] == "J2") {
                isThereJ2  = true;
                       J2r = i;
                       J2c = j;

                continue;
            }

            Pack.erase(Pack.find(A[i][j]));
        }

    vector <pair <int, int>> V;

    for (int r = 1; r <= n-2; r++)
        for (int c = 1; c <= m-2; c++)
            if (check1(r, c))
                V.push_back(make_pair(r, c));

    for (int i = 0; i < V.size(); i++)
        for (int j = i+1; j < V.size(); j++) {
            int r1 = V[i].first;
            int c1 = V[i].second;
            int r2 = V[j].first;
            int c2 = V[j].second;

            if (check2(r1, c1, r2, c2)) {
                if (isThereJ1 && isThereJ2) {
                    for (set <string>::iterator it1 = Pack.begin(); it1 != Pack.end(); it1++)
                        for (set <string>::iterator it2 = Pack.begin(); it2 != Pack.end(); it2++) {
                            if (it1 == it2)
                                continue;

                            A[J1r][J1c] = *it1;
                            A[J2r][J2c] = *it2;

                            if (check3(r1, c1) &&
                                check3(r2, c2)) {

                                    cout << "Solution exists." << endl;
                                    cout << "Replace J1 with " << (*it1) << " and J2 with " << (*it2) << "." << endl;
                                    cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
                                    cout << "Put the second square to (" << r2 << ", " << c2 << ").";

                                    return 0;
                            }

                            A[J1r][J1c] = "J1";
                            A[J2r][J2c] = "J2";
                        }

                    continue;
                }

                if (isThereJ1) {
                    for (set <string>::iterator it = Pack.begin(); it != Pack.end(); it++) {
                        A[J1r][J1c] = *it;

                        if (check3(r1, c1) &&
                            check3(r2, c2)) {

                                cout << "Solution exists." << endl;
                                cout << "Replace J1 with " << (*it) << "." << endl;
                                cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
                                cout << "Put the second square to (" << r2 << ", " << c2 << ").";

                                return 0;
                        }

                        A[J1r][J1c] = "J1";
                    }

                    continue;
                }

                if (isThereJ2) {
                    for (set <string>::iterator it = Pack.begin(); it != Pack.end(); it++) {
                        A[J2r][J2c] = *it;

                        if (check3(r1, c1) &&
                            check3(r2, c2)) {

                                cout << "Solution exists." << endl;
                                cout << "Replace J2 with " << (*it) << "." << endl;
                                cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
                                cout << "Put the second square to (" << r2 << ", " << c2 << ").";

                                return 0;
                        }

                        A[J2r][J2c] = "J2";
                    }

                    continue;
                }

                cout << "Solution exists." << endl;
                cout << "There are no jokers." << endl;
                cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
                cout << "Put the second square to (" << r2 << ", " << c2 << ").";

                return 0;
            }
        }

    cout << "No solution.";

    return 0;
}

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

string s1 = "23456789TJQKA", s2 = "CDHS";
set<string> set1, set2, all;
pair<int, int> J1, J2, ans1, ans2;
string arr[60][60];
bool vi[60][60];
int n, m;

void Init(){
    for (auto i:s1){
        for (auto j:s2){
            string temp = "";
            temp+=i; temp+=j;
            all.insert(temp);
        }
    }
    J1 = J2 = {59, 59};
}

bool Valid(int i, int j, int f){
    if (!f){
        memset(vi, 0, sizeof(vi));
    }
    if (i+2>=n && j+2>=m)
        return 0;
    set<char> st1, st2;
    for (int t=i;t<(i+3);t++){
        for (int k=j;k<(j+3);k++){
            if (vi[t][k] && f)
                return 0;
            vi[t][k] = !f;
            st1.insert(arr[t][k][0]);
            st2.insert(arr[t][k][1]);
        }
    }
    return (st1.size()==9||st2.size()==1);
}

bool Check(){
    for (int i=0;i<n;i++){
        for (int j=0;j<m;j++){
            if (Valid(i, j, 0)){
                for (int ii=0;ii<n;ii++){
                    for (int jj=0;jj<m;jj++){
                        if (Valid(ii, jj, 1)){
                            ans1 = {i, j};
                            ans2 = {ii, jj};
                            return 1;
                        }
                    }
                }
            }
        }
    }
    return 0;
}

int main()
{
    Init();
    cin >> n >> m;
    for (int i=0;i<n;i++){
        for (int j=0;j<m;j++){
            cin >> arr[i][j];
            if (arr[i][j] == "J1"){
                J1 = {i,j};
            } else if (arr[i][j] == "J2"){
                J2 = {i, j};
            } else {
                all.erase(all.find(arr[i][j]));
            }
        }
    }
    /*
    for (int i=0;i<n;i++){
        for (int j=0;j<m;j++){
            cout << arr[i][j] << ' ';
        }
        cout << endl;
    }
    */
    for (auto i:all){
        for (auto j:all){
            if (i != j){
                arr[J1.first][J1.second] = i;
                arr[J2.first][J2.second] = j;
                if (Check()){
                    cout << "Solution exists.\n";
                    if (J1.first == 59 && J2.first == 59){
                        cout << "There are no jokers.\n";
                    }else if (J1.first != 59 && J2.first != 59){
                        cout << "Replace J1 with "<< i << " and J2 with "<< j << ".\n";
                    }else if (J2.first == 59){
                        cout << "Replace J1 with " << i << ".\n";
                    } else if (J1.first == 59){
                        cout << "Replace J2 with " << j << ".\n";
                    }
                    cout << "Put the first square to (" << ans1.first+1<< ", " << ans1.second+1 << ").\n";
                    cout << "Put the second square to (" << ans2.first+1<< ", " << ans2.second+1 << ").\n";
                    return 0;
                }
            }
        }
    }
    cout << "No solution.\n";
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
typedef long long ll;

int a[17][17];

const int maxN = 52;

int used[maxN];
int ff[maxN];
int abs_(int x) {return max(x, -x);}

int n, m;
int ctim = 0;

int check(int i, int j) {
    int o = a[i][j] / 13;
    ctim++;
    int f1 = 1;
    int f2 = 1;
    for (int di = 0; di < 3; di++) {
        for (int dj = 0; dj < 3; dj++) {
            int ii = i + di;
            int jj = j + dj;
            int g = a[ii][jj] % 13;
            if (ff[g] == ctim) {
                f1 = 0;
            }
            ff[g] = ctim;
            if (a[ii][jj] / 13 != o) {
                f2 = 0;
            }
        }
    }
    return f2 | f1;
}

int ii1, jj1, ii2, jj2;

int check() {
    for (int i1 = 0; i1 + 2 < n; i1++) {
        for (int j1 = 0; j1 + 2 < m; j1++) {
            for (int i2 = 0; i2 + 2 < n; i2++) {
                for (int j2 = 0; j2 + 2 < m; j2++) {
                    if (max(abs_(i1 - i2), abs_(j2 - j1)) <= 2) {
                        continue;
                    }
                    if (check(i1, j1) && check(i2, j2)) {
                        ii1 = i1 + 1;
                        jj1 = j1 + 1;
                        ii2 = i2 + 1;
                        jj2 = j2 + 1;
                        return 1;
                    }
                }
            }
        }
    }
    return 0;
}

int main() {
    string R = "23456789TJQKA";
    string S = "CDHS";
    map<string,int> id;
    vector<string> cards;
    for (auto y : S) {
        for (auto x : R) {
            string cur = "xy";
            cur[0] = x;
            cur[1] = y;
            cards.push_back(cur);
        }
    }
    cards.push_back("J1");
    cards.push_back("J2");
    for (int i = 0; i < cards.size(); i++) {
        id[cards[i]] = i;
    //    cout << cards[i] << " ";
    }
    //cout << endl;
    cin >> n >> m;
    int i1 = -1, j1 = -1,  i2 = -1, j2 = -1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            string s;
            cin >> s;
            if (s == "J1") {
                i1 = i;
                j1 = j;
                continue;
            }
            if (s == "J2") {
                i2 = i;
                j2 = j;
                continue;
            }
            a[i][j] = id[s];
            //cout << a[i][j] << " ";
            used[id[s]] = 1;
        }
    //    cout << endl;
    }
    vector<int> unused;
    for (int i = 0; i < 52; i++) {
        if (!used[i]) {
            unused.push_back(i);
        }
    }
    if (i1 == -1 && i2 == -1) {
        if(check()) {
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            cout << "Put the first square to (" << ii1 << ", " << jj1 << ")." << endl;
            cout << "Put the second square to (" << ii2 << ", " << jj2 << ")." << endl;
            return 0;
        }
    } else if (i1 == -1 && i2 != -1) {
        for (auto x : unused) {
            a[i2][j2] = x;
            if(check()) {
                cout << "Solution exists." << endl;
                cout << "Replace J2 with " << cards[x] << "." << endl;
                cout << "Put the first square to (" << ii1 << ", " << jj1 << ")." << endl;
                cout << "Put the second square to (" << ii2 << ", " << jj2 << ")." << endl;
                return 0;
            }
        }
    } else if (i1 != -1 && i2 == -1) {
        for (auto x : unused) {
            a[i1][j1] = x;
            if(check()) {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with " << cards[x] << "." << endl;
                cout << "Put the first square to (" << ii1 << ", " << jj1 << ")." << endl;
                cout << "Put the second square to (" << ii2 << ", " << jj2 << ")." << endl;
                return 0;
            }
        }
    } else {
        for (auto x : unused) {
            for (auto y : unused) {
                a[i1][j1] = x;
                a[i2][j2] = y;
                if (y == x) continue;
                if(check()) {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with " << cards[x] << " and J2 with " << cards[y] <<"." << endl;
                    cout << "Put the first square to (" << ii1 << ", " << jj1 << ")." << endl;
                    cout << "Put the second square to (" << ii2 << ", " << jj2 << ")." << endl;
                    return 0;
                }
            }
        }
    }
    cout << "No solution." << endl;
    return 0;
}

#include <cmath>
#include <iostream>
#include <map>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <iomanip>
#include <queue>

using namespace std;

string suit[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "J", "T", "Q", "K", "A"};
string ranks[4] = {"C", "D", "S", "H"};

vector <string> ms;
vector <bool> used(60);

int mtrx[20][20];
int n, m;
bool f = false;
int yfi, xfi, yse, xse;

void srch()
{
    vector < pair <int, int> > t;
    for(int i = 0; i < n - 2; i++)
        for(int j = 0; j < m - 2; j++)
        {
            int o = 0, d = 0;
            vector <int> mp;
            for(int ii = 0; ii < 3; ++ii)
                for(int jj = 0; jj < 3; ++jj)
                    mp.push_back(mtrx[i + ii][j + jj]);
            for(int ii = 0; ii < mp.size(); ++ii)
                for(int jj = ii + 1; jj < mp.size(); ++jj)
                {
                    if(ms[mp[ii]][0] != ms[mp[jj]][0])
                        o++;
                    if(ms[mp[ii]][1] != ms[mp[jj]][1])
                        d++;
                }
            if(d == 0 || o == 36)
                t.push_back(make_pair(i, j));
        }
    for(int i = 0; i < t.size(); ++i)
        for(int j = i + 1; j < t.size(); ++j)
        {
            int x1 = t[i].first, x2 = t[i].first + 2, y1 = t[i].second, y2 = t[i].second + 2;
            int x3 = t[j].first, x4 = t[j].first + 2, y3 = t[j].second, y4 = t[j].second + 2;
            if(!(min(x1, x2) <= max(x3, x4) && min(y1, y2) <= max(y3, y4) && min(x3, x4) <= max(x1, x2) && min(y3, y4) <= max(y1, y2)))
            {
                f = true;
                yfi = x1, xfi = y1;
                yse = x3, xse = y3;
                return;
            }
        }
}

int main()
{
    int x1 = -1, y1, x2 = -1, y2;
    int uk, uk2;
    string c, j1, j2;
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n >> m;
    for(int i = 0; i < 13; ++i)
        for(int j = 0; j < 4; ++j)
        {
            c = suit[i] + ranks[j];
            ms.push_back(c);
        }
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
        {
            cin >> c;
            for(int k = 0; k < 52; ++k)
                if (ms[k] == c)
                {
                    used[k] = true;
                    mtrx[i][j] = k;
                    break;
                }
            if(c == "J1" || c == "J2")
                if(x1 == -1)
                {
                    x1 = i;
                    y1 = j;
                    j1 = c;
                }
                else
                {
                    x2 = i;
                    y2 = j;
                    j2 = c;
                }
        }
    if(x1 == -1)
    {
        srch();
        if (f)
        {
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            cout << "Put the first square to (" << yfi+1 << ", " << xfi+1 << ")." << endl;
            cout << "Put the second square to (" << yse+1 << ", " << xse+1 << ").";
        }
        else
            cout << "No solution.";
    }
    else if(x2 == -1)
    {
        for (uk = 0; uk < 52; ++uk)
            if(!used[uk])
            {
                mtrx[x1][y1] = uk;
                srch();
                if (f)
                    break;
            }
        if (f)
        {
            cout << "Solution exists." << endl;
            cout << "Replace " << j1 << " with " << ms[uk] << ".\n";
            cout << "Put the first square to (" << yfi+1 << ", " << xfi+1 << ")." << endl;
            cout << "Put the second square to (" << yse+1 << ", " << xse+1 << ").";
        }
        else
            cout << "No solution.";
    }
    else
    {
        if(j1 != "J1")
        {
            swap(j1, j2);
            swap(x1, x2);
            swap(y1, y2);
        }
        for (uk = 0; uk < 52; uk++)
        {
            for (uk2 = 0; uk2 < 52; uk2++)
                if(!used[uk] && !used[uk2])
                {
                    if(uk == uk2) continue;
                    mtrx[x1][y1] = uk;
                    mtrx[x2][y2] = uk2;
                    srch();
                    if (f)
                        break;
                }
            if (f)
                break;
        }
        if (f)
        {
            cout << "Solution exists." << endl;
            cout << "Replace " << j1 << " with " << ms[uk] << " and " << j2 << " with " << ms[uk2] << ".\n";
            cout << "Put the first square to (" << yfi+1 << ", " << xfi+1 << ")." << endl;
            cout << "Put the second square to (" << yse+1 << ", " << xse+1 << ").";
        }
        else
            cout << "No solution.";
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define sqr(x) ((x) * (x))
#define pb push_back
#define eb emplace_back
#define maxn 1000006
#define eps 1e-8
#define pi acos(-1.0)
#define rep(k, i, j) for (int k = i; k < j; k++)
typedef long long ll;
typedef unsigned long long ull;

string A[25][25];

bool check1(int r, int c)
{
  set<char> S;

  int cnt = 0;

  for (int i = r; i <= r + 2; i++)
    for (int j = c; j <= c + 2; j++)
      if (A[i][j] == "J1" ||
          A[i][j] == "J2")
      {

        cnt++;
      }
      else
        S.insert(A[i][j][0]);

  return ((S.size() + cnt) == 9);
}

bool check2(int r1, int c1, int r2, int c2)
{
  for (int i = r1; i <= r1 + 2; i++)
    for (int j = c1; j <= c1 + 2; j++)
      if (r2 <= i && i <= r2 + 2 &&
          c2 <= j && j <= c2 + 2)
      {

        return false;
      }

  return true;
}

bool check3(int r, int c)
{
  set<char> S;

  for (int i = r; i <= r + 2; i++)
    for (int j = c; j <= c + 2; j++)
      S.insert(A[i][j][0]);

  return (S.size() == 9);
}

int main()
{
#ifndef ONLINE_JUDGE
  //   freopen("input.txt","r",stdin);
#endif
  std::ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;

  string tmpRank[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
  string tmpSuit[4] = {"C", "D", "H", "S"};
  set<string> Pack;
  for (int i = 0; i < 13; i++)
    for (int j = 0; j < 4; j++)
      Pack.insert(tmpRank[i] + tmpSuit[j]);
  bool isThereJ1 = false;
  int J1r;
  int J1c;
  bool isThereJ2 = false;
  int J2r;
  int J2c;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
    {
      cin >> A[i][j];
      if (A[i][j] == "J1")
      {
        isThereJ1 = true;
        J1r = i;
        J1c = j;

        continue;
      }
      if (A[i][j] == "J2")
      {
        isThereJ2 = true;
        J2r = i;
        J2c = j;

        continue;
      }
      Pack.erase(Pack.find(A[i][j]));
    }

  vector<pair<int, int>> V;

  for (int r = 1; r <= n - 2; r++)
    for (int c = 1; c <= m - 2; c++)
      if (check1(r, c))
        V.push_back(make_pair(r, c));

  for (int i = 0; i < V.size(); i++)
    for (int j = 0; j < V.size(); j++)
    {
      if (i == j)
        continue;
      int r1 = V[i].first;
      int c1 = V[i].second;
      int r2 = V[j].first;
      int c2 = V[j].second;
      if (check2(r1, c1, r2, c2))
      {
        if (isThereJ1 && isThereJ2)
        {
          for (set<string>::iterator it1 = Pack.begin(); it1 != Pack.end(); it1++)
            for (set<string>::iterator it2 = Pack.begin(); it2 != Pack.end(); it2++)
            {
              if (it1 == it2)
                continue;
              A[J1r][J1c] = *it1;
              A[J2r][J2c] = *it2;
              if (check3(r1, c1) &&
                  check3(r2, c2))
              {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with " << (*it1) << " and J2 with " << (*it2) << "." << endl;
                cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
                cout << "Put the second square to (" << r2 << ", " << c2 << ").";
                return 0;
              }
              A[J1r][J1c] = "J1";
              A[J2r][J2c] = "J2";
            }

          continue;
        }

        if (isThereJ1)
        {
          for (set<string>::iterator it = Pack.begin(); it != Pack.end(); it++)
          {
            A[J1r][J1c] = *it;
            if (check3(r1, c1) &&
                check3(r2, c2))
            {
              cout << "Solution exists." << endl;
              cout << "Replace J1 with " << (*it) << "." << endl;
              cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
              cout << "Put the second square to (" << r2 << ", " << c2 << ").";
              return 0;
            }
            A[J1r][J1c] = "J1";
          }
          continue;
        }
        if (isThereJ2)
        {
          for (set<string>::iterator it = Pack.begin(); it != Pack.end(); it++)
          {
            A[J2r][J2c] = *it;
            if (check3(r1, c1) &&
                check3(r2, c2))
            {
              cout << "Solution exists." << endl;
              cout << "Replace J2 with " << (*it) << "." << endl;
              cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
              cout << "Put the second square to (" << r2 << ", " << c2 << ").";
              return 0;
            }
            A[J2r][J2c] = "J2";
          }
          continue;
        }
        cout << "Solution exists." << endl;
        cout << "There are no jokers." << endl;
        cout << "Put the first square to (" << r1 << ", " << c1 << ")." << endl;
        cout << "Put the second square to (" << r2 << ", " << c2 << ").";
        return 0;
      }
    }
  cout << "No solution.";
}

#include<stdio.h>
#include<vector>
#include<algorithm>
#include <iostream>
#include <cmath>
#include <complex>
#include<queue>
#include <string>
#include<bits/stdc++.h>
#define pi 3.14159265
#define forr(i,a,b) for(int i=a;i<=b;i++)
#define F first
#define S second
using namespace std;
typedef pair<double,double>pdd;
typedef long long  ll;
typedef pair<ll, ll>pii;
//template<typename T>T gcd(T x, T y) { if(y == 0)return x; else return gcd(y, x%y); }
//typedef bitset<8> mask;
//int x[8]={1,0,0,-1,-1,-1,1,1};
//int y[8]={0,1,-1,0,-1,1,-1,1};
//const double PI = acos(-1.0);
//const double EPS = 1e-9;
//typedef complex<double> point;
int n,m,x1,x2,y1,y2,ind;
char c[15],d[15],h[15],s[15],a,b,t;
string ta[53][53];
vector<string>v;
pair<int,int>ans1,ans2;
bool check()
{
    vector<pair<int,int>>num;
   forr(i,1,n-2)
   forr(j,1,m-2)
   {
          set<char>f1,f2;
          forr(u,i,i+2)
          forr(k,j,j+2)
          f1.insert(ta[u][k][0]),f2.insert(ta[u][k][1]);
          if(f1.size()==9||f2.size()==1)
          num.push_back({i,j});
   }
   if(num.size()>1)
   forr(i,0,num.size()-1)
   forr(j,0,num.size()-1)
   {
     if(i==j)continue;
    if(abs(num[i].F-num[j].F)>=3||abs(num[i].S-num[j].S)>=3)
    {
        ans1={num[i].F,num[i].S};
        ans2={num[j].F,num[j].S};
        return 1;
    }
   }
   return 0;
}
int main()
{
    //cout<<Pow((ll)1000000,(ll)110);
//freopen("hotel.in","r",stdin);
//freopen("math.in","w",stdout);
//    char input[15];
//    scanf("%s", &input);
cin>>n>>m;
forr(i,1,n)
forr(j,1,m)
{
    cin>>a>>b;
    ta[i][j].push_back(a);
    ta[i][j].push_back(b);
    if(b=='1'){x1=i,y1=j;continue;}
    if(b=='2'){x2=i,y2=j;continue;}

    if(a=='A')ind =1;
    else if(a=='T')ind=10;
    else if(a=='J')ind=11;
    else if(a=='Q')ind=12;
    else if(a=='K')ind=13;
    else ind=a-'0';

    if(b=='C')c[ind]=1;
    else if(b=='D')d[ind]=1;
    else if(b=='H')h[ind]=1;
    else if(b=='S')s[ind]=1;
}
forr(i,1,13)if(!c[i])
{   if(i==1)t ='A';
    else if(i==10)t='T';
    else if(i==11)t='J';
    else if(i==12)t='Q';
    else if(i==13)t='K';
    else t=i+'0';
    string k="";k.push_back(t);
    k.push_back('C');
    v.push_back(k);
}
forr(i,1,13)if(!d[i])
{   if(i==1)t ='A';
    else if(i==10)t='T';
    else if(i==11)t='J';
    else if(i==12)t='Q';
    else if(i==13)t='K';
    else t=i+'0';
    string k="";k.push_back(t);
    k.push_back('D');
    v.push_back(k);
}
forr(i,1,13)if(!h[i])
{   if(i==1)t ='A';
    else if(i==10)t='T';
    else if(i==11)t='J';
    else if(i==12)t='Q';
    else if(i==13)t='K';
    else t=i+'0';
    string k="";k.push_back(t);
    k.push_back('H');
    v.push_back(k);
}
forr(i,1,13)if(!s[i])
{   if(i==1)t ='A';
    else if(i==10)t='T';
    else if(i==11)t='J';
    else if(i==12)t='Q';
    else if(i==13)t='K';
    else t=i+'0';
    string k="";k.push_back(t);
    k.push_back('S');
    v.push_back(k);
}
if(x1&&x2)
{
forr(i,0,v.size()-1)
{
    forr(j,0,v.size()-1)
    {
        if(i==j)continue;
        ta[x1][y1]=v[i];
        ta[x2][y2]=v[j];
        if(check())
        {
            printf("Solution exists.\n");
            cout<<"Replace J1 with "<<v[i]<<" and J2 with "<<v[j]<<"."<<endl;
            printf("Put the first square to (%d, %d).\n",ans1.F,ans1.S);
            printf("Put the second square to (%d, %d).\n",ans2.F,ans2.S);
            return 0;
        }

    }
}
printf("No solution.\n");
}
else if(x1)
{
forr(i,0,v.size()-1)
{
        ta[x1][y1]=v[i];
        if(check())
        {
            printf("Solution exists.\n");
            cout<<"Replace J1 with "<<v[i]<<"."<<endl;
            printf("Put the first square to (%d, %d).\n",ans1.F,ans1.S);
            printf("Put the second square to (%d, %d).\n",ans2.F,ans2.S);
            return 0;
        }
}
printf("No solution.\n");
}
else if(x2)
{
forr(i,0,v.size()-1)
{
        ta[x2][y2]=v[i];
        if(check())
        {
            printf("Solution exists.\n");
            cout<<"Replace J2 with "<<v[i]<<"."<<endl;
            printf("Put the first square to (%d, %d).\n",ans1.F,ans1.S);
            printf("Put the second square to (%d, %d).\n",ans2.F,ans2.S);
            return 0;
        }
}
printf("No solution.\n");
}
else if(check())
{
            printf("Solution exists.\n");
            printf("There are no jokers.\n");
            printf("Put the first square to (%d, %d).\n",ans1.F,ans1.S);
            printf("Put the second square to (%d, %d).\n",ans2.F,ans2.S);
            return 0;
}
else
    printf("No solution.\n");
return 0;
}

#include <bits/stdc++.h>

using namespace std;
#define  ll long long
#define ld long double
#define f first
#define s second

int n , m;
vector<string> v;
vector< pair<int,int> > jok , sq;
string a[100][100];

void pre()
{
    string aa[15] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K","A"};
    string b[6] = {"C", "D", "H" ,"S"};
    for(int i=0; i<13; i++)
    {
        for(int j=0; j<4; j++)
        {
            string s = aa[i] + b[j];
            v.push_back(s);
        }
    }
}

bool check()
{
    vector< pair<int,int> > vv;
    for(int i=1; i+2<=n; i++)
    {
        for(int j=1; j+2<=m; j++)
        {
            set<char> st ,st2;
            for(int ii=i; ii<=i+2; ii++)
            {
                for(int jj=j; jj<=j+2; jj++)
                {
                    st.insert(a[ii][jj][0]);
                    st2.insert(a[ii][jj][1]);
                }
            }
            if (st.size() == 9 || st2.size()==1) vv.push_back({i,j});
        }
    }

     int vis[19][19]={};
    for(int i=0; i<vv.size(); i++)
    {
        for(int ii=vv[i].f; ii<=vv[i].f+2; ii++)
        {
            for(int jj=vv[i].s; jj<=vv[i].s+2; jj++)
                vis[ii][jj]++;
        }
        for(int j=i+1; j<vv.size(); j++)
        {
            for(int ii=vv[j].f; ii<=vv[j].f+2; ii++)
            {
                for(int jj=vv[j].s; jj<=vv[j].s+2; jj++)
                {
                    if (vis[ii][jj]) goto here;
                }
            }
            sq.push_back(vv[i]);
            sq.push_back(vv[j]);
            return 1;
            here :
            continue;
        }
        for(int ii=vv[i].f; ii<=vv[i].f+2; ii++)
        {
            for(int jj=vv[i].s; jj<=vv[i].s+2; jj++)
                vis[ii][jj]--;
        }
    }
    return 0;
}

void ans(string jokName , string nw)
{
    int x=sq[0].f , y=sq[0].s , xx=sq[1].f , yy=sq[1].s;

    cout << "Solution exists.\n";
    cout << "Replace " << jokName << " with " << nw << ".\n";
    cout << "Put the first square to (" << x << ", " << y << ").\n";
    cout << "Put the second square to (" << xx << ", " << yy << ").\n";
    exit(0);
}

void ans2()
{
    int x=sq[0].f , y=sq[0].s , xx=sq[1].f , yy=sq[1].s;

    cout << "Solution exists.\n";
    cout << "There are no jokers.\n";
    cout << "Put the first square to (" << x << ", " << y << ").\n";
    cout << "Put the second square to (" << xx << ", " << yy << ").\n";
    exit(0);
}

void ans3(string jokName , string jokName2 , string nw , string nw2)
{
    int x=sq[0].f , y=sq[0].s , xx=sq[1].f , yy=sq[1].s;

    cout << "Solution exists.\n";
    if (jokName[1] == '1')
    {
        cout << "Replace " << jokName << " with " << nw << " and " << jokName2 << " with " << nw2 << ".\n";
    }
    else
    {
        cout << "Replace " << jokName2 << " with " << nw2 << " and " << jokName << " with " << nw << ".\n";

    }
    cout << "Put the first square to (" << x << ", " << y << ").\n";
    cout << "Put the second square to (" << xx << ", " << yy << ").\n";
    exit(0);
}

int main()
{
    pre();
    cin >> n >> m;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            cin >> a[i][j];
            if (a[i][j] == "J1" || a[i][j] == "J2") jok.push_back({i,j});
            else
            {
                int idx=0;
                for(idx=0; idx<v.size(); idx++)
                {
                    if (v[idx] == a[i][j]) break;
                }
                v.erase(v.begin()+idx);
            }
        }
    }

    if (!jok.size())
    {
        if (check()) ans2();
    }
    else if (jok.size()==1)
    {
        string jokName = a[jok[0].f][jok[0].s];
        int x = jok[0].f , y = jok[0].s;
        for(int i=0; i<v.size(); i++)
        {
            a[x][y] = v[i];
            if (check())
            {
                ans(jokName , v[i]);
            }
        }
    }
    else
    {
        string jokName = a[jok[0].f][jok[0].s] , jokName2 = a[jok[1].f][jok[1].s];
        int x = jok[0].f , y = jok[0].s , x2 = jok[1].f , y2 = jok[1].s;

        for(int i=0; i<v.size(); i++)
        {
            for(int j=0; j<v.size(); j++)
            {
                if (i==j) continue;
                a[x][y] = v[i] , a[x2][y2] = v[j];
                if (check())
                {
                    ans3(jokName , jokName2 , v[i] , v[j]);
                }
            }
        }
    }

    cout << "No solution.\n";

    return 0;
}

#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EPS 1e-10
#define setNil(x) memset((x),0,sizeof(x))
#define setINF(x) memset((x),63,sizeof(x))
#define setNegINF(x) memset((x),192,sizeof(x)) //NegINF=-INF-1
#define setNeg1(x) memset((x),255,sizeof(x))
#define MP make_pair
#define X first
#define Y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii,pii> ppp;
int n,m,p1x=-1,p1y=-1,p2x=-1,p2y=-1;
string suit[]={"H","C","D","S"};
string rk[]={"2","3","4","5","6","7","8","9","T","J","Q","K","A"};
ppp nosol;
string s[19][19];
map<string,bool> used;
bool valid(int x,int y){
	set<char> ss,sr;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			ss.insert(s[i][j][1]);
			sr.insert(s[i][j][0]);
		}
	}
	return ss.size()==1 || sr.size()==9;
}
ppp check(){
	for(int i=0;i<n-2;i++){
		for(int j=0;j<m-2;j++){
			if(!valid(i,j))continue;
			for(int i2=0;i2<n-2;i2++){
				for(int j2=0;j2<m-2;j2++){
					if(max(i,i2)<=min(i+2,i2+2) && max(j,j2)<=min(j+2,j2+2))continue;
					if(valid(i2,j2))return MP(MP(i,j),MP(i2,j2));
				}
			}
		}
	}
	return nosol;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>s[i][j];
			if(s[i][j]=="J1"){
				p1x=i;
				p1y=j;
			}
			else if(s[i][j]=="J2"){
				p2x=i;
				p2y=j;
			}
			else used[s[i][j]]=1;
		}
	}
	nosol=MP(pii(-1,-1),pii(-1,-1));
	if(~p1x){
		if(~p2x){
			for(int i=0;i<4;i++)for(int j=0;j<13;j++){
				string cur1=rk[j]+suit[i];
				if(used[cur1])continue;
				used[cur1]=1;
				for(int i2=0;i2<4;i2++)for(int j2=0;j2<13;j2++){
					string cur2=rk[j2]+suit[i2];
					if(used[cur2])continue;
					s[p1x][p1y]=cur1;
					s[p2x][p2y]=cur2;
					ppp ans=check();
					if(ans!=nosol){
						cout<<"Solution exists.\nReplace J1 with "<<cur1<<" and J2 with "<<cur2<<".\n";
						cout<<"Put the first square to ("<<ans.X.X+1<<", "<<ans.X.Y+1<<").\n";
						cout<<"Put the second square to ("<<ans.Y.X+1<<", "<<ans.Y.Y+1<<").\n";
						return 0;
					}
				}
				used[cur1]=0;
			}
		}
		else{
			for(int i=0;i<4;i++)for(int j=0;j<13;j++){
				string cur=rk[j]+suit[i];
				if(!used[cur]){
					s[p1x][p1y]=cur;
					ppp ans=check();
					if(ans!=nosol){
						cout<<"Solution exists.\nReplace J1 with "<<cur<<".\n";
						cout<<"Put the first square to ("<<ans.X.X+1<<", "<<ans.X.Y+1<<").\n";
						cout<<"Put the second square to ("<<ans.Y.X+1<<", "<<ans.Y.Y+1<<").\n";
						return 0;
					}
				}
			}
		}
		cout<<"No solution.\n";
	}
	else{
		if(~p2x){
			for(int i=0;i<4;i++)for(int j=0;j<13;j++){
				string cur=rk[j]+suit[i];
				if(!used[cur]){
					s[p2x][p2y]=cur;
					ppp ans=check();
					if(ans!=nosol){
						cout<<"Solution exists.\nReplace J2 with "<<cur<<".\n";
						cout<<"Put the first square to ("<<ans.X.X+1<<", "<<ans.X.Y+1<<").\n";
						cout<<"Put the second square to ("<<ans.Y.X+1<<", "<<ans.Y.Y+1<<").\n";
						return 0;
					}
				}
			}
			cout<<"No solution.\n";
		}
		else{
			ppp ans=check();
			if(ans==nosol)cout<<"No solution.\n";
			else{
				cout<<"Solution exists.\nThere are no jokers.\n";
				cout<<"Put the first square to ("<<ans.X.X+1<<", "<<ans.X.Y+1<<").\n";
				cout<<"Put the second square to ("<<ans.Y.X+1<<", "<<ans.Y.Y+1<<").\n";
			}
		}
	}
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>

#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <list>

using namespace std;

#define f0(_X,_Y) for(int (_X)=0;(_X)<(_Y);++(_X))
#define f1(_X,_Y) for(int (_X)=1;(_X)<=(_Y);++(_X))
#define ff(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<=(_Z);++(_X))
#define fF(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<(_Z);++(_X))
#define rf0(_X,_Y) for(int _X=(_Y)-1;(_X)>=0;--(_X))
#define rf1(_X,_Y) for(int _X=(_Y);(_X)>0;--(_X))
#define rff(_X,_Y,_Z) for(int _X=(_Y);(_X)>=(_Z);--(_X))
#define rfF(_X,_Y,_Z) for(int _X=(_Y);(_X)>(_Z);--(_X))
#define PRT(_X) std::cout<< #_X ": "<<_X<<std::endl;
#define TIME fprintf(stderr,"time : %.2f sec\n",double(clock())/CLOCKS_PER_SEC);
typedef long long ll;
typedef pair<int, int> pii;

#define scan1(_X) scanf("%d",&_X);
#define scan2(_X,_Y) scanf("%d%d",&_X,&_Y);
#define scan3(_X,_Y,_Z) scanf("%d%d%d",&_X,&_Y,&_Z);
#define print1(_X) printf("%d\n",_X);
#define PAIR_STRUCT(_T,_X,_Y,...) struct _T{int _X,_Y,##__VA_ARGS__; bool friend operator < (const _T &p, const _T &q){if(p._X!=q._X) return p._X<q._X; return p._Y<q._Y;}};

int n,m;
struct p{int x,y;} joker[2], ans[2];
struct c{;} ;
char pattern[]="SHCD"; // 4
char _rank[]="A23456789TJQK"; // 13
char in[18][18][3];
char rest[53][3];
char prt[200];
bool poss;

int chk[128];
bool sqr[18][18];

void process()
{

	static int count = 0;
	f1(i,n) f1(j,m) sqr[i][j]=false;
	f1(i,n) if(i+2<=n)
	{
		f1(j,m) if(j+2<=m)
		{
			bool duplicate = false;
			bool same = true;
			++count;
			// same suite || all diff _ranks
			f0(k,3) f0(l,3)
			{
				if(chk[in[i+k][j+l][0]] != count)
					chk[in[i+k][j+l][0]] = count;
				else
					duplicate = true;
				if(in[i+k][j+l][1] != in[i][j][1])
					same=false;
			}
			sqr[i][j] = same || !duplicate;
		}
	}
	f1(i,n)
		f1(j,m) if(sqr[i][j])
		{
			ff(k,i,n) f1(l,m) if(sqr[k][l] && (abs(i-k)>=3 || abs(j-l)>=3))
			{
				ans[0].y=i; ans[0].x=j;
				ans[1].y=k; ans[1].x=l;
				poss=true;
				return;
			}
		}
}

int main()
{
	int num_joker=0, joker_last=0, rn=0;
	scan2(n,m);
	f1(i,n) f1(j,m)
	{
		char card[4];
		scanf("%s",card); in[i][j][0] = card[0]; in[i][j][1]=card[1];
		if(card[1]=='1' || card[1]=='2')
		{
			++num_joker; int no = card[1]-'1';
			joker[no].y=i, joker[no].x=j;
			joker_last = no;
		}
	}

	f0(r,13) f0(p,4)
	{
		bool exist=false;
		f1(i,n) f1(j,m) if(in[i][j][0]==_rank[r] && in[i][j][1]==pattern[p])
		{
			i=n;
			exist=true;
			break;
		}
		if(!exist)
		{
			++rn;
			rest[rn][0] = _rank[r];
			rest[rn][1] = pattern[p];
		}
	}

	if(num_joker==0)
	{
		sprintf(prt,"There are no jokers.");
		process();
	}
	else if(num_joker==1)
	{
		f1(i,rn)
		{
			in[joker[joker_last].y][joker[joker_last].x][0] = rest[i][0];
			in[joker[joker_last].y][joker[joker_last].x][1] = rest[i][1];
			process();
			if(poss)
			{
				sprintf(prt,"Replace J%d with %s.",joker_last+1, rest[i]);
				break;
			}
		}
	}
	else
	{
		f1(i,rn)
		{
			in[joker[0].y][joker[0].x][0] = rest[i][0];
			in[joker[0].y][joker[0].x][1] = rest[i][1];
			f1(j,rn) if(i!=j)
			{
				in[joker[1].y][joker[1].x][0] = rest[j][0];
				in[joker[1].y][joker[1].x][1] = rest[j][1];
				process();
				if(poss)
				{
					sprintf(prt,"Replace J1 with %s and J2 with %s.", rest[i], rest[j]);
					i=rn;
					break;
				}
			}

		}
	}

	if(poss)
	{
		printf("Solution exists.\n");
		printf("%s\n",prt);
		printf("Put the first square to (%d, %d).\n", ans[0].y, ans[0].x);
		printf("Put the second square to (%d, %d).\n", ans[1].y, ans[1].x);

	}
	else
	{
		printf("No solution.\n");
	}

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

mt19937 rnd(339264);

const ll MOD = 998244353;

const string cards = "23456789TJQKA";
const string masts = "CDHS";

vector<pair<int, int>> check(int n, int m, vector<vector<string>> &field) {
    vector<pair<int, int>> good;
    for (int i = 0; i + 3 <= n; i++) {
        for (int j = 0; j + 3 <= m; j++) {
            set<char> card;
            set<char> mast;
            for (int di = 0; di < 3; di++) {
                for (int dj = 0; dj < 3; dj++) {
                    card.insert(field[i + di][j + dj][0]);
                    mast.insert(field[i + di][j + dj][1]);
                }
            }
            if (card.size() == 9 || mast.size() == 1) {
                good.push_back({i, j});
            }
        }
    }
    for (auto p: good) {
        for (auto q: good) {
            if (q.first >= p.first + 3 || q.second >= p.second + 3) {
                return {p, q};
            }
        }
    }
    return {};
}

int main(){
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios_base::sync_with_stdio(0), cin.tie(0);

    vector<string> all_cards;
    for (char c1: cards) {
        for (char c2: masts) {
            string s = {c1, c2};
            all_cards.push_back(s);
        }
    }

    int n, m;
    cin >> n >> m;
    vector<vector<string>> field(n, vector<string>(m));
    set<string> taken;
    pair<int, int> p1 = {-1, -1}, p2 = {-1, -1};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> field[i][j];
            if (field[i][j] == "J1") {
                p1 = {i, j};
            } else if (field[i][j] == "J2") {
                p2 = {i, j};
            } else {
                taken.insert(field[i][j]);
            }
        }
    }

    for (int i = 0; i < all_cards.size(); i++) {
        for (int j = 0; j < all_cards.size(); j++) {
            if (p1.first != -1 && p2.first != -1 && i == j) {
                continue;
            }
            if (p1.first != -1) {
                if (taken.count(all_cards[i])) continue;
                field[p1.first][p1.second] = all_cards[i];
            }
            if (p2.first != - 1) {
                if (taken.count(all_cards[j])) continue;
                field[p2.first][p2.second] = all_cards[j];
            }
            auto vec = check(n, m, field);
            if (!vec.empty()) {
                cout << "Solution exists." << endl;
                if (p1.first == -1 && p2.first == -1) {
                    cout << "There are no jokers." << endl;
                } else {
                    if (p1.first != -1 && p2.first != -1) {
                        cout << "Replace J1 with " << all_cards[i] << " and J2 with " << all_cards[j] << "." << endl;
                    } else if (p1.first != -1) {
                        cout << "Replace J1 with " << all_cards[i] << "." << endl;
                    } else if (p2.first != -1) {
                        cout << "Replace J2 with " << all_cards[j] << "." << endl;
                    }
                }
                cout << "Put the first square to (" << vec[0].first + 1 <<  ", " << vec[0].second + 1 << ")." << endl;
                cout << "Put the second square to (" << vec[1].first + 1 <<  ", " << vec[1].second + 1 << ")." << endl;
                return 0;
            }
        }
    }

    cout << "No solution." << endl;
    return 0;
}

///HEADER FILES///

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<cstdlib>
#include<complex>
#include<iomanip>
#include<utility>
#include<bitset>
#include<list>
#include<assert.h>
#include<numeric>
#include<fstream>
using namespace std;

///DEFINES///

///ALWAYS USEFUL
#define     caseprint(case)     printf("Case %d: ", case++)
#define     caseprintnl(case)   printf("Case %d:\n", case++)
#define     clr(a)              memset(a, 0, sizeof(a))
#define     mem(a, b)           memset(a, b, sizeof(a))
#define     pb                  push_back
#define     pp                  pop_back
#define     ful_vec(v)          v.begin(), v.end()
#define     sort_vec(v)         sort(fulvec(v))
#define     sf                  scanf
#define     pf                  printf
#define     NL                  pf("\n")
#define     sz(a)               (int)a.size()
#define     bitcheck(n, pos)    (n & (1<<(pos)))
#define     biton(n, pos)       (n | (1<<(pos)))
#define     bitoff(n, pos)      (n & ~(1<<(pos)))
#define     sqr(a)              ((a)*(a))

///SCAN
#define     sfs(a)              scanf("%s", &a)
#define     sfi1(a)             scanf("%d", &a)
#define     sfi2(a, b)          scanf("%d %d", &a, &b)
#define     sfi3(a, b, c)       scanf("%d %d %d", &a, &b, &c)
#define     sfi4(a, b, c, d)    scanf("%d %d %d %d", &a, &b, &c, &d)
#define     sfd1(a)             scanf("%lf", &a)
#define     sfd2(a, b)          scanf("%lf %lf", &a, &b)
#define     sfd3(a, b, c)       scanf("%lf %lf %lf", &a, &b, &c)
#define     sfd4(a, b, c, d)    scanf("%lf %lf %lf %lf", &a, &b, &c, &d)
#define     sfll1(a)            scanf("%lld", &a)
#define     sfll2(a, b)         scanf("%lld %lld", &a, &b)
#define     sfll3(a, b, c)      scanf("%lld %lld %lld", &a, &b, &c)
#define     sfll4(a, b, c, d)   scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
#define     sfull1(a)           scanf("%llu", &a)
#define     sfull2(a, b)        scanf("%llu %llu", &a, &b)
#define     sfull3(a, b, c)     scanf("%llu %llu %llu", &a, &b, &c)
#define     sfull4(a, b, c, d)  scanf("%llu %llu %llu %llu", &a, &b, &c, &d)

///GEOMETRY
#define     ang(a, b, c)            acos((sqr(b)+sqr(c)-sqr(a))/(2.0*b*c))
#define     dist(x1, y1, x2, y2)    sqrt(sqr(x1-x2)+sqr(y1-y2))

///TYPES///
typedef     long long           ll;
typedef     unsigned long long  ull;
typedef     pair<int, int>      pii;

///TEMPLATES///
template<class T1>void deb(T1 e)
{
    cout <<"-->"<< e << endl;
}
template<class T1, class T2> void deb(T1 e1, T2 e2)
{
    cout <<"-->"<< e1 << " " << e2 << endl;
}
template<class T1, class T2, class T3> void deb(T1 e1, T2 e2, T3 e3)
{
    cout <<"-->"<< e1 << " " << e2 << " " << e3 << endl;
}
template<class T1, class T2, class T3, class T4> void deb(T1 e1, T2 e2, T3 e3, T4 e4)
{
    cout <<"-->"<< e1 << " " << e2 << " " << e3 << " " << e4 << endl;
}
template<class T1, class T2, class T3, class T4, class T5> void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5)
{
    cout <<"-->"<< e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << endl;
}
template<class T1, class T2, class T3, class T4, class T5, class T6> void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6)
{
    cout <<"-->"<< e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << " " << e6 << endl;
}

//ll extGcd(ll a, ll b, ll& x, ll& y){if (b == 0){x = 1;y = 0;return a;}else{int g = extGcd(b, a % b, y, x);y -= a / b * x;return g;}}
//ll modInv(ll a, ll m){ll x, y; extGcd(a, m, x, y); x %= m; while (x < 0){x += m;} return x;}
//ll bigmod(ll a,ll b,ll m){if(b == 0) return 1%m;ll x = bigmod(a,b/2,m);x = (x * x) % m;if(b % 2 == 1) x = (x * a) % m;return x;}
//ll BigMod(ll B,ll P,ll M){ ll R=1%M; while(P>0) {if(P%2==1){R=(R*B)%M;}P/=2;B=(B*B)%M;} ret urn R;} /// (B^P)%M

//int x[] = {0,0,-1,1};//4-ways
//int y[] = {1,-1,0,0};//4-ways
//int x[] = {-1,-1,-1,0,0,1,1,1};//8-ways
//int y[] = {-1,0,1,-1,1,-1,0,1};//8-ways
//int x[] = {-2,-2,2,2,1,1,-1,-1};//knight moves
//int y[] = {1,-1,1,-1,2,-2,2,-2};//knight moves

///CONSTANTS
#define     pi                  acos(-1.0)
#define     ex                  exp(1)
#define     oo                  (1<<30)

///OTHERS
#define     READ                freopen("/home/dot0/Desktop/input.txt","r",stdin);
#define     WRITE               freopen("out.txt","w",stdout);
#define     accelerate          ios::sync_with_stdio(false)
#define     debug               printf("Ok\n")
#define     MOD                 1000000007
#define     M                   500000

int n, m;
string mat[20][20];
vector<string>cards;
map<string, int>mp, mp1;

string suits[5]= {"S", "D", "H", "C"};
string ranks[15]= {"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q","K"};

struct flag
{
    int r, c, st;
};

struct result
{
    int r1, c1, r2, c2;
};

result ans;

bool isValid(int i, int j, int k, int l)
{
    map< pii, int >mp4;
    for(int i1=i; i1<i+3; i1++)
    {
        for(int j1=j; j1<j+3; j1++)
        {
            mp4[make_pair(i1, j1)]=1;
        }
    }

    for(int i1=k; i1<k+3; i1++)
    {
        for(int j1=l; j1<l+3; j1++)
        {
            if(mp4[make_pair(i1, j1)]) return false;
        }
    }

    return true;
    /*
    if(k>=i && k<i+3 && l>=j && l<j+3)
    {
        //deb(i, j, k, l);
        return false;
    }
    if(i>=k && i<k+3 && j>=l && j<l+3) return false;
    return true;*/
}

bool check1(int i, int j)
{
    map<char, int>mp3;
    string str="";
    for(int i1=i; i1<i+3; i1++)
    {
        for(int j1=j; j1<j+3; j1++)
        {
            if(!mp3[mat[i1][j1][0]])
            {
                str+=mat[i1][j1][0];
                mp3[mat[i1][j1][0]]=1;
            }
        }
    }

    if(sz(str)==9) return true;
    return false;
}

bool check2(int i, int j)
{
    char ch=mat[i][j][1];
    for(int i1=i; i1<i+3; i1++)
    {
        for(int j1=j; j1<j+3; j1++)
        {
            if(mat[i1][j1][1]!=ch) return false;
        }
    }

    return true;
}

bool check(int i, int j, int k, int l)
{
    if((i+3)>n+1 || (j+3)>m+1) return false;
    if((k+3)>n+1 || (l+3)>m+1) return false;

    if(check1(i, j))
    {
        if(check1(k, l)) return true;
        if(check2(k, l)) return true;
    }

    else if(check2(i, j))
    {
        if(check1(k, l)) return true;
        if(check2(k, l)) return true;
    }

    return false;
}

bool isPossible()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            for(int k=1; k<=n; k++)
            {
                for(int l=1; l<=m; l++)
                {
                    if(isValid(i, j, k, l))
                    {
                        if(check(i, j, k, l))
                        {
                            ans.r1=i;
                            ans.c1=j;
                            ans.r2=k;
                            ans.c2=l;
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}

int main()
{
    //READ;
    while(sfi2(n, m)==2)
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<13; j++)
            {
                //deb(ranks[i], suits[j]);
                string s=ranks[j]+suits[i];
                //deb(s);
                cards.pb(s);
                mp[s]=1;
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                cin>>mat[i][j];
                mp1[mat[i][j]]=1;
            }
        }

        flag f1, f2;
        f1.st=0, f2.st=0;

        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(mat[i][j]=="J1")
                {
                    f1.st=1;
                    f1.r=i;
                    f1.c=j;
                    break;
                }
            }
        }

        for(int i=1; i<=n; i++)
        {
            //deb("i ", i);
            for(int j=1; j<=m; j++)
            {
                if(mat[i][j]=="J2")
                {
                    f2.st=1;
                    f2.r=i;
                    f2.c=j;
                    break;
                }
            }
        }

        //deb(f1.st, f2.st);

        ans.r1=ans.c1=ans.r2=ans.c2=-1;

        if(!f1.st && !f2.st)
        {
            if(isPossible())
            {
                pf("Solution exists.\n");
                pf("There are no jokers.\n");
                pf("Put the first square to (%d, %d).\n", ans.r1, ans.c1);
                pf("Put the second square to (%d, %d).\n", ans.r2, ans.c2);
            }
            else pf("No solution.\n");
        }
        else if(f1.st && !f2.st)
        {
            //debug;
            int f=0;
            for(int i=0; i<52; i++)
            {
                if(!mp1[cards[i]])
                {
                    //deb(cards[i]);
                    mat[f1.r][f1.c]=cards[i];
                    if(isPossible())
                    {
                        f=1;
                        pf("Solution exists.\n");
                        pf("Replace J1 with ");
                        cout<<cards[i]<<"."<<endl;
                        pf("Put the first square to (%d, %d).\n", ans.r1, ans.c1);
                        pf("Put the second square to (%d, %d).\n", ans.r2, ans.c2);
                        break;
                    }
                }
            }
            if(!f) pf("No solution.\n");
        }

        else if(!f1.st && f2.st)
        {
            //debug;
            int f=0;
            for(int i=0; i<52; i++)
            {
                if(!mp1[cards[i]])
                {
                    //deb(cards[i]);
                    mat[f2.r][f2.c]=cards[i];
                    if(isPossible())
                    {
                        f=1;
                        pf("Solution exists.\n");
                        pf("Replace J2 with ");
                        cout<<cards[i]<<"."<<endl;
                        pf("Put the first square to (%d, %d).\n", ans.r1, ans.c1);
                        pf("Put the second square to (%d, %d).\n", ans.r2, ans.c2);
                        break;
                    }
                }
            }
            if(!f) pf("No solution.\n");
        }

        else
        {
            int f=0;
            for(int i=0; i<52; i++)
            {
                for(int j=0; j<52; j++)
                {
                    if(i!=j && !mp1[cards[i]] && !mp1[cards[j]])
                    {
                        mat[f1.r][f1.c]=cards[i];
                        mat[f2.r][f2.c]=cards[j];
                        if(isPossible())
                        {
                            f=1;
                            pf("Solution exists.\n");
                            cout<<"Replace J1 with "<<cards[i]<<" and J2 with "<<cards[j]<<"."<<endl;
                            //pf("Replace J1 with %s and J2 with %s.\n", cards[i], cards[j]);
                            pf("Put the first square to (%d, %d).\n", ans.r1, ans.c1);
                            pf("Put the second square to (%d, %d).\n", ans.r2, ans.c2);
                            break;
                        }
                    }
                }
                if(f) break;
            }
            if(!f) pf("No solution.\n");
        }
    }

    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define endl '\n'
vector<vector<string>>s;
vector<pair<string, pair<int,int>>> jocker;
set<string> solitaire;
int r, c;
bool vis[20][20];
bool checkBlock(int row, int col, bool first)
{
    set<char> ranks, suits;
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            if(vis[row + i][col + j])
                return false;
            if(first)
                vis[row + i][col + j] = true;
            ranks.insert(s[row + i][col + j][0]);
            suits.insert(s[row + i][col + j][1]);
        }
    }
    return (ranks.size() == 9 || suits.size() == 1);
}
vector<pair<int, int>> tryFirst()
{
    vector<pair<int, int>> v;
    for(int i = 0; i < r - 2; i++)
    {
        for(int j = 0; j < c - 2; j++)
        {
            memset(vis, 0, sizeof vis);
            if(checkBlock(i, j, 1))
            {
                for(int k = 0; k < r - 2; k++)
                {
                    for(int w = 0; w < c - 2; w++)
                    {
                        if(checkBlock(k, w, 0))
                        {
                            v.push_back({i + 1, j + 1});
                            v.push_back({k + 1, w + 1});
                            return v;
                        }
                    }
                }
            }
        }
    }
    return v;
}
void printVect(vector<pair<int,int>> v)
{
    if(v.size() == 0)
            cout << "No solution.";
    else
    {
        cout << "Put the first square to (" << v[0].first << ", " << v[0].second << ")." << endl;
        cout << "Put the second square to (" << v[1].first << ", " << v[1].second << ")." << endl;
    }
}
int main()
{
    Hello
    char ranks[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    char suits[] = {'C', 'D', 'H', 'S'};
    for(int i = 0; i < 13; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            string temp = "";
            temp += ranks[i];
            temp += suits[j];
            solitaire.insert(temp);
        }
    }
    cin >> r >> c;
    s.resize(r + 5);
    for(int i = 0; i < r; i++)
    {
        s[i].resize(c + 5);
        for(int j = 0; j < c; j++)
        {
            cin >> s[i][j];
            solitaire.erase(s[i][j]);
            if(s[i][j] == "J1" || s[i][j] == "J2")
                jocker.push_back({s[i][j], {i, j}});
        }
    }
    //return 0;
    if(jocker.size() == 0)
    {
        vector<pair<int,int>> v = tryFirst();
        if(v.size())
            cout << "Solution exists." << endl  << "There are no jokers." << endl;
        printVect(v);
    }
    else if(jocker.size() == 1)
    {
        set<string> :: iterator it;
        for(it = solitaire.begin(); it != solitaire.end(); it++)
        {
            s[jocker[0].second.first][jocker[0].second.second] = *it;
            vector<pair<int,int>> v = tryFirst();
            if(v.size())
            {
                cout << "Solution exists." << endl;
                cout << "Replace " << jocker[0].first << " with " << *it << "." << endl;
                printVect(v);
                return 0;
            }
        }
        cout << "No solution.";
    }
    else if(jocker.size() == 2)
    {
        if(jocker[0].first != "J1")
            swap(jocker[0], jocker[1]);
        set<string>::iterator it;
        set<string>::iterator it2;
        for(it = solitaire.begin(); it != solitaire.end(); it++)
        {
            for(it2 = solitaire.begin(); it2 != solitaire.end(); it2++)
            {
                if(it == it2)
                    continue;
                s[jocker[0].second.first][jocker[0].second.second] = *it;
                s[jocker[1].second.first][jocker[1].second.second] = *it2;
                vector<pair<int,int>> v = tryFirst();
                if(v.size())
                {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with " << *it;
                    cout << " and J2 with " << *it2 << "." << endl;
                    printVect(v);
                    return 0;
                }
            }
        }
        cout << "No solution.";
    }
    return 0;
}

#include <bits/stdc++.h>

        using namespace std;

        /* ---*-----*-----
        ---------o--------
        -----------------*/

        typedef long long ll;
        typedef long double ld;

        typedef vector<ll> vl;

        #define mp make_pair
        #define pb push_back
        #define f first
        #define s second
        #define lb lower_bound
        #define ub upper_bound

        const int MOD = 1000000007;
        const int N = 100005;
        const double PI =4*atan(1);
        const ll MAX=9223372036854775807;

        //set<char> vowel={'A', 'O', 'Y','E', 'U', 'I','a','o','e','u','i'};

        int dx[]={1,-1,0,0,1,-1,1,-1};
        int dy[]={0,0,1,-1,1,1,-1,-1};

        ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
        ll lcm(ll a, ll b) { return a * (b / gcd(a, b)); }
        bool issquare(ll w ){return trunc(sqrt(w))*trunc(sqrt(w))==w;}
        bool isprime(ll u){for(ll i=2;i<=(int)sqrt(u);i++){if(u%i==0)return 0;}return 1;}
        ll mod(ll to_mod,ll MOD){to_mod%=MOD;while(to_mod<0)to_mod+=MOD;return to_mod%MOD;}
        ll moduloMultiplication(ll a,ll b,ll mod){ll res = 0;a %= mod;while (b){if (b & 1)
            res = (res + a) % mod;a = (2 * a) % mod;b >>= 1;}return res;}
        ll power(ll x, ll y/*,ll p*/){ll res = 1;x = x /*% p*/;
            while (y > 0){if (y & 1)res = (res*x)/* % p*/;y = y>>1;x = (x*x) /*% p*/;}return res;}
     /*  ll _sieve_size;bitset<10000010> bs;vl primes;
        void sieve(ll upperbound) {_sieve_size = upperbound + 1;bs.set();bs[0] = bs[1] = 0;
            for (ll i = 2; i<= _sieve_size; i++) if (bs[i]) {for (ll j = i * i; j <= _sieve_size; j += i) bs[j] = 0;primes.pb(i);} }
*/

        ll n,m,x,y,res,t,k,ans=0,b,q,z,l,a,c,d;
        set<string> tab[20][20];
        ll dp[20][20];
        bool ok[20][20];
        string grid[20][20];
        vector<string> color={"C","D","H","S"},number={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K","A"};
        set<string> cards;
        bool j3=false,j2=false;
        string j11="",j22="";

        int main(){
            ios::sync_with_stdio(0);
            memset(ok,0,sizeof(ok));
            memset(dp,0,sizeof(dp));
            for(auto t:number){
                for(auto i:color){
                        string sh=t+i;
                    cards.insert(sh);
                    //cout << sh << " ";
                }
            }
            cin >> n >> m;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    string sh ;
                    cin >> sh;
                    if(sh=="J1")j3=true;
                    if(sh=="J2")j2=true;
                    grid[i][j]=sh;
                    cards.erase(sh);
                }
            }
            //cout << cards.size() << endl;
            for(int i=0;i<n-2;i++){
                for(int j=0;j<m-2;j++){
                        set<char> col;
                        set<char> num;
                        res=0;
                        a=0;
                        //cout << i << " " << j << endl;
                    for(int k=i;k<=i+2;k++){
                        for(int u=j;u<=j+2;u++){
                            if(grid[k][u][0]=='J' && (grid[k][u][1]=='1' || grid[k][u][1]=='2')){
                                res++;
                                a=grid[k][u][1]-'0';
                                continue;
                            }
                            col.insert(grid[k][u][1]);
                            num.insert(grid[k][u][0]);
                        }
                    }if(res==0){
                        if(col.size()==1 || num.size()==9){
                            ok[i][j]=1;
                        }
                    }else if(res==1){
                        dp[i][j]=a;
                        if(col.size()>1 && num.size()<8){
                            continue;
                        }
                        if(col.size()==1){
                            for(auto t: cards){
                                if(t[1]==*col.begin()){
                                    tab[i][j].insert(t);
                                }
                            }
                        }
                        if(num.size()==8){
                            for(auto t: cards){
                                if(num.count(t[0])==0){
                                    tab[i][j].insert(t);
                                }
                            }
                        }
                        ok[i][j]=(tab[i][j].size()>=1);
                    }else if(res==2){
                        dp[i][j]=3;
                        if(col.size()>1 && num.size()<7){
                            continue;
                        }
                        if(col.size()==1){
                            for(auto t: cards){
                                for(auto p:cards){
                                    if(t==p)continue;
                                    if(t[1]!=*col.begin() || p[1]!=*col.begin())continue;
                                    tab[i][j].insert(t+" "+p);
                                }
                            }
                        }
                        if(num.size()==7){
                            for(auto t: cards){
                                for(auto p:cards){
                                    if(t[0]==p[0])continue;
                                    if(num.count(t[0])|| num.count(p[0]))continue;
                                    //cout << t << " " << p << endl;
                                    tab[i][j].insert(t+" "+p);
                                }
                            }
                        }
                        ok[i][j]=(tab[i][j].size()>=1);
                    }
                }
            }
            bool flag=false;
            for(int i=0;i<n-2;i++){
                    if(flag)break;
                for(int j=0;j<m-2;j++){
                    if(flag)break;
                    if(ok[i][j]==0)continue;
                    for(int u=0;u<n-2;u++){
                        if(flag)break;
                        for(int k=0;k<m-2;k++){
                            if(flag)break;
                            if(k>=j-2 && k<=j+2 && u>=i-2&& u<=i+2)continue;
                            if(ok[u][k]){
                                if(dp[u][k]==0 && dp[i][j]==0){
                                    flag=true;
                                    a=i;
                                    b=j;
                                    c=u;
                                    d=k;
                                    break;

                                }else if(dp[i][j]!=0 && dp[u][k]==0){
                                    flag= true;
                                    a=i;
                                    b=j;
                                    c=u;
                                    d=k;
                                    if(dp[i][j]==1)j11=*(tab[i][j]).begin();
                                    if(dp[i][j]==2)j22=*(tab[i][j]).begin();
                                    if(dp[i][j]==3){j11=(*(tab[i][j]).begin()).substr(0,2);
                                                    j22=(*(tab[i][j]).begin()).substr(3,2);
                                                    }
                                }else if(dp[i][j]==0 && dp[u][k]!=0){
                                    flag= true;
                                    a=i;
                                    b=j;
                                    c=u;
                                    d=k;
                                    if(dp[u][k]==1)j11=*(tab[u][k]).begin();
                                    if(dp[u][k]==2)j22=*(tab[u][k]).begin();
                                    if(dp[u][k]==3){j11=(*(tab[u][k]).begin()).substr(0,2);
                                                    j22=(*(tab[u][k]).begin()).substr(3,2);
                                                    }
                                }else if(dp[i][j]==1 && dp[u][k]==2){
                                    for(auto t:tab[i][j]){
                                            if(flag)break;
                                        for(auto r:tab[u][k]){
                                            if(t!=r){
                                                j11=t;
                                                j22=r;
                                                flag=true;
                                                a=i;
                                                b=j;
                                                c=u;
                                                d=k;
                                                break;
                                            }
                                        }
                                    }
                                }else if(dp[u][k]==1 && dp[i][j]==2){
                                    for(auto t:tab[i][j]){
                                            if(flag)break;
                                        for(auto r:tab[u][k]){
                                            if(t!=r){
                                                j11=r;
                                                j22=t;
                                                flag=true;
                                                a=i;
                                                b=j;
                                                c=u;
                                                d=k;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
           // cout << flag << endl;
            if(flag==false){
                cout <<"No solution.";
                return 0;
            }
            if(j22!="")cards.erase(j22);
            if(j11!="")cards.erase(j11);
            if(j3){
                if(j11=="")for(auto t: cards){j11=t;cards.erase(t);
                break;}
                if(j11==""){
                    cout <<"No solution.";
                    return 0;
                }

            }

            if(j2){
                if(j22=="")for(auto t: cards){j22=t;cards.erase(t);
                break;}
                if(j22==""){
                    cout <<"No solution.";
                    return 0;
                }
                cards.erase(j11);
            }
            cout << "Solution exists."<< endl;
            if(j3 &&j2){
                cout <<"Replace J1 with "+j11+" and J2 with "+j22+"."<< endl;
            }else if(j3){
                cout <<"Replace J1 with "+j11+"."<<endl;
            }else if(j2){
                cout <<"Replace J2 with "+j22+"."<<endl;
            }else{
                cout <<"There are no jokers."<<endl;
            }
            cout << "Put the first square to ("<<a+1<<", "<<b+1<<")."<<endl;
            cout << "Put the second square to ("<<c+1<<", "<<d+1<<")."<<endl;

            return 0;
        }

#include <iostream>
#include <cstring>
#include <string>
#include <set>
#define P pair<int, int>
#define F first
#define S second
using namespace std;

int n, m;
bool vis[20][20] = {};
P J1 = {0, 0}, J2 {0, 0}, ans1, ans2;
string a[20][20], suits = "SCDH", ranks = "A23456789TJQK";
set<string> rep;

bool valid(int x, int y, int flag)
{
    if (!flag) memset(vis, false, sizeof vis);
    set<char> cnt_suits, cnt_ranks;
    for (int i = x; i <= x + 2; i++)
        for(int j = y; j <= y + 2; j++)
        {
            if (flag && vis[i][j]) return false;
            cnt_ranks.insert(a[i][j][0]);
            cnt_suits.insert(a[i][j][1]);
            vis[i][j] = !flag;
        }
    return (cnt_ranks.size() == 9 || cnt_suits.size() == 1);
}

bool find_ans()
{
    for (int i = 1; i <= n - 2; i++)
        for (int j = 1; j <= m - 2; j++)
            if (valid(i, j, false))
                for (int k = 1; k <= n - 2; k++)
                    for (int l = 1; l <= m - 2; l++)
                        if (valid(k, l, true))
                        {
                            ans1 = {i, j};
                            ans2 = {k, l};
                            return true;
                        }
    return false;
}

int main()
{
    for (auto i : suits)
        for (auto j : ranks)
        {
            string t; t.push_back(j); t += i;
            rep.insert(t);
        }
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            cin >> a[i][j];
            if (a[i][j] == "J1") J1 = {i, j};
            else if (a[i][j] == "J2") J2 = {i, j};
            else rep.erase(a[i][j]);
        }
    for (auto it1 : rep)
        for (auto it2 : rep)
            if (it1 != it2)
            {
                a[J1.F][J1.S] = it1;
                a[J2.F][J2.S] = it2;
                if (find_ans())
                {
                    cout << "Solution exists.\n";
                    if (!J1.F && !J2.F)
                        cout << "There are no jokers.\n";
                    else if (J1.F && J2.F)
                        cout << "Replace J1 with " << it1 << " and J2 with " << it2 << ".\n";
                    else if (J1.F)
                        cout << "Replace J1 with " << it1 << ".\n";
                    else
                        cout << "Replace J2 with " << it2 << ".\n";
                    printf("Put the first square to (%d, %d).\n", ans1.F, ans1.S);
                    printf("Put the second square to (%d, %d).\n", ans2.F, ans2.S);
                    return 0;
                }
            }
    return cout << "No solution.\n", 0;
}

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <string>

#define Forn(i, n) for(i = 0; i < (int)(n); ++i)
#define forn(i, n) for(int i = 0; i < (int)(n); ++i)
#define ford(i, n) for(int i = (int)(n-1); i >= 0; --i)

#define mp make_pair

using namespace std;

int n, m;

string map[17][17], repJ[2];
vector<string> allCard;
string FR = "23456789TJQKA", SD = "CDHS";
int SQ[2][2];
int Bmap[17][17];

bool check2(){
    forn(num, 2){
        bool f2 = 1;
        forn(di, 3)
            forn(dj, 3)
                f2 &= (map[SQ[num][0]+di][SQ[num][1]+dj][1] == map[SQ[num][0]][SQ[num][1]][1]);
        string tmp;
        forn(di, 3)
            forn(dj, 3)
                tmp += map[SQ[num][0]+di][SQ[num][1]+dj][0];
        sort(tmp.begin(), tmp.end());
        if(unique(tmp.begin(), tmp.end()) != tmp.end() && !f2)
            return 0;
    }
    return 1;
}

bool check(){
    Forn(SQ[0][0], n - 2)
        Forn(SQ[0][1], m - 2)
            Forn(SQ[1][0], n - 2)
                Forn(SQ[1][1], m - 2){
                    bool ok = 1;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                if(++Bmap[SQ[num][0]+di][SQ[num][1]+dj] == 2)
                                    ok = 0;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                --Bmap[SQ[num][0]+di][SQ[num][1]+dj];
                    if(ok){
                        if(check2())
                            return 1;
                    }
                }
    return 0;

}

void f(int r, int c){
    if(r < n){
        if(c == m)
            f(r + 1, 0);
        else if(isdigit(map[r][c][1])){
            string J = map[r][c];
            forn(i, allCard.size()){
                if(allCard[i] == repJ[0] || allCard[i] == repJ[1])
                    continue;
                map[r][c] = allCard[i];
                repJ[J[1]-'1'] = map[r][c];
                f(r, c + 1);
                repJ[J[1]-'1'] = "";
            }
            map[r][c] = J;
        }else
            f(r, c + 1);
    }else{
        if(check()){
            cout << "Solution exists." << endl;
            if(repJ[0].length() == 0 && repJ[1].length() == 0 )
                cout << "There are no jokers." << endl;
            else if(repJ[0].length() == 0 || repJ[1].length() == 0 ){
                if(repJ[0].length() == 0)
                    cout << "Replace J2 with " << repJ[1] << "." << endl;
                else
                    cout << "Replace J1 with " << repJ[0] << "." << endl;
            }else{
                cout << "Replace J1 with " << repJ[0] << " and J2 with " << repJ[1] << "." << endl;
            }
            cout << "Put the first square to (" << SQ[0][0] + 1 << ", " << SQ[0][1] + 1 << ")." << endl;
            cout << "Put the second square to (" << SQ[1][0] + 1<< ", " << SQ[1][1] + 1 << ")." << endl;
            exit(0);
        }
    }
}

int main()
{
    forn(i, FR.length())
        forn(j, SD.length())
            allCard.push_back(string(1, FR[i]) + SD[j]);
    cin >> n >> m;
    int tmp = 0;
    forn(i, n)
        forn(j, m){
            cin >> map[i][j];
            if(!isdigit(map[i][j][1]))
                allCard.erase(find(allCard.begin(), allCard.end(), map[i][j]));
            else ++tmp;
        }
    f(0, 0);
    cout << "No solution." << endl;
    return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <string>
#include <set>
#include <complex>
#include <map>
#include <unordered_map>
#include <climits>
#include <bitset>
#include <queue>
using namespace std;

#define all(v)                      v.begin(), v.end()
#define dist2D(x1, y1, x2, y2)            ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
#define dist3D(x1, y1, z1, x2, y2, z2)    ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2))
#define EPS                         1e-16
#define endl                        "\n"
#define FastIO                      ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define FI                          freopen("in.txt", "r", stdin)
#define FO                          freopen("out.txt", "w", stdout)
#define ff                          first
#define INF              1000000000000000000
#define ld                          long double
#define ll                          long long
#define mem(x,y)                    memset(x, y, sizeof x)
#define mp                          make_pair
#define msi                         map<string, int>
#define mii                         map<int, int>
#define mis                         map<int, string>
#define MOD                         1000000007
#define PI                          acos(-1.0)
#define PQ                          priority_queue
#define pb                          push_back
#define pib                         pair<int, bool>
#define pii                         pair<int, int>
#define pll                         pair<ll, ll>
#define present(c, x)               ((c).find(x) != (c).end())
#define sfi(x)                      scanf("%d", &x)
#define sfii(x,y)                   scanf("%d %d", &x, &y)
#define sfiii(x,y,z)                scanf("%d %d %d", &x, &y, &z)
#define siz(x)                      (int)x.size()
#define ss                          second
#define timeTaken                   endd = clock(); cout << (double) (endd - beginn) / CLOCKS_PER_SEC * 1000 << endl
#define timeInit                    clock_t beginn = clock(), endd
#define ull                         unsigned long long
#define umsi                        unordered_map<string, int>
#define umii                        unordered_map<int, int>
#define umis                        unordered_map<int, string>
#define vb                          vector<bool>
#define vi                          vector<int>
#define vvi                         vector<vi>
#define vii                         vector<pii>
#define vvii                        vector<vii>
#define vll                         vector<ll>
#define vvll                        vector<vll>
#define vpll                        vector<pll>
#define bug(...)                    cerr << __PRETTY_FUNCTION__ << " - " << __LINE__ << " : (" << #__VA_ARGS__ << ") = ("; _Print(__VA_ARGS__);
template<class T> void _Print(T &&x) { cerr << x << ")" << endl; }
template<class T, class ...S> void _Print(T &&x, S &&...y) { cerr << x << ", "; _Print(y...); }

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <functional>
using namespace __gnu_pbds;
typedef tree<int,null_type, less<int>, rb_tree_tag,
        tree_order_statistics_node_update> ordered_set;

//os.order_of_key(v): returns how many elements strictly less than v
//os.find_by_order(k - 1): returns kth smallest element's iterator
*/

template<class T> class compare {
public:
    bool operator() (pair<T, T> &x, pair<T, T> &y) {
        if (x.first == y.first) {
            return x.ss > y.ss;
        }
        return x.ff > y.ff;
    }
};

template<class T> ostream &operator<<(ostream &os, const pair<T, T> &a) { return os << a.ff << " " << a.ss; }
ll power(ll a, int b) {
    ll po = 1;
    while (b) {
        if (b & 1)
            po *= a;
        a *= a;
        b >>= 1;
    }
    return po;
}

template<class T> pair<T, T> operator+(const pair<T, T> &a, const pair<T, T> &b) { return {a.ff + b.ff, a.ss + b.ss}; }
template<class T> pair<T, T> operator-(const pair<T, T> &a, const pair<T, T> &b) { return {a.ff - b.ff, a.ss - b.ss}; }
template<class T> pair<T, T> operator*(const pair<T, T> &a, const pair<T, T> &b) { return {a.ff * b.ff, a.ss * b.ss}; }
template<class T> pair<T, T> operator%(const pair<T, T> &a, const pair<T, T> &b) { return {a.ff % b.ff, a.ss % b.ss}; }
template<class T, class U> pair<T, T> operator+(const pair<T, T> &a, const U &b) { return {a.ff + b, a.ss + b}; }
template<class T, class U> pair<T, T> operator*(const pair<T, T> &a, const U &b) { return {a.ff * b, a.ss * b}; }

ll Set(ll N, int pos) { return N = N | (1LL << pos); }
int reset(int N, int pos){ return N = N & ~ (1 << pos); }
bool check(ll N, int pos){ return (bool) (N & (1LL << pos)); }

///=======================================template=======================================///

int main() {

    int n, m;
    cin >> n >> m;
    string suits = "CDHS";
    char rank[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    string jokers[] = {"J1", "J2"};

    string mat[n][m];
    vector<string> option;
    umsi tak;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> mat[i][j];
            tak[mat[i][j]] = 1;
        }
    }

    for (char &i : rank) {
        for (char &j : suits) {
            string now;
            now += i;
            now += j;
            if (!tak[now])
                option.pb(now);
        }
    }

    bool ok = false;
    string j1 = "void", j2 = "void";
    vii res;

    vii jok(2, {-1, -1});

    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {
            if (mat[r][c] == jokers[0])
                jok[0] = {r, c};
            else if (mat[r][c] == jokers[1])
                jok[1] = {r, c};
        }
    }

    for (int i = 0; i <siz(option); i++) {
        for (int j = 0; j < siz(option); j++) {
            if (i == j  and (jok[0].ff != -1 and jok[1].ff != -1))
                continue;
            int cnt = 1;
            for (int k = 0; k < 2; k++) {
                if (jok[k].ff != -1) {
                    if (cnt) {
                        mat[jok[k].ff][jok[k].ss] = option[i];
                        cnt = 0;
                    }
                    else
                        mat[jok[k].ff][jok[k].ss] = option[j];
                }
            }
            vii ans;
            for (int r = 0; r < n - 2; r++) {
                for (int c = 0; c < m - 2; c++) {
                    set<char> ran, sui;
                    for (int cn = 0; cn < 3 ; cn++) {
                        for (int jj = 0; jj < 3; jj++) {
                            ran.insert(mat[r + cn][c + jj][0]);
                            sui.insert(mat[r + cn][c + jj][1]);
                        }
                    }
                    if (siz(sui) == 1 or siz(ran) == 9) {
                        ans.pb({r, c});
                    }
                }
            }

            for (int f = 0; f < siz(ans); f++) {
                for (int s = f + 1; s < siz(ans); s++) {
                    if (abs(ans[f].ff - ans[s].ff) > 2 or abs(ans[f].ss - ans[s].ss) > 2) {
                        res.pb(ans[f]);
                        res.pb(ans[s]);
                        ok = true;

                        cnt = 1;

                        for (int k = 0; k < 2; k++) {
                            if (jok[k].ff != -1) {
                                if (cnt) {
                                    (k == 0 ? j1 : j2) = option[i];
                                    cnt = 0;
                                }
                                else
                                    (k == 0 ? j1 : j2) = option[j];
                            }
                        }
                        goto loop;
                    }
                }
            }

        }
    }

    loop:

    if (ok) {
        cout << "Solution exists." << endl;
        if (j1 == "void" and j2 == "void") {
            cout << "There are no jokers." << endl;
        }
        else if (j1 == "void") {
            cout << "Replace J2 with " << j2 << "." << endl;
        }
        else if (j2 == "void") {
            cout << "Replace J1 with " << j1 << "." << endl;
        }
        else cout << "Replace J1 with " << j1 << " and J2 with " << j2 << "." << endl;
        cout << "Put the first square to (" << res[0].ff + 1 << ", " << res[0].ss + 1 << ")." << endl;
        cout << "Put the second square to (" << res[1].ff + 1 << ", " << res[1].ss + 1 << ")." << endl;
    }
    else {
        cout << "No solution." << endl;
    }

    return 0;
}

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <sstream>
#include <list>
using namespace std;
typedef long long LL;
//typedef __int64 LL;
typedef pair<int,int> PII;
typedef pair<int,char> PIC;
typedef vector<int> VI;
typedef vector<PII> VPI;
typedef vector<bool> VB;
typedef vector<string> VS;
typedef set<int> SI;
typedef list<string> LS;
typedef map<int, int> MII;
#define ALL(x) x.begin(),x.end()
#define REP(i,a,b) for(int i=(a);i<=(b);i++)
#define FOR(i,a) for(int i=0;i<(a);i++)
#define DEP(i,a,b) for(int i=(a);i>=(b);i--)
#define FORIT(it, c) for(__typeof(c.begin())it=c.begin();it!=c.end();it++)
#define CLR(x,a) memset(x,a,sizeof(x))
#define ALL(x) x.begin(),x.end()
#define LB(x) ((x)&(-(x)))
#define MP make_pair
#define PB push_back
#define oo 0x3f3f3f3f
#define X first
#define Y second
#define sqr(x) ((x)*(x))

const int MAXN = 17 + 10, MAXM = 17 + 10;
int n, m;
string gp[MAXN][MAXN];
vector<PII> res;
vector<string> ans1, ans2;
string str[] = {
"2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "TC", "JC", "QC", "KC", "AC",
"2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "TD", "JD", "QD", "KD", "AD",
"2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "TH", "JH", "QH", "KH", "AH",
"2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "TS", "JS", "QS", "KS", "AS"
};
bool cnt[MAXN * MAXN];

bool check(MII& d1, MII& d2){
    bool res1 = true, res2 = true;
    FORIT(it, d1){
        if(it -> Y > 1)res1 = false;
        if(!res1)break;
    }
    if(res1)return true;
    int ans = 0;
    FORIT(it, d2){
        if(it -> Y > 0)ans ++;
        if(ans > 1)res2 = false;
        if(!res2)break;
    }
    return res2;
}

bool overlap(int x1, int y1, int x2, int y2){
    if(x1 + 2 >= x2 && x2 + 2 >= x1 && y1 + 2 >= y2 && y2 + 2 >= y1)return true;
    //if(x1 < x2 || y1 < y2)return true;
    return false;
}

bool calc(MII &d1, MII &d2, int x, int y, int d){
    //cout << d << endl;
    //if(d > 9)cout << d << endl;
    if(d == 9){
        if(!check(d1, d2))return false;
        //if(x == 0 && y == 0)cout << "true " << ans1.size() << endl;
        MII d3, d4;
        FOR(p, n){
            if(p + 3 > n)break;
            FOR(q, m){
                if(q + 3 > m)break;
                if(overlap(p, q, x, y))continue;
                d3.clear(); d4.clear();
                //if(x == p && y == q)continue;
                if(calc(d3, d4, p, q, d + 1)){
                    res.PB(MP(p, q));
                    //cout << ans1.size()<< endl;
                    return true;
                }
            }
        }
        return false;
    }
    if(d == 19){
        return check(d1, d2);
    }
    int td = d > 9 ? (d - 10) : d;
    string t = gp[x + td / 3][y + td % 3];
    if(t == "J1" || t == "J2"){
        FOR(i, 52){
            if(cnt[i] == 1){
                cnt[i] = 0;
                string tt = str[i];
                d1[tt[0]] ++;
                d2[tt[1]] ++;
                ans1.PB(t);
                ans2.PB(tt);
                if(calc(d1, d2, x, y, d + 1))return true;
                d1[tt[0]] --;
                d2[tt[1]] --;
                ans1.pop_back();
                ans2.pop_back();
                cnt[i] = 1;
            }
        }
    }
    else {
        d1[t[0]] ++;
        d2[t[1]] ++;
        if(calc(d1, d2, x, y, d + 1))return true;
        d1[t[0]] --;
        d2[t[1]] --;
    }
    return false;
}

bool solve(){
    CLR(cnt, 1);
    MII d1, d2;
    FOR(i, n)FOR(j, m)FOR(k, 52){
        if(gp[i][j] == str[k])cnt[k] = 0;
    }
    FOR(i, n){
        if(i + 3 > n)break;
        FOR(j, m){
            if(j + 3 > m)break;
            d1.clear(); d2.clear();
            if(calc(d1, d2, i, j, 0)){
                res.PB(MP(i, j));
                return true;
            }
        }
    }
    return false;
}

int main(){
    cin >> n >> m;
    FOR(i, n){
        FOR(j, m){
            cin >> gp[i][j];
        }
    }
    if(solve()){
        puts("Solution exists.");
        //cout<< ans2.size() << endl;
        FOR(i, n)FOR(j, m){
            bool cc = 0;
            if(gp[i][j] != "J1" && gp[i][j] != "J2")continue;
            FOR(k, ans1.size()){
                if(gp[i][j] == ans1[k]) cc = 1;
            }
            if(cc == 0){
                FOR(k, 52)if(cnt[k]){
                    ans1.PB(gp[i][j]);
                    ans2.PB(str[k]);
                    cnt[k] = 0;
                    break;
                }
            }
        }
        if(ans1.size() == 0)puts("There are no jokers.");
        else if(ans1.size() == 1){
            printf("Replace %s with %s.\n",ans1[0].c_str(), ans2[0].c_str());
        }
        else if(ans1.size() ==2){
            if(ans1[0] == "J2") swap(ans2[0], ans2[1]);
            printf("Replace J1 with %s and J2 with %s.\n", ans2[0].c_str(), ans2[1].c_str());
        }
        printf("Put the first square to (%d, %d).\n", res[1].X + 1, res[1].Y + 1);
        printf("Put the second square to (%d, %d).\n", res[0].X + 1, res[0].Y + 1);
    }
    else puts("No solution.");
}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define x first
#define y second
typedef set<pii>::iterator IT;

char suit[]="CDHS";
char rank[]="23456789TJQKA";

pii J1, J2;
pii a[60][60];
int r, c;

int Abs(int x) { return x<0?-x:x; }

set<pii> USE;
bool sol = 0;

void find() {
        set<pii> ans;
        FOR(i,0,r-2) FOR(j,0,c-2) {
                set<int> rk;
                set<int> st;
                bool ok = 1;
                FOR(u,0,3) FOR(v,0,3) {
                        int x=a[i+u][j+v].x;
                        int y=a[i+u][j+v].y;
                        rk.insert(y);
                        st.insert(x);
                        if (st.size() > 1 && rk.size() !=  u*3+v+1) {
                                ok = 0;
                                goto NEXT;
                        }
                }
NEXT:   if (ok) {
                        ans.insert(pii(i,j));
                }
        }
        IT it1, it2;
        for (it1=ans.begin(); it1!=ans.end(); ++it1) {
                for (it2=it1,++it2; it2!=ans.end(); ++it2) {
                        if ( Abs(it1->x - it2->x) >= 3 || Abs(it1->y - it2->y) >= 3) {
                                puts("Solution exists.");
                                bool j1=J1==pii(-1,-1);
                                bool j2=J2==pii(-1,-1);
                                if (j1 && j2) {
                                        puts("There are no jokers.");
                                } else if (!j1 && j2) {
                                        int px=J1.x, py=J1.y;
                                        printf("Replace J1 with %c%c.\n", rank[ a[px][py].y ], suit[ a[px][py].x ]);
                                } else if (j1 && !j2) {
                                        int px=J2.x, py=J2.y;
                                        printf("Replace J2 with %c%c.\n", rank[ a[px][py].y ], suit[ a[px][py].x ]);
                                } else {
                                        int px=J1.x, py=J1.y;
                                        int px2=J2.x, py2=J2.y;
                                        printf("Replace J1 with %c%c and J2 with %c%c.\n",
                                                        rank[ a[px][py].y ], suit[ a[px][py].x ],
                                                        rank[ a[px2][py2].y ], suit[ a[px2][py2].x ] );
                                }
                                printf("Put the first square to (%d, %d).\n", it1->x+1, it1->y+1);
                                printf("Put the second square to (%d, %d).\n", it2->x+1, it2->y+1);
                                sol = 1;
                                return;
                        }
                }
        }
        return;
}

void go(int k) {
        if (sol) return;
        if (k==0 || k==1) {
                pii &J = k==0?J1:J2;
                if (J==pii(-1,-1)) go(k+1);
                else FOR(x,0,4) FOR(y,0,13) if(USE.find(pii(x,y))==USE.end()) {
                        if (sol) return;
                        USE.insert(pii(x,y));
                        a[J.x][J.y]=pii(x,y);
                        go(k+1);
                        USE.erase(pii(x,y));
                }
        } else {
                find();
        }
}

int main() {
        scanf("%d%d", &r, &c);
        J1=pii(-1,-1);
        J2=pii(-1,-1);
        FOR(i,0,r) FOR(j,0,c) {
                char gag[3];
                scanf("%s", gag);
                if (!strcmp(gag,"J1")) J1=pii(i,j);
                else if (!strcmp(gag,"J2")) J2=pii(i,j);
                else {
                        int x=0,y=0;
                        while(rank[y]!=gag[0]) ++y;
                        while(suit[x]!=gag[1]) ++x;
                        a[i][j]=pii(x,y);
                        USE.insert(pii(x,y));
                }
        }
        go(0);
        if (!sol) puts("No solution.");
}

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <set>
using namespace std;

#define X first
#define Y second
#define PB push_back

typedef set<string> SET;
typedef vector<string> Vs;
typedef vector<Vs> Ms;
typedef pair<int, int> P;
typedef vector<int> Vi;
typedef vector<Vi> Mi;
typedef vector<P> Vp;
typedef vector<Vp> Mp;

int vec[256], cas;
char num[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
char pal[4] = { 'C', 'D', 'H', 'S' };

bool squareok(int x, int y, const Ms& mat) {
    bool ok = true;
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            if (mat[x][y][1] != mat[x + i][y + j][1])
                ok = false;
    if (ok) return true;
    ++cas;
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j) {
            if (vec[int(mat[x + i][y + j][0])] == cas) {
//                 cerr << x + i + 1 << " " << y + j + 1 << endl;
                return false;
            }
            vec[int(mat[x + i][y + j][0])] = cas;
        }
    return true;
}

bool boardok(const Ms& mat, P& a, P& b) {
    int f = mat.size();
    int c = mat[0].size();
    for (int i1 = 0; i1 + 3 <= f; ++i1)
        for (int j1 = 0; j1 + 3 <= c; ++j1)
            for (int i2 = 0; i2 + 3 <= f; ++i2)
                for (int j2 = 0; j2 + 3 <= c; ++j2)
                    if (i2 >= i1 + 3 or j2 >= j1 + 3)
                        if (squareok(i1, j1, mat) and squareok(i2, j2, mat)) {
                            a = P(i1, j1);
                            b = P(i2, j2);
                            return true;
                        }
    return false;
}

int main() {
    SET oth;
    for (int i = 0; i < 13; ++i)
        for (int j = 0; j < 4; ++j) {
            string s = "**";
            s[0] = num[i];
            s[1] = pal[j];
            oth.insert(s);
        }

    int f, c;
    cin >> f >> c;
    Vp joker;
    Ms mat(f, Vs(c));
    for (int i = 0; i < f; ++i)
        for (int j = 0; j < c; ++j) {
            cin >> mat[i][j];
            if (mat[i][j][0] == 'J' and (mat[i][j][1] == '1' or mat[i][j][1] == '2'))
                joker.PB(P(i, j));
            oth.erase(mat[i][j]);
        }
    Vs notused(oth.begin(), oth.end());
    Ms original = mat;

//     mat[0][4] = "AS";
//     mat[5][6] = "2C";
//     cerr << squareok(0, 4, mat) << " " << squareok(3, 4, mat) << endl;

    if (joker.size() == 0) {
        P a, b;
        if (boardok(mat, a, b)) {
            ++a.X; ++a.Y; ++b.X; ++b.Y;
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            cout << "Put the first square to (" << a.X << ", " << a.Y << ")." << endl;
            cout << "Put the second square to (" << b.X << ", " << b.Y << ")." << endl;
        }
        else cout << "No solution." << endl;
    }
    else if (joker.size() == 1) {
        int n = notused.size();
        int ri = -1;
        P a, b;
        for (int i = 0; i < n; ++i) {
            mat[joker[0].X][joker[0].Y] = notused[i];
            if (boardok(mat, a, b)) {
                ri = i;
                break;
            }
        }
        if (ri != -1) {
            ++a.X; ++a.Y; ++b.X; ++b.Y;
            cout << "Solution exists." << endl;
            if (original[joker[0].X][joker[0].Y][1] == '1')
                cout << "Replace J1 with " << notused[ri] << "." << endl;
            else cout << "Replace J2 with " << notused[ri] << "." << endl;
            cout << "Put the first square to (" << a.X << ", " << a.Y << ")." << endl;
            cout << "Put the second square to (" << b.X << ", " << b.Y << ")." << endl;
        }
        else cout << "No solution." << endl;
    }
    else {
//         cerr << "(" << joker[0].X + 1 << ", " << joker[0].Y + 1 << ")" << endl;
//         cerr << "(" << joker[1].X + 1 << ", " << joker[1].Y + 1 << ")" << endl;
        if (mat[joker[0].X][joker[0].Y][1] == '2') swap(joker[0], joker[1]);
//         cerr << "(" << joker[0].X + 1 << ", " << joker[0].Y + 1 << ")" << endl;
//         cerr << "(" << joker[1].X + 1 << ", " << joker[1].Y + 1 << ")" << endl;
        int n = notused.size();
        int ri = -1, rj = -1;
        P a, b;
        for (int i = 0; ri == -1 and i < n; ++i) {
            mat[joker[0].X][joker[0].Y] = notused[i];
//             cerr << "mat[" << joker[0].X << "][" << joker[0].Y << "] = " << notused[i] << endl;
            for (int j = 0; ri == -1 and j < n; ++j) {
                if (i == j) continue;
//                 cerr << "J1->" << notused[i] << ", J2->" << notused[j] << endl;
                mat[joker[1].X][joker[1].Y] = notused[j];
//                 if (notused[i] == "2C" and notused[j] == "AS") {
//                     cerr << "$$$" << endl;
//                     for (int x = 0; x < f; ++x) {
//                         for (int y = 0; y < c; ++y)
//                             cerr << " " << mat[x][y];
//                         cerr << endl;
//                     }
//                     cerr << "$$$" << endl;
//                 }
                if (boardok(mat, a, b)) {
                    ri = i;
                    rj = j;
                }
            }
        }
        if (ri != -1) {
            ++a.X; ++a.Y; ++b.X; ++b.Y;
            cout << "Solution exists." << endl;
            cout << "Replace J1 with " << notused[ri] << " and J2 with ";
            cout << notused[rj] << "." << endl;
            cout << "Put the first square to (" << a.X << ", " << a.Y << ")." << endl;
            cout << "Put the second square to (" << b.X << ", " << b.Y << ")." << endl;
        }
        else cout << "No solution." << endl;
    }
}

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define omar ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
string arr[18][18]= {};
unordered_set<string>st;
unordered_set<char>ch,nom;
int n,m;
string arr2[]= {"D","S","H","C"},Arr[]= { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K","A"};
inline bool ongrid(int i,int j,int k,int l)
{
    for (int z=k; z<k+3; ++z)
    {
        for (int t=l; t<l+3; ++t)
            if (i==z&&t==j) return false;
    }
    if (i>=0&&i<n&&j>=0&&j<m) return true;
    return false;
}
inline bool check(int i,int j,int k,int l)
{
    ch.clear();
    nom.clear();
    for (int z=i; z<i+3; ++z)
    {
        for (int q=j; q<j+3; ++q)
        {
            if (!ongrid(z,q,k,l)) return false;
            ch.insert(arr[z][q][1]);
            nom.insert(arr[z][q][0]);
        }
    }
    if (ch.size()>1&&nom.size()!=9) return false;
    return true;
}
int main()
{
    omar;
    cin>>n>>m;
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<m; ++j)
        {
            cin>>arr[i][j];
        }
    }
    for (int i=0; i<13; ++i)
    {
        for (int j=0; j<4; ++j)
        {
            string str="";
            str+=Arr[i];
            str+=arr2[j];
            st.insert(str);
        }
    }
    int x1=-1,y1=-1,x2=-1,y2=-1;
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<m; ++j)
        {
            if (arr[i][j]=="J1") x1=i,y1=j;
            else if (arr[i][j]=="J2") x2=i,y2=j;
            st.erase(arr[i][j]);
        }
    }
    bool is=false;
    int ansx=-1,ansy=-1,ans2x=-1,ans2y=-1;
    string chx,chy;
    for (auto u:st)
    {
        for (auto z:st)
        {
            if (x1!=-1)
            {
                arr[x1][y1]=u;
            }
            if (x2!=-1)
            {
                if (z!=u) arr[x2][y2]=z;
                else continue;
            }
            for (int i=0; i<n; ++i)
            {
                for (int j=0; j<m; ++j)
                {
                    for (int k=0; k<n; ++k)
                    {
                        for (int l=0; l<m; ++l)
                        {
                            if (check(i,j,k,l)&&check(k,l,i,j))
                            {
                                is=true;
                                chx=u;
                                chy=z;
                                ansx=i+1,ansy=j+1,ans2x=k+1,ans2y=l+1;
                                if (is) break;
                            }
                        }
                        if (is) break;
                    }
                    if (is) break;
                }
                if (is) break;
            }
            if (is) break;
        }
        if (is) break;
    }
    if (is)
    {
        cout<<"Solution exists.\n";
        if (x1!=-1)
        {
            if (x2!=-1)
            {
                cout<<"Replace J1 with "<<chx<<" and J2 with "<<chy<<".\n";
            }
            else
            {
                cout<<"Replace J1 with "<<chx<<".\n";
            }
        }
        else if (x2!=-1)
        {
            cout<<"Replace J2 with "<<chy<<".\n";
        }
        else
        {
            cout<<"There are no jokers.\n";
        }
        cout<<"Put the first square to ("<<ansx<<", "<<ansy<<").\n";
        cout<<"Put the second square to ("<<ans2x<<", "<<ans2y<<").\n";
    }
    else cout<<"No solution.\n";
    return 0;
}

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <memory.h>
#include <functional>
#include <string.h>
#include <iomanip>
#include <unordered_set>
#include <unordered_map>
using namespace std;

typedef long long ll;
typedef pair<int,int> pi;
typedef double db;

const int mod=1e9+7;
ll qpow(ll x,ll k){return k==0?1:1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;}
#define MP make_pair
#define FF first
#define SS second
#define LB lower_bound
#define UB upper_bound
#define PB push_back
#define lc ((p<<1)+1)
#define rc ((p<<1)+2)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rrep(i,b,a) for(int i=b;i>=a;i--)
#define all(v) (v).begin(),(v).end()
#define clean(v,a) memset(v,a,sizeof(v))
#define get(a) scanf("%d",&a)
#define get2(a,b) scanf("%d%d",&a,&b)
#define get3(a,b,c) scanf("%d%d%d",&a,&b,&c)

/*
 * high precision: printf("%.12lf",(db)ans);
 *
 * clear output buffer: fflush(stdout);
 *
 * sync off: ios::sync_with_stdio(false);
 *
 */

typedef pair<pi,pi> ppi;

int n,m;
char s[18][18][5];
pi g[18][18];
bool able[15][4];
int x[2],y[2];
int id[256];
int num[256];
char rid[4];
char rnum[15];

void process(int i,int j)
{
	if(s[i][j][0]=='J')
	{
		if(s[i][j][1]=='1')
		{
			x[0]=i;y[0]=j;
		}
		else if(s[i][j][1]=='2')
		{
			x[1]=i;y[1]=j;
		}
		else
		{
			g[i][j]=pi(num[s[i][j][0]],id[s[i][j][1]]);
			able[g[i][j].FF][g[i][j].SS]=false;
		}
	}
	else
	{
		g[i][j]=pi(num[s[i][j][0]],id[s[i][j][1]]);
		able[g[i][j].FF][g[i][j].SS]=false;
	}
}

bool overlap(int a,int b,int c,int d)
{
	if(abs(a-c)<3&&abs(b-d)<3) return true;
	return false;
}

//bool bug=false;

bool checks(int a,int b)
{
	bool flag1=true,flag2=true;
	if(g[a][b].SS!=g[a+1][b].SS||g[a+1][b].SS!=g[a+2][b].SS) flag1=false;
	if(flag1)
	{
		for(int i=0;i<3&&flag1;i++)
		{
			for(int j=1;j<3&&flag1;j++)
			{
				if(g[a+i][b+j-1].SS!=g[a+i][b+j].SS) flag1=false;
			}
		}
	}
	if(flag1) return true;
	bool used[15]={false};
	for(int i=0;i<3&&flag2;i++)
	{
		for(int j=0;j<3&&flag2;j++)
		{
			int x=g[a+i][b+j].FF;
			if(used[x]) flag2=false;
			used[x]=true;
		}
	}
	if(flag2) return true;
	return false;
}

ppi check()
{
	for(int i1=1;i1<=n-2;i1++)
	{
		for(int j1=1;j1<=m-2;j1++)
		{
			for(int i2=1;i2<=n-2;i2++)
			{
				for(int j2=1;j2<=m-2;j2++)
				{
					if(overlap(i1,j1,i2,j2)) continue;
					if(checks(i1,j1)&&checks(i2,j2))
					{
						return ppi(pi(i1,j1),pi(i2,j2));
					}
				}
			}
		}
	}
	return ppi(pi(-1,-1),pi(-1,-1));
}

void print(ppi ret)
{
	printf("Put the first square to (%d, %d).\nPut the second square to (%d, %d).\n",ret.FF.FF,ret.FF.SS,ret.SS.FF,ret.SS.SS);
}

bool solve(int id)
{
	for(int i=1;i<=13;i++)
	{
		for(int j=0;j<4;j++)
		{
			if(!able[i][j]) continue;
			g[x[id]][y[id]]=pi(i,j);
			ppi ret=check();
			if(ret.FF.FF!=-1)
			{
				printf("Solution exists.\nReplace J%d with %c%c.\n",id+1,rnum[i],rid[j]);
				print(ret);
				return true;
			}
		}
	}
	return false;
}

bool solve(int id1,int id2)
{
	for(int i1=1;i1<=13;i1++)
	{
		for(int j1=0;j1<4;j1++)
		{
			if(!able[i1][j1]) continue;
			for(int i2=1;i2<=13;i2++)
			{
				for(int j2=0;j2<4;j2++)
				{
					if(!able[i2][j2]||(i1==i2&&j1==j2)) continue;
					g[x[id1]][y[id1]]=pi(i1,j1);
					g[x[id2]][y[id2]]=pi(i2,j2);
					ppi ret=check();
					if(ret.FF.FF!=-1)
					{
						printf("Solution exists.\nReplace J1 with %c%c and J2 with %c%c.\n",rnum[i1],rid[j1],rnum[i2],rid[j2]);
						print(ret);
						return true;
					}
				}
			}
		}
	}
	return false;
}

int main()
{
	scanf("%d%d",&n,&m);
	clean(able,true);
	id['C']=0;
	id['D']=1;
	id['H']=2;
	id['S']=3;
	rid[0]='C';
	rid[1]='D';
	rid[2]='H';
	rid[3]='S';
	for(int i='2';i<='9';i++)
	{
		num[i]=i-'0';
		rnum[i-'0']=i;
	}
	num['A']=1;
	num['T']=10;
	num['J']=11;
	num['Q']=12;
	num['K']=13;
	rnum[1]='A';
	rnum[10]='T';
	rnum[11]='J';
	rnum[12]='Q';
	rnum[13]='K';
	clean(x,-1);
	clean(y,-1);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%s",s[i][j]);
			process(i,j);
		}
	}
	if(x[0]==-1&&x[1]==-1)
	{
		ppi ret=check();
		if(ret.FF.FF!=-1)
		{
			printf("Solution exists.\nThere are no jokers.\n");
			print(ret);
		}
		else
		{
			printf("No solution.\n");
		}
	}
	else if(x[0]==-1)
	{
		if(!solve(1)) printf("No solution.\n");
	}
	else if(x[1]==-1)
	{
		if(!solve(0)) printf("No solution.\n");
	}
	else
	{
		if(!solve(0,1)) printf("No solution.\n");
	}
	return 0;
}

/*
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

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

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

*/

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <functional>
#include <cmath>
#include <sstream>
#include <memory.h>

#define forn(i,n) for (int i = 0; i < (int)(n); i++)
#define forv(i, a) for(int i=0; i<(int)a.size(); i++)
#define all(a) a.begin(),a.end()
#define mp make_pair
#define pb push_back
#define sz size()
#define VI vector< int >
#define VS vector< string >
#define PII pair< int,int >
#define PDD pair< double,double >
#define PIS pair< int, string >
#define sqr(a) ((a)*(a))
#define cube(a) ((a)*(a)*(a))
#define pi 3.1415926535897932384626433832795
const int inf=500*1000*1000;
#define eps 1e-7
using namespace std;

struct card{
	int m;
	int d;
	bool operator<(const card &c) const{
		if(m!=c.m) return m<c.m;
		else return d<c.d;
	}
};

int J;
int n, m;
card d[18][18];
card jj[2];
PII jok[2];
char dost[13]={'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char mast[4]={'C', 'D', 'H', 'S'};
map<card, bool> used;

card read(){
	char str[3];
	card temp;
	cin>>str;

	temp.m=str[1];
	temp.d=str[0];
	used[temp]=true;

	return temp;
}

bool ok(int x, int y){
	if(x>n-3 || y>m-3) return false;

	int comm=d[x][y].m;
	bool cm=true, dd=true;
	for(int i=x; i<x+3; i++)
		for(int j=y; j<y+3; j++){
			if(d[i][j].m!=comm) cm=false;

			for(int i1=x; i1<x+3; i1++)
				for(int j1=y; j1<y+3; j1++)
					if(!(i==i1 && j==j1) && d[i][j].d==d[i1][j1].d) dd=false;

		}
	return (cm || dd);
}

bool win(int &x1, int &y1, int &x2, int &y2){
	forn(i, n)forn(j, m){
		forn(i1, n)forn(j1, m){
			if(i1>i+2 || j1>j+2)
				if(ok(i, j) && ok(i1, j1)){
					x1=i; y1=j; x2=i1; y2=j1;
					return true;
				}
		}
	}
	return false;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	J=0;
	int x1, x2, y2, y1;
	cin>>n>>m;

	forn(i, n)forn(j, m){
		d[i][j]=read();
		if(d[i][j].d=='J' && (d[i][j].m=='1' || d[i][j].m=='2')){
			jok[J]=mp(i, j);
			jj[J]=d[i][j];
			J++;
		}
	}

	if(J==0){
		if(win(x1, y1, x2, y2)){
		cout<<"Solution exists."<<endl;
		cout<<"There are no jokers."<<endl;
		cout<<"Put the first square to ("<<x1+1<<", "<<y1+1<<")."<<endl;
		cout<<"Put the second square to ("<<x2+1<<", "<<y2+1<<")."<<endl;
		}
		else cout<<"No solution.";
		return 0;
	}

	int px1, py1, px2, py2;
	bool b=false;

	for(px1=0; px1<13; px1++){
		for(py1=0; py1<4; py1++){
			d[jok[0].first][jok[0].second].d=dost[px1];
			d[jok[0].first][jok[0].second].m=mast[py1];
			if(used[d[jok[0].first][jok[0].second]]) continue;
			used[d[jok[0].first][jok[0].second]]=true;
			if(J>1){
				for(px2=0; px2<13; px2++){
					for(py2=0; py2<4; py2++){
						d[jok[1].first][jok[1].second].d=dost[px2];
						d[jok[1].first][jok[1].second].m=mast[py2];
						if(used[d[jok[1].first][jok[1].second]]) continue;
						if(win(x1, y1, x2, y2)){ b=true; break;}
					}
					if(b) break;
				}
			}
			else{
				if(win(x1, y1, x2, y2)) b=true;
			}
			if(b) break;
			used[d[jok[0].first][jok[0].second]]=false;
		}
		if(b) break;
	}

	if(!b){
		cout<<"No solution.";
	}
	else{
		cout<<"Solution exists."<<endl;
		if(jj[1].m=='1') {swap(px1, px2); swap(py1, py2);}
		if(J>1) cout<<"Replace J1 with "<<dost[px1]<<mast[py1]<<" and J2 with "<<dost[px2]<<mast[py2]<<"."<<endl;
		else cout<<"Replace J"<<(char)jj[0].m<<" with "<<dost[px1]<<mast[py1]<<"."<<endl;
		cout<<"Put the first square to ("<<x1+1<<", "<<y1+1<<")."<<endl;
		cout<<"Put the second square to ("<<x2+1<<", "<<y2+1<<")."<<endl;
	}

	return 0;
}

#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#define _USE_MATH_DEFINES
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <sstream>
#include <deque>
#include <bitset>
using namespace std;

template<typename T>
inline T Abs(T a)
{
	return a>0?a:-a;

}
void split(string s,string seps,vector<string> &res,bool doEmpty=false)
{
	int start=0;
	res.clear();
	for(int i=0;i<s.size();i++)
	{
		if(seps.find(s[i])!=string::npos)
		{
			if(doEmpty || i-start>0)
			res.push_back(s.substr(start,i-start));
			start=i+1;
		}

	}
	if(doEmpty || s.size()-start>0)
			res.push_back(s.substr(start,s.size()-start));
}
string Union(vector<string> s,int start=0)
{
	string res;
	for(int i=start;i<s.size();i++)
		res.append(s[i]);
	return res;
}
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<int>::iterator vi_it;
typedef vector<long long> vl;
typedef vector<long long>::iterator vll_it;

typedef vector<string> vs;
typedef vector<string>::iterator vs_it;

string grid[17][17];
int n,m;
int i_1,i2,j_1,j2;
bool check(int x,int y)
{
	int n1=0;
	map<char,int> v1;
	set<char> v2;
	for(int i=x;i<x+3;i++)
		for(int j=y;j<y+3;j++)
		{
			if(grid[i][j]=="J1"||grid[i][j]=="J2")
				return false;
			v1[grid[i][j][1]]++;
			v2.insert(grid[i][j][0]);
		}
		bool ok1=false;
		bool ok2=false;
		ok1=(v2.size()==9);

		for(map<char,int>::iterator it=v1.begin();it!=v1.end();it++)
			if(it->second==9)
				ok2= true;

		return ok1||ok2;

}
bool fullCheck()
{
	for( i_1=0;i_1<n-2;i_1++)
		for(j_1=0;j_1<m-2;j_1++)
			if(check(i_1,j_1))
			{
					for(i2=0;i2<n-2;i2++)
						for( j2=0;j2<m-2;j2++)
							if((Abs(i2-i_1)>2) || (Abs(j2-j_1)>2))
								if(check(i2,j2))
								return true;
			}
	return false;
}
char mm[] ={'C', 'D', 'H', 'S'};
char val[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
int main()
{
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);

	cin >> n>>m;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			cin>>grid[i][j];
	vs notUse;
	for(int i=0;i<4;i++)
		for(int j=0;j<13;j++)
		{
			string t;
			t.push_back(val[j]);
			t.push_back(mm[i]);

			bool fnd=false;
			for(int i_1=0;!fnd&&i_1<n;i_1++)
				for(int j_1=0;j_1<m;j_1++)
					if(t==grid[i_1][j_1])
					{
						fnd=true;
						break;
					}
			if(!fnd)
				notUse.push_back(t);
		}

	vector<pair<int,int> > joks;
	vs js;
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(grid[i][j]=="J1"||grid[i][j]=="J2")
			{
				js.push_back(grid[i][j]);
				joks.push_back(make_pair(i,j));
			}
	if(js.size()>1 &&js[0]>js[1])
	{
		swap(js[0],js[1]);
		swap(joks[0],joks[1]);
	}
	if(joks.size()==0)
		if(fullCheck())
			{
				cout<<"Solution exists."<<endl;
				cout<<"There are no jokers."<<endl;
				cout<<"Put the first square to ("<<(i_1+1)<<", "<<(j_1+1)<<")."<<endl;
cout<<"Put the second square to ("<<(i2+1)<<", "<<(j2+1)<<")."<<endl;
				return 0;
			}
	if(joks.size()==1)
	{
		for(int i=0;i<notUse.size();i++)
		{
			grid[joks[0].first][joks[0].second]=notUse[i];
			if(fullCheck())
			{
				cout<<"Solution exists."<<endl;
				cout<<"Replace "<<js[0]<<" with "<<notUse[i]<<'.'<<endl;
				cout<<"Put the first square to ("<<(i_1+1)<<", "<<(j_1+1)<<")."<<endl;
cout<<"Put the second square to ("<<(i2+1)<<", "<<(j2+1)<<")."<<endl;
				return 0;
			}
		}
	}
	if(joks.size()==2)
	{
		for(int i=0;i<notUse.size();i++)
		{
			grid[joks[0].first][joks[0].second]=notUse[i];
			for(int j=0;j<notUse.size();j++)
				if(i!=j)
				{
					grid[joks[1].first][joks[1].second]=notUse[j];
					if(fullCheck())
					{
						cout<<"Solution exists."<<endl;
						cout<<"Replace "<<js[0]<<" with "<<notUse[i];
						cout<<" and "<<js[1]<<" with "<<notUse[j]<<'.'<<endl;
						cout<<"Put the first square to ("<<(i_1+1)<<", "<<(j_1+1)<<")."<<endl;
		cout<<"Put the second square to ("<<(i2+1)<<", "<<(j2+1)<<")."<<endl;
						return 0;
					}
				}
		}
	}

			cout<<"No solution.";
	return 0;

}

#include <bits/stdc++.h>

using namespace std;

template<typename TH>
void _dbg(const char* sdbg, TH h)
{
	cerr << sdbg << " = " << h << "\n";
}

template<typename TH, typename... TA>
void _dbg(const char* sdbg, TH h, TA... t)
{
	while (*sdbg != ',') cerr << *sdbg++;
	cerr << " = " << h << ",";
	_dbg(sdbg + 1, t...);
}

#define db(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define chkpt cerr << "--- Checkpoint here ---\n";

const int N=17+2;
const string YES="Solution exists.";
const string NO="No solution.";

int n,m;
string a[N][N];
bool b[N][N];

bool CheckPos(int x,int y){
    map<char,bool> mark;
    bool hasSameRank=false;
    for(int i=x;i<=x+2;++i){
        for(int j=y;j<=y+2;++j){
            if(mark.count(a[i][j][0])){
                hasSameRank=true;
                break;
            }
            mark[a[i][j][0]]=true;
        }
    }
    if(!hasSameRank){
        return true;
    }
    mark.clear();
    for(int i=x;i<=x+2;++i){
        for(int j=y;j<=y+2;++j){
            mark[a[i][j][1]]=true;
        }
    }
    return mark.size()==1;
}

vector<pair<int,int>> Check(){
    vector<pair<int,int>> res;
    for(int i=1;i<=n-2;++i){
        for(int j=1;j<=m-2;++j){
            b[i][j]=false;
        }
    }
    for(int i=1;i<=n-2;++i){
        for(int j=1;j<=m-2;++j){
            if(CheckPos(i,j)){
                b[i][j]=true;
            }
        }
    }
    for(int i1=1;i1<=n-2;++i1){
        for(int j1=1;j1<=m-2;++j1){
            if(b[i1][j1]){
                for(int i2=1;i2<=n-2;++i2){
                    for(int j2=1;j2<=m-2;++j2){
                        if(b[i2][j2]){
                            int x=max(i1,i2),u=min(i1+2,i2+2),y=max(j1,j2),v=min(j1+2,j2+2);
                            if(x>u||y>v){
                                res.push_back({i1,j1});
                                res.push_back({i2,j2});
                                return res;
                            }
                        }
                    }
                }
            }
        }
    }
    return res;
}

int main()
{
//    freopen("71D.INP","r",stdin);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	vector<char> ranks={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
	vector<char> suits={'C','D','H','S'};
	vector<string> cards;
	for(char c1:ranks){
        for(char c2:suits){
            string s;
            s.push_back(c1);
            s.push_back(c2);
            cards.push_back(s);
        }
	}
	cin>>n>>m;
	vector<pair<int,int>> jokers;
	map<string,bool> mark;
	for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            cin>>a[i][j];
            if(a[i][j]=="J1"||a[i][j]=="J2"){
                jokers.push_back({i,j});
            }
            else{
                mark[a[i][j]]=true;
            }
        }
	}
	vector<string> unused;
	for(auto s:cards){
        if(!mark.count(s)){
            unused.push_back(s);
        }
	}
	if(jokers.size()==0){
        vector<pair<int,int>> vec=Check();
        if(vec.size()==2){
            cout<<YES<<'\n';
            cout<<"There are no jokers."<<'\n';
            cout<<"Put the first square to ("<<vec[0].first<<", "<<vec[0].second<<")."<<'\n';
            cout<<"Put the second square to ("<<vec[1].first<<", "<<vec[1].second<<")."<<'\n';
        }
        else{
            cout<<NO<<'\n';
        }
	}
	else if(jokers.size()==1){
        string j=a[jokers[0].first][jokers[0].second];
	    for(auto s:unused){
            a[jokers[0].first][jokers[0].second]=s;
            vector<pair<int,int>> vec=Check();
            if(vec.size()>=2){
                cout<<YES<<'\n';
                cout<<"Replace "<<j<<" with "<<s<<"."<<'\n';
                cout<<"Put the first square to ("<<vec[0].first<<", "<<vec[0].second<<")."<<'\n';
                cout<<"Put the second square to ("<<vec[1].first<<", "<<vec[1].second<<")."<<'\n';
                return 0;
            }
	    }
	    cout<<NO<<'\n';
	}
	else if(jokers.size()==2){
        string j1=a[jokers[0].first][jokers[0].second];
        string j2=a[jokers[1].first][jokers[1].second];
        for(int i=0;i<unused.size();++i){
            for(int j=0;j<unused.size();++j){
                if(i!=j){
                    a[jokers[0].first][jokers[0].second]=unused[i];
                    a[jokers[1].first][jokers[1].second]=unused[j];
                    vector<pair<int,int>> vec=Check();
                    if(vec.size()>=2){
                        cout<<YES<<'\n';
                        if(j1=="J1"&&j2=="J2"){
                            cout<<"Replace "<<j1<<" with "<<unused[i];
                            cout<<" and "<<j2<<" with "<<unused[j]<<"."<<'\n';
                        }
                        else{
                            cout<<"Replace "<<j2<<" with "<<unused[j];
                            cout<<" and "<<j1<<" with "<<unused[i]<<"."<<'\n';
                        }
                        cout<<"Put the first square to ("<<vec[0].first<<", "<<vec[0].second<<")."<<'\n';
                        cout<<"Put the second square to ("<<vec[1].first<<", "<<vec[1].second<<")."<<'\n';
                        return 0;
                    }
                }
            }
        }
        cout<<NO<<'\n';
	}
	else{
        assert(false);
	}
    return 0;
}

#ifdef _MSC_VER
#pragma warning(disable:4996)  // deprecations
#endif  //  #ifdef _MSC_VER
#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <utility>
#include <sstream>
#include <complex>
#include <limits>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <time.h>
#if defined(_MSC_VER) && !defined(_STLP_LONG_LONG)
namespace std { long long abs(long long x) { return x < 0 ? -x : x; } }
#endif
using namespace std;

////////////////////// Debug Utilities ///////////////////////
void dprintf(char* format, ...) {
  fprintf(stderr, "DEBUG: ");
  va_list argp; va_start(argp, format);
  vfprintf(stderr, format, argp); va_end(argp);
  fprintf(stderr, "\n");
}
struct Exception {
  const char* message;
  const int line;
  Exception(const char* m, int l) : message(m), line(l) {}
};
#define THROW(M) throw Exception(M, __LINE__)
////////////////////// Debug Utilities ///////////////////////

////////////////////// Reading Utilities ///////////////////////
static char stringReader[2097152];
static inline bool ReadLine() {
  char* ptr = fgets(stringReader, sizeof(stringReader), stdin);
  if ( ptr == 0 ) return false;
  int N = strlen(stringReader);
  if ( stringReader[N - 1] == '\n' ) stringReader[N - 1] = 0;
  return true;
}
////////////////////// Reading Utilities ///////////////////////

///////////////////////// Basic Utilities //////////////////////////
#define SIZE(N, V) int N = static_cast<int>((V).size())
#define GSIZE(N, V) (N) = static_cast<int>((V).size())
#define ALL(V) (V).begin(), (V).end()
#define UNIQUE(C) {sort(ALL(C)); C.resize(unique(ALL(C)) - C.begin());}
#define CAST(X, Y) {stringstream ss; ss << (X); ss >> (Y);}
typedef long long i64;
const i64 ooLL = 0x3f3f3f3f3f3f3f3fLL;
const int oo = 0x3f3f3f3f;
const double eps = 1e-9;
///////////////////////// Basic Utilities //////////////////////////

////////////////////////// Solution ///////////////////////////
typedef char card[3];
int rank(card c) {
  if ( c[0] == 'A' ) return 0;
  if ( isdigit(c[0]) ) return c[0] - '1';
  if ( c[0] == 'T' ) return 9;
  if ( c[0] == 'J' ) return 10;
  if ( c[0] == 'Q' ) return 11;
  if ( c[0] == 'K' ) return 12;
  assert(0);
  return -10000;
}
int suit(card c) {
  if ( c[1] == 'H' ) return 0;
  if ( c[1] == 'C' ) return 1;
  if ( c[1] == 'D' ) return 2;
  if ( c[1] == 'S' ) return 3;
  if ( c[1] == '1' || c[1] == '2' ) return 4;
  assert(0);
  return -10000;
}
char const* _suits = "HCDS";
char const* _ranks = "A23456789TJQK";

bool used[13][4];
card cards[60][60];

int n, m;

struct rect {
  set<int> suits, ranks;
  vector<int> jk;
  int i, j;
  rect(set<int> & s, set<int> & r, vector<int>& _jk, int _i, int _j )
    :
  suits(s),
    ranks(r),
    jk(_jk),
    i(_i),
    j(_j) {}
};

bool overlap(rect const& a, rect const& b) {
  int i0 = min(a.i, b.i);
  int i1 = max(a.i, b.i);
  if ( i1 - i0 >= 3 ) return false;
  i0 = min(a.j, b.j);
  i1 = max(a.j, b.j);
  if ( i1 - i0 >= 3 ) return false;
  return true;
}

int main() {
  try {
#ifdef ZYX_MACHINE
    freopen("xxx.in", "rt", stdin);
#endif // #ifdef ZYX_MACHINE

    while ( scanf("%d%d", &n, &m) == 2 ) {
      memset(used, false, sizeof(used));
      vector<pair<int, int> > jokers;
      for ( int i = 0; i < n; ++i ) for ( int j = 0; j < m; ++j ) {
        scanf("%s", cards[i][j]);
        if ( suit(cards[i][j]) == 4 )
          jokers.push_back(make_pair(i, j));
        else
          used[rank(cards[i][j])][suit(cards[i][j])] = true;
      }
      if ( jokers.size() == 2 && strcmp(cards[jokers[0].first][jokers[0].second], "J1") )
        swap(jokers[0], jokers[1]);
      vector<rect> rects;
      for ( int i = 0; i + 3 <= n; ++i ) for ( int j = 0; j + 3 <= m; ++j ) {
        set<int> suits;
        set<int> ranks;
        vector<int> jk;
        for ( int ii = 0; ii < 3; ++ii ) for ( int jj = 0; jj < 3; ++jj ) {
          if ( suit(cards[i + ii][j + jj]) == 4 ) {
            jk.push_back(jokers[0] == make_pair(i + ii, j + jj) ? 0 : 1);
          } else {
            suits.insert(suit(cards[i + ii][j + jj]));
            ranks.insert(rank(cards[i + ii][j + jj]));
          }
        }
        if ( suits.size() == 1 ) {
          rects.push_back(rect(suits, ranks, jk, i, j));
        } else if ( ranks.size() + jk.size() == 9 ) {
          rects.push_back(rect(suits, ranks, jk, i, j));
        }
      }
      bool ok = false;
      SIZE(R, rects);
      vector<pair<int, int> > rep(jokers.size(), make_pair(-1, -1));
      int _i = -1, _j = -1;
      for ( int i = 0; !ok && i < R; ++i ) for ( int j = i + 1; !ok && j < R; ++j ) {
        if ( overlap(rects[i], rects[j]) ) continue;
        set<pair<int, int> > cana;
        set<pair<int, int> > canb;

        if ( rects[i].jk.size() == 2 ) {
          if ( rects[i].suits.size() == 1 ) {
            vector<int> use;
            int ss = *rects[i].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              use.push_back(k);
            if ( use.size() > 1 ) {
              rep[0].first = use[0];
              rep[0].second = ss;
              rep[1].first = use[1];
              rep[1].second = ss;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
          if ( !ok && rects[i].ranks.size() == 7 ) {
            vector<pair<int, int> > use;
            for ( int k = 0; k < 13; ++k ) if ( rects[i].ranks.find(k) == rects[i].ranks.end() )
              for ( int ss = 0; ss < 4; ++ss ) if ( !used[k][ss] )
                use.push_back(make_pair(k, ss));
            if ( use.size() > 1 ) {
              rep[0].first = use[0].first;
              rep[0].second = use[0].second;
              rep[1].first = use[1].first;
              rep[1].second = use[1].second;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
        } else if ( rects[i].jk.size() == 1 ) {
          if ( rects[i].suits.size() == 1 ) {
            int ss = *rects[i].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              cana.insert(make_pair(k, ss));
          }
          if ( rects[i].ranks.size() == 8 ) {
            for ( int k = 0; k < 13; ++k ) if ( rects[i].ranks.find(k) == rects[i].ranks.end() )
              for ( int ss = 0; ss < 4; ++ss ) if ( !used[k][ss] )
                cana.insert(make_pair(k, ss));
          }
        }

        if ( rects[j].jk.size() == 2 ) {
          if ( rects[j].suits.size() == 1 ) {
            vector<int> use;
            int ss = *rects[j].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              use.push_back(k);
            if ( use.size() > 1 ) {
              rep[0].first = use[0];
              rep[0].second = ss;
              rep[1].first = use[1];
              rep[1].second = ss;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
          if ( !ok && rects[j].ranks.size() == 7 ) {
            vector<pair<int, int> > use;
            for ( int k = 0; k < 13; ++k ) if ( rects[j].ranks.find(k) == rects[j].ranks.end() )
              for ( int ss = 0; ss < 4; ++ss ) if ( !used[k][ss] )
                use.push_back(make_pair(k, ss));
            if ( use.size() > 1 ) {
              rep[0].first = use[0].first;
              rep[0].second = use[0].second;
              rep[1].first = use[1].first;
              rep[1].second = use[1].second;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
        } else if ( rects[j].jk.size() == 1 ) {
          if ( rects[j].suits.size() == 1 ) {
            int ss = *rects[j].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              canb.insert(make_pair(k, ss));
          }
          if ( rects[j].ranks.size() == 8 ) {
            for ( int k = 0; k < 13; ++k ) if ( rects[j].ranks.find(k) == rects[j].ranks.end() )
              for ( int ss = 0; ss < 4; ++ss ) if ( !used[k][ss]  )
                canb.insert(make_pair(k, ss));
          }
        }

        set<pair<int, int> > can;
        can.insert(ALL(cana));
        can.insert(ALL(canb));
        if ( can.size() >= rects[i].jk.size() + rects[j].jk.size() ) {
          if ( cana.size() == 1 ) {
            rep[rects[i].jk[0]] = *cana.begin();
            for ( set<pair<int, int> >::const_iterator it =
              canb.begin(), end = canb.end(); it != end; ++it ) {
                if ( *it == *cana.begin() ) continue;
                rep[rects[j].jk[0]] = *it;
                break;
            }
          } else {
            if ( canb.size() ) rep[rects[j].jk[0]] = *canb.begin();
            for ( set<pair<int, int> >::const_iterator it =
              cana.begin(), end = cana.end(); it != end; ++it ) {
                if ( canb.size() && *it == *canb.begin() ) continue;
                rep[rects[i].jk[0]] = *it;
                break;
            }
          }
          ok = true;
          _i = i;
          _j = j;
          break;
        }
      }
      if ( ok ) {
        vector<int> go;
        if ( jokers.size() && rep[0].first == -1 ) {
          if ( jokers.size() > 1 && rep[1].first == -1 ) {
            go.push_back(0);
            go.push_back(1);
          } else {
            if ( jokers.size() > 1 ) go.push_back(1);
            go.push_back(0);
          }
        } else if ( jokers.size() > 1 && rep[1].first == -1 ) {
            go.push_back(0);
            go.push_back(1);
        }
        for ( vector<int>::const_iterator it = go.begin(), end = go.end(); it != end; ++it ) {
          if ( rep[*it].first == -1 ) {
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                rep[*it] = make_pair(k, ss);
          }
          used[rep[*it].first][rep[*it].second] = true;
        }
        printf("Solution exists.\n");
        if ( jokers.size() == 0 ) printf("There are no jokers.\n");
        else if ( jokers.size() == 1 ) printf("Replace %s with %c%c.\n", cards[jokers[0].first][jokers[0].second], _ranks[rep[0].first], _suits[rep[0].second]);
        else printf("Replace J1 with %c%c and J2 with %c%c.\n", _ranks[rep[0].first], _suits[rep[0].second], _ranks[rep[1].first], _suits[rep[1].second]);
        printf("Put the first square to (%d, %d).\n", rects[_i].i + 1, rects[_i].j + 1);
        printf("Put the second square to (%d, %d).\n", rects[_j].i + 1, rects[_j].j + 1);
      } else {
        printf("No solution.\n");
      }
    }
    return 0;
  } catch ( const Exception& exception ) {
    fprintf(stderr, "******************************\n");
    fprintf(stderr, "ERROR.%d: %s\n", exception.line, exception.message);
    fprintf(stderr, "******************************\n");
    throw exception;
  }
}
////////////////////////// Solution ///////////////////////////
// BEGIN CUT HERE
//Znippet tag
// END CUT HERE

#include<stdio.h>
#include<math.h>

int rank_len=13;
int suit_len=4;
int n,m;

char rank[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K','J', 'A'};
char suit[] = {'C','D','H','S'};
bool vis[300][300];

char input_rank[200][200];
char input_suit[200][200];

int j1x = 100, j1y = 100;
int j2x = 100, j2y = 100;

bool valid(int x, int y) // we consider no jokers in 3x3 square
{
	if(x+3 > n || y+3 > m)
		return false;

	for(int i=x; i<x+3; i++)
		for(int o=y; o<y+3; o++)
			for(int ii=x; ii<x+3; ii++)
				for(int oo=y; oo<y+3; oo++)
				{
					if(i==ii && o==oo)
						continue;
					if( input_rank[i][o] == input_rank[ii][oo])
						return false;
				}
	return true;
}

bool intersect(int x1, int y1, int x2, int y2)
{
	if( abs(x1 - x2) >= 3 || abs( y1 - y2) >= 3 )
		return false;
	return true;
}

bool find_sol()
{
	for(int i=0; i<n; i++)
		for(int o=0; o<m; o++)
			for(int ii=0; ii<n; ii++)
				for(int oo=0; oo<m; oo++)
				{
					if( !intersect(i,o, ii,oo) &&  valid(i,o) && valid(ii,oo) )
					{
						printf("Solution exists.\n");

						if(j1x == 100 && j2x == 100)
							printf("There are no jokers.\n");
						else
						{
							if(j1x != 100 )
								printf("Replace J1 with %c%c", input_rank[j1x][j1y] ,input_suit[j1x][j1y]);
							if(j1x!= 100 && j2x == 100)
								printf(".\n");
							if(j1x != 100 && j2x != 100)
								printf(" and J2 with %c%c.\n",input_rank[j2x][j2y],input_suit[j2x][j2y]);
							if(j1x == 100 && j2x != 100)
								printf("Replace J2 with %c%c.\n",input_rank[j2x][j2y],input_suit[j2x][j2y]);

						}

						printf("Put the first square to (%d, %d).\n",i+1,o+1);
						printf("Put the second square to (%d, %d).",ii+1,oo+1);
						return true;
					}
				}
	return false;
}

int main()
{
	scanf("%d %d\n",&n,&m);

	for(int i=0; i<n; i++)
	{
		for(int o=0; o<m; o++)
		{
			scanf("%c%c ",&input_rank[i][o],&input_suit[i][o]);
			if(input_rank[i][o] == 'J' && input_suit[i][o] == '1' )
				j1x = i, j1y = o;
			if(input_rank[i][o] == 'J' && input_suit[i][o] == '2' )
				j2x = i, j2y = o;
		}
	}

	// generate unused pairs
	for(int i=0; i<n; i++)
		for(int o=0; o<m; o++)
			vis[ input_rank[i][o] ][ input_suit[i][o] ] = 1;

	// scan for jokers
	for(int i=0; i<rank_len; i++)
		for(int o=0; o<suit_len; o++)
			if( vis[ rank[i] ][ suit[o] ] == 0 )
			{
				vis[ rank[i] ][ suit[o] ] = 1;

				input_rank[ j1x ][ j1y ] = rank[i];
				input_suit[ j1x ][ j1y ] = suit[o];

				for(int ii=0; ii<rank_len; ii++)
					for(int oo=0; oo<suit_len; oo++)
						if( vis[ rank[ii] ][ suit[oo] ] == 0 )
						{
							input_rank[ j2x ][ j2y ] = rank[ii];
							input_suit[ j2x ][ j2y ] = suit[oo];

							if(find_sol())
								return 0;

							input_rank[ j2x ][ j2y ] = 'J';
							input_suit[ j2x ][ j2y ] = '2';
						}

				input_rank[ j1x ][ j1y ] = 'J';
				input_suit[ j1x ][ j1y ] = '1';
				vis[ rank[i] ][ suit[o] ] = 0;
			}

	printf("No solution.");
	return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
#include <sstream>
#include <cassert>
using namespace std;
static const double EPS = 1e-10;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define F first
#define S second
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};

string in[17][17];
int n,m,jas;
set<string> app;
PI jpos[2];
int jnum[2];
string repj[2];

string to(int i){
  char cc[]={'C','D','H','S'};
  string ret;
  rep(j,4){
    if(i<=13){
      switch(i){
      case 1:ret+='A';break;
      case 10:ret+='T';break;
      case 11:ret+='J';break;
      case 12:ret+='Q';break;
      case 13:ret+='K';break;
      default:ret+=i+'0';break;
      }
      ret+=cc[j];
      return ret;
    }
    i-=13;
  }
}

bool can(){
  rep(i,n-2){
    rep(j,m-2){
      set<char> sapp;
      set<int> numapp;
      rep(x,3)rep(y,3){
    sapp.insert(in[i+x][j+y][1]);
    numapp.insert(in[i+x][j+y][0]);
      }
      if(sapp.size()!=1 && numapp.size()!=9)continue;
      rep(k,n-2){
    rep(l,m-2){
      bool ok=true;
      rep(x,3)rep(y,3){
        if(i<=k+x && k+x<=i+2 && j<=l+y && l+y<=j+2)ok=false;
      }
      if(!ok)continue;
      set<char> sapp2,numapp2;
      rep(x,3)rep(y,3){
        sapp2.insert(in[k+x][l+y][1]);
        numapp2.insert(in[k+x][l+y][0]);
      }
      if(sapp2.size()!=1 && numapp2.size()!=9)continue;
      cout<<"Solution exists."<<endl;
      if(jas==1){
        cout<<"Replace J"<<jnum[0]<<" with "<<repj[0]<<'.'<<endl;
      }else if(jas==2){
        cout<<"Replace J1 with "<<repj[0]<<" and J2 with "<<repj[1]<<'.'<<endl;
      }else cout<<"There are no jokers."<<endl;
      cout<<"Put the first square to ("<<i+1<<", "<<j+1<<")."<<endl;
      cout<<"Put the second square to ("<<k+1<<", "<<l+1<<")."<<endl;
      return true;
    }
      }
    }
  }
  return false;
}

bool dfs(int df){
  if(df==0){
    return can();
  }
  rep(i,52){
    string rep=to(i+1);
    if(app.count(rep))continue;
    int x=jpos[df-1].F,y=jpos[df-1].S;
    app.insert(rep);
    in[x][y]=rep;
    repj[df-1]=rep;
    if(dfs(df-1))return true;
    app.erase(rep);
  }
  return false;
}

main(){
  cin>>n>>m;
  rep(i,n){
    rep(j,m){
      cin>>in[i][j];
      if(!isdigit(in[i][j][1]))app.insert(in[i][j]);
      else {
    jnum[jas]=in[i][j][1]-'0';
    jpos[jas++]=mp(i,j);
      }
    }
  }

  if(jas==2 && jnum[0]==2){
    swap(jnum[0],jnum[1]);
    swap(jpos[0],jpos[1]);
  }
  if(dfs(jas)){
    return 0;
  }
  cout<<"No solution."<<endl;
}

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cassert>
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <algorithm>
using std::sort; using std::min; using std::max;
#include <vector>
using std::vector;
#include <set>
using std::set;
#include <queue>
using std::queue; using std::priority_queue;
#include <utility>
using std::pair;
typedef pair<int, int> pii;
typedef long long LL;
typedef long double LD;
#define pass printf("%s : Line.%d\n", __FUNCTION__, __LINE__);

const int maxN = 17 + 5;
const set<char> ranks = {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'};
const set<char> suits = {'C', 'D', 'H', 'S'};
struct Card {
	char rk, st;
	Card() {}
	Card(int rk, int st) : rk(rk), st(st) {}
	friend bool operator < (const Card &A, const Card &B) {
		return A.rk != B.rk ? A.rk < B.rk : A.st < B.st;
	}
}a[maxN][maxN], t[maxN][maxN];
struct Point {
	int x, y;
	Point() {}
	Point(int x, int y) : x(x), y(y) {}
}joker[3];
vector<Point> empty;
set<Card> cards;
int n, m;
int jks = 0;
char words[1000];

void initialize() {
	for(char x : ranks) {
		for(char y : suits) {
			cards.insert(Card(x, y));
		}
	}
	cin >> n >> m;
	memset(joker, 0, sizeof(joker));
	empty.clear();
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j) {
			char s[10];
			cin >> s;
			if(suits.count(s[1])) {
				t[i][j] = a[i][j] = (Card){s[0], s[1]};
				cards.erase(Card(s[0], s[1]));
			} else {
				joker[s[1] - '0'] = (Point){i, j};
				jks |= (s[1] - '0');
				if(s[1] == '2') empty.push_back(Point(i, j));
				else empty.insert(empty.begin(), Point(i, j));
			}
		}
}

bool ok(int x, int y) {
	set<char> rk, st;
	rk.clear(); st.clear();
	for(int i = 0; i < 3; ++i) {
		for(int j = 0; j < 3; ++j) {
			rk.insert(t[x + i][y + j].rk);
			st.insert(t[x + i][y + j].st);
		}
	}
	if(rk.size() == 9 || st.size() == 1) return true;
	else return false;
}

bool try_sol() {
	for(int x1 = 1; x1 + 2 <= n; ++x1) {
		for(int y1 = 1; y1 + 2 <= m; ++y1) if(ok(x1, y1)) {
//			printf("(%d, %d) passed\n", x1, y1);
			for(int x2 = 1; x2 + 2 <= n; ++x2) {
				for(int y2 = 1; y2 + 2 <= m; ++y2) if(ok(x2, y2)) {
					if(!(std::min(x1, x2) + 2 >= std::max(x1, x2) &&
						std::min(y1, y2) + 2 >= std::max(y1, y2))) {
							printf("Solution exists.\n");
							printf("%s\n", words);
							printf("Put the first square to (%d, %d).\n", x1, y1);
							printf("Put the second square to (%d, %d).\n", x2, y2);
							return true;
						}
				}
			}
		}
	}
	return false;
}

bool solve() {
	assert(__builtin_popcount(jks) == (int)empty.size());
	if(empty.size() == 0) {
		sprintf(words, "There are no jokers.");
		return try_sol();
	}
	else if(empty.size() == 1) {
		int id = -1;
		if(jks == 1) id = 1;
		else id = 2;
		for(Card c : cards) {
			sprintf(words, "Replace J%d with %c%c.", id, c.rk, c.st);
			t[empty[0].x][empty[0].y] = c;
			if(try_sol()) return true;
		}
	} else {
		for(auto i = cards.begin(); i != cards.end(); ++i) {
			for(auto j = cards.begin(); j != cards.end(); ++j) if(i != j) {
				sprintf(words,
					"Replace J1 with %c%c and J2 with %c%c.", i->rk, i->st, j->rk, j->st);
				t[empty[0].x][empty[0].y] = *i;
				t[empty[1].x][empty[1].y] = *j;
				if(try_sol()) return true;
			}
		}
	}
	return false;
}

int main() {
	initialize();
	if(!solve()) {
		printf("No solution.\n");
	}
	return 0;
}

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
string A[18][18],s;
int n,m , U[101],us, J[3][3];
bool B[1001];
int r1,c1,r2,c2,size;

int tonum(char ch){
    if(ch=='C')return 1;
    if(ch=='D')return 2;
    if(ch=='H')return 3;
    if(ch=='S')return 4;
    if(ch=='T')return 8;
    if(ch=='J')return 9;
    if(ch=='Q')return 10;
    if(ch=='K')return 11;
    if(ch=='A')return 12;
    return (int)ch-50;
}

inline bool inside(int a,int b,int c){
    if(b>c)swap(b,c);
    return (b<=a&&a<=c);
}

inline bool ff(int r,int c){
    bool B[13];
    for(int i=0;i<=12;i++)B[i]=false;

    for(int i=r;i<=r+2;i++)
        for(int j=c;j<=c+2;j++){
            if(B[tonum(A[i][j][0])])return false;
            B[tonum(A[i][j][0])]=true;
        }
    return true;
}

inline bool check(){

    for(int i=1;i<=size;i++)
        for(int j=i+1;j<=size;j++){
            r1=(i%m)?i/m+1:i/m;
            c1=(i%m)?(i%m):m;
            r2=(j%m)?j/m+1:j/m;
            c2=(j%m)?(j%m):m;

            if(!(inside(r2,r1,r1+2)&&inside(c2,c1,c1+2) ) &&
               !(inside(r2,r1,r1+2)&&inside(c2+2,c1,c1+2) ) &&
               inside(r1+2,1,n)&&inside(r2+2,1,n) &&
               inside(c1+2,1,m) && inside(c2+2,1,m) ){

                    if(ff(r1,c1)&&ff(r2,c2))return true;

               }
        }
    return false;

}

char torank(int k){
    int r=(k%4)?k/4+1:k/4;
    if(r<=8)return (char)(r+49);
    if(r==9)return 'T';
    if(r==10)return 'J';
    if(r==11)return 'Q';
    if(r==12)return 'K';
    if(r==13)return 'A';
}

char tosuit(int k){
    int r=k%4;
    if(r==0)return 'S';
    if(r==1)return 'C';
    if(r==2)return 'D';
    if(r==3)return 'H';
}

inline bool replacee(int j,int k){
    if(J[j][1]==0)return false;
    //cout<<J[j][1]<<" "<<J[j][2]<<endl;
    A[J[j][1]][J[j][2]][0]=torank(k);
    A[J[j][1]][J[j][2]][1]=tosuit(k);
    //cout<<torank(k)<<" "<<tosuit(k)<<endl;
    return true;
}

string print(int k){
    char A[3];
    A[0]=torank(k); A[1]=tosuit(k);
    A[2]='\0';
    string str(A);
    return str;
}

void printt(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<A[i][j][0]<<A[i][j][1]<<" ";
        cout<<endl;
    }
    cout<<endl;
}

int main()
{
    bool rep1 , rep2;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>s;
            A[i][j].assign(s);
            if(s[0]=='J'){
                if(s[1]=='1'){
                    J[1][1]=i; J[1][2]=j;
                }
                else if(s[1]=='2'){
                    J[2][1]=i; J[2][2]=j;
                }
            }
            B[tonum(s[0])*4+tonum(s[1])]=true;
        }

    size = n*m;
    for(int i=1;i<=52;i++)
        if( !B[i] )U[us++]=i;

    for(int i=0;i<us;i++)
        for(int j=0;j<us;j++)
            if(i!=j){

                rep1=replacee(1,U[i]);
                rep2=replacee(2,U[j]);

                //cout<<U[i]<<" "<<U[j]<<endl;
                //printt();

                if(check()){
                    cout<<"Solution exists."<<endl;
                    if(!rep1&&!rep2)cout<<"There are no jokers."<<endl;
                    else if(rep1&&rep2)cout<<"Replace J1 with "<<print(U[i])<<" and J2 with "<<print(U[j])<<"."<<endl;
                    else if(rep1)cout<<"Replace J1 with "<<print(U[i])<<"."<<endl;
                    else if(rep2)cout<<"Replace J2 with "<<print(U[j])<<"."<<endl;
                    cout<<"Put the first square to ("<<r1<<", "<<c1<<")."<<endl;
                    cout<<"Put the second square to ("<<r2<<", "<<c2<<")."<<endl;
                    return 0;
                }

            }

    cout<<"No solution."<<endl;

    return 0;
}

#include <iostream>
#include <set>

using namespace std;

#define REP(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,n) REP(i,0,n)
#define foreach(i,c) for(__typeof__((c).end()) i=(c).begin(); i!=(c).end(); i++ )

int n, m, u, v, x, y;
set<string> unused, aset, bset;
set<char> cur_rank, cur_suit;
string cards[17][17], rank[] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" }, suit[] = { "C", "D", "H", "S" };
bool j1, j2, found;

bool okay( int a, int b, string j1str, string j2str )
{
	cur_rank.clear();
	cur_suit.clear();
	rep(p,3) rep(q,3)
	{
		string cur = cards[a+p][b+q];
		if(cur=="J1") cur = j1str;
		if(cur=="J2") cur = j2str;
		cur_rank.insert(cur[0]);
		cur_suit.insert(cur[1]);
	}
	return cur_rank.size()==9 || cur_suit.size()==1;
}

bool find( string j1str, string j2str )
{
	for( u = 0; u < n-2; u++ ) for( v = 0; v < m-2; v++ )
	if(okay(u,v,j1str,j2str))
	for( x = 0; x < n-2; x++ ) for( y = 0; y < m-2; y++ )
	if( ( x>=u+3 || x<=u-3 || y>=v+3 || y<=v-3 ) && okay(x,y,j1str,j2str) )
		return true;
	return false;
}

int main()
{
	rep(i,13) rep(j,4) unused.insert( rank[i] + suit[j] );
	aset.insert("a");
	bset.insert("b");
	cin >> n >> m;
	rep(i,n) rep(j,m)
	{
		cin >> cards[i][j];
		if( cards[i][j] == "J1" ) j1 = true;
		if( cards[i][j] == "J2" ) j2 = true;
		unused.erase( cards[i][j] );
	}
	if(j1) aset = unused;
	if(j2) bset = unused;
	foreach(a,aset) foreach(b,bset) if( *a!=*b && find(*a,*b) )
	{
		cout << "Solution exists." << endl;
		if(j1&&j2) cout << "Replace J1 with " << *a << " and J2 with " << *b << "." << endl;
		else if(j1) cout << "Replace J1 with " << *a << "." << endl;
		else if(j2) cout << "Replace J2 with " << *b << "." << endl;
		else cout << "There are no jokers." << endl;
		cout << "Put the first square to (" << u+1 << ", " << v+1 << ")." << endl;
		cout << "Put the second square to (" << x+1 << ", " << y+1 << ")." << endl;
		return 0;
	}
	cout << "No solution." << endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

string firsts = "23456789TJQKA";
string seconds = "CDHS";

int n, m;
string a[55][55];
vector<pair<string, string>> cur, ans;
vector<pair<int, int>> wh;

bool go(int x, int y) {
    if (y == m) {
        y = 0;
        ++x;
    }
    if (x == n) {
        vector<pair<int, int>> goods;
        for (int i1 = 0; i1 + 2 < n; ++i1) {
            for (int j1 = 0; j1 + 2 < m; ++j1) {
                set<char> f, s;
                for (int x = 0; x < 3; ++x) {
                    for (int y = 0; y < 3; ++y) {
                        f.insert(a[i1 + x][j1 + y][0]);
                        s.insert(a[i1 + x][j1 + y][1]);
                    }
                }
                if (f.size() == 9u || s.size() == 1u) {
                    goods.emplace_back(i1, j1);
                }
            }
        }
        for (auto c1 : goods) {
            for (auto c2 : goods) {
                if (abs(c1.first - c2.first) >= 3 || abs(c1.second - c2.second) >= 3) {
                    ans = cur;
                    wh = {c1, c2};
                    return true;
                }
            }
        }
        return false;
    }
    string th = a[x][y];
    if (th != "J1" && th != "J2")
        return go(x, y + 1);
    for (char f : firsts) {
        for (char s : seconds) {
            string rep = {f, s};
            bool ok = true;
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < m; ++j)
                    ok &= a[i][j] != rep;
            if (!ok)
                continue;
            a[x][y] = rep;
            cur.emplace_back(th, rep);
            if (go(x, y + 1))
                return true;
            cur.pop_back();
            a[x][y] = th;
        }
    }
    return false;
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    if (go(0, 0)) {
        cout << "Solution exists.\n";
        if (ans.empty()) {
            cout << "There are no jokers.\n";
        } else if (ans.size() == 1u) {
            cout << "Replace " << ans[0].first << " with " << ans[0].second << ".\n";
        } else {
            string x = ans[0].second, y = ans[1].second;
            if (ans[0].first != "J1")
                swap(x, y);
            cout << "Replace J1 with " << x << " and J2 with " << y << ".\n";
        }
        cout << "Put the first square to (" << wh[0].first + 1 << ", " << wh[0].second + 1 << ").\n";
        cout << "Put the second square to (" << wh[1].first + 1 << ", " << wh[1].second + 1 << ").\n";
    } else {
        cout << "No solution.\n";
    }
}

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman010 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
int n , m;
string s[20][20];
set<string> st;
vector<pair<int , int>> solve() {
    bool done[20][20] = {};
    vector<pair<int , int>> ans;
    for(int i = 0;i + 2 < n;i++)
        for(int j = 0;j + 2 < m;j++) {
            bool yes = false;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    yes |= done[i + p1][j + p2];
            if(yes)
                continue;
            set<char> st;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    st.insert(s[i + p1][j + p2][0]);
            if(st.size() == 9) {
                ans.push_back({i + 1 , j + 1});
                for(int p1 = 0;p1 < 3;p1++)
                    for(int p2 = 0;p2 < 3;p2++)
                        done[i + p1][j + p2] = true;
            }
        }
    return ans;
}
int main() {
    abdelrahman010
    cin >> n >> m;
    for(auto &i : {'C' , 'D' , 'H' , 'S'}) {
        for(char j = '2';j <= '9';j++) {
            string m = "";
            m += j , m += i;
            st.insert(m);
        }
        for(auto &j : {'T' , 'J' , 'A' , 'Q' , 'K'}) {
            string m = "";
            m += j , m += i;
            st.insert(m);
        }
    }
    vector<pair<int , int>> joker;
    vector<string> p;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++) {
            cin >> s[i][j];
            st.erase(s[i][j]);
            if(s[i][j] == "J1" || s[i][j] == "J2") {
                joker.push_back({i , j});
                p.push_back(s[i][j]);
            }
        }
    vector<string> v;
    for(auto &i : st)
        v.push_back(i);
    if(joker.size() == 1) {
        for(int i = 0;i < v.size();i++) {
            s[joker[0].first][joker[0].second] = v[i];
            vector<pair<int , int>> ans = solve();
            if(ans.size() >= 2) {
                cout << "Solution exists.\n";
                cout << "Replace " << p[0] << " with " << v[i] << ".\n";
                cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
                cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << ").";
                return 0;
            }
        }
    } else if(joker.size() == 2) {
        for(int i = 0;i < v.size();i++)
            for(int j = 0;j < v.size();j++) {
                if(i == j)
                    continue;
                s[joker[0].first][joker[0].second] = v[i];
                s[joker[1].first][joker[1].second] = v[j];
                vector<pair<int , int>> ans = solve();
                if(ans.size() >= 2) {
                    if(p[0] == "J2") {
                        swap(p[0] , p[1]);
                        swap(v[i] , v[j]);
                    }
                    cout << "Solution exists.\n";
                    cout << "Replace " << p[0] << " with " << v[i] << " and " << p[1] << " with " << v[j] << ".\n";
                    cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
                    cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << ").";
                    return 0;
                }
        }
    } else {
        vector<pair<int , int>> ans = solve();
        if(ans.size() >= 2) {
            cout << "Solution exists.\n";
            cout << "There are no jokers.\n";
            cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
            cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << ").";
            return 0;
        }
    }
    cout << "No solution.";
    return 0;
}

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <iostream>
using namespace std;

string c[52][52];
string r[2];
set<string> used;
int n, m;
vector<pair<int,int> > joker;
string cname[52];

bool overlap(int i, int j, int k, int l) {
	if(i-k>=3||k-i>=3||j-l>=3||l-j>=3) return false;
	return true;
}

int uu[128],ucs;
bool check(int i, int j) {
	++ucs;
	int f1=0,f2=0;
	for(int u=0;u<3;u++)
		for(int v=0;v<3;v++) {
			string &ref=(c[i+u][j+v]=="J1"?r[0]:(c[i+u][j+v]=="J2"?r[1]:c[i+u][j+v]));
			string &ref2=(c[i][j]=="J1"?r[0]:(c[i][j]=="J2"?r[1]:c[i][j]));
			if(ref[1]!=ref2[1]) f2=1;
			if(uu[(int)ref[0]]==ucs) f1=1;
			uu[(int)ref[0]]=ucs;
		}
	//printf("i=%d, j=%d f1=%d, f2=%d\n", i, j, f1, f2);
	return !f1||!f2;
}

void output(int i, int j, int k, int l) {
	puts("Solution exists.");
	if(joker.size()==0) puts("There are no jokers.");
	else if(joker.size()==1) {
		printf("Replace %s with %s.\n",
				c[joker[0].first][joker[0].second].c_str(), r[0].c_str());
	} else {
		int f=c[joker[0].first][joker[0].second]=="J1";
		f=1;
		printf("Replace J1 with %s and J2 with %s.\n",
			f?r[0].c_str():r[1].c_str(), f?r[1].c_str():r[0].c_str());
	}
	printf("Put the first square to (%d, %d).\n", i+1, j+1);
	printf("Put the second square to (%d, %d).\n", k+1, l+1);
}

bool test() {
	for(int i=0;i+3<=n;i++)
		for(int j=0;j+3<=m;j++)
			for(int k=0;k+3<=n;k++)
				for(int l=0;l+3<=m;l++)
					if(overlap(i,j,k,l)==false && check(i,j) && check(k,l)) {
						output(i,j,k,l);
						return true;
					}
	return false;
}
int main(void) {
	cin >> n >> m;
	string suit="CDHS";
	string rank="A23456789TJQK";
	for(int i=0;i<52;i++)
		cname[i] = rank.substr(i/4,1)+suit.substr(i%4,1);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++) {
			cin >> c[i][j];
			used.insert(c[i][j]);
			if(c[i][j]=="J1" || c[i][j]=="J2")
				joker.push_back(make_pair(i, j));
		}
	if(joker.size()==0) {
		if(test()) return 0;
	} else if(joker.size()==1) {
		for(int r0=0;r0<52;r0++) {
			if(used.find(cname[r0])!=used.end()) continue;
			r[0] = r[1] = cname[r0];
			if(test()) return 0;
		}
	} else if(joker.size()==2) {
		for(int r0=0;r0<52;r0++) {
			if(used.find(cname[r0])!=used.end()) continue;
			for(int r1=0;r1<52;r1++) {
				r[0]=cname[r0];
				r[1]=cname[r1];
				if(r1==r0 || used.find(cname[r1])!=used.end()) continue;
				if(test()) return 0;
			}
		}
	}
	puts("No solution.");
	return 0;
}

/*
 * main.cpp
 *
 *  Created on: 29.03.2011
 *      Author: skird
 */

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <set>

using namespace std;

int cost(char c)
{
        if (c >= '2' && c <= '9') return c - '2';
        if (c == 'T') return 8;
        if (c == 'J') return 9;
        if (c == 'Q') return 10;
        if (c == 'K') return 11;
        return 12;
}

int color(char c)
{
        if (c == '1') return 100500;
        if (c == '2') return 100600;
        if (c == 'C') return 0;
        if (c == 'D') return 1;
        if (c == 'H') return 2;
        return 3;
}

struct Card
{
        int p, c;

        Card() {}
        Card(int _p, int _c): p(_p), c(_c) {}
        Card(istream &in)
        {
                string token;
                cin >> token;
                p = cost(token[0]);
                c = color(token[1]);
        }

        bool isJoker()
        {
                return c == 100500 || c == 100600;
        }
};

bool operator < (Card a, Card b)
{
        return a.p < b.p || (a.p == b.p && a.c < b.c);
}

int n, m;
vector< vector<Card> > data;

bool goodSquare(int x, int y)
{
        bool used[13];
        fill(used, used + 13, false);
        for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                {
                	if (used[data[x + i][y + j].p]) return false;
                	used[data[x + i][y + j].p] = true;
                }
        return true;
}

bool cross(pair<int, int> a, pair<int, int> b)
{
        int dx = abs(a.first - b.first), dy = abs(b.second - a.second);
        return dx < 3 && dy < 3;
}

pair< pair<int, int>, pair<int, int> > isOk()
{
        vector< pair<int, int> > squares;
        for (int i = 0; i + 2 < n; i++)
                for (int j = 0; j + 2 < m; j++)
                        if (goodSquare(i, j)) squares.push_back(make_pair(i, j));
        for (size_t i = 0; i < squares.size(); i++)
                for (size_t j = 0; j < squares.size(); j++)
                        if (!cross(squares[i], squares[j])) return make_pair(squares[i], squares[j]);
        return make_pair(make_pair(-1, -1), make_pair(-1, -1));
}

set<Card> rest;
vector< pair<int, int> > jokers;

void print(pair<int, int> x)
{
        Card c = data[x.first][x.second];
        if (c.p >= 0 && c.p < 8) cout << (char) (c.p + '2');
        else
        {
                switch (c.p)
                {
                        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 (c.c)
        {
                case 100500: cout << "1"; break;
                case 100600: cout << "2"; break;
                case 0: cout << "C"; break;
                case 1: cout << "D"; break;
                case 2: cout << "H"; break;
                case 3: cout << "S"; break;
        }
}

pair< pair<int, int>, pair<int, int> > rec(int r)
{
        if (r == 0) return isOk();
        set<Card>::iterator it;
        int x = jokers[r - 1].first, y = jokers[r - 1].second;
        vector<Card> q;
        for (it = rest.begin(); it != rest.end(); it++) q.push_back(*it);
        for (size_t i = 0; i < q.size(); i++)
        {
                Card c = q[i];
                rest.erase(c);
                Card copy = data[x][y];
                data[x][y] = c;
                pair< pair<int, int>, pair<int, int> > temp = rec(r - 1);
                if (temp.first.first != -1) return temp;
                data[x][y] = copy;
                rest.insert(c);
        }
        return make_pair(make_pair(-1, -1), make_pair(-1, -1));
}

int main()
{
#ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
#endif
        cin >> n >> m;
        data.assign(n, vector<Card>(m));
        for (int i = 0; i < 13; i++)
                for (int j = 0; j < 4; j++)
                        rest.insert(Card(i, j));
        vector<int> some;
        for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                {
                        data[i][j] = Card(cin);
                        if (!data[i][j].isJoker()) rest.erase(data[i][j]);
                        if (data[i][j].isJoker())
                                jokers.push_back(make_pair(i, j)), some.push_back(data[i][j].c);
                }
        pair< pair<int, int>, pair<int, int> > temp = rec(jokers.size());
        if (temp.first.first == -1)
        {
                cout << "No solution.";
                return 0;
        }
        cout << "Solution exists." << endl;
        if (jokers.size() == 0) cout << "There are no jokers." << endl;
        else if (jokers.size() == 1)
        {
                cout << "Replace J" << (some[0] == 100500 ? 1 : 2) << " with ";
                print(jokers[0]);
                cout << "." << endl;
        }
        else
        {
                if (some[0] != 100500) swap(jokers[0], jokers[1]);
                cout << "Replace J1 with ", print(jokers[0]);
                cout << " and J2 with ", print(jokers[1]);
                cout << "." << endl;
        }
        cout << "Put the first square to (" << temp.first.first + 1 << ", " << temp.first.second + 1 << ")." << endl;
        cout << "Put the second square to (" << temp.second.first + 1 << ", " << temp.second.second + 1 << ").";
        return 0;
}

#include <set>
#include <map>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <utility>
#include <iostream>
#include <algorithm>
#define LL long long
#define pi 3.1415926535897932384626433
#define sqr(a) ((a)*(a))

using namespace std;

char V[4] = {'C', 'D', 'H', 'S'};
char K[13] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
string a[100][100], b[100][100];
int can[60][60];
int u[52], L[100], R[100], U[100], D[100], change[3];
int ans, joker, n, m;

int Candy(int x, int y)
{
    int flag = 1;
    for (int i = x; i <= x + 2; i ++)
        for (int j = y; j <= y + 2; j ++)
            if (b[i][j][1] != b[x][y][1])
                flag = 0;
    if (flag) return 1;
    set<char> u;
    u.clear();
    for (int i = x; i <= x + 2; i ++)
        for (int j = y; j <= y + 2; j ++)
            if (u.count(b[i][j][0]))
                return 0;
            else u.insert(b[i][j][0]);
    return 1;
}

void check()
{
    string o[3];
    o[1] = o[2] = "";
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
        {
            b[i][j] = a[i][j];
            if (b[i][j][0] == 'J' && isdigit(b[i][j][1]))
            {
                int x = b[i][j][1] - 48;
                b[i][j][0] = K[change[min(x, joker)] / 4];
                b[i][j][1] = V[change[min(x, joker)] % 4];
                o[x] = b[i][j];
            }
        }
    memset(can, 0, sizeof(can));
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
        {
            if (i + 2 > n || j + 2 > m)
                continue;
            can[i][j] = Candy(i, j);
        }
    memset(L, 0, sizeof(L));
    memset(R, 0, sizeof(R));
    memset(U, 0, sizeof(U));
    memset(D, 0, sizeof(D));
    //U
    for (int i = 1; i <= n; i ++)
    {
        U[i] = U[i - 1];
        for (int j = 1; j <= m; j ++)
            if (can[i][j]) U[i] = 1;
    }
    //D
    for (int i = n; i; i --)
    {
        D[i] = D[i + 1];
        for (int j = 1; j <= m; j ++)
            if (can[i][j]) D[i] = 1;
    }
    //L
    for (int j = 1; j <= m; j ++)
    {
        L[j] = L[j - 1];
        for (int i = 1; i <= n; i ++)
            if (can[i][j]) L[j] = 1;
    }
    //R
    for (int j = m; j; j --)
    {
        R[j] = R[j + 1];
        for (int i = 1; i <= n; i ++)
            if (can[i][j]) R[j] = 1;
    }
    int flag;
    for (int i = 1; i + 2 < n; i ++)
        if (U[i] && D[i + 3])
        {
            cout << "Solution exists." << endl;
            if (! joker)
                cout << "There are no jokers." << endl;
            else if (joker == 1)
            {
                cout << "Replace J";
                if (o[1].size()) cout << "1"; else cout << "2";
                cout << " with ";
                cout << o[1] + o[2] << "." << endl;
            }
            else
                cout << "Replace J1 with " << o[1] << " and J2 with " << o[2] << "." << endl;
            flag = 0;
            cout << "Put the first square to ";
            for (int x = 1; x <= i; x ++)
            {
                for (int j = 1; j <= m; j ++)
                    if (can[x][j])
                    {
                        cout << "(" << x << ", " << j << ")." << endl;
                        flag = 1; break;
                    }
                if (flag) break;
            }
            flag = 0;
            cout << "Put the second square to ";
            for (int x = i + 3; x <= n; x ++)
            {
                for (int j = 1; j <= m; j ++)
                    if (can[x][j])
                    {
                        cout << "(" << x << ", " << j << ")." << endl;
                        flag = 1; break;
                    }
                if (flag) break;
            }
            ans = 1; return ;
        }
    for (int j = 1; j + 2 < m; j ++)
        if (L[j] && R[j + 3])
        {
            cout << "Solution exists." << endl;
            if (! joker)
                cout << "There are no jokers." << endl;
            else if (joker == 1)
            {
                cout << "Replace J";
                if (o[1].size()) cout << "1"; else cout << "2";
                cout << " with ";
                cout << o[1] + o[2] << "." << endl;
            }
            else
                cout << "Replace J1 with " << o[1] << " and J2 with " << o[2] << "." << endl;
            flag = 0;
            cout << "Put the first square to ";
            for (int y = 1; y <= j; y ++)
            {
                for (int i = 1; i <= n; i ++)
                    if (can[i][y])
                    {
                        cout << "(" << i << ", " << y << ")." << endl;
                        flag = 1; break;
                    }
                if (flag) break;
            }
            flag = 0;
            cout << "Put the second square to ";
            for (int y = j + 3; y <= m; y ++)
            {
                for (int i = 1; i <= n; i ++)
                    if (can[i][y])
                    {
                        cout << "(" << i << ", " << y << ")." << endl;
                        flag = 1; break;
                    }
                if (flag) break;
            }
            ans = 1; return ;
        }
}

void dfs(int x)
{
    if (ans) return ;
    if (x == joker + 1)
    {
        check();
        return ;
    }
    for (int i = 0; i < 52; i ++)
        if (! u[i])
        {
            u[i] = 1;
            change[x] = i;
            dfs(x + 1);
            u[i] = 0;
        }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
#endif
    cin >> n >> m;
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
            cin >> a[i][j];
    //
    joker = 0;
    memset(u, 0, sizeof(u));
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
        {
            if (a[i][j][0] == 'J' && isdigit(a[i][j][1]))
            {
                joker ++; continue;
            }
            int x, y;
            for (int k = 0; k < 13; k ++)
                if (K[k] == a[i][j][0]) x = k;
            for (int k = 0; k < 4; k ++)
                if (V[k] == a[i][j][1]) y = k;
            u[x * 4 + y] = 1;
        }
    //
    ans = 0;
    dfs(1);
    if (! ans)
        cout << "No solution." << endl;
    return 0;
}

#include <bits/stdc++.h>
#include <fstream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

typedef unsigned long long ll;
typedef long double ld;
using namespace std;
using namespace __gnu_pbds;

#define endl "\n"
#define FIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ordered_set tree<pair<int,int>, null_type,less<pair<int,int>>, rb_tree_tag,tree_order_statistics_node_update>
const int N=1e6+5, mxN=(1<<19)+5;
int mod=998244353 ;
int n,m;
string s[18][18];
map<int, char>mp1,mp2;
vector<pair<int,int>>v, ans;
bool check_cube(int x,int y)
{
    if(x+2>=n||y+2>=m)
        return 0;
    set<char>st1,st2;
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
        {
            st1.insert(s[x+i][y+j][0]);
            st2.insert(s[x+i][y+j][1]);

        }

    }

    return (st2.size()==1||st1.size()==9);

}
bool check()
{
    vector<pair<int,int>>v1;
    set<string>st;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(check_cube(i,j))
                v1.push_back({i,j});
            st.insert(s[i][j]);

        }
    }

    if(st.size()==m*n)
    {
        for(int i=0; i<v1.size(); i++)
        {
            for(int j=i+1; j<v1.size(); j++)
            {
                if(abs(v1[i].first-v1[j].first)>=3||abs(v1[i].second-v1[j].second)>=3)
                {
                    ans.push_back({v1[i].first+1,v1[i].second+1});
                    ans.push_back({v1[j].first+1,v1[j].second+1});
                    return 1;
                }

            }

        }

    }
    return 0;
}

void build()
{
    mp1[0]='2';
    mp1[1]='3';
    mp1[2]='4';
    mp1[3]='5';
    mp1[4]='6';
    mp1[5]='7';
    mp1[6]='8';
    mp1[7]='9';
    mp1[8]='T';
    mp1[9]='J';
    mp1[10]='Q';
    mp1[11]='K';
    mp1[12]='A';

    mp2[0]='C';
    mp2[1]='D';
    mp2[2]='H';
    mp2[3]='S';

}
int main()
{
    FIO
    build();
    cin>>n>>m;
    int x=0;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            cin>>s[i][j];
            if(s[i][j]=="J1")
                v.push_back({i,j}),x=1;

        }

    }

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(s[i][j]=="J2")
                v.push_back({i,j}),x=2;
        }

    }
    if(v.size()==0)
    {
        if(check())
        {
            cout<<"Solution exists.\n";
            cout<<"There are no jokers.\n";
            cout<<"Put the first square to ("<<ans[0].first<<", "<<ans[0].second<<").\n";
            cout<<"Put the second square to ("<<ans[1].first<<", "<<ans[1].second<<").\n";
            return 0;
        }

    }
    else if( v.size()==1)
    {
        for(int j=0; j<13; j++)
        {
            for(int i=0; i<4; i++)
            {

                string ss;
                ss+=mp1[j];
                ss+=mp2[i];
                s[v[0].first][v[0].second]=ss;
                if(check())
                {
                    cout<<"Solution exists.\n";
                    cout<<"Replace J"<<x<<" with "<<ss<<".\n";
                    cout<<"Put the first square to ("<<ans[0].first<<", "<<ans[0].second<<").\n";
                    cout<<"Put the second square to ("<<ans[1].first<<", "<<ans[1].second<<").\n";
                    return 0;

                }
            }

        }

    }
    else if(v.size()==2)
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<13; j++)
            {
                for(int a=0; a<4; a++)
                {
                    for(int b=0; b<13; b++)
                    {

                        string ss;ss+=mp1[j];ss+=mp2[i];
                        s[v[0].first][v[0].second]=ss;
                        string sss="";sss+=mp1[b];sss+=mp2[a];
                        s[v[1].first][v[1].second]=sss;

                        if(check())
                        {
                            cout<<"Solution exists.\n";
                            cout<<"Replace J1 with "<<ss<<" and J2 with "<<sss<<".\n";
                            cout<<"Put the first square to ("<<ans[0].first<<", "<<ans[0].second<<").\n";
                            cout<<"Put the second square to ("<<ans[1].first<<", "<<ans[1].second<<").\n";
                            return 0;

                        }
                    }

                }
            }
        }

    }

    cout<<"No solution." ;

    return 0;
}

#include <bits/stdc++.h>
typedef long long ll ;
using namespace std;

string A = "23456789TJQKA" ;
string B = "CDHS";
vector < string > cards ;

int n , m ;
vector < vector < string > > grid ;
map < string , pair < int , int > > exist ;

bool overlap(int x1 , int y1 , int x2 , int y2) {
    if (x1 + 3 <= x2) return false;
    if (x2 + 3 <= x1) return false;
    if (y1 + 3 <= y2) return false;
    if (y2 + 3 <= y1) return false;
    return true;
}

bool different(int x , int y) {

    bool diff = 1;
    vector < bool > ok(1000 , 0) ;

    for(int i = x ; i < x + 3 && diff ; i++) {
        for(int j = y ; j < y + 3 && diff ; j++) {
            if(grid[i][j] == "J1" || grid[i][j] == "J2") continue ;
            if(ok[grid[i][j][0]]) diff = 0 ;
            else ok[grid[i][j][0]] = 1 ;
        }
    }

    return diff ;
}

string getSquare(int x , int y , int xx ,int yy){

    vector < bool > ok(1000 , 0) ;
    for(int i = x ; i < x + 3  ; i++) {
        for(int j = y ; j < y + 3 ; j++) {
            if(grid[i][j] == "J1" || grid[i][j] == "J2") continue ;
            ok[grid[i][j][0]] = 1 ;
        }
    }

    for(auto s : cards){
           if(exist.find(s) != exist.end()) continue ;
           if(ok[s[0]]) continue ;
           exist[s] = {xx , yy};
           grid[xx][yy] = s;
           return s;
    }

    return "";
}

string getRandom(int xx , int yy){

     for(auto s : cards) if(exist.find(s) == exist.end()) {
           exist[s] = {xx , yy};
           grid[xx][yy] = s ;
          return s ;
     }

     return "" ;
}

int main() {

    ios::sync_with_stdio(false);

    for(int i = 0 ; i < 4 ; i++) {
        for(int j = 0 ; j < 13 ; j++) {
            string s ;
            s.push_back(A[j]);
            s.push_back(B[i]);
            cards.push_back(s);
        }
    }

    cin >> n >> m ;

    grid.resize(n) ;

    for(int i = 0 ; i < n ; i++) {
        for(int j = 0 ; j < m ; j++) {
            string s ;
            cin >> s ;
            grid[i].push_back(s);
            exist[s] = {i , j} ;
        }
    }

    for(int i = 0 ; i + 2 < n ; i++) {
        for(int j = 0 ; j + 2 < m ; j++) {

            if(!different(i , j)) continue ;

            for(int k = 0 ; k + 2 < n ; k++) {
                for(int t = 0 ; t + 2 < m ; t++) {

                    if(overlap(i , j , k , t)) continue ;
                    if(!different(k , t)) continue ;

                    if(exist.find("J1") == exist.end() && exist.find("J2") == exist.end()){
                           puts("Solution exists.");
                           puts("There are no jokers.");
                           printf("Put the first square to (%d, %d).\n",i+1,j+1);
                           printf("Put the second square to (%d, %d).\n",k+1,t+1);
                           return 0 ;
                    }

                    if(exist.find("J1") != exist.end() && exist.find("J2") != exist.end()){

                        auto axis1 = exist["J1"];
                        auto axis2 = exist["J2"];

                        string s1 , s2 ;

                        int c1 = 0 , c2 = 0 ;

                        if( (axis1.first >= i && axis1.first <= i + 2) && (axis1.second >= j && axis1.second <= j + 2) ){
                            s1 = getSquare(i , j , axis1.first , axis1.second) ;
                            if(s1.empty()) c1 = -1 ;

                        }
                        if( (axis1.first >= k && axis1.first <= k + 2) && (axis1.second >= t && axis1.second <= t + 2) ){
                            s1 = getSquare(k , t , axis1.first , axis1.second );
                            if(s1.empty()) c1 = -1 ;
                        }
                        if( (axis2.first >= i && axis2.first <= i + 2) && (axis2.second >= j && axis2.second <= j + 2) ){
                             s2 = getSquare(i , j , axis2.first , axis2.second );
                             if(s2.empty()) c2 = -1 ;
                        }
                        if( (axis2.first >= k && axis2.first <= k + 2) && (axis2.second >= t && axis2.second <= t + 2) ){
                             s2 = getSquare(k , t , axis2.first , axis2.second);
                             if(s2.empty()) c2 = -1 ;
                        }

                        if(!c1 && s1.empty()){
                             s1 = getRandom(axis1.first , axis1.second);
                        }

                        if(!c2 && s2.empty()){
                             s2 = getRandom(axis2.first , axis2.second);
                        }

                        if(s1.empty() || s2.empty()){
                               puts("No solution.");
                               return 0 ;
                        }

                        puts("Solution exists.");
                        printf("Replace J1 with %s and J2 with %s.\n",s1.c_str(),s2.c_str());
                        printf("Put the first square to (%d, %d).\n",i+1,j+1);
                        printf("Put the second square to (%d, %d).\n",k+1,t+1);
                        return 0 ;
                    }

                    if(exist.find("J1") != exist.end() || exist.find("J2") != exist.end()){

                         pair < int , int > axis ;

                         if(exist.find("J1") != exist.end()) axis = exist["J1"];
                         else axis = exist["J2"] ;

                         string s ;
                         int c = 0 ;

                         if( (axis.first >= i && axis.first <= i + 2) && (axis.second >= j && axis.second <= j + 2) ){
                              s = getSquare(i , j , axis.first , axis.second);
                              if(s.empty()) c = -1 ;
                         }
                         if( (axis.first >= k && axis.first <= k + 2) && (axis.second >= t && axis.second <= t + 2) ) {
                              s = getSquare(k , t , axis.first , axis.second);
                              if(s.empty()) c = -1 ;
                         }
                         if(!c && s.empty()){
                             s = getRandom(axis.first , axis.second);
                         }

                         if(s.empty()){
                               puts("No solution.");
                               return 0 ;
                         }

                         puts("Solution exists.");
                         if(exist.find("J1") != exist.end()) printf("Replace J1 with %s.\n",s.c_str());
                         else printf("Replace J2 with %s.\n",s.c_str());
                         printf("Put the first square to (%d, %d).\n",i+1,j+1);
                         printf("Put the second square to (%d, %d).\n",k+1,t+1);
                         return 0 ;
                    }
                }
            }
        }
    }

    puts("No solution.");

    return 0;
}

#include <iostream>
#include <string>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;

string rank[15] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
string suit[5] = {"C", "D", "H", "S"};

int ans1i, ans1j, ans2i, ans2j;

int check(string str[100][100], int m, int n)
{
	int ret[100][100];
	int used[500];
	char st;
	int flag = 0;
	int i, j, k, l;
	int ok = 0;

	memset(ret, 0, sizeof(ret));
	for(i = 2;i < m;i++)
		for(j = 2;j < n;j++)
		{
			flag = 1;
			st = str[i - 2][j - 2][1];
			memset(used, 0, sizeof(used));
			for(k = i - 2;k <= i;k++)
			{
				for(l = j - 2;l <= j;l++)
					if (used[str[k][l][0]] > 0)
					{
						flag = 0;
						break;
					}
					else
						used[str[k][l][0]]++;
				if (flag == 0)
					break;
			}
			if (flag == 1)
			{
				ret[i][j] = 1;
				continue;
			}
			flag = 1;
			for(k = i - 2;k <= i;k++)
			{
				for(l = j - 2;l <= j;l++)
					if (str[k][l][1] > st)
					{
						flag = 0;
						break;
					}
				if (flag == 0)
					break;
			}
		}

//	if (str[4][2] == "JD" && str[2][7] == "7H")
//		printf("%d %d\n", ret[4][2], ret[4][7]);
	for(i = 2;i < m;i++)
	{
		for(j = 2;j < n;j++)
		{
			if (ret[i][j])
			{
				for(k = i + 3;k < m;k++)
				{
					for(l = 2;l < n;l++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				if (ok)
					break;
			//	if (str[4][2] == "JD" && str[2][7] == "7H" && i == 4 && j == 2)
			//		printf("ok %d %d %d\n", 2, j + 3, ret[4][7]);
				for(l = j + 3;l < n;l++)
				{
					for(k = 2;k < m;k++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				if (ok)
					break;
			}
			if (ok)
				break;
		}
		if (ok)
			break;
	}

	return ok;
}

int main()
{
	int m, n;
	int rk, st, rk2, st2;
	int pi1, pj1, pi2, pj2;
	int i, j;
	int flag;
	string arr[100][100];
	set <string> used;
	cin>>m>>n;

	pi1 = pj1 = pi2 = pj2 = -1;
	for(i = 0;i < m;i++)
		for(j = 0;j < n;j++)
		{
			cin>>arr[i][j];
			if (arr[i][j] != "J1" && arr[i][j] != "J2")
				used.insert(arr[i][j]);
			if (arr[i][j] == "J1")
			{
				pi1 = i;
				pj1 = j;
			}
			if (arr[i][j] == "J2")
			{
				pi2 = i;
				pj2 = j;
			}
		}

	flag = 0;
	for(rk = 0;rk < 13;rk++)
	{
		for(st = 0;st < 4;st++)
		{
			if (pi1 != -1)
			{
				arr[pi1][pj1] = rank[rk] + suit[st];
				if (used.find(arr[pi1][pj1]) != used.end())
					continue;
			}

			for(rk2 = 0;rk2 < 13;rk2++)
			{
				for(st2 = 0;st2 < 4;st2++)
				{
					if (pi1 != -1 && rk == rk2 && st == st2)
						continue;
					if (pi2 != -1)
					{
						arr[pi2][pj2] = rank[rk2] + suit[st2];
						if (used.find(arr[pi2][pj2]) != used.end())
							continue;
					}

			//		if (arr[pi1][pj1] == "JD" && arr[pi2][pj2] == "7H")
			//			printf("%d\n", check(arr, m, n));
					if (check(arr, m, n))
					{
						flag = 1;
						break;
					}
				}
				if (flag == 1)
					break;
			}
			if (flag == 1)
				break;
		}
		if (flag)
			break;
	}

	if (flag)
	{
		printf("Solution exists.\n");
		if (pi1 == -1 && pi2 == -1)
			printf("There are no jokers.\n");
		else if (pi1 != -1 && pi2 != -1)
			printf("Replace J1 with %s and J2 with %s.\n", arr[pi1][pj1].c_str(), arr[pi2][pj2].c_str());
		else if (pi2 != -1)
			printf("Replace J2 with %s.\n", arr[pi2][pj2].c_str());
		else if (pi1 != -1)
			printf("Replace J1 with %s.\n", arr[pi1][pj1].c_str());

		printf("Put the first square to (%d, %d).\n", ans1i, ans1j);
		printf("Put the second square to (%d, %d).\n", ans2i, ans2j);
	}
	else
		printf("No solution.\n");

	return 0;
}

#include <cstdio>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < n; i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define y0 y3487465
#define y1 y8687969

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) {
    re x > 0 ? x : -x;
}

const char ra[4] = {'C', 'D', 'H', 'S'};
const char rb[13] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};

int n;
int m;
int g[20][20];
int was[54];

int get (string s) {
    if (s[0] == 'J' && (s[1] == '2' || s[1] == '1')) re s[1] - '0' + 51;
    int tmp = 0;
    for (int i = 0; i < 4; i++)
        if (s[1] == ra[i])
            tmp += 13 * i;
    for (int i = 0; i < 13; i++)
        if (s[0] == rb[i])
            tmp += i;
    re tmp;
}

int cross (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
    re int (max (x1, x3) <= min (x2, x4) && max (y1, y3) <= min (y2, y4));
}

int check (int x, int y, int j1, int j2) {
    int ok1 = 1, ok2 = 1;
    for (int a = 0; a < 3; a++)
        for (int b = 0; b < 3; b++)
            for (int c = 0; c < 3; c++)
                for (int d = 0; d < 3; d++) {
                    if (a == c && b == d) continue;
                    int p = g[x + a][y + b];
                    if (p == 52) p = j1;
                    if (p == 53) p = j2;
                    int q = g[x + c][y + d];
                    if (q == 52) q = j1;
                    if (q == 53) q = j2;
                    if (p / 13 != q / 13) ok1 = 0;
                    if (p % 13 == q % 13) ok2 = 0;
                }
    re ok1 | ok2;
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            string s;
            cin >> s;
            g[i][j] = get (s);
            was[g[i][j]] = 1;
        }
    for (int j1 = -1; j1 < 52; j1++)
        if (j1 == -1 && !was[52] || j1 != -1 && was[52] && !was[j1])
            for (int j2 = -1; j2 < 52; j2++)
                if ((j2 == -1 && !was[53] || j2 != -1 && was[53] && !was[j2]) && (j1 == -1 || j2 == -1 || j1 != j2))
                    for (int p = 0; p + 2 < n; p++)
                        for (int q = 0; q + 2 < m; q++)
                            if (check (p, q, j1, j2))
                                for (int a = 0; a + 2 < n; a++)
                                    for (int b = 0; b + 2 < m; b++)
                                        if (check (a, b, j1, j2) && !cross (p, q, p + 2, q + 2, a, b, a + 2, b + 2)) {
                                            printf ("Solution exists.\n");
                                            if (j1 == -1 && j2 == -1) printf ("There are no jokers.\n");
                                            if (j1 != -1 && j2 == -1) printf ("Replace J1 with %c%c.\n", rb[j1 % 13], ra[j1 / 13]);
                                            if (j1 == -1 && j2 != -1) printf ("Replace J2 with %c%c.\n", rb[j2 % 13], ra[j2 / 13]);
                                            if (j1 != -1 && j2 != -1) printf ("Replace J1 with %c%c and J2 with %c%c.\n", rb[j1 % 13], ra[j1 / 13], rb[j2 % 13], ra[j2 / 13]);
                                            printf ("Put the first square to (%d, %d).\n", p + 1, q + 1);
                                            printf ("Put the second square to (%d, %d).\n", a + 1, b + 1);
                                            re 0;
                                        }
    printf ("No solution.\n");
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
string arr[18][18];
vector<string > zero;
vector<pair<string, string > > choose;
int n, m;
bool check_square(int x, int y)
{
    if(x+3>n || y+3>m)return 0;
    set<char>st;
    for(int j=x ; j<min(n,x+3) ; j++)
    {
        for(int h=y ; h<min(m,y+3) ; h++)
        {
            st.insert(arr[j][h][0]);
        }
    }

    if(st.size() == 9)
        return 1;
    return 0;
}
bool check_intersection(int x1, int y1, int x2, int y2)
{
    if (abs(x1-x2)<3 && abs(y1-y2)<3)return 0;
    return 1;
}
int main ()
{
    string rnk[]= { "2", "3", "4", "5", "6", "7", "8", "9","J", "T", "Q", "K","A"};
    string suit[]= {"C", "D", "H","S"};
    map<string, int >  mp;
    for(int i =0 ; i<13   ; i ++)
    {
        for(int j=0 ; j<4 ; j++)
        {
            string t=rnk[i];
            t+=suit[j];
            mp[t]=0;
        }
    }
    scanf("%d%d",&n,&m);
    int J1_x,J1_y,J2_x,J2_y,j1=0,j2=0;
    for(int i =0  ; i <n ; i++)
    {
        for(int j=0 ; j<m ; j++)
        {
            string s;
            cin >>s;
            arr[i][j]=s;
            if (s[0]=='J' && (s[1]=='1' || s[1]=='2'))
            {
                if (s[1]=='1')
                {
                    j1=1;
                    J1_x=i;
                    J1_y=j;
                }
                if (s[1]=='2')
                {
                    j2=1;
                    J2_x=i;
                    J2_y=j;
                }
                continue;
            }
            mp[s]++;

        }
    }
    for(auto &it : mp)
    {
        if (it.second==0)zero.push_back(it.first);
    }
    for(int i =0 ; i<zero.size() ; i++)
    {
        for(int j=i+1 ; j<zero.size() ; j++)
        {
            choose.push_back({zero[i],zero[j]});
            choose.push_back({zero[j],zero[i]});
        }
    }

    if (j1&&j2)
    {

        string temp1=arr[J1_x][J1_y],temp2=arr[J2_x][J2_y];
        for(int q=0 ; q<choose.size() ; q++)
        {
            vector<pair<int,int > > square;

            arr[J1_x][J1_y]=choose[q].first;
            arr[J2_x][J2_y]=choose[q].second;

            for(int i =0 ; i<n ; i++)
            {
                for(int j=0 ; j<m ; j++)
                {
                    if (check_square(i,j))square.push_back({i,j});
                    //cout<<check_square(i,j)<<endl;
                }
            }
           // cout<<square[0].first<<' ' <<square[0].second << ' ' <<square[1].first << ' '<<square[1].second<<endl;
            for(int i =0 ; i<square.size() ; i++)
            {
                for(int j=i+1 ; j<square.size() ; j++)
                {
                    if (check_intersection(square[i].first,square[i].second,square[j].first,square[j].second))
                    {
                        printf("Solution exists.\n");
                        printf("Replace J1 with ");
                        cout<<choose[q].first<<" and ";
                        printf("J2 with ");
                        cout<<choose[q].second<<"."<<endl;
                        printf("Put the first square to (%d, %d).\n",square[i].first+1,square[i].second+1);
                        printf("Put the second square to (%d, %d).\n",square[j].first+1,square[j].second+1);

                        return 0;
                    }
                }
            }
            arr[J1_x][J1_y]=temp1, arr[J2_x][J2_y]=temp2;
        }
    }
    else if (j1)
    {
        string temp1=arr[J1_x][J1_y];
        for(int q=0 ; q<zero.size() ; q++)
        {
            vector<pair<int, int > > square;
            arr[J1_x][J1_y]=zero[q];
            for(int i =0 ; i<n ; i++)
            {
                for(int j=0 ; j<m ; j++)
                {
                    if (check_square(i,j))square.push_back({i,j});
                }
            }
            for(int i =0 ; i<square.size() ; i++)
            {
                for(int j=i+1 ; j<square.size() ; j++)
                {
                    if (check_intersection(square[i].first,square[i].second,square[j].first,square[j].second))
                    {
                        printf("Solution exists.\n");
                        printf("Replace J1 with ");
                        cout<<zero[q]<<"."<<endl;
                        printf("Put the first square to (%d, %d).\n",square[i].first+1,square[i].second+1);
                        printf("Put the second square to (%d, %d).\n",square[j].first+1,square[j].second+1);

                        return 0;
                    }
                }
            }
            arr[J1_x][J1_y]=temp1;

        }
    }
    else if (j2)
    {
        string temp2=arr[J2_x][J2_y];
        for(int q=0 ; q<zero.size() ; q++)
        {
            vector<pair<int, int > > square;
            arr[J2_x][J2_y]=zero[q];
            for(int i =0 ; i<n ; i++)
            {
                for(int j=0 ; j<m ; j++)
                {
                    if (check_square(i,j))square.push_back({i,j});
                }
            }
            for(int i =0 ; i<square.size() ; i++)
            {
                for(int j=i+1 ; j<square.size() ; j++)
                {
                    if (check_intersection(square[i].first,square[i].second,square[j].first,square[j].second))
                    {
                        printf("Solution exists.\n");
                        printf("Replace J2 with ");
                        cout<<zero[q]<<"."<<endl;
                        printf("Put the first square to (%d, %d).\n",square[i].first+1,square[i].second+1);
                        printf("Put the second square to (%d, %d).\n",square[j].first+1,square[j].second+1);

                        return 0;
                    }
                }
            }
            arr[J2_x][J2_y]=temp2;

        }
    }
    else
    {
        vector<pair<int,int > > square;
        for(int i =0 ; i<n ; i++)
        {
            for(int j=0 ; j<m ; j++)
            {
                if (check_square(i,j))square.push_back({i,j});
            }
        }
        for(int i =0 ; i<square.size() ; i++)
        {
            for(int j=i+1 ; j<square.size() ; j++)
            {
                if (check_intersection(square[i].first,square[i].second,square[j].first,square[j].second))
                {
                    printf("Solution exists.\n");
                    printf("There are no jokers.\n");
                    printf("Put the first square to (%d, %d).\n",square[i].first+1,square[i].second+1);
                    printf("Put the second square to (%d, %d).\n",square[j].first+1,square[j].second+1);

                    return 0;
                }
            }
        }
    }
    printf("No solution.");
    return 0;
}

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define li		long long
#define rep(i,to)	for(li i=0;i<((li)to);i++)
#define pb		push_back
#define sz(v)		((li)v.size())

string cards[]={"2S","2C","2H","2D","3S","3C","3H","3D","4S","4C","4H","4D","5S","5C","5H","5D","6S","6C","6H","6D","7S","7C","7H","7D","8S","8C","8H","8D","9S","9C","9H","9D","AC","AD","AH","AS","TC","TD","TH","TS","JC","JD","JH","JS","QC","QD","QH","QS","KC","KD","KH","KS","J1","J2"};
map<string,int> stoi;
string board[54][54];
int used[54];
int h,w;
pair<int,int> check2(int x,int y){
	pair<int,int> res;
	res.first=res.second=-1;
	rep(i,h)rep(j,w)if(i+2<h && j+2<w && !(i-2<=x && x<=i+2 && j-2<=y && y<=j+2)){
		set<char> number;
		set<char> suits;
		rep(k,3)rep(l,3){
			number.insert(board[i+k][j+l][0]);
			suits.insert(board[i+k][j+l][1]);
		}
		if(sz(number)==9 || sz(suits)==1){
			res.first=x*w+y;
			res.second=i*w+j;
			return res;
		}
	}
	return res;
}
pair<int,int> check(){
	pair<int,int> res;
	res.first=res.second=-1;
	rep(i,h)rep(j,w)if(i+2<h && j+2<w){
		set<char> number;
		set<char> suits;
		rep(k,3)rep(l,3){
			number.insert(board[i+k][j+l][0]);
			suits.insert(board[i+k][j+l][1]);
		}
		if(sz(number)==9 || sz(suits)==1) res=check2(i,j);
		if(res.first!=-1) return res;
	}
	return res;
}
int main(){
	cin>>h>>w;
	rep(i,h)rep(j,w) cin>>board[i][j];
	rep(i,54) stoi[cards[i]]=i;
	rep(i,54) used[i]=0;
	rep(i,h)rep(j,w) used[stoi[board[i][j]]]=1;
	int j1=-1,j2=-1;
	rep(i,h)rep(j,w){
		if(board[i][j]=="J1") j1=i*w+j;
		if(board[i][j]=="J2") j2=i*w+j;
	}
	int ok=0;
	pair<int,int> res;
	if(j1!=-1 && j2!=-1){
		rep(i,52)rep(j,52)if(ok==0 && i!=j && used[i]==0 && used[j]==0){
			board[j1/w][j1%w]=cards[i];
			board[j2/w][j2%w]=cards[j];
			res=check();
			if(res.first!=-1){
				ok=1;
				cout<<"Solution exists."<<endl;
				cout<<"Replace J1 with "<<cards[i]<<" and J2 with "<<cards[j]<<"."<<endl;
				printf("Put the first square to (%d, %d).\n",res.first/w+1,1+res.first%w);
				printf("Put the second square to (%d, %d).\n",res.second/w+1,1+res.second%w);
			}
		}
		if(ok==0)	cout<<"No solution."<<endl;
	}else if(j1!=-1 ){
		rep(i,52)if(used[i]==0 && ok==0){
			board[j1/w][j1%w]=cards[i];
			res=check();
			if(res.first!=-1){
				ok=1;
				cout<<"Solution exists."<<endl;
				cout<<"Replace J1 with "<<cards[i]<<"."<<endl;
				printf("Put the first square to (%d, %d).\n",res.first/w+1,1+res.first%w);
				printf("Put the second square to (%d, %d).\n",res.second/w+1,1+res.second%w);
			}
		}
		if(ok==0)	cout<<"No solution."<<endl;
	}else if(j2!=-1 ){
		rep(i,52)if(used[i]==0 && ok==0){
			board[j2/w][j2%w]=cards[i];
			res=check();
			if(res.first!=-1){
				ok=1;
				cout<<"Solution exists."<<endl;
				cout<<"Replace J2 with "<<cards[i]<<"."<<endl;
				printf("Put the first square to (%d, %d).\n",res.first/w+1,1+res.first%w);
				printf("Put the second square to (%d, %d).\n",res.second/w+1,1+res.second%w);
			}
		}
		if(ok==0)	cout<<"No solution."<<endl;
	}else{
		res=check();
		if(res.first!=-1){
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
			printf("Put the first square to (%d, %d).\n",res.first/w+1,1+res.first%w);
			printf("Put the second square to (%d, %d).\n",res.second/w+1,1+res.second%w);
		}else{
			cout<<"No solution.\n";
		}
	}
}

#include <vector>
#include <queue>
#include <stack>
#include <fstream>
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <string>
#include <set>
#include <cmath>
#include <ctime>
#include <cstring>
#include <map>
#include <stack>
#include <utility>
#include <tuple>
#define pause system("pause")
#define input ios_base::sync_with_stdio(0)
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

char cards[] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
char color[] = { 'C', 'D', 'H', 'S' };

string g[20][20];
map<string, bool> cardsMap;
set <string> avail;
vector <tuple <int, int, vector<string>, int, bool, bool, bool, bool>> p;
//             row  col  cards    jokers  unCol	unCards firstJ secondJ
int amountofJ;
bool firstJ, secondJ;

void output(const pii &a, const pii &b, string s1, string s2)
{
	cout << "Solution exists." << endl;
	if (s1 != "" && s2 != "")
	{
		cout << "Replace J1 with " << s1 << " and J2 with " << s2 << "." << endl;
	}
	else if (s1 != "" && s2 == "")
	{
		cout << "Replace J1 with " << s1 << "." << endl;
	}
	else if (s2 != "" && s1 == "")
	{
		cout << "Replace J2 with " << s2 << "." << endl;
	}
	else if (s1 == "" && s2 == "")
	{
		cout << "There are no jokers." << endl;
	}
	cout << "Put the first square to (" << a.first + 1<< ", " << a.second + 1<< ")." << endl;
	cout << "Put the second square to (" << b.first + 1<< ", " << b.second + 1<< ")." << endl;
}

bool f(tuple <int, int, vector<string>, int, bool, bool, bool, bool> &a, const tuple <int, int, vector<string>, int, bool, bool, bool, bool> &b)
{
	int j;
	j = get<3>(a);
	vector <string> answer;
	if (get<4>(a))
	{
		for (auto &qwe : avail)
		{
			if (qwe[1] == (*get<2>(a).begin()).at(1))
			{
				answer.push_back(qwe);
				get<2>(a).push_back(qwe);
			}
		}
	}
	if (answer.size() < get<3>(a) && get<5>(a))
	{
		answer.clear();
		for (auto &qwe : avail)
		{
			bool flag = 0;
			for (auto card : get<2>(a))
			{
				if (card[0] == qwe[0])
				{
					flag = 1;
					break;
				}
			}
			if (!flag)
			{
				answer.push_back(qwe);
				get<2>(a).push_back(qwe);
			}
		}
	}
	if (answer.size() >= get<3>(a))
	{
		if (answer.size() < 2 && amountofJ == 2)
		{
			for (auto qwe : avail)
			{
				if (answer.size() > 0 && qwe != answer[0])
				{
					answer.push_back(qwe);
				}
			}
			if (answer.size() == 1)
			{
				return 0;
			}
		}
		answer.push_back("");
		answer.push_back("");
		if (secondJ && !firstJ)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), string(""), answer[0]);
		}
		else if (firstJ && !secondJ)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), answer[0], string(""));
		}
		else
		{
			if (get<6>(a))
			{
				output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), answer[0], answer[1]);
			}
			else
			{
				output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), answer[1], answer[0]);
			}
		}
		return 1;
	}
	return 0;
}

bool insert(tuple <int, int, vector<string>, int, bool, bool, bool, bool> &a, tuple <int, int, vector<string>, int, bool, bool, bool, bool> &b)
{
	if (!get<3>(a) && !get<3>(b))
	{
		if (amountofJ == 0)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), "", "");
			return 1;
		}
		else if (firstJ && !secondJ && avail.size() >= 1)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), *avail.begin(), "");
			return 1;
		}
		else if (firstJ && !secondJ && avail.size() >= 1)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), "", *avail.begin());
			return 1;
		}
		else if (avail.size() >= 2)
		{
			auto it = avail.begin();
			it++;
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), *avail.begin(), *it);
			return 1;
		}
		return 0;
	}
	if (get<3>(a) && get<3>(b))
	{
		if (get<4>(a))
		{
			if (get<4>(b))
			{
				for (auto qwe : avail)
				{
					if (qwe[1] == (*get<2>(a).begin()).at(1))
					{
						for (auto ewq : avail)
						{
							if (ewq == qwe) continue;
							if (ewq[1] == (*get<2>(b).begin()).at(1))
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)),s1,s2);
								return 1;
							}
						}
					}
				}
			}
			if (get<5>(b))
			{
				for (auto qwe : avail)
				{
					if (qwe[1] == (*get<2>(a).begin()).at(1))
					{
						for (auto ewq : avail)
						{
							bool flag = 0;
							if (ewq == qwe) continue;
							for (auto card : get<2>(b))
							{
								if (ewq[0] == card[0])
								{
									flag = 1;
									break;
								}
							}
							if (!flag)
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
		}
		if (get<5>(a))
		{
			if (get<4>(b))
			{
				for (auto qwe : avail)
				{
					bool flag = 0;
					for (auto card1 : get<2>(a))
					{
						if (qwe[0] == card1[0])
						{
							flag = 1;
							break;
						}
					}
					if (!flag)
					{
						for (auto ewq : avail)
						{
							if (qwe == ewq) continue;
							if (ewq[1] == (*get<2>(b).begin()).at(1))
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
			if (get<5>(b))
			{
				for (auto qwe : avail)
				{
					bool flag = 0;
					for (auto card1 : get<2>(a))
					{
						if (qwe[0] == card1[0])
						{
							flag = 1;
							break;
						}
					}
					if (!flag)
					{
						for (auto ewq : avail)
						{
							if (qwe == ewq) continue;
							bool flag1 = 0;
							for (auto card2 : get<2>(b))
							{
								if (ewq[0] == card2[0])
								{
									flag1 = 1;
									break;
								}
							}
							if (!flag1)
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
		}
	}
	else
	{
		if (get<3>(a))
		{
			return f(a, b);
		}
		else
		{
			return f(b, a);
		}
	}
	return 0;
}

int main()
{
	input;
	int n, m;
	cin >> n >> m;
	for (auto i : cards)
	{
		for (auto j : color)
		{
			string t;
			t.push_back(i);
			t.push_back(j);
			avail.insert(t);
		}
	}
	if (n < 6 && m < 6)
	{
		cout << "No solution.";
		return 0;
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> g[i][j];
			avail.erase(g[i][j]);
		}
	}
	for (int i = 0; i < n - 2; i++)
	{
		for (int j = 0; j < m - 2; j++)
		{
			set <char> sqCards;
			set <char> sqColors;
			vector <string> tmp;
			int joker = 0;
			bool first = false, second = false;
			for (int k = 0; k < 3; k++)
			{
				for (int z = 0; z < 3; z++)
				{
					if (g[i + k][j + z][1] == '1' || g[i + k][j + z][1] == '2')
					{
						joker++;
						if (g[i + k][j + z][1] == '1') firstJ = 1;
						else secondJ = 1;
						first |= g[i + k][j + z][1] == '1';
						second |= g[i + k][j + z][1] == '2';
					}
					else
					{
						sqCards.insert(g[i + k][j + z][0]);
						sqColors.insert(g[i + k][j + z][1]);
						tmp.push_back(g[i + k][j + z]);
					}
				}
			}
			if (sqColors.size() == 1 || sqCards.size() + joker == 9)
			{
				p.emplace_back(i, j, tmp, joker, sqColors.size() == 1, sqCards.size() + joker == 9, first, second);
			}
		}
	}
	amountofJ = firstJ + secondJ;
	if (p.size() < 2)
	{
		cout << "No solution.";
		return 0;
	}
	for (int i = 0; i < p.size(); i++)
	{
		for (int j = 0; j < p.size(); j++)
		{
			if (i != j && (abs(get<0>(p[i]) - get<0>(p[j])) >= 3 || abs(get<1>(p[i]) - get<1>(p[j])) >= 3) && insert(p[i], p[j]))
			{
				return 0;
			}
		}
	}
	cout << "No solution.";
	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using ll = int64_t;
using ld = long double;
using ull = uint64_t;
using namespace std;
using namespace __gnu_pbds;
typedef vector <int> vi;
typedef pair <int, int> ii;

const int INF = (int)1e9;

#define maxn 100010

ii x, y;
int n, m;
vector <vector <string> > a;

bool solve() {
    set <char> va;
    set <char> cl;
    int cnt = 0;
    for(int i = 0; i < n - 2; i++) {
        for(int j = 0; j < m - 2; j++) {
            va.clear();
            cl.clear();
            for(int p = 0; p < 3; p++) {
                for(int q = 0; q < 3; q++) {
                    va.insert(a[i + p][j + q][0]);
                    cl.insert(a[i + p][j + q][1]);
                }
            }
            if(va.size() == 9 || cl.size() == 1) {
                if(cnt == 0) {
                    x.first = i + 1;
                    x.second = j + 1;
                    cnt++;
                }  else if(cnt == 1 and (abs(x.first - i - 1) >= 3 || abs(x.second - j - 1) >= 3)) {
                    y.first = i + 1;
                    y.second = j + 1;
                    cnt++;
                    return true;
                }
            }
        }
    }
    return false;
}

int main() {
#ifdef BZ
    freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cout.setf(ios::fixed); cout.precision(6);

    cin >> n >> m;
    a.resize(n, vector <string> (m));

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }

    ii j1, j2;

    bool f1 = false, f2 = false;

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(a[i][j][1] == '1') {
                j1.first = i, j1.second = j;
                f1 = true;
            } else if(a[i][j][1] == '2'){
                j2.first = i, j2.second = j;
                f2 = true;
            }
        }
    }

    vector <string> nud;
    set <string> used;

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            used.insert(a[i][j]);
        }
    }

    char va[15] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    char cl[4] = {'C', 'D', 'H', 'S'};

    for(int i = 0; i < 13; i++) {
        for(int j = 0; j < 4; j++) {
            string c = string(1, va[i]) + cl[j];
            if(!used.count(c)) {
                nud.push_back(c);
            }
        }
    }

    int q = nud.size();

    if(!(f1 | f2)) {
        if(solve()) {
            cout << "Solution exists.\n" <<
                    "There are no jokers.\n" <<
                    "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                    "Put the second square to (" << y.first << ", " << y.second << ").\n";
        } else {
            cout << "No solution.\n";
        }
    } else if((f1 & !f2) | (f2 & !f1)) {
        if(f2) j1 = j2;
        for(int i =  0; i < q; i++) {
            a[j1.first][j1.second] = nud[i];
            if(solve()) {
                cout << "Solution exists.\n" <<
                    "Replace J";
                cout << ((f1) ? "1" : "2");
                cout << " with " << nud[i] << ".\n" <<
                    "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                    "Put the second square to (" << y.first << ", " << y.second << ").\n";
                return 0;
            }
        }
        cout << "No solution.\n";
    } else if(f1 && f2) {
        for(int i = 0; i < q; i++) {
            a[j1.first][j1.second] = nud[i];
            for(int j = 0; j < q; j++) {
                if(i == j) continue;
                a[j2.first][j2.second] = nud[j];
                if(solve()) {
                    cout << "Solution exists.\n" <<
                         "Replace J1 with " << nud[i] << " and J2 with " << nud[j] << ".\n" <<
                         "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                         "Put the second square to (" << y.first << ", " << y.second << ").\n";
                    return 0;
                }
            }
        }
        cout << "No solution.\n";
    }
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

mt19937 rnd(339264);

const ll MOD = 998244353;

const string cards = "23456789TJQKA";
const string masts = "CDHS";

vector<pair<int, int>> check(int n, int m, vector<vector<string>> &field) {
    vector<pair<int, int>> good;
    for (int i = 0; i + 3 <= n; i++) {
        for (int j = 0; j + 3 <= m; j++) {
            set<char> card;
            set<char> mast;
            for (int di = 0; di < 3; di++) {
                for (int dj = 0; dj < 3; dj++) {
                    card.insert(field[i + di][j + dj][0]);
                    mast.insert(field[i + di][j + dj][1]);
                }
            }
            if (card.size() == 9 || mast.size() == 1) {
                good.push_back({i, j});
            }
        }
    }
    for (auto p: good) {
        for (auto q: good) {
            if (q.first >= p.first + 3 || q.second >= p.second + 3) {
                return {p, q};
            }
        }
    }
    return {};
}

int main(){
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios_base::sync_with_stdio(0), cin.tie(0);

    vector<string> all_cards;
    for (char c1: cards) {
        for (char c2: masts) {
            string s = {c1, c2};
            all_cards.push_back(s);
        }
    }

    int n, m;
    cin >> n >> m;
    vector<vector<string>> field(n, vector<string>(m));
    set<string> taken;
    pair<int, int> p1 = {-1, -1}, p2 = {-1, -1};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> field[i][j];
            if (field[i][j] == "J1") {
                p1 = {i, j};
            } else if (field[i][j] == "J2") {
                p2 = {i, j};
            } else {
                taken.insert(field[i][j]);
            }
        }
    }

    for (int i = 0; i < all_cards.size(); i++) {
        for (int j = 0; j < all_cards.size(); j++) {
            if (p1.first != -1 && p2.first != -1 && i == j) {
                continue;
            }
            if (p1.first != -1) {
                if (taken.count(all_cards[i])) continue;
                field[p1.first][p1.second] = all_cards[i];
            }
            if (p2.first != - 1) {
                if (taken.count(all_cards[j])) continue;
                field[p2.first][p2.second] = all_cards[j];
            }
            auto vec = check(n, m, field);
            if (!vec.empty()) {
                cout << "Solution exists." << endl;
                if (p1.first == -1 && p2.first == -1) {
                    cout << "There are no jokers." << endl;
                } else {
                    if (p1.first != -1 && p2.first != -1) {
                        cout << "Replace J1 with " << all_cards[i] << " and J2 with " << all_cards[j] << "." << endl;
                    } else if (p1.first != -1) {
                        cout << "Replace J1 with " << all_cards[i] << "." << endl;
                    } else if (p2.first != -1) {
                        cout << "Replace J2 with " << all_cards[j] << "." << endl;
                    }
                }
                cout << "Put the first square to (" << vec[0].first + 1 <<  ", " << vec[0].second + 1 << ")." << endl;
                cout << "Put the second square to (" << vec[1].first + 1 <<  ", " << vec[1].second + 1 << ")." << endl;
                return 0;
            }
        }
    }

    cout << "No solution." << endl;
    return 0;
}

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<map>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m;
int graph[60][60];
struct fff
{
    int x,y;
};
fff a,b;
vector<int>ooxx;
set<int>pp;
int aaaa,bbbb;
bool solve()
{
    ooxx.clear();
    int p,q;
    int x,y;
    bool flag1,flag2;
    for(int i=0;i<n-2;i++)
        for(int j=0;j<m-2;j++)
        {
            p=graph[i][j]/100;
            q=graph[i][j]%100;
            flag1=flag2=true;
            int mark[20];
            memset(mark,false,sizeof(mark));
            for(int a=0;a<3;a++)
                for(int b=0;b<3;b++)
                {
                    x=graph[i+a][j+b]/100;
                    y=graph[i+a][j+b]%100;
                    if(p != x)
                        flag1=false;
                    if(mark[y])
                        flag2=false;
                    mark[y]=true;
                }

            if(flag1 || flag2)
                ooxx.push_back(i*100+j);
        }
    int len=ooxx.size();
    bool flag=true;
    for(int i=0;i<len && flag;i++)
        for(int j=i+1;j<len && flag;j++)
        {
            x=ooxx[i]/100;
            y=ooxx[i]%100;
            p=ooxx[j]/100;
            q=ooxx[j]%100;
            if(fabs(x-p) >= 3 || fabs(y-q) >= 3)
            {
                aaaa=x*100+y;
                bbbb=p*100+q;
                flag=false;
            }
        }
    return !flag;
}
int main()
{
    string s;
    cin >> n >> m;
    a.x=-1;
    b.x=-1;
    pp.clear();
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            cin >> s;
            if(s[0] == 'T')
                graph[i][j]=10;
            else if(s[0] == 'J' && s[1] != '1' && s[1] != '2')
                graph[i][j]=11;
            else if(s[0] == 'Q')
                graph[i][j]=12;
            else if(s[0] == 'K')
                graph[i][j]=13;
            else if(s[0] == 'A')
                graph[i][j]=1;
            else if(s[0] == 'J')
            {
                if(s[1] == '1')
                {
                    graph[i][j]=-1;
                    a.x=i;
                    a.y=j;
                }
                else
                {
                    //cout << "aaaa" << endl;
                    graph[i][j]=-2;
                    b.x=i;
                    b.y=j;
                }
                continue;
            }
            else
                graph[i][j]=s[0]-'0';
            if(s[1] == 'S')
                graph[i][j]+=100;
            else if(s[1] == 'H')
                graph[i][j]+=200;
            else if(s[1] == 'D')
                graph[i][j]+=300;
            else
                graph[i][j]+=400;
            pp.insert(graph[i][j]);
        }
    //cout << "aaaa" << endl;
    int x,y;
    //cout << a.x << " " << b.x << endl;
    if(a.x != -1 && b.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                for(int p=1;p<=4 && flag;p++)
                    for(int q=1;q<=13 && flag;q++)
                    {
                        x=i*100+j;
                        y=p*100+q;
                        if(pp.find(x) != pp.end())
                            continue;
                        if(pp.find(y) != pp.end())
                            continue;
                        if(x == y)
                            continue;
                        graph[a.x][a.y]=x;
                        graph[b.x][b.y]=y;
                        if(solve())
                        {
                            flag=false;
                            x=graph[a.x][a.y]/100;
                            y=graph[a.x][a.y]%100;
                            p=graph[b.x][b.y]/100;
                            q=graph[b.x][b.y]%100;
                            string c,d;
                            //cout << x << " " << y << " " << p << " " << q << " " << endl;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            if(q == 10)
                                d+="T";
                            else if(q == 11)
                                d+="J";
                            else if(q == 12)
                                d+="Q";
                            else if(q == 13)
                                d+="K";
                            else if(q == 1)
                                d+="A";
                            else
                                d+=q+'0';
                            if(p == 1)
                                d+="S";
                            else if(p == 2)
                                d+="H";
                            else if(p == 3)
                                d+="D";
                            else
                                d+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J1 with " << c << " and J2 with " << d << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                        //cout << "aaaa" << endl;
                    }
        //cout << "aaaa" << endl;
        if(flag)
            cout << "No solution." << endl;
    }
    else if(a.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                    {
                        x=i*100+j;
                        if(pp.find(x) != pp.end())
                            continue;
                        graph[a.x][a.y]=x;
                        if(solve())
                        {
                            flag=false;
                            x=graph[a.x][a.y]/100;
                            y=graph[a.x][a.y]%100;
                            string c,d;
                            //cout << x << " " << y << " " << p << " " << q << " " << endl;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J1 with " << c << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                    }
        if(flag)
            cout << "No solution." << endl;
    }
    else if(b.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                    {
                        x=i*100+j;
                        if(pp.find(x) != pp.end())
                            continue;
                        graph[b.x][b.y]=x;
                        if(solve())
                        {
                            flag=false;
                            x=graph[b.x][b.y]/100;
                            y=graph[b.x][b.y]%100;
                            string c,d;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J2 with " << c << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                    }
        if(flag)
            cout << "No solution." << endl;
    }
    else
    {
        bool flag=true;
        if(solve())
        {
            flag=false;
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
        }
        if(flag)
            cout << "No solution." << endl;
    }
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>
#include <complex>
using namespace std;
#define pb push_back
#define mp make_pair
#define point complex<double>
#define xx real()
#define yy imag()

set <string> used;

int n, m, i1, j11, i2, j2;
string s[50][50];

int check(int a, int b){
    int i, j;
    set<char> sym1, sym2;
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++){
            sym1.insert(s[a + i][b + j][0]);
            sym2.insert(s[a + i][b + j][1]);
        }
    }
    if (sym1.size() == 9 || sym2.size() == 0)
        return 1;
    return 0;
}

int gen_check(){
    for(i1 = 0; i1 < n - 2; i1++){
        for(j11 = 0; j11 < m - 2; j11++){
            if (!check(i1, j11))
                continue;
            for(i2 = i1; i2 < min(n - 2, i1 + 3); i2++){
                for(j2 = 0; j2 < j11 - 2; j2++){
                    if (check(i2, j2))
                        return 1;
                }
                for(j2 = j11 + 3; j2 < m - 2; j2++){
                    if (check(i2, j2))
                        return 1;
                }
            }
            for(i2 = i1 + 3; i2 < n - 2; i2++){
                for(j2 = 0; j2 < m - 2; j2++){
                    if (check(i2, j2))
                        return 1;
                }
            }
        }
    }
    return 0;
}

string c1[15], c2[15];

void init(){
    c2[0] = "C";
    c2[1] = "D";
    c2[2] = "H";
    c2[3] = "S";

    c1[0] = "2";
    c1[1] = "3";
    c1[2] = "4";
    c1[3] = "5";
    c1[4] = "6";
    c1[5] = "7";
    c1[6] = "8";
    c1[7] = "9";
    c1[8] = "T";
    c1[9] = "J";
    c1[10] = "Q";
    c1[11] = "K";
    c1[12] = "A";
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int i, j, ii, jj, f, a1, b1, a2, b2;
    string ss, sss;
    init();
    cin >> n >> m;
    f = 0;
    for(i = 0; i < n; i++){
        for(j = 0; j < m; j++){
            cin >> s[i][j];
            if (s[i][j] == "J1" || s[i][j] == "J2")
                f++;
            else
                used.insert(s[i][j]);;
        }
    }
    if (!f){
        if (gen_check()){
            printf("Solution exists.\n");
            printf("There are no jokers.\n");
            printf("Put the first square to (%d, %d).\n", i1 + 1, j11 + 1);
            printf("Put the second square to (%d, %d).\n", i2 + 1, j2 + 1);
            return 0;
        }
        printf("No solution.");
        return 0;
    }
    if (f == 1){
        int f1 = 2;
        for(i = 0; i < n; i++){
            for(j = 0; j < m; j++){
                if (s[i][j] == "J1" || s[i][j] == "J2"){
                    a1 = i;
                    b1 = j;
                    if (s[i][j] == "J1")
                        f1 = 1;
                }
            }
        }
        for(i = 0; i < 13; i++){
            for(j = 0; j < 4; j++){
                ss = c1[i] + c2[j];
                if (used.find(ss) != used.end())
                    continue;
                s[a1][b1] = ss;
                if (gen_check()){
                    printf("Solution exists.\n");
                    printf("Replace J%d with %c%c.\n", f1, ss[0], ss[1]);
                    printf("Put the first square to (%d, %d).\n", i1 + 1, j11 + 1);
                    printf("Put the second square to (%d, %d).\n", i2 + 1, j2 + 1);
                    return 0;
                }

            }
        }
        printf("No solution.");
        return 0;
    }
    for(i = 0; i < n; i++){
        for(j = 0; j < m; j++){
            if (s[i][j] == "J1"){
                a1 = i;
                b1 = j;
            }
            if (s[i][j] == "J2"){
                a2 = i;
                b2 = j;
            }
        }
    }
    for(i = 0; i < 13; i++){
        for(j = 0; j < 4; j++){
            ss = c1[i] + c2[j];
            if (used.find(ss) != used.end())
                continue;
            s[a1][b1] = ss;
            for(ii = 0; ii < 13; ii++){
                for(jj = 0; jj < 4; jj++){
                    sss = c1[ii] + c2[jj];
                    if (used.find(sss) != used.end())
                        continue;
                    s[a2][b2] = sss;
                    if (i == ii && j == jj)
                        continue;
                    if (used.find(sss) != used.end())
                        continue;
                    if (gen_check()){
                        printf("Solution exists.\n");
                        printf("Replace J1 with %c%c and J2 with %c%c.\n", ss[0], ss[1], sss[0], sss[1]);
                        printf("Put the first square to (%d, %d).\n", i1 + 1, j11 + 1);
                        printf("Put the second square to (%d, %d).\n", i2 + 1, j2 + 1);
                        return 0;
                    }
                }
            }
        }
    }
    printf("No solution.");
    return 0;
}

#include <bits/stdc++.h>

using namespace std;
inline void FAST_IO(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);}

template<class F, class S> ostream& operator<<(ostream& os, pair<F, S> &p) {
	os << "(" << p.first << "," << p.second << ")";
	return os;
}

template<class T, class S> ostream& operator<<(ostream& os, map<T, S> &v) {
	os << "{";
	for(auto &i : v) cout << "{" << i.first << "," << i.second << "}";
	os << "}";
	return os;
}

template<class T> ostream& operator<<(ostream& os, set<T> &v) {
	os << "{";
	for(auto &i : v) cout << i << ",";
	os << "}";
	return os;
}

template<class T> ostream& operator<<(ostream& os, vector<T> &v) {
	os << "[";
	if(v.size()) os << v[0];
	for(int i = 1; i < v.size(); ++i) os << "," << v[i];
	os << "]";
	return os;
}

/*----------------------------------------------------------------------------*/

int main (){
	// FAST_IO();

	char hanks[13]{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
	char suits[4]{'C', 'D', 'H', 'S'};

	int n, m;
	cin >> n >> m;
	vector<vector<string>> board(n, vector<string>(m));
	set<string> used;
	vector<pair<int, int>> pos;
	vector<string> joker;

	for(int i = 0; i < n ; ++i) {
		for(int j = 0; j < m ; ++j) {
			cin >> board[i][j];
			used.insert(board[i][j]);

			if(board[i][j] == "J1" || board[i][j] == "J2") {
				pos.push_back({i,j});
				joker.push_back(board[i][j]);
			}
		}
	}

	if (pos.size() == 2) {
		if(joker[0] == "J2") {
			swap(joker[0], joker[1]);
			swap(pos[0], pos[1]);
		}
	}

	set<string> free;
	for(auto h : hanks) {
		for(auto s : suits){
			string card{h,s};
			if (!used.count(card)) {
				free.insert(card);
			}
		}
	}

	function<void(set<string>, int)> iterate = [&](set<string> term, int it) {
		if(it != pos.size()) {
			int i = pos[it].first;
			int j = pos[it].second;
			for(auto f : free) {
				if (!term.count(f)) {
					board[i][j] = f;
					term.insert(f);
					iterate(term, it + 1);
					term.erase(f);
				}
			}
		} else {
			vector<pair<int, int>> resp;
			for(int i = 0; i <= n - 3; ++i) {
				for(int j = 0; j <= m - 3; ++j) {
					set<char> hank;
					set<char> suit;
					for(int a = 0; a < 3 ; ++a) {
						for(int b = 0; b < 3 ; ++b) {
							int r = i + a;
							int c = j + b;

							hank.insert(board[r][c][0]);
							suit.insert(board[r][c][1]);
						}
					}

					if (hank.size() == 9 || suit.size() == 9) resp.push_back({i,j});
				}
			}

			vector<pair<int, int>> resp_filtered;
			for(auto p1 : resp) {
				int matches = 0;
				for(auto p2 : resp){
					if (p1 == p2) continue;
					if (abs(p1.first - p2.first) >= 3 || abs(p1.second - p2.second) >= 3) {
						resp_filtered.push_back(p1);
						resp_filtered.push_back(p2);
						break;
					}
				}
				if(resp_filtered.size() >= 2) break;
			}

			if (resp_filtered.size() == 2) {
				printf("Solution exists.\n");
				if (pos.size() == 0) {
					printf("There are no jokers.\n");
				} else if (pos.size() == 1) {
					printf("Replace %s with %s.\n", joker[0].c_str(), board[pos[0].first][pos[0].second].c_str());
				} else {
					printf("Replace J1 with %s and J2 with %s.\n",
						board[pos[0].first][pos[0].second].c_str(),
						board[pos[1].first][pos[1].second].c_str()
					);
				}

				printf("Put the first square to (%d, %d).\n", resp_filtered[0].first + 1, resp_filtered[0].second + 1);
				printf("Put the second square to (%d, %d).\n", resp_filtered[1].first + 1, resp_filtered[1].second + 1);
				exit(0);
			}
		}
	};

	iterate({}, 0);

	printf("No solution.\n");

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define F first
#define S second
#define gcd __gcd
#define nset __builtin_popcount
#define pb push_back
#define btoe(x) x.begin(), x.end()
#define trim_chains(x) (x).resize(unique(btoe(x)) - (x).begin())
#define rep(i, a, b)  for (int i = int(a); i <= int(b); i++)
#define nrep(i, a, b) for (int i = int(a); i >= int(b); i--)
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define circ_inc(i, n) (i + 1) % int(n)
#define circ_dec(i, n) (i + int(n) - 1) % int(n)
#define round(x) (int)((double)int(x) + 0.5)

void println() { cout << '\n'; }
template <typename Head, typename... Tail>
void println(Head H, Tail... T) {
    cout << " " << H;
    println(T...);
}
void debug_out() { cerr << '\n'; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<long> vl;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vector<int> > vvi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef map<string, int> msi;
typedef istringstream iss;

const int INF = 1e9;
const ll MOD = 1e9 + 7;

int n, m;
int s1x, s1y, s2x, s2y;
int j1x, j1y, j2x, j2y;
vector<vs> board;

bool issquareok(int i, int j) {
    vector<char> suits;
    vector<char> ranks;
    rep(p, 0, 2) {
        rep(q, 0, 2) {
            ranks.pb(board[i+p][j+q][0]);
            suits.pb(board[i+p][j+q][1]);
        }
    }
    sort(btoe(suits));
    sort(btoe(ranks));
    trim_chains(suits);
    trim_chains(ranks);
    return suits.size() == 1 || ranks.size() == 9;
}

bool check() {
    int okcnt = 0;
    for(int i = 0; i <= n-3; i++) {
        for(int j = 0; j <= m-3; j++) {
            for(int k = i+3; k <= n-3; k++) {
                for(int l = j+3; l <= m-3; l++) {
                    if(issquareok(i, j) && issquareok(k, l)) {
                        s1x = i; s1y = j;
                        s2x = k; s2y = l;
                        return true;
                    }
                }
            }
            for(int k = i+3; k <= n-3; k++) {
                for(int l = 0; l <= m-3; l++) {
                    if(issquareok(i, j) && issquareok(k, l)) {
                        s1x = i; s1y = j;
                        s2x = k; s2y = l;
                        return true;
                    }
                }
            }
            for(int k = 0; k <= n-3; k++) {
                for(int l = j+3; l <= m-3; l++) {
                    if(issquareok(i, j) && issquareok(k, l)) {
                        s1x = i; s1y = j;
                        s2x = k; s2y = l;
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

void print_answer() {
    cout << "Solution exists.\n";
    if(j1x >= 0 && j2x >= 0)
        cout << "Replace J1 with " <<  board[j1x][j1y]
             << " and J2 with " << board[j2x][j2y] << ".\n";
    else if(j1x >= 0) cout << "Replace J1 with " << board[j1x][j1y] << ".\n";
    else if(j2x >= 0) cout << "Replace J2 with " << board[j2x][j2y] << ".\n";
    else cout << "There are no jokers.\n";
    printf("Put the first square to (%d, %d).\n", s1x + 1, s1y + 1);
    printf("Put the second square to (%d, %d).\n", s2x + 1, s2y + 1);
}

int main()
{
    //FASTIO;
    j1x = j1y = j2x = j2y = -1;
    s1x = s1y = s2x = s2y = -1;
    cin >> n >> m;
    board.assign(n, vs(m));
    vvb present(13, vb(4, false));

    rep(i, 0, n-1) rep(j, 0, m-1) {
        cin >> board[i][j];
        if(board[i][j] == "J1") {
            j1x = i; j1y = j;
        }
        else if(board[i][j] == "J2") {
            j2x = i; j2y = j;
        }
        else {
            char rank = board[i][j][0], suit = board[i][j][1];
            int r, s;
            if(rank >= '0' && rank <= '9') r = rank - '0';
            else switch(rank) {
                case 'A': r = 1; break;
                case 'T': r = 10; break;
                case 'J': r = 11; break;
                case 'Q': r = 12; break;
                case 'K': r = 13; break;
            }
            switch(suit) {
                case 'C': s = 1; break;
                case 'D': s = 2; break;
                case 'H': s = 3; break;
                case 'S': s = 4; break;
            }
            present[r-1][s-1] = true;
        }
    }

    vs notpresent;
    rep(i, 0, 12) {
        rep(j, 0, 3) {
            if(!present[i][j]) {
                string card = "";
                if(i+1 >= 2 && i+1 <= 9) card += i + 1 + '0';
                else switch(i+1) {
                    case 1: card += 'A'; break;
                    case 10: card += 'T'; break;
                    case 11: card += 'J'; break;
                    case 12: card += 'Q'; break;
                    case 13: card += 'K'; break;
                }
                switch(j+1) {
                    case 1: card += 'C'; break;
                    case 2: card += 'D'; break;
                    case 3: card += 'H'; break;
                    case 4: card += 'S'; break;
                }
                notpresent.pb(card);
            }
        }
    }

    int np = notpresent.size();
    if(j1x >= 0 && j2x >= 0) {
        rep(i, 0, np-1) {
            rep(j, i+1, np-1) {
                board[j1x][j1y] = notpresent[i];
                board[j2x][j2y] = notpresent[j];
                if(check()) {
                    print_answer();
                    return 0;
                }
                board[j1x][j1y] = notpresent[j];
                board[j2x][j2y] = notpresent[i];
                if(check()) {
                    print_answer();
                    return 0;
                }
            }
        }
    }
    else if(j1x >= 0) {
        rep(i, 0, np-1) {
            board[j1x][j1y] = notpresent[i];
            if(check()) {
                print_answer();
                return 0;
            }
        }
    }
    else if(j2x >= 0) {
        rep(i, 0, np-1) {
            board[j2x][j2y] = notpresent[i];
            if(check()) {
                print_answer();
                return 0;
            }
        }
    }
    else if(check()) {
        print_answer();
        return 0;
    }
    cout << "No solution.\n";
    return 0;
}

#include <bits/stdc++.h>

#define all(v) (v).begin(), (v).end()
#define upmax(a, b) a = ((b > a) ? b : a)

using namespace std;
using ll = long long;

vector <string> cards;
string a[20][20];
int n, m;

vector <pair<int, int>> check() {
    vector <pair<int, int>> norm;
    for (int i = 0; i + 2 < n; ++i) {
        for (int j = 0; j + 2 < m; ++j) {
            set <char> dst;
            set <char> fi;
            for (int k = i; k < i + 3; ++k) {
                for (int c = j; c < j + 3; ++c) {
                    dst.insert(a[k][c][1]);
                    fi.insert(a[k][c][0]);
                }
            }
            if (dst.size() == 9 || fi.size() == 1) {
                norm.push_back({i, j});
            }
        }
    }
    vector <pair<int, int>> ret;
    for (int i = 0; i < norm.size(); ++i) {
        for (int j = i + 1; j < norm.size(); ++j) {
            set <pair<int, int>> cl1, cl2;
            for (int k = norm[i].first; k < norm[i].first + 3; ++k)
                for (int c = norm[i].second; c < norm[i].second + 3; ++c)
                    cl1.insert({k, c});
            for (int k = norm[j].first; k < norm[j].first + 3; ++k)
                for (int c = norm[j].second; c < norm[j].second + 3; ++c)
                    cl2.insert({k, c});
            bool ans = 1;
            for (auto i : cl1) {
                ans &= cl2.count(i) == 0;
            }
            if (ans) {
                ret.push_back(norm[i]);
                ret.push_back(norm[j]);
                return ret;
            }
        }
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    for (char m : "CDHS") {
        for (char c : "23456789TJQKA") {
            if (c == '\0' || m == '\0')
                continue;
            string put;
            put += m;
            put += c;
            cards.push_back(put);
        }
    }
    cin >> n >> m;
    vector <pair<pair<int, int>,int>> crs;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> a[i][j];
            swap(a[i][j][0], a[i][j][1]);
            if (a[i][j][1] == 'J' && (a[i][j][0] == '1' || a[i][j][0] == '2')) {
                crs.push_back({{i, j}, a[i][j][0] - '0'});
            }
            for (int k = 0; k < cards.size(); ++k) {
                if (cards[k] == a[i][j]) {
                    cards.erase(cards.begin() + k);
                    break;
                }
            }
        }
    }
    if (crs.size() == 0) {
        auto z = check();
        if (z.size() == 0) {
            cout << "No solution.\n";
        }
        else {
            cout << "Solution exists.\nThere are no jokers.\n";
            cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
            cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
        }
    }
    else if (crs.size() == 1) {
        for (int i = 0; i < cards.size(); ++i) {
            a[crs[0].first.first][crs[0].first.first] = cards[i];
            auto z = check();
            if (z.size() == 2) {
                cout << "Solution exists.\n";
                cout << "Replace J" << crs[0].second << " with " << cards[i][1] << cards[i][0] << ".\n";
                cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
                cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
                return 0;
            }
        }
        cout << "No solution.\n";
    }
    else {
        if (crs[1].second == 1) swap(crs[1], crs[0]);
        for (int i = 0; i < cards.size(); ++i) {
            for (int j = 0; j < cards.size(); ++j) {
                if (i == j) continue;
                a[crs[0].first.first][crs[0].first.second] = cards[i];
                a[crs[1].first.first][crs[1].first.second] = cards[j];
                auto z = check();
                if (z.size() == 2) {
                    cout << "Solution exists.\n";
                    cout << "Replace J" << crs[0].second << " with " << cards[i][1] << cards[i][0] << " and J" <<crs[1].second <<" with " <<cards[j][1] << cards[j][0] << ".\n";
                    cout << "Put the first square to (" << z[0].first + 1 << ", " << z[0].second + 1 << ").\n";
                    cout << "Put the second square to (" << z[1].first + 1 << ", " << z[1].second + 1 << ").\n";
                    return 0;
                }
            }
        }
        cout << "No solution.\n";
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const string rk[13]={"2","3","4","5","6","7","8","9","T","J","Q","K","A"};
const string su[4]={"C","D","H","S"};
string a[111][111];
set<string>st;
int n,m,i1=-1,i2=-1,j11=-1,j2=-1;
bool gao(int x,int y)
{
	set<char>s,r;
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			r.insert(a[x+i][y+j][0]);
			s.insert(a[x+i][y+j][1]);
		}
	}
	return s.size()==1 || r.size()==9;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<13;j++)
		{
			st.insert(rk[j]+su[i]);
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			string s;
			cin>>s;
			a[i][j]=s;
			st.erase(s);
			if(s=="J1")
			{
				i1=i;
				j11=j;
			}
			else if(s=="J2")
			{
				i2=i;
				j2=j;
			}
		}
	}
	st.insert("@1");
	st.insert("@2");
	for(set<string>::iterator it1=st.begin();it1!=st.end();it1++)
	{
		if(i1!=-1)
		{
			if((*it1)[0]=='@')
			{
				continue;
			}
			a[i1][j11]=*it1;
		}
		for(set<string>::iterator it2=st.begin();it2!=st.end();it2++)
		{
			if(it1==it2)
			{
				continue;
			}
			if(i2!=-1)
			{
				if((*it2)[0]=='@')
				{
					continue;
				}
				a[i2][j2]=*it2;
			}
			vector<pair<int,int> >ok;
			for(int i=0;i+3<=n;i++)
			{
				for(int j=0;j+3<=m;j++)
				{
					if(gao(i,j))
					{
						ok.push_back(make_pair(i,j));
					}
				}
			}
			for(vector<pair<int,int> >::iterator ii=ok.begin();ii!=ok.end();ii++)
			{
				for(vector<pair<int,int> >::iterator jj=ok.begin();jj!=ok.end();jj++)
				{
					if(ii->first+3<=jj->first || jj->first+3<=ii->first || ii->second+3<=jj->second || jj->second+3<=ii->second)
					{
						cout<<"Solution exists."<<endl;
						if(i1!=-1 && i2!=-1)
						{
							cout<<"Replace J1 with "<<*it1<<" and J2 with "<<*it2<<"."<<endl;
						}
						else if(i1!=-1)
						{
							cout<<"Replace J1 with "<<*it1<<"."<<endl;
						}
						else if(i2!=-1)
						{
							cout<<"Replace J2 with "<<*it2<<"."<<endl;
						}
						else
						{
							cout<<"There are no jokers."<<endl;
						}
						cout<<"Put the first square to ("<<ii->first+1<<", "<<ii->second+1<<")."<< endl;
						cout<<"Put the second square to ("<<jj->first+1<<", "<<jj->second+1<<")."<< endl;
						return 0;
					}
				}
			}
		}
	}
	cout<<"No solution."<<endl;
	return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<string.h>
#include<cstring>
#include<stack>
#include<queue>
#include<cassert>
#include<cmath>
using namespace std;

#define LL long long int
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define INF 1000000000
#define ab(x) ((x)>0?(x):-(x))
char vals[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char cols[]={'C','D','H','S'};
char val[20][20],col[20][20],ispos[20][20],ocu[400];
vector<PII> locs;
pair<PII,PII> ans;
bool chkpos(int m,int n){
	memset(ocu,0,sizeof(ocu));
	int i,j,k,l,ss,sn,cid=1;
	locs.clear();
	for(i=1;i<=m-2;i++){
		for(j=1;j<=n-2;j++){
			ss=sn=1;
			cid++;
			for(k=i;k<=i+2;k++){
				for(l=j;l<=j+2;l++){
					ss&=(col[k][l]==col[i][j]);
					sn&=(ocu[val[k][l]]!=cid);
					ocu[val[k][l]]=cid;
				}
			}
			if(sn || ss)
				locs.PB(MP(i,j));
		}
	}
	for(i=0;i<locs.size();i++){
		for(j=i+1;j<locs.size();j++){
			if(ab(locs[i].first-locs[j].first)>=3 || ab(locs[i].second-locs[j].second)>=3){
				ans=MP(locs[i],locs[j]);
				return true;
			}
		}
	}
	return false;
}
int main(){
	set<pair<char,char> > s;
	set<pair<char,char> > ::iterator it;
	set<pair<char,char> > ::iterator it2;
	vector<pair<char,PII> > jloc;
	int i,j,m,n;
	char x,y;
	cin>>m>>n;
	for(i=0;i<13;i++)
		for(j=0;j<4;j++)
			s.insert(MP(vals[i],cols[j]));
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++){
			scanf(" %c%c",&x,&y);
			val[i][j]=x;
			col[i][j]=y;
			if(x=='J' && (y=='1' || y=='2')){

				jloc.PB(MP(y,MP(i,j)));
				continue;
			}
			s.erase(MP(x,y));
		}
	if(jloc.size()==0){
		if(chkpos(m,n)){
			printf("Solution exists.\n");
			printf("There are no jokers.\n");
			printf("Put the first square to (%d, %d).\n",ans.first.first,ans.first.second);
			printf("Put the second square to (%d, %d).\n",ans.second.first,ans.second.second);
		}
		else printf("No solution.\n");
		return 0;
	}
	else if( jloc.size()==1){
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].second.first][jloc[0].second.second]=it->first;
			col[jloc[0].second.first][jloc[0].second.second]=it->second;
			if(chkpos(m,n)){
				printf("Solution exists.\n");
				printf("Replace J%c with %c%c.\n",jloc[0].first,it->first,it->second);
				printf("Put the first square to (%d, %d).\n",ans.first.first,ans.first.second);
				printf("Put the second square to (%d, %d).\n",ans.second.first,ans.second.second);
				return 0;
			}
		}
		printf("No solution.\n");
		return 0;
	}
	else{
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].second.first][jloc[0].second.second]=it->first;
			col[jloc[0].second.first][jloc[0].second.second]=it->second;
			for(it2=s.begin();it2!=s.end();it2++){
				if(*it==*it2)continue;
				val[jloc[1].second.first][jloc[1].second.second]=it2->first;
				col[jloc[1].second.first][jloc[1].second.second]=it2->second;
				if(chkpos(m,n)){
					printf("Solution exists.\n");
					if(jloc[0].first=='2')
						printf("Replace J1 with %c%c and J2 with %c%c.\n",it2->first,it2->second,it->first,it->second);
					else
						printf("Replace J1 with %c%c and J2 with %c%c.\n",it->first,it->second,it2->first,it2->second);
					printf("Put the first square to (%d, %d).\n",ans.first.first,ans.first.second);
					printf("Put the second square to (%d, %d).\n",ans.second.first,ans.second.second);
					return 0;
				}
			}
		}
		printf("No solution.\n");
		return 0;
	}
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>

#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <list>

using namespace std;

#define f0(_X,_Y) for(int (_X)=0;(_X)<(_Y);++(_X))
#define f1(_X,_Y) for(int (_X)=1;(_X)<=(_Y);++(_X))
#define ff(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<=(_Z);++(_X))
#define fF(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<(_Z);++(_X))
#define rf0(_X,_Y) for(int _X=(_Y)-1;(_X)>=0;--(_X))
#define rf1(_X,_Y) for(int _X=(_Y);(_X)>0;--(_X))
#define rff(_X,_Y,_Z) for(int _X=(_Y);(_X)>=(_Z);--(_X))
#define rfF(_X,_Y,_Z) for(int _X=(_Y);(_X)>(_Z);--(_X))
#define PRT(_X) std::cout<< #_X ": "<<_X<<std::endl;
#define TIME fprintf(stderr,"time : %.2f sec\n",double(clock())/CLOCKS_PER_SEC);
typedef long long ll;
typedef pair<int, int> pii;

#define scan1(_X) scanf("%d",&_X);
#define scan2(_X,_Y) scanf("%d%d",&_X,&_Y);
#define scan3(_X,_Y,_Z) scanf("%d%d%d",&_X,&_Y,&_Z);
#define print1(_X) printf("%d\n",_X);
#define PAIR_STRUCT(_T,_X,_Y,...) struct _T{int _X,_Y,##__VA_ARGS__; bool friend operator < (const _T &p, const _T &q){if(p._X!=q._X) return p._X<q._X; return p._Y<q._Y;}};

int n,m;
struct p{int x,y;} joker[2], ans[2];
struct c{;} ;
char pattern[]="SHCD"; // 4
char _rank[]="A23456789TJQK"; // 13
char in[18][18][3];
char rest[53][3];
char prt[200];
bool poss;

int chk[128];
bool sqr[18][18];

void process()
{

    int count = 0;
    f1(i,n) f1(j,m) sqr[i][j]=false;
    f1(i,n) if(i+2<=n)
    {
        f1(j,m) if(j+2<=m)
        {
            bool duplicate = false;
            bool same = true;
            ++count;
            // same suite || all diff _ranks
            f0(k,3) f0(l,3)
            {
                if(chk[in[i+k][j+l][0]] != count)
                    chk[in[i+k][j+l][0]] = count;
                else
                    duplicate = true;
                if(in[i+k][j+l][1] != in[i][j][1])
                    same=false;
            }
            // if(in[2][4][0]=='A' && in[2][4][1]=='H' && i==1 && j==4)
            // {
            //  PRT(same);
            //  PRT(duplicate);
            // }
            sqr[i][j] = same || !duplicate;
        }
    }
    f1(i,n)
        f1(j,m) if(sqr[i][j])
        {
            ff(k,i,n) f1(l,m) if(sqr[k][l] && (abs(i-k)>=3 || abs(j-l)>=3))
            {
                ans[0].y=i; ans[0].x=j;
                ans[1].y=k; ans[1].x=l;
                poss=true;
                return;
            }
        }
}

int main()
{
    int num_joker=0, joker_last=0, rn=0;
    scan2(n,m);
    f1(i,n) f1(j,m)
    {
        char card[4];
        scanf("%s",card); in[i][j][0] = card[0]; in[i][j][1]=card[1];
        if(card[0]=='J')
        {
            ++num_joker; int no = card[1]-'1';
            joker[no].y=i, joker[no].x=j;
            joker_last = no;
        }
    }

    f0(r,13) f0(p,4)
    {
        bool exist=false;
        f1(i,n) f1(j,m) if(in[i][j][0]==_rank[r] && in[i][j][1]==pattern[p])
        {
            i=n;
            exist=true;
            break;
        }
        if(!exist)
        {
            ++rn;
            rest[rn][0] = _rank[r];
            rest[rn][1] = pattern[p];
        }
    }

    if(num_joker==0)
    {
        sprintf(prt,"There are no jokers.");
        process();
    }
    else if(num_joker==1)
    {
        f1(i,rn)
        {
            in[joker[joker_last].y][joker[joker_last].x][0] = rest[i][0];
            in[joker[joker_last].y][joker[joker_last].x][1] = rest[i][1];
            process();
            if(poss)
            {
                sprintf(prt,"Replace J%d with %s.",joker_last+1, rest[i]);
                break;
            }
        }
    }
    else
    {
        f1(i,rn)
        {
            in[joker[0].y][joker[0].x][0] = rest[i][0];
            in[joker[0].y][joker[0].x][1] = rest[i][1];
            ff(j,i+1,rn)
            {
                in[joker[1].y][joker[1].x][0] = rest[j][0];
                in[joker[1].y][joker[1].x][1] = rest[j][1];
                process();
                if(poss)
                {
                    i=rn;
                    sprintf(prt,"Replace J1 with %s and J2 with %s.", rest[i], rest[j]);
                    break;
                }
            }

        }
    }

    if(poss)
    {
        printf("Solution exists.\n");
        printf("%s\n",prt);
        printf("Put the first squre to (%d, %d).\n", ans[0].y, ans[0].x);
        printf("Put the second squre to (%d, %d).\n", ans[1].y, ans[1].x);

    }
    else
    {
        printf("No solution.\n");
    }

    return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<string.h>
#include<cstring>
#include<stack>
#include<queue>
#include<cassert>
#include<cmath>
using namespace std;

#define LL long long int
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define INF 1000000000
#define ab(x) ((x)>0?(x):-(x))
char vals[]={'1','2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char cols[]={'C','D','H','S'};
char val[20][20],col[20][20],ispos[20][20],ocu[400];
vector<PII> locs;
pair<PII,PII> ans;
bool chkpos(int m,int n){
	memset(ocu,0,sizeof(ocu));
	int i,j,k,l,ss,sn;
	locs.clear();
	for(i=1;i<=m-2;i++){
		for(j=1;j<=n-2;j++){
			ss=sn=1;
			for(k=i;k<=i+2;k++){
				for(l=j;l<=j+2;l++){
					ss&=(col[k][l]==col[i][j]);
					sn&=(ocu[val[k][l]]!=20*i+j);
					ocu[val[k][l]]=20*i+j;
				}
			}
			if(sn || ss)
				locs.PB(MP(i,j));
		}
	}
	for(i=0;i<locs.size();i++){
		for(j=i+1;j<locs.size();j++){
			if(ab(locs[i].first-locs[j].first)>=3 || ab(locs[i].second-locs[j].second)>=3){
				ans=MP(locs[i],locs[j]);
				return true;
			}
		}
	}
	return false;
}
int main(){
	set<pair<char,char> > s;
	set<pair<char,char> > ::iterator it;
	set<pair<char,char> > ::iterator it2;
	vector<PII> jloc;
	int i,j,m,n;
	char x,y;
	cin>>m>>n;
	for(i=0;i<14;i++)
		for(j=0;j<4;j++)
			s.insert(MP(vals[i],cols[j]));
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++){
			scanf(" %c%c",&x,&y);
			val[i][j]=x;
			col[i][j]=y;
			if(x=='J' && y=='1'){
				jloc.PB(MP(i,j));
				continue;
			}
			s.erase(MP(x,y));
		}
	if(jloc.size()==0){
		if(chkpos(m,n)){
			printf("Solution Exists.\n");
			printf("There are no jokers.\n");
			printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
			printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
		}
		else printf("No Solution.\n");
		return 0;
	}
	else if( jloc.size()==1){
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].first][jloc[0].second]=it->first;
			col[jloc[0].first][jloc[0].second]=it->second;
			if(chkpos(m,n)){
				printf("Solution Exists.\n");
				printf("Replace J1 with %c%c.\n",it->first,it->second);
				printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
				printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
				return 0;
			}
		}
		printf("No Solution.\n");
		return 0;
	}
	else{
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].first][jloc[0].second]=it->first;
			col[jloc[0].first][jloc[0].second]=it->second;
			for(it2=s.begin();it2!=s.end();it2++){
				if(*it==*it2)continue;
				val[jloc[1].first][jloc[1].second]=it2->first;
				col[jloc[1].first][jloc[1].second]=it2->second;
				if(chkpos(m,n)){
					printf("Solution Exists.\n");
					printf("Replace J1 with %c%c and J2 with %c%c.\n",it->first,it->second,it2->first,it2->second);
					printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
					printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
					return 0;
				}
			}
		}
		printf("No Solution.\n");
		return 0;
	}
	return 0;
}

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<list>
#include<deque>
#include<bitset>
#include<fstream>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair<int,int >
#define iii(x,y,z,w) mp(mp(x,y),mp(z,w))
#define iiii pair<pii,pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i,x) for(int (i)=0;(i)<(x);(i)++)
inline int getint()
{
	int x=0,p=1;char c=getchar();
	while (c<=32)c=getchar();
	if(c==45)p=-p,c=getchar();
	while (c>32)x=x*10+c-48,c=getchar();
	return x*p;
}
using namespace std;
//purplesun is pupil.
const int N=100;
int n,m,vis1[N],vis2[N];
char ei;
vector<pii >v;
string s[N][N],hh="23456789TJQKA",hh2="CDHS";
pii to[3];
bool vis[N][N];
//
int ff(string ss,char c)
{
	rep(i,ss.size())if(ss[i]==c)return i;
	return -1;
}
bool isbad(int x,int y,int z,int w)
{
	int xx=abs(x-z),yy=abs(y-w);
	if(xx<=2&&yy<=2)return true;
	return false;
}
iiii check()
{
	vector<pii >chv;
	rep(i,n)rep(j,m)if(i+3<=n&&j+3<=m)
	{
		memset(vis1,0,sizeof(vis1));
		memset(vis2,0,sizeof(vis2));
		int cnt=0,cnt2=0;
		rep(k,3)rep(l,3)
		{
			if(!vis1[ff(hh,s[i+k][j+l][0])])
			{
				vis1[ff(hh,s[i+k][j+l][0])]=true;
				cnt2++;
			}
			if(!vis2[ff(hh2,s[i+k][j+l][1])])
			{
				vis2[ff(hh2,s[i+k][j+l][1])]=true;
				cnt++;
			}
		}
		if(cnt2==9||cnt==1)chv.push_back(mp(i,j));
	}
	rep(i,chv.size())for(int j=i+1;j<chv.size();j++)
		if(!isbad(chv[i].first,chv[i].second,chv[j].first,chv[j].second))
			return mp(chv[i],chv[j]);
	return iii(-1,-1,-1,-1);
}
void go(iiii x)
{
	printf("Solution exists.\n");
	if(v.empty())printf("There are no jokers.\n");
	if(v.size()==1)
	{
		printf("Replace J%c with ",ei);
		cout<<s[v[0].first][v[0].second]<<'.'<<endl;
	}
	if(v.size()==2)cout<<"Replace J1 with "<<s[v[0].first][v[0].second]<<" and J2 with "<<s[v[1].first][v[1].second]<<".\n";
	printf("Put the first square to (%d, %d).\n",x.first.first+1,x.first.second+1);
	printf("Put the second square to (%d, %d).\n",x.second.first+1,x.second.second+1);
}
int main()
{
	n=getint();m=getint();
	rep(i,n)rep(j,m)
	{
		cin>>s[i][j];
		if(s[i][j][0]=='J')v.push_back(mp(i,j));
		else vis[ff(hh,s[i][j][0])][ff(hh2,s[i][j][1])]=true;
	}
	if(v.size()==2&&s[v[1].first][v[1].second]=="J1")swap(v[0],v[1]);
	if(v.size()==1)ei=s[v[0].first][v[0].second][1];
	rep(ii,v.size())rep(i,hh.size())rep(j,hh2.size())
	{
		if(vis[i][j])continue;
		s[v[ii].first][v[ii].second][0]=hh[i];
		s[v[ii].first][v[ii].second][1]=hh2[j];
		if(ii==1&&s[v[ii].first][v[ii].second]==s[v[0].first][v[0].second])continue;
		if(ii==v.size()-1&&check()!=iii(-1,-1,-1,-1))
		{
			go(check());
			return 0;
		}
	}
	if(v.empty()&&check()!=iii(-1,-1,-1,-1))
	{
		go(check());
		return 0;
	}
	printf("No solution.\n");
	return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<string.h>
#include<cstring>
#include<stack>
#include<queue>
#include<cassert>
#include<cmath>
using namespace std;

#define LL long long int
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define INF 1000000000
#define ab(x) ((x)>0?(x):-(x))
char vals[]={'1','2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char cols[]={'C','D','H','S'};
char val[20][20],col[20][20],ispos[20][20],ocu[400];
vector<PII> locs;
pair<PII,PII> ans;
bool chkpos(int m,int n){
	memset(ocu,0,sizeof(ocu));
	int i,j,k,l,ss,sn;
	locs.clear();
	for(i=1;i<=m-2;i++){
		for(j=1;j<=n-2;j++){
			ss=sn=1;
			for(k=i;k<=i+2;k++){
				for(l=j;l<=j+2;l++){
					ss&=(col[k][l]==col[i][j]);
					sn&=(ocu[val[k][l]]!=20*i+j);
					ocu[val[k][l]]=20*i+j;
				}
			}
			if(sn || ss)
				locs.PB(MP(i,j));
		}
	}
	for(i=0;i<locs.size();i++){
		for(j=i+1;j<locs.size();j++){
			if(ab(locs[i].first-locs[j].first)>=3 || ab(locs[i].second-locs[j].second)>=3){
				ans=MP(locs[i],locs[j]);
				return true;
			}
		}
	}
	return false;
}
int main(){
	set<pair<char,char> > s;
	set<pair<char,char> > ::iterator it;
	set<pair<char,char> > ::iterator it2;
	vector<PII> jloc;
	int i,j,m,n;
	char x,y;
	cin>>m>>n;
	for(i=0;i<14;i++)
		for(j=0;j<4;j++)
			s.insert(MP(vals[i],cols[j]));
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++){
			scanf(" %c%c",&x,&y);
			val[i][j]=x;
			col[i][j]=y;
			if(x=='J' && y=='1'){
				jloc.PB(MP(i,j));
				continue;
			}
			s.erase(MP(x,y));
		}
	if(jloc.size()==0){
		if(chkpos(m,n)){
			printf("Solution exists.\n");
			printf("There are no jokers.\n");
			printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
			printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
		}
		else printf("No solution.\n");
		return 0;
	}
	else if( jloc.size()==1){
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].first][jloc[0].second]=it->first;
			col[jloc[0].first][jloc[0].second]=it->second;
			if(chkpos(m,n)){
				printf("Solution exists.\n");
				printf("Replace J1 with %c%c.\n",it->first,it->second);
				printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
				printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
				return 0;
			}
		}
		printf("No solution.\n");
		return 0;
	}
	else{
		for(it=s.begin();it!=s.end();it++){
			val[jloc[0].first][jloc[0].second]=it->first;
			col[jloc[0].first][jloc[0].second]=it->second;
			for(it2=s.begin();it2!=s.end();it2++){
				if(*it==*it2)continue;
				val[jloc[1].first][jloc[1].second]=it2->first;
				col[jloc[1].first][jloc[1].second]=it2->second;
				if(chkpos(m,n)){
					printf("Solution exists.\n");
					printf("Replace J1 with %c%c and J2 with %c%c.\n",it->first,it->second,it2->first,it2->second);
					printf("Put the first square to (%d,%d).\n",ans.first.first,ans.first.second);
					printf("Put the second square to (%d,%d).\n",ans.second.first,ans.second.second);
					return 0;
				}
			}
		}
		printf("No solution.\n");
		return 0;
	}
	return 0;
}

//I love natalia

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <string>

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].rank != 'J')
                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() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    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 == 4 && r == 1)
                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 < V2.size(); j++) {
            int l1 = V1[i].first;
            int r1 = V1[i].second;
            int l2 = V2[j].first;
            int r2 = V2[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;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>

using namespace std;

typedef vector <string> vs;
typedef vector <int> vi;
#define clr(x) memset((x), 0, sizeof(x))
#define SORT(x) sort(x.begin(),x.end())
#define forn(i, n) for(int i = 0; i< n; i++)
#define all(i, x) for(int i = 0; i< x.size(); i++)
const long double EPS = 1e-11;

class card{
public:
	char color,number;
	card(){}
	card(char c,char n)
	{color = c; number = n;}
	bool friend operator == (const card a,const card b)
	{
		return (a.color == b.color && a.number == b.number);
	}
};
card a[17][17],all[54];
char nn[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' , 'A' };
char cc[4] = { 'C' , 'D' , 'H' ,'S' };
int main()
{
//	freopen("test.txt","r",stdin);
 //   freopen("test.out","w",stdout);
	set<char> color,number;
	int n,m,num = 0;
	card tmp;
	forn(i,13)
		forn(j,4)
		{
			tmp.number = nn[i];
			tmp.color = cc[j];
			all[num++] = tmp;
		}
	card J1('1','J');
	card J2('2','J');
	vector <card> replace,replaced,JVec;
	cin>>n>>m;
	forn(i,n)
		forn(j,m)
			cin>>a[i][j].number>>a[i][j].color;
	int xFirst = -3,yFirst = -3,xSecond = -1,ySecond = -1;
	forn(i,n)
	{
		if(xSecond > 0)
			break;
		forn(j,m)
		{
			JVec.clear();
			color.clear();
			number.clear();
			if(xSecond > 0)
				break;
			if(i + 2 < n && j + 2 < m && (i >= xFirst + 3 || j >= yFirst + 3) )
			{
				forn(r,3)
					forn(c,3)
					{
						if(a[i+r][j+c] == J1 || a[i+r][j+c] == J2)
							JVec.push_back(a[i+r][j+c]);
						else
						{
							color.insert(a[i+r][j+c].color);
							number.insert(a[i+r][j+c].number);
						}
					}
				if(JVec.empty())
				{
					if(color.size() == 1 || number.size() == 9)
					{
						if(xFirst == -3)
						{
							xFirst = i;
							yFirst = j;
						}
						else
						{
							xSecond = i;
							ySecond = j;
						}
					}
				}
				else
				{
					if(color.size() == 1 || number.size() == 9 - JVec.size())
					{
						int Jnum = JVec.size();
						for(int k = 0; k < 52 && !JVec.empty(); k++)
						{
							if((color.size() == 1 && color.count(all[k].color) == 1)
								||(number.size() == 9 - Jnum && number.count(all[k].number) == 0))
							{
								int used = 0;
								for(int r = 0; r < n && !JVec.empty(); r++)
									for(int c = 0; c < m && !JVec.empty(); c++)
									{
										if((all[k] == a[r][c]))
											used = 1;
									}
								if(used == 0)
								{
									replace.push_back(all[k]);
									replaced.push_back(JVec.back());
									JVec.pop_back();
									if(JVec.size() == 0)
									{
										if(xFirst == -3)
										{
											xFirst = i;
											yFirst = j;
										}
										else
										{
											xSecond = i;
											ySecond = j;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	if(xSecond > 0)
	{
		cout<<"Solution exists."<<endl;
		if(replaced.empty())
			cout<<"There are no jokers."<<endl;
		else
		{
			if(replaced.size() == 2)
			{
				if(replaced[0].color == '1')
				{
					cout<<"Replace J1 with ";
					cout<<replace[0].number<<replace[0].color<<" and J2 with ";
					cout<<replace[1].number<<replace[1].color<<"."<<endl;
				}
				else
				{
					cout<<"Replace J1 with ";
					cout<<replace[1].number<<replace[1].color<<" and J2 with ";
					cout<<replace[0].number<<replace[0].color<<"."<<endl;
				}
			}
			else if(replaced.size() == 1)
			{
				cout<<"Replace J"<<replaced[0].color<<" with ";
				cout<<replace[0].number<<replace[0].color<<"."<<endl;
			}
		}
		cout<<"Put the first square to ("<<xFirst+1<<", "<<yFirst+1<<")."<<endl;
		cout<<"Put the second square to ("<<xSecond+1<<", "<<ySecond+1<<")."<<endl;
	}
	else
		cout<<"No solution."<<endl;
	return 0;
}

#include <iostream>
#include <string>
using namespace std;

string pack[54];
int n,m;
string arr[17][17];

void gen()
{
	string a1[13]={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" , "A"};
	string a2[4]={"C", "D", "H" , "S"};

	for(int i=0;i<4;i++)
		for(int j=0;j<13;j++)
			pack[i*13+j]=a1[j]+a2[i];

	pack[52]="J1";
	pack[53]="j2";
}

bool isOk(int str,int stb)
{
	if(str+2>=n || stb+2>=m)
		return false;

	if( str==1 && stb==3)
	{
		int y=4234;
		int h=4234;
	}

	bool ans=true;
	for(int i=str;i<str+3;i++)
		for(int j=stb;j<stb+3;j++)
			for(int k=str;k<str+3;k++)
				for(int l=stb;l<stb+3;l++)
					if( (i!=k || j!=l) && arr[i][j][1]!=arr[k][l][1])
						ans = false;
	if(ans)
		return true;
	ans=true;
	for(int i=str;i<str+3;i++)
		for(int j=stb;j<stb+3;j++)
			for(int k=str;k<str+3;k++)
				for(int l=stb;l<stb+3;l++)
					if((i!=k || j!=l) && arr[i][j][0]==arr[k][l][0])
						ans = false;
	if(ans)
		return true;
	return false;
}
pair<int,int> s1,s2;
bool isSolve()
{
	pair<int,int> minStr(100,0),maxStr(0,0),minStb(100,0),maxStb(0,0);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
			if(isOk(i,j))
			{
				if(minStr.first>i)
					minStr=make_pair(i,j);
				if(maxStr.first<i)
					maxStr=make_pair(i,j);
				if(minStb.first>j)
					minStb=make_pair(j,i);
				if(maxStb.first<j)
					maxStb=make_pair(j,i);
			}
	}
	if(maxStr.first-minStr.first>=3)
	{
		s1=minStr;
		s2=maxStr;
	}
	if(maxStb.first-minStb.first>=3)
	{
		s1=make_pair(minStb.second,minStb.first);
		s2=make_pair(maxStb.second,maxStb.first);
	}
	return minStr.first!=100 && (maxStr.first-minStr.first>=3 || maxStb.first-minStb.first>=3);
}
int posCard[54];
int main()
{
	//freopen("input.txt","r",stdin);
	gen();
	cin>>n>>m;

	int pos[2][2];
	int cntJ=0;
	int j2=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			string t;

			cin>>t;
			arr[i][j]=t;
			for(int k=0;k<54;k++)
				if(pack[k]==t)
					posCard[k]=1;
			if(t=="J1")
			{
				pos[0][0]=i;
				pos[0][1]=j;
				cntJ++;
			}
			if(t=="J2")
			{
				pos[1][0]=i;
				pos[1][1]=j;
				cntJ++;
				j2=1;
			}
		}

	if(cntJ==0)
		if(isSolve())
		{
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
		}
	if(cntJ==1)
	{
		for(int i=0;i<52;i++)
		{
			if(posCard[i]==0)
			{
				if(j2==0)
					arr[pos[0][0]][pos[0][1]]=pack[i];
				else
					arr[pos[1][0]][pos[1][1]]=pack[i];
				if(isSolve())
				{
					cout<<"Solution exists."<<endl;
					if(j2==0)
						cout<<"Replace J1 with "<<pack[i]<<" ."<<endl;
					else
						cout<<"Replace J2 with "<<pack[i]<<" ."<<endl;
					break;
				}
			}
		}
	}
	if(cntJ==2)
	{
		int solved=false;

		for(int i=0;i<52;i++)
			for(int j=0;j<52;j++)
				if(i!=j && !solved && posCard[i]==0 && posCard[j]==0)
				{
					arr[pos[0][0]][pos[0][1]]=pack[i];
					arr[pos[1][0]][pos[1][1]]=pack[j];
					if(isSolve())
					{
						cout<<"Solution exists."<<endl;
						cout<<"Replace J1 with "<<pack[i];
						cout<<" and J2 with "<<pack[j]<<" ."<<endl;
						solved=true;
					}
				}
	}
	if(isSolve())
	{
		printf("Put the first square to (%d, %d).\n",s1.first+1,s1.second+1);
		printf("Put the second square to (%d, %d).\n",s2.first+1,s2.second+1);
	}
	else
		cout<<"No solution.";
	return 0;
}

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman010 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
int n , m;
vector<pair<int , int>> ans;
map<int , string> joker;
string s[20][20];
set<string> in;
bool done[20][20];
void mark(int i , int j , set<char> &st , set<char> &st2) {
    ans.push_back({i + 1 , j + 1});
    for(int p1 = 0;p1 < 3;p1++)
        for(int p2 = 0;p2 < 3;p2++)
            done[i + p1][j + p2] = true;
    for(auto &k : st2)
        st.erase(k);
}
int main() {
    abdelrahman010
    cin >> n >> m;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++)
            cin >> s[i][j] , in.insert(s[i][j]);
    for(int i = 0;i + 2 < n;i++)
        for(int j = 0;j + 2 < m;j++) {
            set<char> st , st1 , st2;
            vector<int> v;
            bool yes = false;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    yes |= done[i + p1][j + p2];
            if(yes)
                continue;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    if(s[i + p1][j + p2][0] == 'J')
                        v.push_back(s[i + p1][j + p2][1] - '0');
                    else {
                        st1.insert(s[i + p1][j + p2][1]);
                        st2.insert(s[i + p1][j + p2][0]);
                    }
            for(char c = '2';c <= '9';c++)
                st.insert(c);
            st.insert('T') , st.insert('Q');
            st.insert('R') , st.insert('A');
            st.insert('J');
            if(st1.size() == 1) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    string m = "";
                    for(char c = '2';c <= '9';c++) {
                        m += c;
                        m += *st1.begin();
                        if(!in.count(m))
                            break;
                        else
                            m = "";
                    }
                    if(m == "")
                        for(auto &c : {'A' , 'Q' , 'K' , 'T' ,'J'}) {
                            m += c;
                            m += *st1.begin();
                            if(!in.count(m))
                                break;
                            else
                                m = "";
                        }
                    if(m == "")
                        return cout << "No solution." , 0;
                    in.insert(m);
                    joker[k] = m;
                }
            } else if(st2.size() + v.size() == 9) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    string m = "";
                    for(auto &p1 : st) {
                        m = "";
                        for(auto &p2 : {'C' , 'D' , 'H' , 'S'}) {
                            m += p1 , m += p2;
                            if(!in.count(m))
                                break;
                            else
                                m = "";
                        }
                        if(m != "")
                            break;
                    }
                    if(m == "")
                        return cout << "No solution." , 0;
                    in.insert(m);
                    joker[k] = m;
                }
            }
        }
    if(ans.size() < 2)
        return cout << "No solution." , 0;
    cout << "Solution exists.\n";
    vector<pair<string , string>> jr;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++)
                if(s[i][j] == "J1" || s[i][j] == "J2") {
                    int k = s[i][j][1] - '0';
                    if(!joker.count(k)) {
                        string m = "";
                        for(auto &p1 : {'C' , 'D' , 'H' , 'S'})
                            for(char p2 = '2';p2 <= '9';p2++) {
                                m += p2 , m+= p1;
                                if(!in.count(m))
                                    break;
                                else
                                    m = "";
                            }
                        if(m == "") {
                            for(auto &p1 : {'C' , 'D' , 'H' , 'S'})
                                for(auto &p2 : {'A' , 'Q' , 'K' , 'T' ,'J'}) {
                                    m += p2 , m+= p1;
                                    if(!in.count(m))
                                        break;
                                    else
                                        m = "";
                                }
                        }
                        joker[k] = m;
                    }
                    jr.push_back({s[i][j] , joker[k]});
                }
    if(!jr.size())
        cout << "There are no jokers.\n";
    else if(jr.size() == 1)
        cout << "Replace " << jr[0].first << " with " << jr[0].second << ".\n";
    else {
        if(jr[0].first == "J2")
            swap(jr[0] , jr[1]);
        cout << "Replace " << jr[0].first << " with " << jr[0].second << " and " << jr[1].first << " with " << jr[1].second << ".\n";
    }
    cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
    cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << ").";
    return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
#include <queue>
#include <deque>
#include <set>
#define ll long long
#define MP make_pair
#define PII pair<int, int>
#define F first
#define S second
#define SHN 1e9
#define lSHN 1e18
using namespace std;
int n,m;
string s[20][20];
map<string, bool> mp;
int j1x=-1,j1y=-1,j2x=-1,j2y=-1;
vector<string> v;
string sui="CDHS";
string ran="23456789TJQKA";
inline bool ok(int x,int y)
{
	set<char> st;
	bool fl=1;
	for (int i=x;i<x+3;i++)
	{
		for (int j=y;j<y+3;j++)
		{
			st.insert(s[i][j][0]);
			if (s[i][j][1]!=s[x][y][1]) fl=0;
		}
	}
	if (!fl && st.size()!=9) return 0;
	return 1;
}
void outj12(int i1,int j1,int i2,int j2,int tr1,int tr2)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J1 with "<<v[tr1]<<" and J2 with "<<v[tr2]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj12()
{
	for (int tr1=0;tr1<v.size();tr1++)
	{
		for (int tr2=0;tr2<v.size();tr2++)
		{
			if (tr1==tr2) continue;
			s[j1x][j1y]=v[tr1];
			s[j2x][j2y]=v[tr2];
			for (int i1=0;i1<n-2;i1++)
			{
				for (int j1=0;j1<m-2;j1++)
				{
					for (int i2=0;i2<n-2;i2++)
					{
						for (int j2=0;j2<m-2;j2++)
						{
							if (MP(i1,j1)>=MP(i2,j2)) continue;
							if (i1==i2 && j1==j2) continue;
							if (ok(i1,j1) && ok(i2,j2))
							    outj12(i1,j1,i2,j2,tr1,tr2);
						}
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void outj1(int i1,int j1,int i2,int j2,int tr1)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J1 with "<<v[tr1]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj1()
{
	for (int tr1=0;tr1<v.size();tr1++)
	{
		s[j1x][j1y]=v[tr1];
		for (int i1=0;i1<n-2;i1++)
		{
			for (int j1=0;j1<m-2;j1++)
			{
				for (int i2=0;i2<n-2;i2++)
				{
					for (int j2=0;j2<m-2;j2++)
					{
						if (MP(i1,j1)>=MP(i2,j2)) continue;
						if (i1==i2 && j1==j2) continue;
						if (ok(i1,j1) && ok(i2,j2))
						    outj1(i1,j1,i2,j2,tr1);
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void outj2(int i1,int j1,int i2,int j2,int tr2)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J2 with "<<v[tr2]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj2()
{
    for (int tr2=0;tr2<v.size();tr2++)
	{
		s[j2x][j2y]=v[tr2];
		for (int i1=0;i1<n-2;i1++)
	    {
			for (int j1=0;j1<m-2;j1++)
			{
				for (int i2=0;i2<n-2;i2++)
				{
					for (int j2=0;j2<m-2;j2++)
					{
						if (MP(i1,j1)>=MP(i2,j2)) continue;
						if (i1==i2 && j1==j2) continue;
						if (ok(i1,j1) && ok(i2,j2))
						    outj2(i1,j1,i2,j2,tr2);
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void out(int i1,int j1,int i2,int j2)
{
	cout <<"Solution exists.\n";
	cout <<"There are no jokers.\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void go()
{
    for (int i1=0;i1<n-2;i1++)
	{
		for (int j1=0;j1<m-2;j1++)
		{
			for (int i2=0;i2<n-2;i2++)
			{
				for (int j2=0;j2<m-2;j2++)
				{
					if (MP(i1,j1)>=MP(i2,j2)) continue;
					if (i1==i2 && j1==j2) continue;
					if (ok(i1,j1) && ok(i2,j2))
					    out(i1,j1,i2,j2);
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
int main()
{
	cin >>n>>m;
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			cin >>s[i][j];
			if (s[i][j][0]!='J')
			{
				mp[s[i][j]]=1;
				continue;
			}
			if (s[i][j][1]=='1')
			{
				j1x=i;
				j1y=j;
			}
			else
			{
				j2x=i;
				j2y=j;
			}
		}
	}
	for (int i=0;i<4;i++)
	{
		for (int j=0;j<13;j++)
		{
			string ss="  ";
			ss[0]=ran[j];
			ss[1]=sui[i];
			if (!mp[ss]) v.push_back(ss);
		}
	}
	if (j1x!=-1 && j2x==-1) goj1();
	else if (j1x==-1 && j2x!=-1) goj2();
	else if (j1x!=-1 && j2x!=-1) goj12();
	else go();
	return 0;
}

#include<iostream>
using namespace std;

int a[20][20],ff[20][20];
bool flag[60],fnum[20];
char word[15]="A23456789TJQK";
char suit[5]="CDHS",x,y;

bool OL(int i,int j,int ii,int jj)
{
    int k;
    if(ii-i>0) k=ii-i;
    else k=i-ii;
    if(k<3) return true;

    if(jj-j>0) k=jj-j;
    else k=j-jj;
    if(k<3) return true;

    return false;
/*
    if(ii>=i&&ii<i+3&&jj>=j&&jj<j+3)
        return true;
    if(ii>=i&&ii<i+3&&jj+2>=j&&jj+2<j+3)
        return true;
    if(ii+2>=i&&ii+2<i+3&&jj>=j&&jj<j+3)
        return true;
    if(ii+2>=i&&ii+2<i+3&&jj+2>=j&&jj+2<j+3)
        return true;
    return false;*/
}
void Find(int k)
{
    int i=k/13,j=k%13;
    x=word[j];
    y=suit[i];
}
bool OK(int ii,int jj)
{
    bool tag[20],t1,t2;
    int i,j,s1;
    for(i=0;i<20;i++)
        tag[i]=false;

    s1=a[ii][jj]/13;
    t1=false,t2=false;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++)
        {
            if(a[i+ii][j+jj]/13!=s1)
                t1=true;
            if(tag[a[ii+i][jj+j]%13])
                t2=true;
            else tag[a[ii+i][jj+j]%13]=true;
        }
    if(t1&&t2) return false;
    return true;
}
int main()
{
    int n,m,i,j,ii,jj,x1,x2,y1,y2,k1,k2;
    char ss[10];
    bool tag;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(flag,false,sizeof(flag));
        memset(a,-1,sizeof(a));
        x1=y1=x2=y2=-1;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                scanf("%s",ss);
                if(!strcmp(ss,"J1"))
                {
                    a[i][j]=60;
                    x1=i,y1=j;
                }
                else if(!strcmp(ss,"J2"))
                {
                    a[i][j]=70;
                    x2=i,y2=j;
                }
                else
                {
                    for(ii=0;ii<13;ii++)
                        if(word[ii]==ss[0])
                            break;
                    for(jj=0;jj<4;jj++)
                        if(suit[jj]==ss[1])
                            break;

                    a[i][j]=jj*13+ii;
                    flag[jj*13+ii]=true;
                }
            }

        memset(ff,0,sizeof(ff));
        for(i=0;i<n-2;i++)
        {
            for(j=0;j<m-2;j++)
            {
                if((x1>=i&&x1<=i+2&&y1>=j&&y1<=j+2)||(x2>=i&&x2<=i+2&&y2>=j&&y2<=j+2))
                    ff[i][j]=1;
                else if(!OK(i,j))
                    ff[i][j]=-1;
            }
        }

    /*  for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
                printf("%d ",ff[i][j]);
            printf("\n");
        }
        printf("\n");*/
        tag=false;
        for(i=0;i<n-2&&!tag;i++)
            for(j=0;j<m-2&&!tag;j++)
            {
                if(ff[i][j]==-1) continue;
                for(ii=i;ii<n-2&&!tag;ii++)
                    for(jj=0;jj<m-2&&!tag;jj++)
                    {
                        if(ff[ii][jj]==-1) continue;
                        if(ii==i&&jj<=j) continue;
                        if(OL(i,j,ii,jj))
                            continue;

                        if((x1>=i&&x1<=i+2&&y1>=j&&y1<=j+2)||(x1>=ii&&x1<=ii+2&&y1>=jj&&y1<=jj+2))
                        {
                            for(k1=0;k1<52&&!tag;k1++)
                                if(!flag[k1])
                                {
                                    a[x1][y1]=k1;
                                    if((x2>=i&&x2<=i+2&&y2>=j&&y2<=j+2)||(x2>=ii&&x2<=ii+2&&y2>=jj&&y2<=jj+2))
                                    {
                                        for(k2=0;k2<52;k2++)
                                            if(!flag[k2]&&k2!=k1)
                                            {
                                                a[x2][y2]=k2;
                                                if(OK(i,j)&&OK(ii,jj))
                                                {
                                                    tag=true;
                                                    printf("Solution exists.\n");
                                                    Find(k1);
                                                    printf("Replace J1 with %c%c",x,y);
                                                    Find(k2);
                                                    printf(" and J2 with %c%c.\n",x,y);
                                                    printf("Put the first square to (%d, %d).\n",i+1,j+1);
                                                    printf("Put the second square to (%d, %d).\n",ii+1,jj+1);
                                                    break;
                                                }
                                            }
                                    }
                                    else
                                    {
                                        if(OK(i,j)&&OK(ii,jj))
                                        {
                                            tag=true;
                                            printf("Solution exists.\n");
                                            Find(k1);
                                            printf("Replace J1 with %c%c.\n",x,y);
                                            printf("Put the first square to (%d, %d).\n",i+1,j+1);
                                            printf("Put the second square to (%d, %d).\n",ii+1,jj+1);
                                            break;
                                        }
                                    }
                                }
                        }
                        else
                        {
                            if((x2>=i&&x2<=i+2&&y2>=j&&y2<=j+2)||(x2>=ii&&x2<=ii+2&&y2>=jj&&y2<=jj+2))
                            {
                                for(k2=0;k2<52;k2++)
                                    if(!flag[k2])
                                    {
                                        a[x2][y2]=k2;
                                        if(OK(i,j)&&OK(ii,jj))
                                        {
                                            tag=true;
                                            printf("Solution exists.\n");
                                            Find(k2);
                                            printf("Replace J2 with %c%c.\n",x,y);
                                            printf("Put the first square to (%d, %d).\n",i+1,j+1);
                                            printf("Put the second square to (%d, %d).\n",ii+1,jj+1);
                                            break;
                                        }
                                    }
                            }
                            else
                            {
                                if(OK(i,j)&&OK(ii,jj))
                                {
                                    tag=true;
                                    printf("Solution exists.\n");
                                    printf("There are no jokers.\n");
                                    printf("Put the first square to (%d, %d).\n",i+1,j+1);
                                    printf("Put the second square to (%d, %d).\n",ii+1,jj+1);
                                    break;
                                }
                            }
                        }
                    }
            }
        if(!tag) printf("No solution.\n");
    }
    return 0;
}

#include<iostream>
#include<string>
#include <sstream>
using namespace std;

string s[18][18];
	string ss[]={
		"2C", "3C", "4C", "5C", "6C", "7C","8C","9C","TC", "QC", "KC","AC", "JC",
		"2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "TD","QD","KD","AD","JD",
		"2H" ,"3H", "4H", "5H" ,"6H", "7H", "8H", "9H", "TH", "QH", "KH", "AH", "JH",
		"2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "TS", "QS" ,"KS" ,"AS","JS"};
int count[52];

string rep[52];
int n,m,t,num;
int flag1=0,flag2=0;
int temp[4];
int rank[85];

int map(int a[],string b[],string c[])
{
	int i;int sum=0;
	for(i=0;i<52;i++)
		if(a[i]==0)
		{
			b[sum]=c[i];
			sum++;
		}
		return sum;
}

int check2(int i,int j)
{
	int k,t,ii;
	memset(rank,0,sizeof(rank));
	for(k=i;k<i+3;k++)
		for(t=j;t<j+3;t++)
		{
			ii=s[k][t][0];
			rank[ii]++;
		}
		for(k=0;k<85;k++)
			if(rank[k]>1)return 0;
		return 1;
}

int check1(int i,int j)
{
	int k,t;
	for(k=i;k<i+3;k++)
		for(t=j;t<j+3;t++)
		{
			if(s[k][t][1]!=s[i][j][1])return check2(i,j);
		}
		return 1;
}
bool overlap(int x1,int y1, int x2, int y2)
{
	if(x1+2>=x2&&x2+2>=x1&&y1+2>=y2&&y2+2>=y1)
		return true;
	return false;
}

bool solve()
{
	for(int i=0;i<n-2;i++)
	{
		for(int j=0;j<m-2;j++)
		{
			if(!check1(i,j))continue;

			for(int p=0;p<n-2;p++)
			{
				for(int q=0;q<m-2;q++)
				{
					if(!check1(p,q))continue;
					if(!overlap(i,j,p,q))
					{
						cout<<"Solution exists."<<endl;
						if(flag1==1&&flag2==1)cout<<"Replace J1 with "<<s[temp[0]][temp[1]]<<" and J2 with "<<s[temp[2]][temp[3]]<<endl;
						else
							if(flag1!=0)cout<<"Replace J1 with "<<s[temp[0]][temp[1]]<<endl;
							else
								if(flag2!=0)cout<<"Replace J2 with "<<s[temp[2]][temp[3]]<<endl;
								else
									cout<<"There are no jokers."<<endl;
						cout<<"Put the first square to "<<"("<<i+1<<", "<<j+1<<")."<<endl;
						cout<<"Put the second square to "<<"("<<p+1<<", "<<q+1<<")."<<endl;
						return true;
					}
				}
			}
		}
	}
	return false;
}

bool run(int t)
{
	for(int i=0;i<t;i++)
		{
			for(int j=0;j<t;j++)
			{
				if(i==j)continue;
				else
				{
					if(flag1!=0)s[temp[0]][temp[1]]=rep[i];
					if(flag2!=0)s[temp[2]][temp[3]]=rep[j];
				}
				if(solve())return true;
			}
		}
	return false;
}
int main()
{

	memset(count,0,sizeof(count));
		cin>>n>>m;
		num=n*m;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				cin>>s[i][j];
				for(int k=0;k<52;k++)
				{
					if(ss[k]==s[i][j])count[k]=1;
				}
				if(s[i][j]=="J1")
				{
					flag1=1;
					temp[0]=i;
					temp[1]=j;
				}
				if(s[i][j]=="J2")
				{
					flag2=1;
					temp[2]=i;
					temp[3]=j;
				}
			}
		}
		int t=map(count, rep,ss);

		if(!run(t))cout<<"No solution."<<endl;
}
		//getline(cin,s[i]);
		//stringstream fin(s[i]);
		//fin>>ss[j++];

//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//#pragma GCC target("avx,tune=native")
#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
const int inf=0x3f3f3f3f;
const double eps=1e-6;
const int mod=1000000007;
typedef long long ll;
int calc1(char c){
	if(c=='C')return 1;
	if(c=='D')return 2;
	if(c=='H')return 3;
	if(c=='S')return 4;
}
inline calc2(char c){
	if(isdigit(c))return c-'0';
	if(c=='T')return 10;
	if(c=='J')return 11;
	if(c=='Q')return 12;
	if(c=='K')return 13;
	if(c=='A')return 1;
}
inline char get1(int x){
	if(x==1)return 'C';
	if(x==2)return 'D';
	if(x==3)return 'H';
	if(x==4)return 'S';
}
inline char get2(int x){
	if(2<=x&&x<10)return '0'+x;
	if(x==10)return 'T';
	if(x==11)return 'J';
	if(x==12)return 'Q';
	if(x==13)return 'K';
	if(x==1)return 'A';
}
bool cross(int i1,int j1,int i2,int j2){
	vector<int>s1,s2;
	for(int i=i1;i<i1+3;i++){
		for(int j=j1;j<j1+3;j++){
			s1.push_back(i*100+j);
		}
	}
	for(int i=i2;i<i2+3;i++){
		for(int j=j2;j<j2+3;j++){
			s2.push_back(i*100+j);
		}
	}
	for(auto p:s1)for(auto q:s2)if(p==q)return true;
	return false;
}
bool ok(int x,int y,vector<vector<pair<int,int> > >&mat){
	bool samecolor=true;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(mat[i][j].first!=mat[x][y].first)samecolor=false;
		}
	}
	bool difranks=true;
	set<int>all;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(all.count(mat[i][j].second))difranks=false;
			all.insert(mat[i][j].second);
		}
	}
	return samecolor|difranks;
}
pair<pair<int,int>,pair<int,int> >check(vector<vector<pair<int,int> > >mat){
	int n=mat.size(),m=mat[0].size();
	for(int i1=0;i1<=n-3;i1++){
		for(int j1=0;j1<=m-3;j1++){
			for(int i2=0;i2<=n-3;i2++){
				for(int j2=0;j2<=m-3;j2++){
					if(!cross(i1,j1,i2,j2)&&ok(i1,j1,mat)&&ok(i2,j2,mat)){
						return make_pair(make_pair(i1+1,j1+1),make_pair(i2+1,j2+1));
					}
				}
			}
		}
	}
	return make_pair(make_pair(-1,-1),make_pair(-1,-1));
}
int n,m;
int main(){
	cin>>n>>m;
	vector<vector<pair<int,int> > >card(n,vector<pair<int,int> >(m,make_pair(0,0)));
	int cntj=0;
	vector<pair<int,int> >jokers;
	vector<string>vs;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			string s;
			cin>>s;
			if(s[0]=='J'&&isdigit(s[1])){
				cntj++;
				jokers.push_back(make_pair(i,j));
				vs.push_back(s);
				card[i][j]=make_pair(-1,-1);
				continue;
			}
			card[i][j]=make_pair(calc1(s[1]),calc2(s[0]));
			//color rank
		}
	}
	set<pair<int,int> >S;
	for(int i=1;i<=4;i++)for(int j=1;j<=13;j++)S.insert(make_pair(i,j));
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(card[i][j].first!=-1){
				S.erase(S.find(card[i][j]));
			}
		}
	}
	vector<pair<int,int> >restcards(S.begin(),S.end());
	if(cntj==0){
		auto p=check(card);
		if(p.first.first!=-1){
			puts("Solution exists.");
			puts("There are no jokers.");
			printf("Put the first square to (%d, %d).\n",p.first.first,p.first.second);
			printf("Put the second square to (%d, %d).\n",p.second.first,p.second.second);
			return 0;
		}else{
			puts("No solution.");
			return 0;
		}
	}else if(cntj==1){
		int x=jokers[0].first,y=jokers[0].second;
		for(auto p:restcards){
			card[x][y]=p;
			auto _p=check(card);
			if(_p.first.first!=-1){
				puts("Solution exists.");
				printf("Replace %s with %c%c.\n",vs[0].c_str(),get2(p.second),get1(p.first));
				printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
				printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
				return 0;
			}
			card[x][y]=make_pair(-1,-1);
		}
	}else{
		int x[2]={jokers[0].first,jokers[1].first},y[2]={jokers[0].second,jokers[1].second};
		for(auto p:restcards){
			for(auto q:restcards){
				if(p!=q){
					card[x[0]][y[0]]=p;
					card[x[1]][y[1]]=q;
					auto _p=check(card);
					if(_p.first.first!=-1){
						puts("Solution exists.");
						pair<char,char>c1,c2;
						if(vs[0]=="J1"){
							c1=make_pair(get2(p.second),get1(p.first));
							c2=make_pair(get2(q.second),get2(q.first));
						}else{
							c2=make_pair(get2(p.second),get1(p.first));
							c1=make_pair(get2(q.second),get2(q.first));
						}
						printf("Replace J1 with %c%c and J2 with %c%c.\n",c1.first,c1.second,c2.first,c2.second);
						printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
						printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
					}
					card[x[0]][y[0]]=make_pair(-1,-1);
					card[x[1]][y[1]]=make_pair(-1,-1);
				}
			}
		}
	}
	puts("No solution.");
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

map <char,int> rankktono;
map <int,char> notorankk;
map <char,int> suittono;
map <int,char> notosuit;
void init(){

    suittono['C']=0;
    suittono['D']=1;
    suittono['H']=2;
    suittono['S']=3;

    notosuit[0]='C';
    notosuit[1]='D';
    notosuit[2]='H';
    notosuit[3]='S';

    rankktono['0']=0;
    rankktono['1']=1;
    rankktono['2']=2;
    rankktono['3']=3;
    rankktono['4']=4;
    rankktono['5']=5;
    rankktono['6']=6;
    rankktono['7']=7;
    rankktono['8']=8;
    rankktono['9']=9;
    rankktono['T']=10;
    rankktono['J']=11;
    rankktono['Q']=12;
    rankktono['K']=13;
    rankktono['A']=14;

    notorankk[0]='0';
    notorankk[1]='1';
    notorankk[2]='2';
    notorankk[3]='3';
    notorankk[4]='4';
    notorankk[5]='5';
    notorankk[6]='6';
    notorankk[7]='7';
    notorankk[8]='8';
    notorankk[9]='9';
    notorankk[10]='T';
    notorankk[11]='J';
    notorankk[12]='Q';
    notorankk[13]='K';
    notorankk[14]='A';
}

char rankk[500][500];
char suit[500][500];

bool vis[500][500];

int main()
{
    // cout << "Hello World!" << endl;
    ios::sync_with_stdio(false);
    init();

    vector <pair <int,int> > position;
    vector <pair <char,char> > rankknsuit;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>rankk[i][j]>>suit[i][j];
            if(rankk[i][j]=='J'){
                position.push_back(make_pair(i,j));
                rankknsuit.push_back(make_pair(rankk[i][j],suit[i][j]));
            }
        }
    }
    int cnt=position.size();

    if(cnt==0){
        // cout<<"Nigga\n";
        vector <pair <int,int> > poss;

        for(int i=1;i<=n-3+1;i++){
            for(int j=1;j<=m-3+1;j++){
                // cout<<i<<" ,, "<<j<<"\n";
                bool samesuit=true,diffrankk=true;
                for(int k=0;k<3;k++){
                    for(int l=0;l<3;l++){
                        for(int m=0;m<3;m++){
                            for(int nn=0;nn<3;nn++){
                                if(k!=m||l!=nn){
                                    if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                        diffrankk=false;
                                    }
                                    if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                        samesuit=false;
                                        // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                    }
                                    // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                    // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                }
                            }
                        }
                    }
                }
                // cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                if((samesuit|diffrankk)){
                    // cout<<i<<" ::: "<<j<<"@@@@\n";
                    poss.push_back(make_pair(i,j));
                }
            }
        }

        if(poss.size()==0){
            cout<<"No solution.\n";
        }
        else{
            for(int i=0;i<poss.size();i++){
                for(int j=0;j<poss.size();j++){
                    if(i!=j){
                        int x1,y1,x2,y2;
                        x1=poss[i].first;
                        y1=poss[i].second;
                        x2=poss[j].first;
                        y2=poss[j].second;
//                        if(1){
                         if(!(x1>=x2&&y1>=y2)){
                            cout<<"Solution exists.\nThere are no jokers.\n";
                            cout<<"Put the first square to ("<<x1<<", "<<y1<<").\n";
                            cout<<"Put the second square to ("<<x2<<", "<<y2<<").\n";
                            return 0;
                        }
                    }

                }
            }

            cout<<"No solution.\n";
        }

    }
    else{
        if(cnt==2)
        if(rankknsuit[0].second>rankknsuit[1].second){
            swap(position[0],position[1]);
            swap(rankknsuit[0],rankknsuit[1]);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(rankk[i][j]=='J'){

                }
                else{
                    vis[suittono[suit[i][j]]][rankktono[rankk[i][j]]]=true;

                }
            }
        }

        vector <pair <char,char> > boka14;

        for(int i=0;i<=3;i++){
            for(int j=2;j<=14;j++){
                char cursuit,currankk;
                cursuit=notosuit[i];
                currankk=notorankk[j];
                if(vis[i][j]==false){
                    boka14.push_back(make_pair(cursuit,currankk));
                    // cout<<cursuit<<" : "<<currankk<<"\n";
                }
            }
        }

        if(position.size()==1){
            for(auto boka : boka14){
                vector <pair <int,int> > poss;
                suit[position[0].first][position[0].second]=boka.first;
                rankk[position[0].first][position[0].second]=boka.second;
                for(int i=1;i<=n-3+1;i++){
                for(int j=1;j<=m-3+1;j++){
                    // cout<<i<<" ,, "<<j<<"\n";
                    bool samesuit=true,diffrankk=true;
                    for(int k=0;k<3;k++){
                        for(int l=0;l<3;l++){
                            for(int m=0;m<3;m++){
                                for(int nn=0;nn<3;nn++){
                                    if(k!=m||l!=nn){
                                        if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                            diffrankk=false;
                                        }
                                        if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                            samesuit=false;
                                            // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                        }                                            // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                            // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                    }
                                }
                            }
                        }
                    }
                    // cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                    if((samesuit|diffrankk)){
                        // cout<<i<<" ::: "<<j<<"@@@@\n";
                        poss.push_back(make_pair(i,j));
                    }
                }
            }

                for(int i=0;i<poss.size();i++){
                    for(int j=0;j<poss.size();j++){
                        if(i!=j){
                            int x1,y1,x2,y2;
                            x1=poss[i].first;
                            y1=poss[i].second;
                            x2=poss[j].first;
                            y2=poss[j].second;
//                            if(1){
                             if(!(x1>=x2&&y1>=y2)){
                                cout<<"Solution exists.\nReplace "<<rankknsuit[0].first<<rankknsuit[0].second<<" with "<<boka.second<<boka.first<<".\n";
                                cout<<"Put the first square to ("<<x1<<", "<<y1<<").\n";
                                cout<<"Put the second square to ("<<x2<<", "<<y2<<").\n";
                                return 0;
                            }
                        }

                    }
                }

            }
            cout<<"No solution.\n";
            return 0;
        }
        else{
            for(auto boka : boka14){
            for(auto choda : boka14){
            if(!(boka.first==choda.first&&boka.second==choda.second)){
                vector <pair <int,int> > poss;
                suit[position[0].first][position[0].second]=boka.first;
                rankk[position[0].first][position[0].second]=boka.second;
                suit[position[1].first][position[1].second]=choda.first;
                rankk[position[1].first][position[1].second]=choda.second;
                for(int i=1;i<=n-3+1;i++){
                for(int j=1;j<=m-3+1;j++){
                    // cout<<i<<" ,, "<<j<<"\n";
                    bool samesuit=true,diffrankk=true;
                    for(int k=0;k<3;k++){
                        for(int l=0;l<3;l++){
                            for(int m=0;m<3;m++){
                                for(int nn=0;nn<3;nn++){
                                    if(k!=m||l!=nn){
                                        if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                            diffrankk=false;
                                        }
                                        if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                            samesuit=false;
                                            // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                        }                                            // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                            // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                    }
                                }
                            }
                        }
                    }
                    //  cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                    if((samesuit|diffrankk)){
                        // cout<<i<<" ::: "<<j<<"@@@@\n";
                        poss.push_back(make_pair(i,j));
                    }
                }
            }

                for(int i=0;i<poss.size();i++){
                    for(int j=0;j<poss.size();j++){
                        if(i!=j){
                            int x1,y1,x2,y2;
                            x1=poss[i].first;
                            y1=poss[i].second;
                            x2=poss[j].first;
                            y2=poss[j].second;
//                            if(1){
                             if(!(x1>=x2&&y1>=y2)){
                                cout<<"Solution exists.\nReplace "<<rankknsuit[0].first<<rankknsuit[0].second<<" with "<<boka.second<<boka.first<<" and ";
                                cout<<rankknsuit[1].first<<rankknsuit[1].second<<" with "<<choda.second<<choda.first<<".\n";
                                cout<<"Put the first square to ("<<x1<<", "<<y1<<").\n";
                                cout<<"Put the second square to ("<<x2<<", "<<y2<<").\n";
                                return 0;
                            }
                        }

                    }
                }

            }

            }

            }
            cout<<"No solution.\n";
            return 0;
        }

    }

    return 0;
}

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
#include <queue>
#include <deque>
#include <set>
#define ll long long
#define MP make_pair
#define PII pair<int, int>
#define F first
#define S second
#define SHN 1e9
#define lSHN 1e18
using namespace std;
int n,m;
string s[20][20];
map<string, bool> mp;
int j1x=-1,j1y=-1,j2x=-1,j2y=-1;
vector<string> v;
string sui="CDHS";
string ran="23456789TJQKA";
inline bool ok(int x,int y)
{
	set<char> st;
	bool fl=1;
	for (int i=x;i<x+3;i++)
	{
		for (int j=y;j<y+3;j++)
		{
			st.insert(s[i][j][0]);
			if (s[i][j][1]!=s[x][y][1]) fl=0;
		}
	}
	if (!fl && st.size()!=9) return 0;
	return 1;
}
void outj12(int i1,int j1,int i2,int j2,int tr1,int tr2)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J1 with "<<v[tr1]<<" and J2 with "<<v[tr2]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj12()
{
	for (int tr1=0;tr1<v.size();tr1++)
	{
		for (int tr2=0;tr2<v.size();tr2++)
		{
			if (tr1==tr2) continue;
			s[j1x][j1y]=v[tr1];
			s[j2x][j2y]=v[tr2];
			for (int i1=0;i1<n-2;i1++)
			{
				for (int j1=0;j1<m-2;j1++)
				{
					for (int i2=0;i2<n-2;i2++)
					{
						for (int j2=0;j2<m-2;j2++)
						{
							if (MP(i1,j1)>=MP(i2,j2)) continue;
							if (abs(i2-i1)<3 && abs(j2-j1)<3) continue;
							if (ok(i1,j1) && ok(i2,j2))
							    outj12(i1,j1,i2,j2,tr1,tr2);
						}
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void outj1(int i1,int j1,int i2,int j2,int tr1)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J1 with "<<v[tr1]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj1()
{
	for (int tr1=0;tr1<v.size();tr1++)
	{
		s[j1x][j1y]=v[tr1];
		for (int i1=0;i1<n-2;i1++)
		{
			for (int j1=0;j1<m-2;j1++)
			{
				for (int i2=0;i2<n-2;i2++)
				{
					for (int j2=0;j2<m-2;j2++)
					{
						if (MP(i1,j1)>=MP(i2,j2)) continue;
						if (abs(i2-i1)<3 && abs(j2-j1)<3) continue;
						if (ok(i1,j1) && ok(i2,j2))
						    outj1(i1,j1,i2,j2,tr1);
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void outj2(int i1,int j1,int i2,int j2,int tr2)
{
	cout <<"Solution exists.\n";
	cout <<"Replace J2 with "<<v[tr2]<<".\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void goj2()
{
    for (int tr2=0;tr2<v.size();tr2++)
	{
		s[j2x][j2y]=v[tr2];
		for (int i1=0;i1<n-2;i1++)
	    {
			for (int j1=0;j1<m-2;j1++)
			{
				for (int i2=0;i2<n-2;i2++)
				{
					for (int j2=0;j2<m-2;j2++)
					{
						if (MP(i1,j1)>=MP(i2,j2)) continue;
						if (abs(i2-i1)<3 && abs(j2-j1)<3) continue;
						if (ok(i1,j1) && ok(i2,j2))
						    outj2(i1,j1,i2,j2,tr2);
					}
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
void out(int i1,int j1,int i2,int j2)
{
	cout <<"Solution exists.\n";
	cout <<"There are no jokers.\n";
	cout <<"Put the first square to ("<<i1+1<<", "<<j1+1<<").\n";
	cout <<"Put the second square to ("<<i2+1<<", "<<j2+1<<").\n";
	exit(0);
}
void go()
{
    for (int i1=0;i1<n-2;i1++)
	{
		for (int j1=0;j1<m-2;j1++)
		{
			for (int i2=0;i2<n-2;i2++)
			{
				for (int j2=0;j2<m-2;j2++)
				{
					if (MP(i1,j1)>=MP(i2,j2)) continue;
					if (abs(i2-i1)<3 && abs(j2-j1)<3) continue;
					if (ok(i1,j1) && ok(i2,j2))
					    out(i1,j1,i2,j2);
				}
			}
		}
	}
	cout <<"No solution.\n";
	exit(0);
}
int main()
{
	cin >>n>>m;
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			cin >>s[i][j];
			if (s[i][j][0]!='J')
			{
				mp[s[i][j]]=1;
				continue;
			}
			if (s[i][j][1]=='1')
			{
				j1x=i;
				j1y=j;
			}
			else
			{
				j2x=i;
				j2y=j;
			}
		}
	}
	for (int i=0;i<4;i++)
	{
		for (int j=0;j<13;j++)
		{
			string ss="  ";
			ss[0]=ran[j];
			ss[1]=sui[i];
			if (!mp[ss]) v.push_back(ss);
		}
	}
	if (j1x!=-1 && j2x==-1) goj1();
	else if (j1x==-1 && j2x!=-1) goj2();
	else if (j1x!=-1 && j2x!=-1) goj12();
	else go();
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
vector<vector< pair<string,string> > >jokers;
vector< pair< pair<int,int>  ,vector<int>   >    >vsol;
set<char>Rset;
vector<int>vnum;
vector<string>vs;
vector<pair<string,string> >vjk;
bool overlap(vector<int>v1,vector<int>v2){
int freq[150]={0};
for(int i=0;i<(int)v1.size();i++)
if((++freq[ v1[i] ]>1)||(++freq[ v2[i] ]>1))return 1;

return 0;
}

int main(){
set<string>Dset;
vector<char>Ranks={'A','2','3','4','5','6','7','8','9','T','J','Q','K'};

for(int i=0;i<(int)Ranks.size();i++){
string s1="C",s2="D",s3="S",s4="H";
Dset.insert(Ranks[i]+s1);
Dset.insert(Ranks[i]+s2);
Dset.insert(Ranks[i]+s3);
Dset.insert(Ranks[i]+s4);
}
int n=0,m=0;
string arr[50][50];
cin>>n>>m;
for(int i=0;i<n;i++)for(int j=0;j<m;j++){cin>>arr[i][j];Dset.erase(arr[i][j]);}
for(int i=0;n-i>=3;i++)
for(int j=0;m-j>=3;j++){
int jk=0;
bool diff_rank=1;
Rset.clear();
vnum.clear();
vs.clear();
vjk.clear();
for(int k=0;k<(int)Ranks.size();k++)Rset.insert(Ranks[k]);

for(int k=i;k<i+3;k++)for(int z=j;z<j+3;z++){
    if(arr[k][z]=="J1"||arr[k][z]=="J2")jk++,vjk.push_back(make_pair(arr[k][z],""));
    else{
       if(Rset.find(arr[k][z][0])!=Rset.end())Rset.erase(arr[k][z][0]);
       else diff_rank=0;

    }

    vnum.push_back((k*m)+(z+1));

    }
for(int k=0;k<jk&&diff_rank;k++){
for(auto it:Dset)
    if(Rset.find(it[0])!=Rset.end()){vs.push_back(it);Rset.erase(it[0]);break;}

Dset.erase(vs[vs.size()-1]);
vjk[k].second=vs[vs.size()-1];
}
while((int)vs.size()){Dset.insert(vs.back());vs.pop_back();}
if(diff_rank){
vsol.push_back(make_pair( make_pair(i+1,j+1)   , vnum    ));
jokers.push_back(vjk);
}

}
for(int i=0;i<(int)vsol.size();i++)
   for(int j=0;j<(int)vsol.size();j++)
   if(!overlap(vsol[i].second,vsol[j].second)){
cout<<"Solution exists.\n";
vector<pair<string,string> >jo;
for(int k=0;k<(int)jokers[i].size();k++)jo.push_back(jokers[i][k]);
for(int k=0;k<(int)jokers[j].size();k++)jo.push_back(jokers[j][k]);
sort(jo.begin(),jo.end());
if(!(int)jo.size())cout<<"There are no jokers.\n";
if((int)jo.size()>0)cout<<"Replace "<<jo[0].first<<" with "<<jo[0].second;
if((int)jo.size()>1)cout<<" and "<<jo[1].first<<" with "<<jo[1].second<<".\n";
else if((int)jo.size())cout<<".\n";
cout<<"Put the first square to"<<'('<<vsol[i].first.first<<','<<vsol[i].first.second<<").\n";
cout<<"Put the second square to"<<'('<<vsol[j].first.first<<','<<vsol[j].first.second<<").";
return 0;
   }

cout<<"No solution.";

    return 0;
}

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int n,m;
int a[17][17];
bool kol[52];
bool used[17][17];
vector<char> jok1;
vector<int> jok;
map<char,int> d1;
map<char,int> m1;
char d2[13];
char m2[4];

bool check(int x,int y)
{
    bool d[13];
    bool ma[4];
    for(int i=0;i<13;i++)
        d[i]=false;
    for(int j=0;j<4;j++)
        ma[j]=false;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        {
            if(used[x+i][y+j])return false;
            int z=a[x+i][y+j]%4;
            int q=a[x+i][y+j]/4;
            ma[z]=true;
            d[q]=true;
        }
    int c1=0,c2=0;
    for(int i=0;i<13;i++)
        if(d[i])c1++;
    for(int j=0;j<4;j++)
        if(ma[j])c2++;
    return(c1==9||c2==1);

}

bool doit(int deep)
{
    if(deep==jok.size())
    {
        for(int x1=0;x1<n-2;x1++)
            for(int y1=0;y1<m-2;y1++)
            {

                if(check(x1,y1))
                {
                    for(int i=0;i<3;i++)
                        for(int j=0;j<3;j++)
                            used[x1+i][y1+j]=true;
                    for(int x2=x1;x2<n-2;x2++)
                        for(int y2=0;y2<m-2;y2++)
                            if(check(x2,y2))
                            {
                                cout<<"Solution exists."<<endl;
                                if(deep==1)
                                {
                                    int q=jok[0]%4;
                                    int w=jok[0]/4;
                                    cout<<"Replace J"<<jok1[0]<<" with "<<d2[w]<<m2[q]<<"."<<endl;
                                }
                                else
                                    if(deep==2)
                                    {
                                        int q1=jok[0]%4;
                                        int w1=jok[0]/4;
                                        int q2=jok[1]%4;
                                        int w2=jok[1]/4;
                                        if(jok1[0]=='1')
                                            cout<<"Replace J1 with "<<d2[w1]<<m2[q1]<<" and J2 with "<<d2[w2]<<m2[q2]<<"."<<endl;
                                        else
                                            cout<<"Replace J1 with "<<d2[w2]<<m2[q2]<<" and J2 with "<<d2[w1]<<m2[q1]<<"."<<endl;
                                    }
                                    else
                                        cout<<"There are no jokers."<<endl;
                                cout<<"Put the first square to ("<<x1+1<<", "<<y1+1<<")."<<endl;
                                cout<<"Put the second square to ("<<x2+1<<", "<<y2+1<<").";
                                return true;
                            }
                    for(int i=0;i<3;i++)
                        for(int j=0;j<3;j++)
                            used[x1+i][y1+j]=false;
                }

            }
            return false;
    }
    int x=jok[deep]/20;
    int y=jok[deep]%20;
    for(int i=0;i<52;i++)
    {
        if(kol[i])
        {
            jok[deep]=i;
            a[x][y]=i;
            kol[i]=false;
            if(doit(deep+1))return true;

            kol[i]=true;
        }
    }
    return false;
}

int main()
{

    d2={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
    m2={'C','D','H','S'};
    d1['2']=0;
    d1['3']=1;
    d1['4']=2;
    d1['5']=3;
    d1['6']=4;
    d1['7']=5;
    d1['8']=6;
    d1['9']=7;
    d1['T']=8;
    d1['J']=9;
    d1['Q']=10;
    d1['K']=11;
    d1['A']=12;

    m1['C']=0;
    m1['D']=1;
    m1['H']=2;
    m1['S']=3;

    cin>>n>>m;

    for(int i=0;i<52;i++)
    {
        kol[i]=true;
    }
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            string s;
            cin>>s;
            if(s=="J1"||s=="J2")
            {
                a[i][j]='0'-s[1];
                jok.push_back(i*20+j);
                jok1.push_back(s[1]);
            }
            else
            {
                int x=d1[s[0]],y=m1[s[1]];
                kol[x*4+y]=false;
                a[i][j]=x*4+y;
            }
        }
    /*for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        cout<<d2[a[i][j]/4]<<m2[a[i][j]%4]<<' ';
        cout<<endl;
    }*/
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)used[i][j]=false;
    if(!doit(0))
    {
        cout<<"No solution.";
    }
    return 0;
}

#include "bits/stdc++.h"
using namespace std;

#define pb push_back
#define mp make_pair
#define fst first
#define snd second

#define fr(i,n)     for(int i=0;i<n;i++)
#define frr(i,n)    for(int i=1;i<=n;i++)

#define ms(x,i) memset(x,i,sizeof(x))
#define dbg(x)  cout << #x << " = " << x << endl
#define all(x)  x.begin(),x.end()

#define gnl cout << endl
#define chapa cout << "oi meu chapa" << endl
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
//cout << setprecision(9)<<fixed;

typedef long long int ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<pii> vii;
typedef pair<ll,ll> pll;

const int INF = 0x3f3f3f3f;
const ll llINF = (long long)(1e18) + 100;
const int MAXN = 100100;
const int MAXM = 1001000;
const ll mod=1e9+7;
const int LMAXN = 25;

int n, m;
bool in[100];
std::vector<string> v, joker;
vii jokerp;
string ranq[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
string suits[4] = {"C", "D", "H", "S"};
string tab[18][18];
std::map<string, bool> esta;

void genstrings(){
	fr( i, 4)
		fr( j, 13) {
			v.pb( ranq[j] + suits[i]);
			esta[ranq[j] + suits[i]] = 0;
		}
}

bool valid(int a, int b, int c, int d){
	if (a <= c and c <= a + 2 and b <= d and d <= b + 2)
		return false;
	if (c <= a and a <= c + 2 and d <= b and b <= d + 2)
		return false;
	return true;
}

bool check_rank(int a, int b) {
	int used_rank[300];
	ms(used_rank, 0);

	fr(i,3)
		fr(j,3) {
			if (used_rank[ tab[i + a][j + b][0] ] == 1)
				return false;
			else
				used_rank[ tab[i + a][j + b][0] ] = 1;
		}
	return true;
}

vii ans;

bool check_valid(){

	fr(i, n - 2)
		fr(j, m - 2)
			if (check_rank( i, j)) {
				fr(a, n - 2)
					fr(b, m - 2)
						if (valid( i, j, a, b) and check_rank( a, b)){
							ans.pb({i + 1, j + 1});
							ans.pb({a + 1, b + 1});
							return true;
						}
			}
	return false;
}

int main(){
	fastio;
	genstrings();
	cin>>n>>m;

	string s;
	fr(i,n) {
		fr(j,m) {
			cin>>s;
			tab[i][j] = s;
			esta[s] = 1;
			if (s == "J1" or s == "J2") {
				joker.pb(s);
				jokerp.pb({i,j});
			}
		}
	}

	if (joker.size() == 2 and joker[0] == "J2"){
		swap(jokerp[0], jokerp[1]);
		swap(joker[0],joker[1]);
	}

	if (!joker.size()) {
		if (check_valid()) {
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
			cout<<"Put the first square to ("<<ans[0].fst<<", "<<ans[0].snd<<")."<<endl;
			cout<<"Put the second square to ("<<ans[1].fst<<", "<<ans[1].snd<<")."<<endl;
			return 0;
		}
		else {
			cout<<"No solution."<<endl;
			return 0;
		}
	}

	if (joker.size() == 1) {
		fr(i,v.size()) {
			if (!esta[v[i]]){
				tab[jokerp[0].fst][jokerp[0].snd] = v[i];
				if (check_valid()) {
					cout<<"Solution exists."<<endl;
					cout<<"Replace "<<joker[0]<<" with "<<v[i]<<"."<<endl;
					cout<<"Put the first square to ("<<ans[0].fst<<", "<<ans[0].snd<<")."<<endl;
					cout<<"Put the second square to ("<<ans[1].fst<<", "<<ans[1].snd<<")."<<endl;
					return 0;
				}
			}
		}
	}
	if (joker.size() == 1) {
		cout<<"No solution."<<endl;
		return 0;
	}

	fr(i,v.size())
		fr(j,v.size())
			if (i != j and !esta[v[i]] and !esta[v[j]]){
				tab[jokerp[0].fst][jokerp[0].snd] = v[i];
				tab[jokerp[1].fst][jokerp[1].snd] = v[j];
				if (check_valid()) {
					cout<<"Solution exists."<<endl;
					cout<<"Replace "<<joker[0]<<" with "<<v[i]<<" and "<<joker[1]<<" with "<<v[j]<<"."<<endl;
					cout<<"Put the first square to ("<<ans[0].fst<<", "<<ans[0].snd<<")."<<endl;
					cout<<"Put the second square to ("<<ans[1].fst<<", "<<ans[1].snd<<")."<<endl;
					return 0;
				}

			}

	cout<<"No solution."<<endl;
	return 0;
}

#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int card[20][20][3];///card阵
bool exits[15][4];///记录已存在的card
pair<int,int>P[2];///记录jokers的位置
pair<int,int>res[2];///记录结果3x3矩阵的位置
vector<pair<int,int> >G;///存储没用到的牌；
char Jo[2][3];
bool flag;///判断是否已找到
int n,m;
int rank_(char *s)
{
    if(s[0]>='2'&&s[0]<='9')
    {
        return s[0]-'0';
    }///rank:2----9转数字
    else
    {
        if(s[0]=='T') return 10;
        if(s[0]=='J'&&s[1]!='1'&&s[1]!='2') return 11;
        if(s[0]=='Q') return 12;
        if(s[0]=='K') return 13;
        if(s[0]=='A') return 1;
        if(s[0]=='J') return 14;
    }///rank:TJQKAJ转数字
}
char rerank(int k)
{
    if(k>=2&&k<=9) return k+'0';
    if(k==1) return 'A';
    if(k==10) return 'T';
    if(k==11) return 'J';
    if(k==12) return 'Q';
    if(k==13) return 'K';
}
int suit(char *s)
{
    if(s[1]=='C') return 0;
    if(s[1]=='D') return 1;
    if(s[1]=='H') return 2;
    if(s[1]=='S') return 3;
    if(s[1]=='1') return 0;
    if(s[1]=='2') return 1;
}///suit:CDHS12转数字
char resuit(int k)
{
    if(k==0) return 'C';
    if(k==1) return 'D';
    if(k==2) return 'H';
    if(k==3) return 'S';
}
bool judge(int x1,int y1)
{
    bool Ju[15];
    memset(Ju,false,sizeof(Ju));
    for(int i=x1; i<x1+3; i++)
        for(int j=y1; j<y1+3; j++)
        {
            if(Ju[card[i][j][0]])
            {
                return false;
            }
            else
            {
                Ju[card[i][j][0]]=true;
            }
        }
    return true;
}
void solve()
{
    //cout<<n<<endl;
    for(int i=1; i+2<=n; i++)
    {
        //cout<<"sd";
        for(int j=1; j+2<=m; j++)
        {
            for(int k=1; k+2<=n; k++)
            {
                for(int e=j+3; e+2<=m; e++)
                {

                    if(judge(i,j)&&judge(k,e))
                    {
                        //cout<<"sd";
                        res[0].first=i,res[0].second=j;
                        res[1].first=k,res[1].second=e;
                        flag=true;
                        break;
                    }
                }
                if(flag) break;
            }
            if(flag)break;
        }
        if(flag) break;
    }
     for(int i=1; i+2<=n; i++)
    {
        //cout<<"sd";
        for(int j=1; j+2<=m; j++)
        {
            for(int k=j+3; k+2<=n; k++)
            {
                for(int e=j; e+2<=m; e++)
                {

                    if(judge(i,j)&&judge(k,e))
                    {
                        //cout<<"sd";
                        res[0].first=i,res[0].second=j;
                        res[1].first=k,res[1].second=e;
                        flag=true;
                        break;
                    }
                }
                if(flag) break;
            }
            if(flag)break;
        }
        if(flag) break;
    }
}
int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        G.clear();
        memset(exits,false,sizeof(exits));
        int Joker=0;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                char op[3];
                scanf("%s",op);
                int r=rank_(op);
                int s=suit(op);
                card[i][j][0]=r;
                card[i][j][1]=s;
                exits[r][s]=true;
                if(r==14)
                {
                    P[Joker].first=i;
                    P[Joker].second=j;
                    Jo[Joker][0]=op[0];
                    Jo[Joker][1]=op[1];
                    Jo[Joker][3]='\0';
                    Joker++;
                }
            }
        }
        for(int i=1; i<=13; i++)
        {
            for(int j=0; j<=3; j++)
            {
                if(!exits[i][j])
                {
                    G.push_back(make_pair(i,j));
                }
            }
        }
        // cout<<Joker<<endl;
        flag=false;
        if(Joker==1)
        {
            int len=G.size();
            for(int i=0; i<len; i++)
            {
                int inx=P[0].first;
                int iny=P[0].second;
                card[inx][iny][0]=G[i].first;
                card[inx][iny][1]=G[i].second;
                solve();
                if(flag) break;
            }
        }
        else if(Joker==2)
        {
            int len=G.size();
            for(int i=0; i<len; i++)
            {
                int inx=P[0].first;
                int iny=P[0].second;
                card[inx][iny][0]=G[i].first;
                card[inx][iny][1]=G[i].second;
                for(int j=0; j<len; j++)
                {
                    if(j!=i)
                    {
                        inx=P[1].first;
                        iny=P[1].second;
                        card[inx][iny][0]=G[j].first;
                        card[inx][iny][1]=G[j].second;
                        solve();
                    }
                    if(flag) break;
                }
                if(flag) break;
            }

        }
        else
        {
            solve();
            //cout<<flag<<endl;
        }
        if(flag)
        {
            if(!Joker)
            {
                printf("Solution exists.\n");
                printf("There are no jokers.\n");
                printf("Put the first square to (%d, %d).\n",res[0].first,res[0].second);
                printf("Put the second square to (%d, %d).\n",res[1].first,res[1].second);
            }
            else if(Joker==1)
            {
                int jx=P[0].first;
                int jy=P[0].second;
                char rank_char=rerank(card[jx][jy][0]);
                char suit_char=resuit(card[jx][jy][1]);
                printf("Solution exists.\n");
                printf("Replace %s with %c%c.\n",Jo[0],rank_char,suit_char);
                printf("Put the first square to (%d, %d).\n",res[0].first,res[0].second);
                printf("Put the second square to (%d, %d).\n",res[1].first,res[1].second);
            }
            else if(Joker==2)
            {
                printf("Solution exists.\n");
                int jx=P[0].first;
                int jy=P[0].second;
                int jx1=P[1].first;
                int jy1=P[1].second;
                char rank_char1=rerank(card[jx][jy][0]);
                char suit_char1=resuit(card[jx][jy][1]);
                char rank_char2=rerank(card[jx1][jy1][0]);
                char suit_char2=resuit(card[jx1][jy1][1]);
                if(Jo[0][1]=='1')
                printf("Replace %s with %c%c and %s with %c%c.\n",Jo[0],rank_char1,suit_char1,Jo[1],rank_char2,suit_char2);
                else
                printf("Replace %s with %c%c and %s with %c%c.\n",Jo[1],rank_char2,suit_char2,Jo[0],rank_char1,suit_char1);
                printf("Put the first square to (%d, %d).\n",res[0].first,res[0].second);
                printf("Put the second square to (%d, %d).\n",res[1].first,res[1].second);
            }

        }
        else
        {
            printf("No solution.\n");
        }
    }
    return 0;
}

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int n,m;
int a[17][17];
bool kol[52];
bool used[17][17];
vector<char> jok1;
vector<int> jok;
map<char,int> d1;
map<char,int> m1;
char d2[13];
char m2[4];

bool check(int x,int y)
{
    bool d[13];
    bool ma[4];
    for(int i=0;i<13;i++)
        d[i]=false;
    for(int j=0;j<4;j++)
        ma[j]=false;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        {
            if(used[x+i][y+j])return false;
            int z=a[x+i][y+j]%4;
            int q=a[x+i][y+j]/4;
            ma[z]=true;
            d[q]=true;
        }
    int c1=0,c2=0;
    for(int i=0;i<13;i++)
        if(d[i])c1++;
    for(int j=0;j<4;j++)
        if(ma[j])c2++;
    return(c1==9||c2==1);

}

bool doit(int deep)
{
    if(deep==jok.size())
    {
        for(int x1=0;x1<n-2;x1++)
            for(int y1=0;y1<m-2;y1++)
            {

                if(check(x1,y1))
                {
                    for(int i=0;i<3;i++)
                        for(int j=0;j<3;j++)
                            used[x1+i][y1+j]=true;
                    for(int x2=x1;x2<n-2;x2++)
                        for(int y2=0;y2<m-2;y2++)
                            if(check(x2,y2))
                            {
                                cout<<"Solution exists."<<endl;
                                if(deep==1)
                                {
                                    int q=jok[0]%4;
                                    int w=jok[0]/4;
                                    cout<<"Replace J"<<jok1[0]<<" with "<<d2[w]<<m2[q]<<"."<<endl;
                                }
                                else
                                    if(deep==2)
                                    {
                                        int q1=jok[0]%4;
                                        int w1=jok[0]/4;
                                        int q2=jok[1]%4;
                                        int w2=jok[1]/4;
                                        if(jok1[0]=='1')
                                            cout<<"Replace J1 with "<<d2[w1]<<m2[q1]<<" and J2 with"<<d2[w2]<<m2[q2]<<"."<<endl;
                                        else
                                            cout<<"Replace J1 with "<<d2[w2]<<m2[q2]<<" and J2 with"<<d2[w1]<<m2[q1]<<"."<<endl;
                                    }
                                    else
                                        cout<<"There are no jokers."<<endl;
                                cout<<"Put the first square to ("<<x1+1<<","<<y1+1<<")"<<endl;
                                cout<<"Put the second square to ("<<x2+1<<","<<y2+1<<")";
                                return true;
                            }
                    for(int i=0;i<3;i++)
                        for(int j=0;j<3;j++)
                            used[x1+i][y1+j]=false;
                }

            }
            return false;
    }
    int x=jok[deep]/20;
    int y=jok[deep]%20;
    for(int i=0;i<52;i++)
    {
        if(kol[i])
        {
            jok[deep]=i;
            a[x][y]=i;
            kol[i]=false;
            if(doit(deep+1))return true;

            kol[i]=true;
        }
    }
    return false;
}

int main()
{

    d2={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
    m2={'C','D','H','S'};
    d1['2']=0;
    d1['3']=1;
    d1['4']=2;
    d1['5']=3;
    d1['6']=4;
    d1['7']=5;
    d1['8']=6;
    d1['9']=7;
    d1['T']=8;
    d1['J']=9;
    d1['Q']=10;
    d1['K']=11;
    d1['A']=12;

    m1['C']=0;
    m1['D']=1;
    m1['H']=2;
    m1['S']=3;

    cin>>n>>m;

    for(int i=0;i<52;i++)
    {
        kol[i]=true;
    }
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            string s;
            cin>>s;
            if(s=="J1"||s=="J2")
            {
                a[i][j]='0'-s[1];
                jok.push_back(i*20+j);
                jok1.push_back(s[1]);
            }
            else
            {
                int x=d1[s[0]],y=m1[s[1]];
                kol[x*4+y]=false;
                a[i][j]=x*4+y;
            }
        }
    /*for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        cout<<d2[a[i][j]/4]<<m2[a[i][j]%4]<<' ';
        cout<<endl;
    }*/
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)used[i][j]=false;
    if(!doit(0))
    {
        cout<<"No solution.";
    }
    return 0;
}

#include <bits/stdc++.h>
typedef long long       ll;
#define PI                acos(-1)
#define pb                push_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
#define fore(i,b,e)		  for(int i=(int)b;i<(int)e;++i)
#define forr(i,b,e)		  for(int i=(int)b;i<(int)e;++i)
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;

typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
const int INF = 1234567890;

string M[20][20];
string ranks = "23456789TJQKA";
string suits = "CDHS";
set<string> cards;

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    for (char c : ranks) {
    	for (char s : suits) {
    		string tmp = "";
    		tmp += c;
    		tmp += s;
    		cards.insert( tmp );
    	}
    }
    ii joker[2] = {{19,19}, {19,19}};
    int n, m;
    cin >> n >> m;
    fore(i, 0, n) {
    	fore(j, 0, m) {
    		cin >> M[i][j];
    		if (M[i][j][1] == '1') {
    			joker[0] = {i,j};
    		}
    		else if (M[i][j][1] == '2') {
    			joker[1] = {i,j};
    		}
    		else {
    			cards.erase(M[i][j]);
    		}
    	}
    }
    vector<string> sobra;
    for (string x : cards) {
    	sobra.pb(x);
    }
    fore(ite1, 0, sobra.size()) {
    	fore(ite2, 0, sobra.size()) {
    		if (ite1 == ite2)
    			break;
    		M[joker[0].F][joker[0].S] = sobra[ite1];
    		M[joker[1].F][joker[1].S] = sobra[ite2];
    		vii posibles;
    		fore(i, 0, n) {
    			fore(j, 0, m) {
    				set<char> rank;
    				fore(k, i, i+3) {
    					fore(l, j, j+3) {
    						if (k >= n || l >= m)
    							break;
    						rank.insert(M[k][l][0]);
    					}
    				}
    				if (rank.size() == 9)
    					posibles.pb({i,j});
    			}
    		}
    		for (ii p1 : posibles) {
    			for (ii p2 : posibles) {
    				if (p1 == p2)
    					continue;
    				if (abs(p1.F - p2.F) >= 3 || abs(p1.S - p2.S) >= 3) {
    					cout << "Solution exists." << '\n';
    					int jokrs = ( joker[0].F < n ) + ( joker[1].F < n );
    					if (jokrs == 0)
    						cout << "There are no jokers." << '\n';
    					else if (jokrs == 1)
    						cout << "Replace J" << (joker[0].F < n ? 1 : 2) << " with " << (joker[0].F < n ? sobra[ite1] : sobra[ite2]) << ".\n";
    					else
    						cout << "Replace J1 with " << sobra[ite1] << " and J2 with " << sobra[ite2] << ".\n";
    					cout << "Put the first square to (" << p1.F+1 << ", " << p1.S+1 << ")." << '\n';
    					cout << "Put the second square to (" << p2.F+1 << ", " << p2.S+1 << ")." << '\n';
    					return 0;
    				}
    			}
    		}
    	}
    }
    cout << "No solution." << '\n';
    return 0;
}
// PLUS ULTRA!

#ifdef _MSC_VER
#pragma warning(disable:4996)  // deprecations
#endif  //  #ifdef _MSC_VER
#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <utility>
#include <sstream>
#include <complex>
#include <limits>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <time.h>
#if defined(_MSC_VER) && !defined(_STLP_LONG_LONG)
namespace std { long long abs(long long x) { return x < 0 ? -x : x; } }
#endif
using namespace std;

////////////////////// Debug Utilities ///////////////////////
void dprintf(char* format, ...) {
  fprintf(stderr, "DEBUG: ");
  va_list argp; va_start(argp, format);
  vfprintf(stderr, format, argp); va_end(argp);
  fprintf(stderr, "\n");
}
struct Exception {
  const char* message;
  const int line;
  Exception(const char* m, int l) : message(m), line(l) {}
};
#define THROW(M) throw Exception(M, __LINE__)
////////////////////// Debug Utilities ///////////////////////

////////////////////// Reading Utilities ///////////////////////
static char stringReader[2097152];
static inline bool ReadLine() {
  char* ptr = fgets(stringReader, sizeof(stringReader), stdin);
  if ( ptr == 0 ) return false;
  int N = strlen(stringReader);
  if ( stringReader[N - 1] == '\n' ) stringReader[N - 1] = 0;
  return true;
}
////////////////////// Reading Utilities ///////////////////////

///////////////////////// Basic Utilities //////////////////////////
#define SIZE(N, V) int N = static_cast<int>((V).size())
#define GSIZE(N, V) (N) = static_cast<int>((V).size())
#define ALL(V) (V).begin(), (V).end()
#define UNIQUE(C) {sort(ALL(C)); C.resize(unique(ALL(C)) - C.begin());}
#define CAST(X, Y) {stringstream ss; ss << (X); ss >> (Y);}
typedef long long i64;
const i64 ooLL = 0x3f3f3f3f3f3f3f3fLL;
const int oo = 0x3f3f3f3f;
const double eps = 1e-9;
///////////////////////// Basic Utilities //////////////////////////

////////////////////////// Solution ///////////////////////////
typedef char card[3];
int rank(card c) {
  if ( c[0] == 'A' ) return 0;
  if ( isdigit(c[0]) ) return c[0] - '1';
  if ( c[0] == 'T' ) return 9;
  if ( c[0] == 'J' ) return 10;
  if ( c[0] == 'Q' ) return 11;
  if ( c[0] == 'K' ) return 12;
  assert(0);
  return -10000;
}
int suit(card c) {
  if ( c[1] == 'H' ) return 0;
  if ( c[1] == 'C' ) return 1;
  if ( c[1] == 'D' ) return 2;
  if ( c[1] == 'S' ) return 3;
  if ( c[1] == '1' || c[1] == '2' ) return 4;
  assert(0);
  return -10000;
}
char const* _suits = "HCDS";
char const* _ranks = "A123456789TJQK";

bool used[13][4];
card cards[60][60];

int n, m;

struct rect {
  set<int> suits, ranks;
  vector<int> jk;
  int i, j;
  rect(set<int> & s, set<int> & r, vector<int>& _jk, int _i, int _j )
    :
  suits(s),
    ranks(r),
    jk(_jk),
    i(_i),
    j(_j) {}
};

bool overlap(rect const& a, rect const& b) {
  int i0 = min(a.i, b.i);
  int i1 = max(a.i, b.i);
  if ( i1 - i0 >= 3 ) return false;
  i0 = min(a.j, b.j);
  i1 = max(a.j, b.j);
  if ( i1 - i0 >= 3 ) return false;
  return true;
}

int main() {
  try {
#ifdef ZYX_MACHINE
    freopen("xxx.in", "rt", stdin);
#endif // #ifdef ZYX_MACHINE

    while ( scanf("%d%d", &n, &m) == 2 ) {
      memset(used, false, sizeof(used));
      vector<pair<int, int> > jokers;
      for ( int i = 0; i < n; ++i ) for ( int j = 0; j < m; ++j ) {
        scanf("%s", cards[i][j]);
        if ( suit(cards[i][j]) == 4 )
          jokers.push_back(make_pair(i, j));
        else
          used[rank(cards[i][j])][suit(cards[i][j])] = true;
      }
      if ( jokers.size() == 2 && strcmp(cards[jokers[0].first][jokers[0].second], "J1") )
        swap(jokers[0], jokers[1]);
      vector<rect> rects;
      for ( int i = 0; i + 3 <= n; ++i ) for ( int j = 0; j + 3 <= m; ++j ) {
        set<int> suits;
        set<int> ranks;
        vector<int> jk;
        for ( int ii = 0; ii < 3; ++ii ) for ( int jj = 0; jj < 3; ++jj ) {
          if ( suit(cards[i + ii][j + jj]) == 4 ) {
            jk.push_back(jokers[0] == make_pair(i + ii, j + jj) ? 0 : 1);
          } else {
            suits.insert(suit(cards[i + ii][j + jj]));
            ranks.insert(rank(cards[i + ii][j + jj]));
          }
        }
        if ( suits.size() == 1 ) {
          rects.push_back(rect(suits, ranks, jk, i, j));
        } else if ( ranks.size() + jk.size() == 9 ) {
          rects.push_back(rect(suits, ranks, jk, i, j));
        }
      }
      bool ok = false;
      SIZE(R, rects);
      vector<pair<int, int> > rep(jokers.size(), make_pair(-1, -1));
      int _i = -1, _j = -1;
      for ( int i = 0; !ok && i < R; ++i ) for ( int j = i + 1; !ok && j < R; ++j ) {
        if ( overlap(rects[i], rects[j]) ) continue;
        set<pair<int, int> > cana;
        set<pair<int, int> > canb;

        if ( rects[i].jk.size() == 2 ) {
          if ( rects[i].suits.size() == 1 ) {
            vector<int> use;
            int ss = *rects[i].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              use.push_back(k);
            if ( use.size() > 1 ) {
              rep[0].first = use[0];
              rep[0].second = ss;
              rep[1].first = use[1];
              rep[1].second = ss;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
          if ( !ok && rects[i].ranks.size() == 7 ) {
            vector<pair<int, int> > use;
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                use.push_back(make_pair(k, ss));
            if ( use.size() > 1 ) {
              rep[0].first = use[0].first;
              rep[0].second = use[0].second;
              rep[1].first = use[1].first;
              rep[1].second = use[1].second;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
        } else if ( rects[i].jk.size() == 1 ) {
          if ( rects[i].suits.size() == 1 ) {
            int ss = *rects[i].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              cana.insert(make_pair(k, ss));
          }
          if ( rects[i].ranks.size() == 8 ) {
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                cana.insert(make_pair(k, ss));
          }
        }

        if ( rects[j].jk.size() == 2 ) {
          if ( rects[j].suits.size() == 1 ) {
            vector<int> use;
            int ss = *rects[j].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              use.push_back(k);
            if ( use.size() > 1 ) {
              rep[0].first = use[0];
              rep[0].second = ss;
              rep[1].first = use[1];
              rep[1].second = ss;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
          if ( !ok && rects[j].ranks.size() == 7 ) {
            vector<pair<int, int> > use;
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                use.push_back(make_pair(k, ss));
            if ( use.size() > 1 ) {
              rep[0].first = use[0].first;
              rep[0].second = use[0].second;
              rep[1].first = use[1].first;
              rep[1].second = use[1].second;
              ok = true;
              _i = i;
              _j = j;
              break;
            }
          }
        } else if ( rects[j].jk.size() == 1 ) {
          if ( rects[j].suits.size() == 1 ) {
            int ss = *rects[j].suits.begin();
            for ( int k = 0; k < 13; ++k ) if ( !used[k][ss] )
              canb.insert(make_pair(k, ss));
          }
          if ( rects[j].ranks.size() == 8 ) {
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                canb.insert(make_pair(k, ss));
          }
        }

        set<pair<int, int> > can;
        can.insert(ALL(cana));
        can.insert(ALL(canb));
        if ( can.size() >= rects[i].jk.size() + rects[j].jk.size() ) {
          if ( cana.size() == 1 ) {
            rep[rects[i].jk[0]] = *cana.begin();
            for ( set<pair<int, int> >::const_iterator it =
              canb.begin(), end = canb.end(); it != end; ++it ) {
                if ( *it == *cana.begin() ) continue;
                rep[rects[j].jk[0]] = *it;
                break;
            }
          } else {
            if ( canb.size() ) rep[rects[j].jk[0]] = *canb.begin();
            for ( set<pair<int, int> >::const_iterator it =
              cana.begin(), end = cana.end(); it != end; ++it ) {
                if ( canb.size() && *it == *canb.begin() ) continue;
                rep[rects[i].jk[0]] = *it;
                break;
            }
          }
          ok = true;
          _i = i;
          _j = j;
          break;
        }
      }
      if ( ok ) {
        vector<int> go;
        if ( jokers.size() && rep[0].first == -1 ) {
          if ( jokers.size() > 1 && rep[1].first == -1 ) {
            go.push_back(0);
            go.push_back(1);
          } else {
            if ( jokers.size() > 1 ) go.push_back(1);
            go.push_back(0);
          }
        } else if ( jokers.size() > 1 && rep[1].first == -1 ) {
            go.push_back(0);
            go.push_back(1);
        }
        for ( vector<int>::const_iterator it = go.begin(), end = go.end(); it != end; ++it ) {
          if ( rep[*it].first == -1 ) {
            for ( int k = 0; k < 13; ++k ) for ( int ss = 0; ss < 4; ++ss )
              if ( !used[k][ss] )
                rep[*it] = make_pair(k, ss);
          }
          used[rep[*it].first][rep[*it].second] = true;
        }
        printf("Solution exists.\n");
        if ( jokers.size() == 0 ) printf("There are no jokers.\n");
        else if ( jokers.size() == 1 ) printf("Replace J1 with %c%c.\n", _ranks[rep[0].first], _suits[rep[0].second]);
        else printf("Replace J1 with %c%c and J2 with %c%c.\n", _ranks[rep[0].first], _suits[rep[0].second], _ranks[rep[1].first], _suits[rep[1].second]);
        printf("Put the first square to (%d, %d).\n", rects[_i].i + 1, rects[_i].j + 1);
        printf("Put the second square to (%d, %d).\n", rects[_j].i +  1, rects[_j].j + 1);
      } else {
        printf("No solution.\n");
      }
    }
    return 0;
  } catch ( const Exception& exception ) {
    fprintf(stderr, "******************************\n");
    fprintf(stderr, "ERROR.%d: %s\n", exception.line, exception.message);
    fprintf(stderr, "******************************\n");
    throw exception;
  }
}
////////////////////////// Solution ///////////////////////////
// BEGIN CUT HERE
//Znippet tag
// END CUT HERE

#include <cstdio>
#include <cassert>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;

#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define for1(i, n) for(int i = 1; i <= int(n); ++i)
#define forv(i, v) forn(i, v.size())
#define pb push_back
#define all(v) v.begin(), v.end()
#define mp make_pair

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;

void require(bool cond, const string& message = "Runtime error")
{
    if (!cond) {
        cerr << message << endl;
        assert(false);
    }
}

void readData()
{
}

const string ORD = "23456789TJQKA";
const string SUIT = "CDHS";

pair<int, int> parse()
{
    string s; cin >> s;
    if (s[0] == 'J') {
        if (s[1] == '1') {
            return mp(-1, -1);
        }
        else {
            return mp(-2, -2);
        }
    }
    return mp(ORD.find(s[0]), SUIT.find(s[1]));
}

pair<int, int> a[100][100];
int n, m;
set<pii> used;
pii first(-1,-1), second(-1,-1);

bool good(int x, int y) {
    set<int> ord;
    set<int> suit;
    forn(i, 3) {
        forn(j, 3) {
            ord.insert(a[x+i][y+j].first);
            suit.insert(a[x+i][y+j].second);
        }
    }
    return (suit.size() == 1 || ord.size() == 9);
}

bool inter(int x1, int y1, int x2, int y2)
{
    if (x1 + 3 <= x2) return false;
    if (x2 + 3 <= x1) return false;
    if (y1 + 3 <= y2) return false;
    if (y2 + 3 <= y1) return false;
    return true;
}

string conv(pii p)
{
    ostringstream os;
    os << ORD[p.first] << SUIT[p.second];
    return os.str();
}

void solveG()
{
    forn(i, n-2) {
        forn(j, m-2) {
            if (!good(i, j)) continue;
            forn(i1, n-2) {
                forn(j1, m-2) {
                    if (inter(i,j,i1,j1)) continue;
                    if (!good(i1,j1)) continue;
                    cout << "Solution exists." << endl;
                    if (first.first == -1 && second.first == -1) {
                        cout << "There are no jokers." << endl;
                    }
                    else if (first.first == -1) {
                        cout << "Replace J2 with " << conv(second) << "." << endl;
                    }
                    else if (second.first == -1) {
                        cout << "Replace J1 with " << conv(first) << "." << endl;
                    }
                    else {
                        cout << "Replace J1 with " << conv(first) << " and J2 with " << conv(second) << "." << endl;
                    }
                    printf("Put the first square to (%d, %d).\n", i+1, j+1);
                    printf("Put the second square to (%d, %d).\n", i1+1, j1+1);
                    exit(0);
                }
            }
        }
    }
}

void solveF()
{
    forn(i, n) {
        forn(j, m) {
            if (a[i][j].first == -2) {
                forv(o, ORD) {
                    forv(s, SUIT) {
                        if (!used.count(mp(o, s)) && mp(o, s) != first) {
                            a[i][j] = mp(o, s);
                            second = mp(o, s);
                            solveG();
                        }
                    }
                }
                cout << "No solution." << endl;
                return;
            }
        }
    }
    solveG();
}

void solve()
{
    cin >> n >> m;
    forn(i, n) {
        forn(j, m) {
            a[i][j] = parse();
            used.insert(a[i][j]);
        }
    }
    forn(i, n) {
        forn(j, m) {
            if (a[i][j].first == -1) {
                forv(o, ORD) {
                    forv(s, SUIT) {
                        if (!used.count(mp(o, s))) {
                            a[i][j] = mp(o, s);
                            first = mp(o, s);
                            solveF();
                        }
                    }
                }
                cout << "No solution." << endl;
                return;
            }
        }
    }
    solveF();
    cout << "No solution." << endl;
}

int main()
{
    ios_base::sync_with_stdio(false);
    readData();
    solve();
    return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>

using namespace std;

typedef vector <string> vs;
typedef vector <int> vi;
#define clr(x) memset((x), 0, sizeof(x))
#define SORT(x) sort(x.begin(),x.end())
#define forn(i, n) for(int i = 0; i< n; i++)
#define all(i, x) for(int i = 0; i< x.size(); i++)
const long double EPS = 1e-11;

class card{
public:
	char color,number;
	card(){}
	card(char c,char n)
	{color = c; number = n;}
	bool friend operator == (const card a,const card b)
	{
		return (a.color == b.color && a.number == b.number);
	}
};
card a[17][17],all[54];
char nn[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' , 'A' };
char cc[4] = { 'C' , 'D' , 'H' ,'S' };
int main()
{
//	freopen("test.txt","r",stdin);
 //   freopen("test.out","w",stdout);
	set<char> color,number;
	int n,m,num = 0;
	card tmp;
	forn(i,13)
		forn(j,4)
		{
			tmp.number = nn[i];
			tmp.color = cc[j];
			all[num++] = tmp;
		}
	card J1('1','J');
	card J2('2','J');
	vector <card> replace,replaced,JVec;
	cin>>n>>m;
	forn(i,n)
		forn(j,m)
			cin>>a[i][j].number>>a[i][j].color;
	int xFirst = -3,yFirst = -3,xSecond = -1,ySecond = -1;
	forn(i,n)
	{
		if(xSecond > 0)
			break;
		forn(j,m)
		{
			JVec.clear();
			color.clear();
			number.clear();
			if(xSecond > 0)
				break;
			if(i + 2 < n && j + 2 < m && (i >= xFirst + 3 || j >= yFirst + 3) )
			{
				forn(r,3)
					forn(c,3)
					{
						if(a[i+r][j+c] == J1 || a[i+r][j+c] == J2)
							JVec.push_back(a[i+r][j+c]);
						else
						{
							color.insert(a[i+r][j+c].color);
							number.insert(a[i+r][j+c].number);
						}
					}
				if(JVec.empty())
				{
					if(color.size() == 1 || number.size() == 9)
					{
						if(xFirst == -3)
						{
							xFirst = i;
							yFirst = j;
						}
						else
						{
							xSecond = i;
							ySecond = j;
						}
					}
				}
				else
				{
					if(color.size() == 1 || number.size() == 9 - JVec.size())
					{
						int Jnum = JVec.size();
						for(int k = 0; k < 52 && !JVec.empty(); k++)
						{
							if((color.size() == 1 && color.count(all[k].color) == 1)
								||(number.size() == 9 - Jnum && number.count(all[k].number) == 0))
							{
								int used = 0;
								for(int r = 0; r < n && !JVec.empty(); r++)
									for(int c = 0; c < m && !JVec.empty(); c++)
									{
										if((all[k] == a[r][c]))
											used = 1;
									}
								if(used == 0)
								{
									replace.push_back(all[k]);
									replaced.push_back(JVec.back());
									JVec.pop_back();
									if(JVec.size() == 0)
									{
										if(xFirst == -3)
										{
											xFirst = i;
											yFirst = j;
										}
										else
										{
											xSecond = i;
											ySecond = j;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	if(xSecond > 0)
	{
		cout<<"Solution exists."<<endl;
		if(replaced.empty())
			cout<<"There are no jokers."<<endl;
		else
		{
			if(replaced.size() == 2)
			{
				if(replaced[0].color == '1')
				{
					cout<<"Replace J1 with ";
					cout<<replace[0].number<<replace[0].color<<" and J2 with ";
					cout<<replace[1].number<<replace[1].color<<"."<<endl;
				}
				else
				{
					cout<<"Replace J1 with ";
					cout<<replace[1].number<<replace[1].color<<" and J2 with ";
					cout<<replace[0].number<<replace[0].color<<"."<<endl;
				}
			}
			else if(replaced.size() == 1)
			{
				cout<<"Replace J"<<replaced[0].color<<" with ";
				cout<<replace[0].number<<replace[0].color<<"."<<endl;
			}
		}
		cout<<"Put the first square to ("<<xFirst+1<<", "<<yFirst+1<<")."<<endl;
		cout<<"Put the second square to ("<<xSecond+1<<", "<<ySecond+1<<")."<<endl;
	}
	else
		cout<<"No solution."<<endl;
	return 0;
}

#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <cmath>
using namespace std;
int n,m;
vector<vector<pair<char, char>>> desk;

struct joker{
	int i;
	int j;
	joker(){
		i = -1;
		j = -1;
	}
};
struct sqrNormal{
	int i;
	int j;
	sqrNormal(){
		i = -1;
		j = -1;
	}
};
sqrNormal sqr1, sqr2;

vector<pair<char, char>> genCards(){
	vector<pair<char, char>> cards;
	char mastChar[] = {'C','D','H','S'};
	vector<char> mast(mastChar, mastChar + sizeof(mastChar) / sizeof(char) );
	char numberChar[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
	vector<char> number(numberChar, numberChar + sizeof(numberChar) / sizeof(char) );

	for (int i = 0; i < mast.size(); i++){
		for (int j = 0; j < number.size(); j++){
			cards.push_back(make_pair(number[j],mast[i]));
		}
	}
 	return cards;
}

vector<pair<char, char>> findFreeCards(vector<pair<char, char>> cards){
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			if (desk[i][j] == make_pair('J','1') || desk[i][j] == make_pair('J','2'))
				continue;
			cards.erase(find(cards.begin(), cards.end(),desk[i][j]));
		}
	}
	return cards;
}

void findJoker(joker &j1, joker &j2){
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			if (desk[i][j] == make_pair('J','1') ){
				j1.i = i; j1.j = j;
			}
			if (desk[i][j] == make_pair('J','2')){
				j2.i = i; j2.j = j;
			}
		}
	}
}

bool isNormalSqrMast(int x, int y){
	if (x+3 > n || y+3 > m)
		return false;
	char mast = desk[x][y].second;
	bool flag = true;
	for (int i = x; i < x+3; i++){
		for (int j = y; j < y+3; j++){
			if (!(mast == desk[i][j].second)){
				flag = false;
				break;
			}
		}
		if (!flag)
			break;
	}
	return flag;
}
bool isNormalSqrNumber(int x, int y){
	//cout << x << " " << y ;
	if (x+3 > n || y+3 > m)
		return false;
	//cout<< " uu"<< endl;
	char numberChar[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
	vector<char> number(numberChar, numberChar + sizeof(numberChar) / sizeof(char) );

	for (int i = x; i < x+3; i++){
		for (int j = y; j < y+3; j++){
			if (find(number.begin(), number.end(),desk[i][j].first) != number.end())
				number.erase(find(number.begin(), number.end(),desk[i][j].first));
			else
				return false;
		}
	}
	return true;
}
bool isNormalDesk(){

	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			if (isNormalSqrMast(i,j) || isNormalSqrNumber(i,j)){
				for (int ii = 0; ii < n; ii++){
					for (int jj = 0; jj < m; jj++){
						if (ii == i && jj== j)
							continue;
						//cout << i << " " << ii << " " ;
						//cout << j << " " << jj << " " ;
						//cout << endl;
						if (abs(i - ii) < 2 && abs(j - jj) < 2)
							continue;
						//cout << " " <<endl;
						if(isNormalSqrMast(ii,jj) || isNormalSqrNumber(ii,jj)){
							sqr1.i = i;sqr1.j = j;
							sqr2.i = ii;sqr2.j = jj;
							return true;
						}
					}
				}
			}
		}
	}
	return false;
}
int main(){
	//freopen("input.txt", "r", stdin);
	cin >> n >> m;
	for (int i = 0; i < n; i++){
		vector<pair<char,char>> stroka;
		for (int j = 0; j < m; j++){
			char mast,number;
			cin >> mast >> number;
			stroka.push_back(make_pair(mast, number));
		}
		desk.push_back(stroka);
	}
	vector<pair<char, char>> cards = genCards();
	vector<pair<char, char>> freeCards = findFreeCards(cards);

	joker j1, j2;
	findJoker(j1,j2);

	char numberjoker1;
	char numberjoker2;
	if (j1.i !=-1 && j1.j != -1)
		numberjoker1 = desk[j1.i][j1.j].second;
	if (j2.i !=-1 && j2.j != -1)
		numberjoker2 = desk[j2.i][j2.j].second;

	for (int i = 0; i < freeCards.size(); i++){
		if (j1.i !=-1 && j1.j != -1){
				desk[j1.i][j1.j] = freeCards[i];
		}
		for (int j = 0; j < freeCards.size(); j++){
			if (i == j)
				continue;
			if (j2.i !=-1 && j2.j != -1){
				desk[j2.i][j2.j] = freeCards[j];
			}
			if (isNormalDesk()){
				cout << "Solution exists." << endl;
				if (j1.i == -1 && j1.j == -1 && j2.i == -1 && j2.j == -1)
					cout << "There are no jokers." <<endl;
				else if (j2.i == -1 && j2.j == -1)
					cout << "Replace J" << numberjoker1 << " with " << freeCards[i].first << freeCards[i].second << "." << endl;
				else if (j1.i == -1 && j1.j == -1)
					cout << "Replace J" << numberjoker2 << " with " << freeCards[j].first << freeCards[j].second << "." << endl;
				else {
					cout << "Replace J1" ;
					if ( numberjoker1 == '1')
						cout << " 1with " << freeCards[i].first << freeCards[i].second << " and J2 with " << freeCards[j].first << freeCards[j].second << "." << endl;
					else
						cout << " with " << freeCards[j].first << freeCards[j].second << " and J2 with " << freeCards[i].first << freeCards[i].second << "." << endl;
				}
				cout << "Put the first square to (" <<  sqr1.i + 1 << ", " << sqr1.j + 1 << ")." << endl;
				cout << "Put the second square to (" <<  sqr2.i + 1 << ", " << sqr2.j + 1 << ")." << endl;
				return 0;
			}
		}
	}
	cout << "No solution." << endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

map <char,int> rankktono;
map <int,char> notorankk;
map <char,int> suittono;
map <int,char> notosuit;
void init(){

    suittono['C']=0;
    suittono['D']=1;
    suittono['H']=2;
    suittono['S']=3;

    notosuit[0]='C';
    notosuit[1]='D';
    notosuit[2]='H';
    notosuit[3]='S';

    rankktono['0']=0;
    rankktono['1']=1;
    rankktono['2']=2;
    rankktono['3']=3;
    rankktono['4']=4;
    rankktono['5']=5;
    rankktono['6']=6;
    rankktono['7']=7;
    rankktono['8']=8;
    rankktono['9']=9;
    rankktono['T']=10;
    rankktono['J']=11;
    rankktono['Q']=12;
    rankktono['K']=13;
    rankktono['A']=14;

    notorankk[0]='0';
    notorankk[1]='1';
    notorankk[2]='2';
    notorankk[3]='3';
    notorankk[4]='4';
    notorankk[5]='5';
    notorankk[6]='6';
    notorankk[7]='7';
    notorankk[8]='8';
    notorankk[9]='9';
    notorankk[10]='T';
    notorankk[11]='J';
    notorankk[12]='Q';
    notorankk[13]='K';
    notorankk[14]='A';
}

char rankk[500][500];
char suit[500][500];

bool vis[500][500];

int main()
{
    // cout << "Hello World!" << endl;
    ios::sync_with_stdio(false);
    init();

    vector <pair <int,int> > position;
    vector <pair <char,char> > rankknsuit;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>rankk[i][j]>>suit[i][j];
            if(rankk[i][j]=='J'){
                position.push_back(make_pair(i,j));
                rankknsuit.push_back(make_pair(rankk[i][j],suit[i][j]));
            }
        }
    }
    int cnt=position.size();

    if(cnt==0){
        // cout<<"Nigga\n";
        vector <pair <int,int> > poss;

        for(int i=1;i<=n-3+1;i++){
            for(int j=1;j<=m-3+1;j++){
                // cout<<i<<" ,, "<<j<<"\n";
                bool samesuit=true,diffrankk=true;
                for(int k=0;k<3;k++){
                    for(int l=0;l<3;l++){
                        for(int m=0;m<3;m++){
                            for(int nn=0;nn<3;nn++){
                                if(k!=m||l!=nn){
                                    if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                        diffrankk=false;
                                    }
                                    if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                        samesuit=false;
                                        // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                    }
                                    // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                    // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                }
                            }
                        }
                    }
                }
                // cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                if((samesuit|diffrankk)){
                    // cout<<i<<" ::: "<<j<<"@@@@\n";
                    poss.push_back(make_pair(i,j));
                }
            }
        }

        if(poss.size()==0){
            cout<<"No solution\n";
        }
        else{
            for(int i=0;i<poss.size();i++){
                for(int j=0;j<poss.size();j++){
                    if(i!=j){
                        int x1,y1,x2,y2;
                        x1=poss[i].first;
                        y1=poss[i].second;
                        x2=poss[j].first;
                        y2=poss[j].second;
//                        if(1){
                         if(!(x1>=x2&&y1>=y2)){
                            cout<<"Solution exists.\nThere are no jokers.\n";
                            cout<<"Move the first square to ("<<x1<<", "<<y1<<").\n";
                            cout<<"Move the second square to ("<<x2<<", "<<y2<<").\n";
                            return 0;
                        }
                    }

                }
            }

            cout<<"No solution.\n";
        }

    }
    else{
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(rankk[i][j]=='J'){

                }
                else{
                    vis[suittono[suit[i][j]]][rankktono[rankk[i][j]]]=true;

                }
            }
        }

        vector <pair <char,char> > boka14;

        for(int i=0;i<=3;i++){
            for(int j=0;j<=14;j++){
                char cursuit,currankk;
                cursuit=notosuit[i];
                currankk=notorankk[j];
                if(vis[i][j]==false){
                    boka14.push_back(make_pair(cursuit,currankk));
                    // cout<<cursuit<<" : "<<currankk<<"\n";
                }
            }
        }

        if(position.size()==1){
            for(auto boka : boka14){
                vector <pair <int,int> > poss;
                suit[position[0].first][position[0].second]=boka.first;
                rankk[position[0].first][position[0].second]=boka.second;
                for(int i=1;i<=n-3+1;i++){
                for(int j=1;j<=m-3+1;j++){
                    // cout<<i<<" ,, "<<j<<"\n";
                    bool samesuit=true,diffrankk=true;
                    for(int k=0;k<3;k++){
                        for(int l=0;l<3;l++){
                            for(int m=0;m<3;m++){
                                for(int nn=0;nn<3;nn++){
                                    if(k!=m||l!=nn){
                                        if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                            diffrankk=false;
                                        }
                                        if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                            samesuit=false;
                                            // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                        }                                            // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                            // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                    }
                                }
                            }
                        }
                    }
                    // cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                    if((samesuit|diffrankk)){
                        // cout<<i<<" ::: "<<j<<"@@@@\n";
                        poss.push_back(make_pair(i,j));
                    }
                }
            }

                for(int i=0;i<poss.size();i++){
                    for(int j=0;j<poss.size();j++){
                        if(i!=j){
                            int x1,y1,x2,y2;
                            x1=poss[i].first;
                            y1=poss[i].second;
                            x2=poss[j].first;
                            y2=poss[j].second;
//                            if(1){
                             if(!(x1>=x2&&y1>=y2)){
                                cout<<"Solution exists.\nReplace "<<rankknsuit[0].first<<rankknsuit[0].second<<" with "<<boka.second<<boka.first<<".\n";
                                cout<<"Move the first square to ("<<x1<<", "<<y1<<").\n";
                                cout<<"Move the second square to ("<<x2<<", "<<y2<<").\n";
                                return 0;
                            }
                        }

                    }
                }

            }
            cout<<"No solution\n";
            return 0;
        }
        else{
            for(auto boka : boka14){
            for(auto choda : boka14){
            if(!(boka.first==choda.first&&boka.second==choda.second)){
                vector <pair <int,int> > poss;
                suit[position[0].first][position[0].second]=boka.first;
                rankk[position[0].first][position[0].second]=boka.second;
                suit[position[1].first][position[1].second]=choda.first;
                rankk[position[1].first][position[1].second]=choda.second;
                for(int i=1;i<=n-3+1;i++){
                for(int j=1;j<=m-3+1;j++){
                    // cout<<i<<" ,, "<<j<<"\n";
                    bool samesuit=true,diffrankk=true;
                    for(int k=0;k<3;k++){
                        for(int l=0;l<3;l++){
                            for(int m=0;m<3;m++){
                                for(int nn=0;nn<3;nn++){
                                    if(k!=m||l!=nn){
                                        if(rankk[i+k][j+l]==rankk[i+m][j+nn]){
                                            diffrankk=false;
                                        }
                                        if(suit[i+k][j+l]!=suit[i+m][j+nn]){
                                            samesuit=false;
                                            // cout<<suit[i+k][j+l]<<" ,, "<<suit[i+m][j+nn]<<"\n";
                                        }                                            // cout<<"("<<i+k<<" , "<<j+l<<") , ("<<i+m<<" , "<<j+nn<<") \n";
                                            // cout<<rankk[i+k][j+l]<<" :::: "<<rankk[i+m][j+nn]<<"\n";
                                    }
                                }
                            }
                        }
                    }
                    //  cout<<i<<" : "<<j<<" ,,,, "<<samesuit<<" : : : : "<<diffrankk<<"\n";

                    if((samesuit|diffrankk)){
                        // cout<<i<<" ::: "<<j<<"@@@@\n";
                        poss.push_back(make_pair(i,j));
                    }
                }
            }

                for(int i=0;i<poss.size();i++){
                    for(int j=0;j<poss.size();j++){
                        if(i!=j){
                            int x1,y1,x2,y2;
                            x1=poss[i].first;
                            y1=poss[i].second;
                            x2=poss[j].first;
                            y2=poss[j].second;
//                            if(1){
                             if(!(x1>=x2&&y1>=y2)){
                                cout<<"Solution exists.\nReplace "<<rankknsuit[0].first<<rankknsuit[0].second<<" with "<<boka.second<<boka.first<<" and ";
                                cout<<rankknsuit[1].first<<rankknsuit[1].second<<" with "<<choda.second<<choda.first<<".\n";
                                cout<<"Move the first square to ("<<x1<<", "<<y1<<").\n";
                                cout<<"Move the second square to ("<<x2<<", "<<y2<<").\n";
                                return 0;
                            }
                        }

                    }
                }

            }

            }

            }
            cout<<"No solution\n";
            return 0;
        }

    }

    return 0;
}

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;
int n,m;
string s[70][70];
vector <string> ve;
map <string,int> ma;
int larara;
int klj[80][80];
int fla[10000];
int kla=0;
vector <pair<int,int> > votv;
int cnt[80][80];
int main() {
    string s1="23456789TJQKA";
    string s2="CDHS";
    int n,m;
    cin>>n>>m;
    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;
            ma[s3]=1;
        }
    int kljok=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            cin>>s[i][j];
            ma[s[i][j]]=0;
            if(s[i][j]=="J1" || s[i][j]=="J2") kljok++;
            if (s[i][j]=="J1") larara=1;
        }

    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;

            if (ma[s3]==1) ve.push_back(s3);

        }
    for (int i=0; i<n-2; i++)
        for (int j=0; j<m-2; j++) {
            map<char,int> mra;
            int f1=0,f2=0;
            int kj=0;
            for (int i1=0; i1<3; i1++)
                for (int j1=0; j1<3; j1++) {
                    if (s[i+i1][j+j1]!="J1" && s[i+i1][j+j1]!="J2") {
                        if (mra[s[i+i1][j+j1][0]]==0)
                            mra[s[i+i1][j+j1][0]]++;
                        else f1=1;
                        if (mra[s[i+i1][j+j1][1]]==0) {
                            mra[s[i+i1][j+j1][1]]=1;
                            f2++;
                        }

                    } else if (s[i+i1][j+j1]=="J1")kj++;
                    else if (s[i+i1][j+j1]=="J2") kj+=2;
                }
            //cout<<i<<' '<<j<<' '<<f1<<' '<<f2<<' '<<kj<<endl;
            klj[i][j]=kj;
            if (f1==0 || f2==1) {
                votv.push_back(make_pair(i,j));
            }
        }
        for (int i=0;i<votv.size();i++)
    if (votv.size()<2) {
        cout<<"No solution.";
        return 0;
    }
    string jock1="",jock2="";
    int nom1=-1,nom2=-1;

    for(int i=0; i<votv.size(); i++){if (nom1!=-1 && nom2!=-1) break;jock1="";jock2="";
        for (int j=i+1; j<votv.size(); j++) {
                if (nom1!=-1 && nom2!=-1) break;
            jock1="",jock2="";
            for (int ra=0;ra<ve.size();ra++)
                fla[i]=0;

            nom1=-1;nom2=-1;
            int x=votv[i].first;
            int y=votv[i].second;
            int x1=votv[j].first;
            int y1=votv[j].second;
            if (abs(x-x1)>2 || abs(y-y1)>2) {
                if (klj[x][y]==0 && klj[x1][y1]==0) {
                    nom1=i;
                    nom2=j;int lar=1;
                    for (int l=0;l<ve.size();l++)
                    if (lar==1) {jock1=ve[l];lar++;}
                    else if (kljok==1) break;
                    else {jock2=ve[l];break;}
                    break;
                }
                if (klj[x][y]!=0 && klj[x][y]!=3) {
                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if (s[x+i1][y+j1]!="J1" && s[x+i1][y+j1]!="J2") {
                                if (mra[s[x+i1][y+j1][0]]==0)
                                    mra[s[x+i1][y+j1][0]]++;
                                else f1=1;
                                if (mra[s[x+i1][y+j1][1]]==0) {
                                    mra[s[x+i1][y+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) { char r;
                        if (s[x][y]!="J1" && s[x][y]!="J2")
                            r=s[x][y][1];
                        else if (s[x][y+1]!="J1" && s[x][y]!="J2")
                             r=s[x][y+1][1];
                        else  r=s[x+1][y][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r && fla[l]==0) {
                                jock1=ve[l];fla[l]=1;
                                break;
                            }
                    }
                    if (f1==0) {
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0 && fla[l]==0) {
                                jock1=ve[l];fla[l]=1;
                                break;
                            }

                    }
                }
                if (klj[x1][y1]!=0  && klj[x1][y1]!=3) {
                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if (s[x1+i1][y1+j1]!="J1" && s[x1+i1][y1+j1]!="J2") {

                                if (mra[s[x1+i1][y1+j1][0]]==0)
                                    mra[s[x1+i1][y1+j1][0]]++;
                                else f1=1;
                                if (mra[s[x1+i1][y1+j1][1]]==0) {
                                    mra[s[x1+i1][y1+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        if (s[x1][y1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1][1];
                        else if (s[x1][y1+1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1+1][1];
                        else r=s[x1+1][y1][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r && fla[l]==0) {
                                jock2=ve[l];fla[l]=1;
                                break;
                            }
                    }
                    if (f1==0) {
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0 && fla[l]==0) {
                                jock2=ve[l];fla[l]=1;if (i==0 && j==3)
                                break;
                            }
                    }
                }
                if (klj[x][y]==3) {

                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if(s[x+i1][y+y1]!="J1" && s[x+i1][y+j1]!="J2") {
                                if (mra[s[x+i1][y+j1][0]]==0)
                                    mra[s[x+i1][y+j1][0]]++;
                                else f1=1;
                                if (mra[s[x+i1][y+j1][1]]==0) {
                                    mra[s[x+i1][y+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        int lrr=1;
                        if (s[x][y]!="J1" && s[x][y]!="J2")
                             r=s[x][y][1];
                        else if (s[x][y+1]!="J1" && s[x][y]!="J2")
                             r=s[x][y+1][1];
                        else  r=s[x+1][y][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                } else {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                    if (f1==0) {
                        int lrr=1;
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                    mra[ve[l][0]]=1;
                                } else  {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                }
                if (klj[x1][y1]==3) {

                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++)

                        {
                            if (s[x1+i1][y1+j1]!="J1" && s[x1+i1][y1+j1]!="J2") {
                                if (mra[s[x1+i1][y1+j1][0]]==0)
                                    mra[s[x1+i1][y1+j1][0]]++;
                                else f1=1;
                                if (mra[s[x1+i1][y1+j1][1]]==0) {
                                    mra[s[x1+i1][y1+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        int lrr=1;
                        if (s[x1][y1]!="J1" && s[x1][y1]!="J2")
                            r=s[x1][y1][1];
                        else if (s[x1][y1+1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1+1][1];
                        else r=s[x1+1][y1][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                } else {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                    if (f1==0) {
                        int lrr=1;
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                    mra[ve[l][0]]=1;
                                } else  {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                }

if (kljok==2 && jock1!="" && jock2!="") {
                    nom1=i;
                    nom2=j;
                    break;
                } else if (kljok==1 && ((jock1!="") || jock2!="")) {
                    nom1=i;
                    nom2=j;
                    break;
                } else if (kljok==0) {
                    nom1=i;
                    nom2=j;
                    break;
                }
                else if ((jock1!="" && klj[x1][y1]==0) || (jock2!="" && klj[x][y]==0))
                {
                    nom1=i;nom2=j;
                    for (int l=0;l<ve.size();l++)
                    if (fla[l]==0) {if (jock1=="")jock1=ve[l];
                    else jock2=ve[l];fla[l]=1;break;}break;}
                }
            }

        }
    if (nom1==-1 || nom2==-1) {
        cout<<"No solution.";
        return 0;
    }
    cout<<"Solution exists."<<endl;
    if (kljok==0) {
        cout<<"There are no jokers."<<endl;
    }
    if (kljok==1) {
        if (jock1=="") {
            string sr="";
            if (klj[votv[nom2].first][votv[nom2].second]==1) sr="J1";
            else sr="J2";if (kljok==1 && larara==1) sr="J1";else sr="J2";
            cout<<"Replace "<<sr<<" with "<<jock2<<'.'<<endl;
        } else  {
            string sr="";
            if (klj[votv[nom1].first][votv[nom1].second]==1) sr="J1";
            else sr="J2";if (kljok==1 && larara==1) sr="J1";else sr="J2";
            cout<<"Replace "<<sr<<" with "<<jock1<<'.'<<endl;
        }
    }string sr;string srr;
    if (kljok==2) {if (klj[votv[nom1].first][votv[nom1].second]==1) sr="J1";
    else if (klj[votv[nom2].first][votv[nom2].second]==1) sr="J2";else sr="J1";if (sr=="J2") srr="J1";
    else srr="J2";
    if (sr=="J1")
        cout<<"Replace "<<sr<<" with "<<jock1<<" and "<<srr<<" with "<<jock2<<'.'<<endl;
        else cout<<"Replace "<<srr<<" with "<<jock2<<" and "<<sr<<" with "<<jock1<<'.'<<endl;

        }
    cout<<"Put the first square to ("<<votv[nom1].first+1<<", "<<votv[nom1].second+1<<")."<<endl;
    cout<<"Put the second square to ("<<votv[nom2].first+1<<", "<<votv[nom2].second+1<<")."<<endl;

}

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define f first
#define s second
#define mp make_pair
using namespace std;

int n, m;
string crank = "A23456789TJQK";
string suit = "CDHS";
vector<vector<bool> > inDeck(13, vector<bool>(4, true));
vector<int> crankCount(13, 4);
vector<vector<string> > card;

pair<int, int> cardData(string card) {
	if(card[0] == 'J' && card[1] >= '1' && card[1] <= '2')
		return mp(-1, card[1] - '1');
	return mp(crank.find(card[0]), suit.find(card[1]));
}

bool validArea(int y, int x) {
	int jcount = 0;
	vector<bool> used(13, false);

	for(int dy = 0; dy < 3; dy++)
		for(int dx = 0; dx < 3; dx++) {
			int cy = y + dy;
			int cx = x + dx;

			auto data = cardData(card[cy][cx]);
			if(data.f == -1)
				jcount++;
			else {
				if(used[data.f])
					return false;
				used[data.f] = true;
			}

		}

	for(int i=0;i<13 && jcount > 0; i++)
		if(!used[i] && crankCount[i] > 0)
			jcount--;
	return jcount == 0;
}

//------------------------------------------------------
//placement function

vector<pair<int, int> > jreplace(2);

void place(int y, int x) {
	vector<bool> used(13, false);
	vector<int> jokers;

	for(int dy = 0; dy < 3; dy++)
		for(int dx = 0; dx < 3; dx++) {
			int cy = y + dy, cx = x + dx;

			auto data = cardData(card[cy][cx]);
			if(data.f == -1)
				jokers.push_back(data.s);
			else
				used[data.f] = true;
		}

	for(int i=0;i<13;i++)
		if(!used[i])
			for(int j=0;j<4;j++)
				if(inDeck[i][j] && jokers.size() > 0) {
					jreplace[jokers.back()] = mp(i, j);
					jokers.pop_back();
				}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	card.resize(n, vector<string>(m));
	vector<int> jokers;

	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++) {
			cin >> card[i][j];

			auto data = cardData(card[i][j]);
			if(data.f != -1) {
				inDeck[data.f][data.s] = false;
				crankCount[data.f]--;
			}
			else
				jokers.push_back(data.s);
		}

	vector<vector<bool> > valid(n, vector<bool>(m, false) );
	for(int i=0;i+3 <= n; i++)
		for(int j=0;j+3<=m;j++)
			valid[i][j] = validArea(i, j);

	for(int y1 = 0; y1+3 <= n; y1++)
		for(int x1 = 0; x1+3 <= m; x1++)
			for(int y2 = 0; y2+3 <= n; y2++)
				for(int x2 = 0; x2+3 <= m; x2++) if(valid[y1][x1] && valid[y2][x2])
					if(y2+3 <= y1 || y1+3 <= y2 || x1+3 <= x2 || x2+3 <= x1) {
						place(y1, x1);
						place(y2, x2);

						cout << "Solution exists.\n";

						if(jokers.size() == 1) {
							auto card = jreplace[jokers[0]];
							cout << "Replace J" << jokers[0] + 1 << " with " << crank[card.f] << suit[card.s] << ".\n";
						}
						else if(jokers.size() == 2) {
							auto card1=  jreplace[0];
							auto card2 = jreplace[1];

							cout << "Replace J1 with " << crank[card1.f] << suit[card1.s];
							cout << " and J2 with " << crank[card2.f] << suit[card2.s] << ".\n";
						}
						else
							cout << "There are no jokers.\n";

						cout << "Put the first square to (" << y1+1 << ", " << x1+1 << ").\n";
						cout << "Put the second square to (" << y2+1 << ", " << x2+1 << ").\n";

						return 0;
					}

	cout << "No solution.\n";
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 18;
string grid[N][N];

int n, m;

bool isGood(int i, int j)
{
	if (i + 2 > n || j + 2 > m) return 0;

	set<char> a, b;

	for (int x = i; x <= i + 2; ++x)
	{
		for (int y = j; y <= j + 2; ++y)
		{
			a.insert(grid[x][y][0]);
			b.insert(grid[x][y][1]);
		}
	}

	return (a.size() == 9) || (b.size() == 1);
}

bool flag;

pair< pair<int, int>, pair<int, int> > solve()
{
	vector< pair<int, int> > sq;

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			if (isGood(i, j))
			{
				sq.push_back(make_pair(i, j));
			}
		}
	}

	int k = (int) sq.size();

	for (int i = 0; i < k; ++i)
	{
		for (int j = i + 1; j < k; ++j)
		{
			const pair<int, int> &a = sq[i];
			const pair<int, int> &b = sq[j];

			int x1 = a.first, y1 = a.second;
			int x2 = b.first, y2 = b.second;

			if (x1 > x2 + 2 || y1 > y2 + 2 || x2 > x1 + 2 || y2 > y1 + 2)
			{
				flag = true;
				return make_pair(a, b);
			}
		}
	}

	return make_pair(make_pair(-1, -1), make_pair(-1, -1));
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	cin >> n >> m;

	vector< pair<string, pair<int, int>> > jokers;
	jokers.reserve(2);

	char ranks[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
	char suits[4] = { 'C', 'D', 'D', 'S' };

	set<string> rem;

	for (int i = 0; i < 13; i++)
	{
		for (int j = 0; j < 4; ++j)
		{
			string cur = "";
			cur += ranks[i];
			cur += suits[j];
			rem.insert(cur);
		}
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; ++j)
		{
			cin >> grid[i][j];

			if (grid[i][j][0] == 'J')
			{
				jokers.emplace_back(make_pair(grid[i][j], make_pair(i, j)));
			}
			else
			{
				auto it = rem.find(grid[i][j]);
				if (it != rem.end()) rem.erase(it);
			}
		}
	}

	sort(jokers.begin(), jokers.end());

	if (jokers.size() == 0)
	{
		pair< pair<int, int>, pair<int, int> > ans = solve();

		if (flag)
		{
			cout << "Solution exists.\nThere are no jokers.\n";
			cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
			cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
			return 0;
		}
	}
	else if (jokers.size() == 1)
	{
		for (const auto& cur : rem)
		{
			grid[jokers[0].second.first][jokers[0].second.second] = cur;
			pair< pair<int, int>, pair<int, int> > ans = solve();

			if (flag)
			{
				cout << "Solution exists.\n";
				cout << "Replace " << jokers[0].first << " with " << cur << ".\n";
				cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
				cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
				return 0;
			}
		}
	}
	else
	{
		vector< string > v(rem.begin(), rem.end());
		for (int i = 0; i < (int) v.size(); i++)
		{
			for (int j = i + 1; j < (int) v.size(); ++j)
			{
				grid[jokers[0].second.first][jokers[0].second.second] = v[i];
				grid[jokers[1].second.first][jokers[1].second.second] = v[j];
				pair< pair<int, int>, pair<int, int> > ans1 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace " << jokers[0].first << " with " << v[i] <<
						" and " << jokers[1].first << " with " << v[j] << ".\n";
					cout << "Put the first square to (" << ans1.first.first << ", " << ans1.first.second << ").\n";
					cout << "Put the second square to (" << ans1.second.first << ", " << ans1.second.second << ").\n";
					return 0;
				}

				grid[jokers[0].second.first][jokers[0].second.second] = v[j];
				grid[jokers[1].second.first][jokers[1].second.second] = v[i];
				pair< pair<int, int>, pair<int, int> > ans2 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace " << jokers[0].first << " with " << v[j] <<
						" and " << jokers[1].first << " with " << v[i] << ".\n";
					cout << "Put the first square to (" << ans2.first.first << ", " << ans2.first.second << ").\n";
					cout << "Put the second square to (" << ans2.second.first << ", " << ans2.second.second << ").\n";
					return 0;
				}
			}
		}
	}
	cout << "No solution.\n";
}

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;
int n,m;
string s[70][70];
vector <string> ve;
map <string,int> ma;
int klj[80][80];
int kla=0;
vector <pair<int,int> > votv;
int cnt[80][80];
int main() {
    string s1="23456789TJQKA";
    string s2="CDHS";
    int n,m;
    cin>>n>>m;
    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;
            ma[s3]=1;
        }int kljok=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            cin>>s[i][j];
            ma[s[i][j]]=0;
            if(s[i][j]=="J1" || s[i][j]=="J2") kljok++;
        }

    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;

            if (ma[s3]==1) ve.push_back(s3);

        }
    for (int i=0; i<n-2; i++)
        for (int j=0; j<m-2; j++) {
            map<char,int> mra;
            int f1=0,f2=0;
            int kj=0;
            for (int i1=0; i1<3; i1++)
                for (int j1=0; j1<3; j1++) {
                    if (s[i+i1][j+j1]!="J1" && s[i+i1][j+j1]!="J2") {
                        if (mra[s[i+i1][j+j1][0]]==0)
                            mra[s[i+i1][j+j1][0]]++;
                        else f1=1;
                        if (mra[s[i+i1][j+j1][1]]==0) {
                            mra[s[i+i1][j+j1][1]]=1;
                            f2++;
                        }

                    } else kj++;
                }
            //cout<<i<<' '<<j<<' '<<f1<<' '<<f2<<' '<<kj<<endl;
            klj[i][j]=kj;
            if (f1==0 || f2==1) {
                votv.push_back(make_pair(i,j));
            }
        }

    if (votv.size()<2) {
        cout<<"No solution.";
        return 0;
    }
                string jock1="",jock2="";
int nom1=-1,nom2=-1;
    for(int i=0; i<votv.size(); i++)
        for (int j=i+1; j<votv.size(); j++) {
             jock1="",jock2="";nom1=-1,nom2=-1;
             int x=votv[i].first;
            int y=votv[i].second;
            int x1=votv[j].first;
            int y1=votv[j].second;
            if (abs(x-x1)>2 || abs(y-y1)>2) {
            if (klj[x][y]==0 && klj[x1][y1]==0) {
                nom1=i;nom2=j;
                break;
            }
            if (klj[x][y]==1) { int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++) {
                        if (mra[s[x+i1][y+j1][0]]==0)
                            mra[s[x+i1][y+j1][0]]++;
                        else f1=1;
                        if (mra[s[x+i1][y+j1][1]]==0) {
                            mra[s[x+i1][y+j1][1]]=1;
                            f2++;
                        }
                    }
                if (f2==1) {
                    char r=s[x][y][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            jock1=ve[l];
                            break;
                        }
                }
                if (f1==0) {
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                            jock1=ve[l];
                            break;
                        }

                }
            }
            if (klj[x1][y1]==1) {int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++) {
                        if (mra[s[x1+i1][y1+j1][0]]==0)
                            mra[s[x1+i1][y1+j1][0]]++;
                        else f1=1;
                        if (mra[s[x1+i1][y1+j1][1]]==0) {
                            mra[s[x1+i1][y1+j1][1]]=1;
                            f2++;
                        }
                    }
                if (f2==1) {
                    char r=s[x1][y1][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            jock2=ve[l];
                            break;
                        }
                }
                if (f1==0) {
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                            jock2=ve[l];
                            break;
                        }
                }
            }
            if (kljok==2 && jock1!="" && jock2!="") {nom1=i;nom2=j;break;}
            else if (kljok==1 && ((jock1!="") || jock2!="")) {nom1=i;nom2=j;break;}
            else if (kljok==0) {nom1=i;nom2=j;break;}
        }
        }
        if (nom1==-1 || nom2==-1) {cout<<"No solution.";return 0;}
        cout<<"Solution exists."<<endl;
        if (kljok==0) {cout<<"There are no jokers."<<endl;}
        if (kljok==1) {if (jock1=="") cout<<"Replace J1 with "<<jock2<<'.'<<endl;
        else cout<<"Replace J1 with "<<jock1<<'.'<<endl;}
        if (kljok==2)
        cout<<"Replace J1 with "<<jock1<<" and J2 with "<<jock2<<'.'<<endl;
        cout<<"Put the first square to ("<<votv[nom1].first+1<<", "<<votv[nom1].second+1<<")."<<endl;
        cout<<"Put the second square to ("<<votv[nom2].first+1<<", "<<votv[nom2].second+1<<")."<<endl;

}

#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<climits>
using namespace std;
string a[100][100];
string f[]={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" ,"A"};
string p[]={"C", "D", "H" , "S"};
int n,m,jk=0,ok=0;
set<string>st;
vector<string>out;
string ff[]={"J1","J2"};
bool check(int x,int y)
{
	int i,j,k;
	int vis[130]={0};
	for (i=x;i<x+3;i++)
	{
		for (j=y;j<y+3;j++)
		{
			vis[a[i][j][0]]=1;
			//if (x==1&&y==0)printf("%c\n",a[i][j][0]);
		}
	}

	if (count(vis,vis+130,1)==9)return 1;
	memset(vis,0,sizeof(vis));
	for (i=x;i<x+3;i++)
	{
		for (j=y;j<y+3;j++)
		{
			vis[a[i][j][1]]=1;
		}
	}
	if (count(vis,vis+130,1)==1)return 1;
	return 0;
}
void dfs(int now)
{
	int i,j,k,l,u;
	if (ok)return;
	if (now==jk)
	{
		for (i=0;i+2<n;i++)
		{
			for (j=0;j+2<m;j++)
			{
				if (check(i,j))
				{
					for (k=0;k+2<n;k++)
					{
						for (l=0;l+2<m;l++)
						{
							if ((k<=i+2&&l<=j+2))continue;
							if (check(k,l))
							{
								puts("Solution exists.");
								if (!jk)
								{
									puts("There are no jokers.");
								}
								else
								{
									for (u=0;u<out.size();u++)
									{
										cout<<out[u]<<endl;
									}
								}
								printf("Put the first square to (%d, %d).\n",i+1,j+1);
								printf("Put the second square to (%d, %d).\n",k+1,l+1);
								ok=1;
								return;
							}
						}
					}
				}
			}
		}
		return;
	}
	int x,y;
 	for (i=0;i<n;i++)
 	{
 		for (j=0;j<m;j++)
 		{
 			if (a[i][j][0]=='J'&&a[i][j][1]-'0'==now+1)
 			{
 				x=i,y=j;
 			}
 		}
 	}
 	if (ok)return;
 	for (set<string>::iterator ptr=st.begin();ptr!=st.end();++ptr)
 	{	if (ok)return;
 		string tmp=*ptr;
 		st.erase(tmp);
 		string tt=a[x][y];
 		a[x][y]=tmp;
 		out.push_back("Replace "+ff[now]+" with "+tmp+".");
 		dfs(now+1);
 			if (ok)return;
 		out.pop_back();
 		st.insert(tmp);
 		a[x][y]=tt;
 	}
}
int main()
{
	int i,j,k;
	for (i=0;i<13;i++)
	{
		for (j=0;j<4;j++)
		{
			st.insert(f[i]+p[j]);
		}
	}
	cin>>n>>m;
	for (i=0;i<n;i++)
	{
		for (j=0;j<m;j++)
		{
			cin>>a[i][j];
			if (a[i][j][0]!='J')st.erase(a[i][j]);
			else ++jk;
		}
	}
	dfs(0);
	if (!ok)puts("No solution.");
	return 0;
}

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman010 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
int n , m;
vector<pair<int , int>> ans;
map<int , string> joker;
string s[20][20];
bool done[20][20];
void mark(int i , int j , set<char> &st , set<char> &st2) {
    ans.push_back({i + 1 , j + 1});
    for(int p1 = 0;p1 < 3;p1++)
        for(int p2 = 0;p2 < 3;p2++)
            done[i + p1][j + p2] = true;
    for(auto &k : st2)
        st.erase(k);
}
int main() {
    abdelrahman010
    cin >> n >> m;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++)
            cin >> s[i][j];
    for(int i = 0;i + 2 < n;i++)
        for(int j = 0;j + 2 < m;j++) {
            if(done[i][j])
                continue;
            set<char> st , st1 , st2;
            vector<int> v;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    if(s[i + p1][j + p2][0] == 'J')
                        v.push_back(s[i + p1][j + p2][1] - '0');
                    else {
                        st1.insert(s[i + p1][j + p2][1]);
                        st2.insert(s[i + p1][j + p2][0]);
                    }
            for(char c = '2';c <= '9';c++)
                st.insert(c);
            st.insert('T') , st.insert('Q');
            st.insert('R') , st.insert('A');
            if(st1.size() == 1) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    joker[k][0] = *st.begin();
                    joker[k][1] = *st1.begin();
                }
            } else if(st2.size() + v.size() == 9) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    joker[k][0] = *st.begin();
                    st.erase(st.begin());
                    joker[k][1] = 'Q';
                }
            }
        }
    if(ans.size() < 2)
        return cout << "No solution." , 0;
    cout << "Solution exists.\n";
    vector<pair<string , string>> j;
    for(int i = 0;i < 2;i++)
        for(int p1 = 0;p1 < 3;p1++)
            for(int p2 = 0;p2 < 3;p2++)
                if(s[ans[i].first + p1][ans[i].second + p2][0] == 'J') {
                    int k = s[ans[i].first + p1][ans[i].second + p2][1] - '0';
                    string m = "";
                    m += joker[k][0] , m += joker[k][1];
                    j.push_back({s[ans[i].first + p1][ans[i].second + p2] , m});
                }
    if(!j.size())
        cout << "There are no jokers.\n";
    else if(j.size() == 1)
        cout << "Replace " << j[0].first << " with " << j[0].second << ".\n";
    else
        cout << "Replace " << j[0].first << " with " << j[0].second << " and " << j[1].first << " with " << j[1].second << ".\n";
    cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
    cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << "). ";
    return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
#define REP(i,a,b) for (int i = a ; i <= b ; i++)
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;

const int OO = 1e9+7;
const int MOD = 1e9+7;
const int N = 52+7;

pair<char,char> a[N][N];
map<pair<char,char> ,int> c;
int n,m;
pi w1,w2;
bool check()
{
    vector<pi> vec;
    REP(i,0,n-3) REP(j,0,m-3)
    {
        set<char> st;
        bool oks = 1;
        char suit = '\0';
        REP(ki,0,2) REP(kj,0,2)
        {
            st.insert( a[i+ki][j+kj].F );
            if (suit == '\0') suit = a[i+ki][j+kj].S;
            else if (suit != a[i+ki][j+kj].S) oks = 0;
        }
        if (oks || st.size() == 9) vec.PB({i,j});
    }

    int sz = vec.size();
    REP(i,0,sz-1) REP(j,0,sz-1)
    {
        if (i==j)continue;
        if (vec[j].F+2 < vec[i].F || vec[j].S+2 < vec[i].S) {w1 = vec[i];w2 = vec[j];return 1;}
        else if (vec[j].F > vec[i].F+2 || vec[j].S > vec[i].S+2) {w1 = vec[i];w2 = vec[j];return 1;}
    }

    return 0;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    string r = "23456789TKA";
    string s = "CDHS";

    cin >> n >> m;
    int J1i = -1,J1j = -1,J2i = -1,J2j = -1;

    REP(i,0,n-1) REP(j,0,m-1)
    {
        cin >> a[i][j].F >> a[i][j].S;
        if (a[i][j].F == 'J')
        {
            if (a[i][j].S = '1') {J1i = i;J1j = j;}
            else {J2i = i;J2j = j;}
        }
        c[a[i][j]]++;
    }

    if (J1i != -1 && J2i != -1)
    {
        REP(i1,0,10) REP(j1,0,4)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            REP(i2,0,10) REP(j2,0,4)
            {
                if (c[{r[i2],s[j2]}] > 0) continue;
                c[{r[i2],s[j2]}]++;
                a[J2i][J2j] = {r[i2],s[j2]};
                if (check())
                {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with "<< r[i1]<<s[j1] <<" and J2 with " << r[i2]<<s[j2] << "." << endl;
                    cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                    cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                    return 0;
                }
                a[J2i][J2j] = {'J','2'};
                c[{r[i2],s[j2]}]--;
            }
            a[J1i][J1j] = {'J','1'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J1i != -1)
    {
        REP(i1,0,10) REP(j1,0,4)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with "<< r[i1]<<s[j1] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J1i][J1j] = {'J','2'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J2i != -1)
    {
        REP(i2,0,10) REP(j2,0,4)
        {
            if (c[{r[i2],s[j2]}] > 0) continue;
            c[{r[i2],s[j2]}]++;
            a[J2i][J2j] = {r[i2],s[j2]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J2 with " << r[i2]<<s[j2] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J2i][J2j] = {'J','2'};
            c[{r[i2],s[j2]}]--;
        }
    }
    else if (check())
    {
        cout << "Solution exists." << endl;
        cout << "There are no jokers." << endl;
        cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
        cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
        return 0;
    }

    cout << "No solution." << endl;

    return 0;
}

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<map>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m;
int graph[60][60];
struct fff
{
    int x,y;
};
fff a,b;
vector<int>ooxx;
set<int>pp;
int aaaa,bbbb;
bool solve()
{
    ooxx.clear();
    int p,q;
    int x,y;
    bool flag1,flag2;
    for(int i=0;i<n-2;i++)
        for(int j=0;j<m-2;j++)
        {
            p=graph[i][j]/100;
            q=graph[i][j]%100;
            flag1=flag2=true;
            int mark[20];
            memset(mark,false,sizeof(mark));
            for(int a=0;a<3;a++)
                for(int b=0;b<3;b++)
                {
                    x=graph[i+a][j+b]/100;
                    y=graph[i+a][j+b]%100;
                    if(p != x)
                        flag1=false;
                    if(mark[y])
                        flag2=false;
                    mark[y]=true;
                }

            if(flag1 || flag2)
                ooxx.push_back(i*100+j);
        }
    int len=ooxx.size();
    bool flag=true;
    for(int i=0;i<len && flag;i++)
        for(int j=i+1;j<len && flag;j++)
        {
            x=ooxx[i]/100;
            y=ooxx[i]%100;
            p=ooxx[j]/100;
            q=ooxx[j]%100;
            if(fabs(x-p) >= 3 || fabs(y-q) >= 3)
            {
                aaaa=x*100+y;
                bbbb=p*100+q;
                flag=false;
            }
        }
    return !flag;
}
int main()
{
    string s;
    cin >> n >> m;
    a.x=-1;
    b.x=-1;
    pp.clear();
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            cin >> s;
            if(s[0] == 'T')
                graph[i][j]=10;
            else if(s[0] == 'J' && s[1] != '1' && s[1] != '2')
                graph[i][j]=11;
            else if(s[0] == 'Q')
                graph[i][j]=12;
            else if(s[0] == 'K')
                graph[i][j]=13;
            else if(s[0] == 'A')
                graph[i][j]=1;
            else if(s[0] == 'J')
            {
                if(s[1] == '1')
                {
                    graph[i][j]=-1;
                    a.x=i;
                    a.y=j;
                }
                else
                {
                    //cout << "aaaa" << endl;
                    graph[i][j]=-2;
                    b.x=i;
                    b.y=j;
                }
                continue;
            }
            else
                graph[i][j]=s[0]-'0';
            if(s[1] == 'S')
                graph[i][j]+=100;
            else if(s[1] == 'H')
                graph[i][j]+=200;
            else if(s[1] == 'D')
                graph[i][j]+=300;
            else
                graph[i][j]+=400;
            pp.insert(graph[i][j]);
        }
    //cout << "aaaa" << endl;
    int x,y;
    //cout << a.x << " " << b.x << endl;
    if(a.x != -1 && b.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                for(int p=1;p<=4 && flag;p++)
                    for(int q=1;q<=13 && flag;q++)
                    {
                        x=i*100+j;
                        y=p*100+q;
                        if(pp.find(x) != pp.end())
                            continue;
                        if(pp.find(y) != pp.end())
                            continue;
                        if(x == y)
                            continue;
                        graph[a.x][a.y]=x;
                        graph[b.x][b.y]=y;
                        if(solve())
                        {
                            flag=false;
                            x=graph[a.x][a.y]/100;
                            y=graph[a.x][a.y]%100;
                            p=graph[b.x][b.y]/100;
                            q=graph[b.x][b.y]%100;
                            string c,d;
                            //cout << x << " " << y << " " << p << " " << q << " " << endl;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            if(q == 10)
                                d+="T";
                            else if(q == 11)
                                d+="J";
                            else if(q == 12)
                                d+="Q";
                            else if(q == 13)
                                d+="K";
                            else if(q == 1)
                                d+="A";
                            else
                                d+=y+'0';
                            if(p == 1)
                                d+="S";
                            else if(p == 2)
                                d+="H";
                            else if(p == 3)
                                d+="D";
                            else
                                d+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J1 with " << c << "." << endl;
                            cout << "Replace J2 with " << d << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                        //cout << "aaaa" << endl;
                    }
        //cout << "aaaa" << endl;
        if(flag)
            cout << "No solution." << endl;
    }
    else if(a.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                    {
                        x=i*100+j;
                        if(pp.find(x) != pp.end())
                            continue;
                        graph[a.x][a.y]=x;
                        if(solve())
                        {
                            flag=false;
                            x=graph[a.x][a.y]/100;
                            y=graph[a.x][a.y]%100;
                            string c,d;
                            //cout << x << " " << y << " " << p << " " << q << " " << endl;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J1 with " << c << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                    }
        if(flag)
            cout << "No solution." << endl;
    }
    else if(b.x != -1)
    {
        bool flag=true;
        for(int i=1;i<=4 && flag;i++)
            for(int j=1;j<=13 && flag;j++)
                    {
                        x=i*100+j;
                        if(pp.find(x) != pp.end())
                            continue;
                        graph[b.x][b.y]=x;
                        if(solve())
                        {
                            flag=false;
                            x=graph[b.x][b.y]/100;
                            y=graph[b.x][b.y]%100;
                            string c,d;
                            if(y == 10)
                                c+="T";
                            else if(y == 11)
                                c+="J";
                            else if(y == 12)
                                c+="Q";
                            else if(y == 13)
                                c+="K";
                            else if(y == 1)
                                c+="A";
                            else
                                c+=y+'0';
                            if(x == 1)
                                c+="S";
                            else if(x == 2)
                                c+="H";
                            else if(x == 3)
                                c+="D";
                            else
                                c+="C";
                            cout << "Solution exists." << endl;
                            cout << "Replace J2 with " << c << "." << endl;
                            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
                            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
                        }
                    }
        if(flag)
            cout << "No solution." << endl;
    }
    else
    {
        bool flag=true;
        if(solve())
        {
            flag=false;
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            printf("Put the first square to (%d, %d).\n",aaaa/100+1,aaaa%100+1);
            printf("Put the second square to (%d, %d).\n",bbbb/100+1,bbbb%100+1);
        }
        if(flag)
            cout << "No solution." << endl;
    }
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>

#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <list>

using namespace std;

#define f0(_X,_Y) for(int (_X)=0;(_X)<(_Y);++(_X))
#define f1(_X,_Y) for(int (_X)=1;(_X)<=(_Y);++(_X))
#define ff(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<=(_Z);++(_X))
#define fF(_X,_Y,_Z) for(int (_X)=(_Y);(_X)<(_Z);++(_X))
#define rf0(_X,_Y) for(int _X=(_Y)-1;(_X)>=0;--(_X))
#define rf1(_X,_Y) for(int _X=(_Y);(_X)>0;--(_X))
#define rff(_X,_Y,_Z) for(int _X=(_Y);(_X)>=(_Z);--(_X))
#define rfF(_X,_Y,_Z) for(int _X=(_Y);(_X)>(_Z);--(_X))
#define PRT(_X) std::cout<< #_X ": "<<_X<<std::endl;
#define TIME fprintf(stderr,"time : %.2f sec\n",double(clock())/CLOCKS_PER_SEC);
typedef long long ll;
typedef pair<int, int> pii;

#define scan1(_X) scanf("%d",&_X);
#define scan2(_X,_Y) scanf("%d%d",&_X,&_Y);
#define scan3(_X,_Y,_Z) scanf("%d%d%d",&_X,&_Y,&_Z);
#define print1(_X) printf("%d\n",_X);
#define PAIR_STRUCT(_T,_X,_Y,...) struct _T{int _X,_Y,##__VA_ARGS__; bool friend operator < (const _T &p, const _T &q){if(p._X!=q._X) return p._X<q._X; return p._Y<q._Y;}};

int n,m;
struct p{int x,y;} joker[2], ans[2];
struct c{;} ;
char pattern[]="SHCD"; // 4
char _rank[]="A23456789TJQK"; // 13
char in[18][18][3];
char rest[53][3];
char prt[200];
bool poss;

int chk[128];
bool sqr[18][18];

void process()
{

    int count = 0;
    f1(i,n) f1(j,m) sqr[i][j]=false;
    f1(i,n) if(i+2<=n)
    {
        f1(j,m) if(j+2<=m)
        {
            bool duplicate = false;
            bool same = true;
            ++count;
            // same suite || all diff _ranks
            f0(k,3) f0(l,3)
            {
                if(chk[in[i+k][j+l][0]] != count)
                    chk[in[i+k][j+l][0]] = count;
                else
                    duplicate = true;
                if(in[i+k][j+l][1] != in[i][j][1])
                    same=false;
            }
            // if(in[2][4][0]=='A' && in[2][4][1]=='H' && i==1 && j==4)
            // {
            //  PRT(same);
            //  PRT(duplicate);
            // }
            sqr[i][j] = same || !duplicate;
        }
    }
    f1(i,n)
        f1(j,m) if(sqr[i][j])
        {
            ff(k,i,n) f1(l,m) if(sqr[k][l] && (abs(i-k)>=3 || abs(j-l)>=3))
            {
                ans[0].y=i; ans[0].x=j;
                ans[1].y=k; ans[1].x=l;
                poss=true;
                return;
            }
        }
}

int main()
{
    int num_joker=0, joker_last=0, rn=0;
    scan2(n,m);
    f1(i,n) f1(j,m)
    {
        char card[4];
        scanf("%s",card); in[i][j][0] = card[0]; in[i][j][1]=card[1];
        if(card[0]=='J')
        {
            ++num_joker; int no = card[1]-'1';
            joker[no].y=i, joker[no].x=j;
            joker_last = no;
        }
    }

    f0(r,13) f0(p,4)
    {
        bool exist=false;
        f1(i,n) f1(j,m) if(in[i][j][0]==_rank[r] && in[i][j][1]==pattern[p])
        {
            i=n;
            exist=true;
            break;
        }
        if(!exist)
        {
            ++rn;
            rest[rn][0] = _rank[r];
            rest[rn][1] = pattern[p];
        }
    }

    if(num_joker==0)
    {
        sprintf(prt,"There are no jokers.");
        process();
    }
    else if(num_joker==1)
    {
        f1(i,rn)
        {
            in[joker[joker_last].y][joker[joker_last].x][0] = rest[i][0];
            in[joker[joker_last].y][joker[joker_last].x][1] = rest[i][1];
            process();
            if(poss)
            {
                sprintf(prt,"Replace J%d with %s.",joker_last+1, rest[i]);
                break;
            }
        }
    }
    else
    {
        f1(i,rn)
        {
            in[joker[0].y][joker[0].x][0] = rest[i][0];
            in[joker[0].y][joker[0].x][1] = rest[i][1];
            ff(j,i+1,rn)
            {
                in[joker[1].y][joker[1].x][0] = rest[j][0];
                in[joker[1].y][joker[1].x][1] = rest[j][1];
                process();
                if(poss)
                {
                    i=rn;
                    sprintf(prt,"Replace J1 with %s and J2 with %s.", rest[i], rest[j]);
                    break;
                }
            }

        }
    }

    if(poss)
    {
        printf("Solution exists.\n");
        printf("%s\n",prt);
        printf("Put the first square to (%d, %d).\n", ans[0].y, ans[0].x);
        printf("Put the second square to (%d, %d).\n", ans[1].y, ans[1].x);

    }
    else
    {
        printf("No solution.\n");
    }

    return 0;
}

#include <iostream>
#include <string>
#include <map>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#pragma comment(linker,"/STACK:64000000")
using namespace std;

typedef vector<int> vint;
#define fs first
#define sc second
#define pb push_back
#define mp make_pair
const int INF=1000000000;

const int CardLimit=54;
const int OneMstCardLimit=13;
int toNumber(string s){
	int a=0;
	int b=0;
	if (s[1]!='1' && s[1]!='2'){
		if (s[1]=='C') a=0;
		if (s[1]=='D') a=1;
		if (s[1]=='H') a=2;
		if (s[1]=='S') a=3;
		if (s[0]>='0' && s[0]<='9') b=s[0]-'0'-2;
		if (s[0]=='T') b=8;
		if (s[0]=='J') b=9;
		if (s[0]=='Q') b=10;
		if (s[0]=='K') b=11;
		if (s[0]=='A') b=12;
		return a*OneMstCardLimit+b;
	}
	else{
		if (s[1]=='1')
			return OneMstCardLimit*4;
		if (s[1]=='2')
			return OneMstCardLimit*4+1;
	}
}
string toMst(int numb){
	if (numb==4*OneMstCardLimit)
		return "J1";
	if (numb==4*OneMstCardLimit+1)
		return "J2";
	int a=numb/OneMstCardLimit;
	int b=numb%OneMstCardLimit;
	char symb1,symb2;
	if (a==0) symb1='C';
	if (a==1) symb1='D';
	if (a==2) symb1='H';
	if (a==3) symb1='S';
	if (b>=0 && b<=7) symb2=b+2+'0';
	if (b==8) symb2='T';
	if (b==9) symb2='J';
	if (b==10) symb2='Q';
	if (b==11) symb2='K';
	if (b==12) symb2='A';
	string ans="";ans+=symb2;ans+=symb1;
	return ans;
}

int n,m;
string T[20][20];
void input(){
	scanf("%d %d",&n,&m);
	for (int i=0;i<n;i++)
	for (int j=0;j<m;j++)
		cin>>T[i][j];
}

int joker1i=-1,joker1j=-1,joker1Numb=1;
int joker2i=-1,joker2j=-1;
vector<string> notOnTable;

bool oneMst(string a, string b){
	return a[1]==b[1];
}
bool oneDst(string a, string b){
	return a[0]==b[0];
}
bool itsJoker(string a){
	return a[1]=='1' || a[1]=='2';
}
void formGoodData(){
	bool B[54]={};
	for (int i=0;i<n;i++)
	for (int j=0;j<m;j++){
		B[toNumber(T[i][j])]=1;
		if (itsJoker(T[i][j]))
			if (T[i][j][1]=='1')
				joker1i=i, joker1j=j;
			else
				joker2i=i, joker2j=j;
	}
	if (joker1i==-1 && joker2i!=-1)
		swap(joker1i,joker2i),swap(joker1j,joker2j),joker1Numb=2;
	for (int i=0;i<52;i++)
		if (!B[i])
			notOnTable.push_back(toMst(i));
}

bool checkOnOneMst(int n1, int m1){
	if (n-n1<3 || m-m1<3)
		return false;
	for (int i=n1;i<n1+3;i++)
	for (int j=m1;j<m1+3;j++){
		if (!oneMst(T[i][j],T[n1][m1]))
			return false;
	}
	return true;
}

bool checkOnDifDst(int n1, int m1){
	if (n-n1<3 || m-m1<3)
		return false;
	for (int i1=n1;i1<n1+3;i1++)
	for (int j1=m1;j1<m1+3;j1++)
		for (int i2=n1;i2<n1+3;i2++)
		for (int j2=m1;j2<m1+3;j2++){
			if (i1==i2 && j1==j2) continue;
			if (oneDst(T[i1][j1],T[i2][j2]))
				return false;
		}

	return true;

}
bool answerExist=false;
int oneMstN1=-1,oneMstM1=-1,difDstN1=-1,difDstM1=-1;
inline int mabs(int a){return a<0 ? -a : a;}
bool globalCheck(){
	for (int i1=0;i1<=n-3;i1++)
	for (int j1=0;j1<=m-3;j1++)
		for (int i2=0;i2<=n-3;i2++)
		for (int j2=0;j2<=m-3;j2++){
			if (i2==3 && j2==0 && i1==0 && j1==0)
				int STOP=1;
			if (mabs(i2-i1)<3 && mabs(j2-j1)<3) continue;
			if (checkOnOneMst(i1,j1) && checkOnDifDst(i2,j2)){
				oneMstN1=i1; oneMstM1=j1;
				difDstN1=i2; difDstM1=j2;
				return true;
			}
		}
	return false;
}

void solve(){
	if (joker1i==-1)
		if (globalCheck()){
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
			if (mp(oneMstN1,oneMstM1)>mp(difDstN1,difDstM1))
				swap(oneMstN1,difDstN1),swap(oneMstM1,difDstM1);
			cout<<"Put the first square to ("<<oneMstN1+1<<", "<<oneMstM1+1<<")."<<endl;
			cout<<"Put the second square to ("<<difDstN1+1<<", "<<difDstM1+1<<")."<<endl;
		}
		else{
			cout<<"No solution."<<endl;
		}
	if (joker1i!=-1 && joker2i==-1){
		for (int t=0;t<notOnTable.size();t++){
			T[joker1i][joker1j]=notOnTable[t];
			if (globalCheck()){
				cout<<"Solution exists."<<endl;
				cout<<"Replace J"<<joker1Numb<<" with "<<notOnTable[t]<<"."<<endl;
				if (mp(oneMstN1,oneMstM1)>mp(difDstN1,difDstM1))
					swap(oneMstN1,difDstN1),swap(oneMstM1,difDstM1);
				cout<<"Put the first square to ("<<oneMstN1+1<<", "<<oneMstM1+1<<")."<<endl;
				cout<<"Put the second square to ("<<difDstN1+1<<", "<<difDstM1+1<<")."<<endl;
				return;
			}
		}
		cout<<"No solution."<<endl;
	}
	if (joker1i!=-1 && joker2i!=-1){
		for (int t1=0;t1<notOnTable.size();t1++)
		for (int t2=0;t2<notOnTable.size();t2++){
			if (t1==t2) continue;
			T[joker1i][joker1j]=notOnTable[t1];
			T[joker2i][joker2j]=notOnTable[t2];
			if (globalCheck()){
				cout<<"Solution exists."<<endl;
				cout<<"Replace J1 with "<<notOnTable[t1]<<" and J2 with "<<notOnTable[t2]<<"."<<endl;
				if (mp(oneMstN1,oneMstM1)>mp(difDstN1,difDstM1))
					swap(oneMstN1,difDstN1),swap(oneMstM1,difDstM1);
				cout<<"Put the first square to ("<<oneMstN1+1<<", "<<oneMstM1+1<<")."<<endl;
				cout<<"Put the second square to ("<<difDstN1+1<<", "<<difDstM1+1<<")."<<endl;
				return;
			}
		}

		cout<<"No solution."<<endl;
	}
}

int main(){
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	input();
	formGoodData();
	solve();
	return 0;
}

#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <cstring>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <cassert>
#include <functional>
#include <utility>

#define forn( i,n ) for ( int i=0; i<(int)(n); i++ )

using namespace std;

int n,m,define[260];
string revdef[55],tmp1,tmp2;
bool isJ1=false,isJ2=false,J1=false,J2=false,solved=false,solved1=false;
vector<vector<int>> cards(17,17);
vector<pair<int,int>> dots,quedots;
set<int> destr,pack;
vector<int> pac,have(13);
pair<int,int> st,nd;
vector<bool> has(13);
string transformer(int k)
{
	int md = k / 13,dv = k % 13;
	string tmp = revdef[dv];
	if (md == 0)
		tmp.append("C");
	if (md == 1)
		tmp.append("D");
	if (md == 2)
		tmp.append("H");
	if (md == 3)
		tmp.append("S");
	return tmp;
}
void transform()
{
	int cc1=-1,cc2=-1,tmpx,tmpy,z1=0,z2=0;
	bool breaker=false,swapp = false;
	vector<int> dst;
	forn(z,2)
	{
		if (z == 0)
		{ tmpx = st.first; tmpy = st.second;}
		else
			{ tmpx = nd.first; tmpy = nd.second;}
	  forn(s,3)
			forn(k,3)
			if (cards[tmpx+s][tmpy+k] != 52 && cards[tmpx+s][tmpy+k] != 53)
			   dst.push_back(cards[tmpx+s][tmpy+k] % 13);
			else if ((cards[tmpx+s][tmpy+k] == 53 && z==0) || (cards[tmpx+s][tmpy+k] == 51 && z==1))
				swapp = true;
			if (dst.size() == 8 || dst.size() == 7)
			{
				int k = 8;
				if (dst.size() == 7) k = 7;
				forn(j,13) {
					if (has[j] == true)
						continue;
				forn(i,k)
				{
					if (dst[i] == j)
						break;
				    if (i==k-1)
					{
						if (cc1==-1)
						cc1 = j;
						else
						{
							cc2 = j;
							breaker = true;
							break;
						}
						if (dst.size() == 8 && cc1!=-1)
							breaker = true;
					}
				}
				if (breaker) break;
				}
			}
			breaker = false;
			dst.clear();
	}
	if (cc1 == -1 && cc2 == -1)
	{
		cout << "No solution.";
		exit(0);
	}
	forn(i,pac.size())
		if ((pac[i] == cc1)||(pac[i] == cc1+13)||
			(pac[i] == cc1+26) || (pac[i] == cc1+39))
		{
			z1 = pac[i];
			break;
		}
	if (cc2!=-1)
		forn(i,pac.size())
		if ((pac[i] == cc2)||(pac[i] == cc2+13)||
			(pac[i] == cc2+26) || (pac[i] == cc2+39))
		{
			z2 = pac[i];
			break;
		}
	if (!swapp)
	{
	    tmp1 = transformer(z1);
	    if (z2!=-1) tmp2 = transformer(z2);
	}
	if (swapp)
	{
		tmp1 = transformer(z2);
	    tmp2 = transformer(z1);
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	forn(i,52)
		pack.insert(i);
	define['2'] = 0;
	define['3'] = 1;
	define['4'] = 2;
	define['5'] = 3;
	define['6'] = 4;
	define['7'] = 5;
	define['8'] = 6;
	define['9'] = 7;
	define['T'] = 8;
	define['J'] = 9;
	define['Q'] = 10;
	define['K'] = 11;
	define['A'] = 12;
	define['C'] = 0;
	define['D'] = 1;
	define['H'] = 2;
	define['S'] = 3;
	revdef[0] = "2";
	revdef[1] = "3";
	revdef[2] = "4";
	revdef[3] = "5";
	revdef[4] = "6";
	revdef[5] = "7";
	revdef[6] = "8";
	revdef[7] = "9";
	revdef[8] = "T";
	revdef[9] = "J";
	revdef[10] = "Q";
	revdef[11] = "K";
	revdef[12] = "A";
	cin >> n >> m;
	forn(i,n)
		forn(j,m)
	{
		   char x,y;
		   cin >> x >> y;
		   if (y == '1')
		   {
			   cards[i][j] = 52;
			   isJ1 = true;
		   }
		   else if (y == '2')
		   {
			   cards[i][j] = 53;
			   isJ2 = true;
		   }
		   else
		   {
			   have[define[x]]++;
		       cards[i][j] = define[x] + define[y]*13;
			   pack.erase(cards[i][j]);
		   }
	}
	pac.resize(pack.size());
	copy(pack.begin(),pack.end(),pac.begin());
	forn(i,have.size())
	{
		if (have[i] == 4)
			has[i] = true;
	}
	forn(i,n-2)
		forn(j,m-2)
	    {
			forn(s,3)
			forn(k,3)
			{
			if (cards[i+s][j+k] != 52 && cards[i+s][j+k] != 53)
			   destr.insert(cards[i+s][j+k] % 13);
			else if (cards[i+s][j+k] == 52) J1 = true;
			else if (cards[i+s][j+k] == 53) J2 = true;
			}
			if (destr.size() == 9)
				dots.push_back(make_pair(i,j));
			else if ((J1 && destr.size() == 8) || (J2 && destr.size() == 8))
				quedots.push_back(make_pair(i,j));
			else if (J1 && J2 && destr.size() == 7)
				quedots.push_back(make_pair(i,j));
			destr.clear();
			J1 = false;
			J2 = false;
	    }
	if ((dots.size() > 1) || (dots.size() >=1 && quedots.size() >=1) || (quedots.size() > 1))
	{
		if (dots.size() > 1)
		{
			forn(i,dots.size())
			{
				for(int j=dots.size()-1;j>i;j--)
				{
					st = dots[i];
					nd = dots[j];
					if ((st.second > nd.second + 2) || (st.first > nd.first + 2) ||
						(nd.second > st.second + 2) || (nd.first > st.first + 2))
					{
						solved1 = true;
						solved = true;
						break;
					}
				}
				if (solved) break;
			}
		}
		if (quedots.size() > 1 && solved == false)
		{
			forn(i,quedots.size())
			{
				for(int j=quedots.size()-1;j>i;j--)
				{
					st = quedots[i];
					nd = quedots[j];
					if ((st.second > nd.second + 2) || (st.first > nd.first + 2) ||
						(nd.second > st.second + 2) || (nd.first > st.first + 2))
					{
						solved = true;
						break;
					}
				}
				if (solved) break;
			}
		}
		if (dots.size() >=1 && quedots.size() >=1 && solved == false)
		{
			forn(i,dots.size())
			{
				for(int j=quedots.size()-1;j>=0;j--)
				{
					st = dots[i];
					nd = quedots[j];
					if ((st.second > nd.second + 2) || (st.first > nd.first + 2) ||
						(nd.second > st.second + 2) || (nd.first > st.first + 2))
					{
						solved = true;
						break;
					}
				}
				if (solved) break;
			}
		}
	}
	else
	{
		cout << "No solution." ;  exit(0);
	}
	if (nd.first < st.first || (nd.first == st.first && nd.second < st.second))
	{
		pair <int,int> tmp;
		tmp = st;
		st = nd;
		nd = tmp;
	}
	if (!solved)
	{
		cout << "No solution.";
		exit(0);
	}
	else if (isJ1 && isJ2)
	{
		transform();
		cout << "Solution exists." << endl;
		cout << "Replace J1 with " << tmp1 << " and J2 with " << tmp2 << "." << endl;
	}
	else if (isJ1)
	{
		transform();
		cout << "Solution exists." << endl;
		cout << "Replace J1 with " << tmp1 << "." << endl;
	}
	else if (isJ2)
	{
		transform();
		cout << "Solution exists." << endl;
		cout << "Replace J2 with " << tmp1 << "." << endl;
	}
	else if (solved1)
	{
		cout << "Solution exists." << endl;
		cout << "There are no jokers." << endl;
	}
	cout << "Put the first square to ("<<st.first+1<<", "<<st.second+1<<")."<<endl;
	cout << "Put the second square to ("<<nd.first+1<<", "<<nd.second+1<<")."<<endl;
	return 0;
}

#include <iostream>
#include <cmath>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#define REPN(i,a,N) for( int i = (int)a ; i < (int) N ; i++ )
#define REP(i,N) REPN(i,0,N)
#define all(x) x.begin(),x.end()

using namespace std;

typedef pair< int , int > pii;
int n , m;
int esta[130];
string suit = "CDHS";
int tab[20][20];
vector< pii > J;

int encode( string s ){
	char c = s[s.size()-1];
	s = s.substr(0,s.size()-1);
	int nat;
	if( s[0] == 'J' ) return '0'-c;
	if( s[0] == 'T' )  nat = 10;
	else if( s[0] == 'J' ) nat = 11;
	else if( s[0] == 'Q' ) nat = 12;
	else if( s[0] == 'K' ) nat = 13;
	else if( s[0] == 'A' )  nat = 1;
	else{
	istringstream is( s );
	is >> nat;
	}
	return nat*10 + suit.find(c);
}

bool inter( int a , int b , int i , int j ){
	int dx = abs( a - i );
	int dy = abs( b - j );
	if( dx < 3 and dy < 3 ) return 1;
	return 0;
}

bool solute( int i1 , int j1 ){
	int bien = true;
	REPN(i , i1 , i1+3 ){
		REPN( j , j1 , j1+3 ){
			if( tab[i][j] != tab[i1][j1] ){
				bien = false;
				goto fin;
			}
		}
	}
	if( bien ) return 1;
	fin:
	REPN( i , i1 , i1 + 3 ){
		REPN( j , j1 , j1+3 ){
			REPN( a , i1 , i1+3 ){
				REPN( b , j1 , j1+3 ){
					if( a ==i && b == j ) continue;
					if( tab[i][j]/10 == tab[a][b]/10) return 0;
				}
			}
		}
	}
	return 1;
}

vector< pii > solve( ){
	vector< pii > ans;
	REP( i1 , n-2 ){
		REP( j1 , m-2 ){
			REP( i2 , n-2  ){
				REP( j2 , m-2 ){
					if( inter( i1 , j1 , i2 , j2 ) ) continue;
					if( solute( i1, j1 ) && solute(i2,j2 ) ){
						ans.push_back( pii(i1,j1) );
						ans.push_back( pii(i2,j2) );
						return ans;
					}
				}
			}
		}
	}
	return ans;
}

int valid( int i ){
	char c = i%10;
	int rank = i/10;
	if( rank > 13 || rank <= 0 ) return 0;
	if( c > 3 || c < 0  ) return 0;
	return 1;
}

int decode( int a ){
	char c = suit[a%10];
	int peso = a/10;
	if( peso == 1 ) cout <<"A";
	else if( peso >= 10 ){
		string tmp = "TJQK";
		cout << tmp[peso-10];
	}
	else{
		cout << peso ;
	}
	cout << c ;
	return 1;
}

int main(){
	vector< int > ides;
	cin >> n >> m;
	memset( esta , 0 , sizeof( esta ) ) ;
	REP( i , n ) REP( j , m ){
		string str;
		cin >> str;
		int tmp = encode( str );
		if( tmp < 0 ){
			J.push_back( pii(i,j) );
			ides.push_back(-tmp);
		}
		else esta[tmp] = 1;
		tab[i][j] = tmp;
	}
	vector< pii > ans;
	if( J.empty() ){
		ans = solve();
		if( ans.empty() ) cout << "No solution." << endl;
		else{
			cout << "Solution exists." << endl;
			cout << "There are no jokers." << endl;
		}
	}
	else{
		if( J.size() == 1 ){
			REP( i , 130 ){
				if( valid(i) && esta[i] == 0 ){
					tab[J[0].first][J[0].second] = i;
					ans = solve();
					if( !ans.empty() ) break;
				}
			}
		}
		else{
			int i1 = J[0].first , i2 = J[1].first;
			int j1 = J[0].second , j2 = J[1].second;
			//cout << "----->>" << esta[81] << endl;
			REP( i , 130 ){
		//		cout << i << endl;
				if( i == 81 ) cout << " adjfhadkj " << endl;
				if( !valid(i) ) continue;
				if( esta[i] ) continue;
				REP( j , 130 ){
					if( esta[j] ) continue;
					if( !valid(j) ) continue;
					if( i == j ) continue;
		//			decode( i ); cout << endl;
		//			decode( j ); cout << endl;
					tab[i1][j1] = i;
					tab[i2][j2] = j;
					ans = solve();
					if( !ans.empty() ) break;
				}
		//		cout << ans.empty() << endl;
				if( !ans.empty() ) break;
			}
		}
		if( ans.empty() ) cout << "No solution." << endl;
		else  			  cout << "Solution exists." << endl;
	}
	if( !ans.empty() ){
		if( J.size() == 2 )
			if( ides[0] > ides[1] ) swap( J[0] , J[1] );

		REP(i  , J.size()-1 ){
			int a = J[i].first;
			int b = J[i].second;
			printf("Replace J%d with ",i+1 );
			decode( tab[a][b] );
		}
		if( J.size() == 2 ){
			printf(" and J2 with ");
			decode( tab[J[1].first][J[1].second]);
		}
			cout << "." << endl;
		printf("Put the first square to (%d, %d).\n",ans[0].first+1 , ans[0].second+1);
		printf("Put the second square to (%d, %d).\n",ans[1].first+1 , ans[1].second+1);
	}
	return 0;
}

#include <vector>
#include <queue>
#include <stack>
#include <fstream>
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <string>
#include <set>
#include <cmath>
#include <ctime>
#include <cstring>
#include <map>
#include <stack>
#include <utility>
#include <tuple>
#define pause system("pause")
#define input ios_base::sync_with_stdio(0)
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

char cards[] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
char color[] = { 'C', 'D', 'H', 'S' };

string g[20][20];
map<string, bool> cardsMap;
set <string> avail;
vector <tuple <int, int, vector<string>, int, bool, bool, bool, bool>> p;
//             row  col  cards    jokers  unCol	unCards firstJ secondJ
int amountofJ;
bool firstJ, secondJ;

void output(const pii &a, const pii &b, string s1, string s2)
{
	cout << "Solution exists." << endl;
	if (s1 != "" && s2 != "")
	{
		cout << "Replace J1 with " << s1 << " and J2 with " << s2 << "." << endl;
	}
	else if (s1 != "" && s2 == "")
	{
		cout << "Replace J1 with " << s1 << "." << endl;
	}
	else if (s2 != "" && s1 == "")
	{
		cout << "Replace J2 with " << s2 << "." << endl;
	}
	else if (s1 == "" && s2 == "")
	{
		cout << "There are no jokers." << endl;
	}
	cout << "Put the first square to (" << a.first + 1<< ", " << a.second + 1<< ")." << endl;
	cout << "Put the second square to (" << b.first + 1<< ", " << b.second + 1<< ")." << endl;
}

bool f(tuple <int, int, vector<string>, int, bool, bool, bool, bool> &a, const tuple <int, int, vector<string>, int, bool, bool, bool, bool> &b)
{
	int j;
	j = get<3>(a);
	vector <string> answer;
	if (get<4>(a))
	{
		for (auto &qwe : avail)
		{
			if (qwe[1] == (*get<2>(a).begin()).at(1))
			{
				answer.push_back(qwe);
				get<2>(a).push_back(qwe);
			}
		}
	}
	if (answer.size() < get<3>(a) && get<5>(a))
	{
		answer.clear();
		for (auto &qwe : avail)
		{
			bool flag = 0;
			for (auto card : get<2>(a))
			{
				if (card[0] == qwe[0])
				{
					flag = 1;
					break;
				}
			}
			if (!flag)
			{
				answer.push_back(qwe);
				get<2>(a).push_back(qwe);
			}
		}
	}
	if (answer.size() >= get<3>(a))
	{
		if (answer.size() == 1 && amountofJ == 2)
		{
			for (auto qwe : avail)
			{
				if (qwe != answer[0])
				{
					answer.push_back(qwe);
					break;
				}
			}
			if (answer.size() == 1)
			{
				return 0;
			}
		}
		answer.push_back("");
		answer.push_back("");
		if (secondJ && !firstJ)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), string(""), answer[0]);
		}
		else if (firstJ && !secondJ)
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), answer[0], string(""));
		}
		else
		{
			output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), answer[0], answer[1]);
		}

		return 1;
	}
	return 0;
}

bool insert(tuple <int, int, vector<string>, int, bool, bool, bool, bool> &a, tuple <int, int, vector<string>, int, bool, bool, bool, bool> &b)
{
	if (!get<3>(a) && !get<3>(b))
	{
		output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), "", "");
		return 1;
	}
	if (get<3>(a) && get<3>(b))
	{
		if (get<4>(a))
		{
			if (get<4>(b))
			{
				for (auto qwe : avail)
				{
					if (qwe[1] == (*get<2>(a).begin()).at(1))
					{
						for (auto ewq : avail)
						{
							if (ewq == qwe) continue;
							if (ewq[1] == (*get<2>(b).begin()).at(1))
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)),s1,s2);
								return 1;
							}
						}
					}
				}
			}
			if (get<5>(b))
			{
				for (auto qwe : avail)
				{
					if (qwe[1] == (*get<2>(a).begin()).at(1))
					{
						for (auto ewq : avail)
						{
							bool flag = 0;
							if (ewq == qwe) continue;
							for (auto card : get<2>(b))
							{
								if (ewq[0] == card[0])
								{
									flag = 1;
									break;
								}
							}
							if (!flag)
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
		}
		if (get<5>(a))
		{
			if (get<4>(b))
			{
				for (auto qwe : avail)
				{
					bool flag = 0;
					for (auto card1 : get<2>(a))
					{
						if (qwe[0] == card1[0])
						{
							flag = 1;
							break;
						}
					}
					if (!flag)
					{
						for (auto ewq : avail)
						{
							if (qwe == ewq) continue;
							if (ewq[1] == (*get<2>(b).begin()).at(1))
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
			if (get<5>(b))
			{
				for (auto qwe : avail)
				{
					bool flag = 0;
					for (auto card1 : get<2>(a))
					{
						if (qwe[0] == card1[0])
						{
							flag = 1;
							break;
						}
					}
					if (!flag)
					{
						for (auto ewq : avail)
						{
							if (qwe == ewq) continue;
							bool flag1 = 0;
							for (auto card2 : get<2>(a))
							{
								if (ewq[0] == card2[0])
								{
									flag = 1;
									break;
								}
							}
							if (!flag)
							{
								string s1, s2;
								if (get<6>(a))
								{
									s1 = qwe;
									s2 = ewq;
								}
								else
								{
									s1 = ewq;
									s2 = qwe;
								}
								output(make_pair(get<0>(a), get<1>(a)), make_pair(get<0>(b), get<1>(b)), s1, s2);
								return 1;
							}
						}
					}
				}
			}
		}
	}
	else
	{
		if (get<3>(a))
		{
			return f(a, b);
		}
		else
		{
			return f(b, a);
		}
	}
	return 0;
}

int main()
{
	input;
	int n, m;
	cin >> n >> m;
	for (auto i : cards)
	{
		for (auto j : color)
		{
			string t;
			t.push_back(i);
			t.push_back(j);
			avail.insert(t);
		}
	}
	if (n < 6 && m < 6)
	{
		cout << "No solution.";
		return 0;
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> g[i][j];
			avail.erase(g[i][j]);
		}
	}
	for (int i = 0; i < n - 2; i++)
	{
		for (int j = 0; j < m - 2; j++)
		{
			set <char> sqCards;
			set <char> sqColors;
			vector <string> tmp;
			int joker = 0;
			bool first = false, second = false;
			for (int k = 0; k < 3; k++)
			{
				for (int z = 0; z < 3; z++)
				{
					if (g[i + k][j + z][1] == '1' || g[i + k][j + z][1] == '2')
					{
						joker++;
						if (g[i + k][j + z][1] == '1') firstJ = 1;
						else secondJ = 1;
						first |= g[i + k][j + z][1] == '1';
						second |= g[i + k][j + z][1] == '2';
					}
					else
					{
						sqCards.insert(g[i + k][j + z][0]);
						sqColors.insert(g[i + k][j + z][1]);
						tmp.push_back(g[i + k][j + z]);
					}
				}
			}
			if (sqColors.size() == 1 || sqCards.size() + joker == 9)
			{
				p.emplace_back(i, j, tmp, joker, sqColors.size() == 1, sqCards.size() + joker == 9, first, second);
			}
		}
	}
	amountofJ = firstJ + secondJ;
	if (p.size() < 2)
	{
		cout << "No solution.";
		return 0;
	}
	for (int i = 0; i < p.size(); i++)
	{
		for (int j = 0; j < p.size(); j++)
		{
			if (i != j && (abs(get<0>(p[i]) - get<0>(p[j])) >= 3 || abs(get<1>(p[i]) - get<1>(p[j])) >= 3) && insert(p[i], p[j]))
			{
				return 0;
			}
		}
	}
	cout << "No solution.";
	return 0;
}

#include<bits/stdc++.h>
#include<chrono>
#include<random>
#define int long long
#define INF 1e+18
#define pii pair<int,int>
#define endl "\n"
#define all(mas) mas.begin(),mas.end()
#define forn(i,n) for(int i = 0; i < n; i++)
#define forn_(i,n) for(int i = n - 1; i >= 0; i--)
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,m,joker1 = 0,joker2 = 0;
string mas[18][18];
string cards = "23456789TJQK";
set<string> av;

bool check(int x,int y,string j1,string j2) {
	set<char> type, val;

	forn(i, 3) {
		forn(j, 3) {
			auto cur = mas[x + i][y + j];
			if (cur == "J1") cur = j1;
			if (cur == "J2") cur = j2;

			val.insert(cur[0]);
			type.insert(cur[1]);
		}
	}

	return val.size() == 9 || type.size() == 1;
}

signed main() {
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	cin >> n >> m;

	forn (i, cards.size()) {
		string cur = cards.substr(i,1);
		av.insert(cur + "C");
		av.insert(cur + "D");
		av.insert(cur + "H");
		av.insert(cur + "S");
	}

	forn(i, n) {
		forn(j, m) {
			cin >> mas[i][j];
			if (mas[i][j] == "J1") joker1 = 1;
			if (mas[i][j] == "J2") joker2 = 1;
			av.erase(mas[i][j]);
		}
	}

	for (auto j1 : av) {
		for (auto j2 : av) {
			if (j1 == j2) continue;

			vector<pii> p;
			forn(i, n - 2) {
				forn(j, m - 2) {
					if (check(i, j, j1, j2)) p.push_back({i,j});
				}
			}

			forn (i,p.size()) {
				forn(j, p.size()) {
					if (i == j) continue;

					if (abs(p[i].first - p[j].first) >= 3 || abs(p[i].second - p[j].second) >= 3) {
						cout << "Solution exists.\n";

						if (!joker1 && !joker2) cout << "There are no jokers.\n";
						else if (joker1 || joker2) {
							if (joker1) cout << "Replace J1 with " << j1 << ".\n";
							if (joker2) cout << "Replace J2 with " << j2 << ".\n";
						}
						else cout << "Replace J1 with " << j1 << " and J2 with " << j2 << ".\n";

						cout << "Put the first square to (" << p[i].first + 1 << ", " << p[i].second + 1 << ").\n";
						cout << "Put the second  square to (" << p[j].first + 1 << ", " << p[j].second + 1 << ").\n";
						return 0;
					}
				}
			}
		}
	}

	cout << "No solution.";
	return 0;
}

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;
const int N = 55;
int n, m;
string a[N][N];
set<string>cards;
vector<pair<int, int> >joker;
string suits[] = {"C", "D", "H", "S"};
string ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
void get_cards(){
    for(auto i : suits)
        for(auto j : ranks)
            cards.insert(j + i);
}
void get_input(){
    get_cards();
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> a[i][j];
            if(a[i][j][0] == 'J')
                joker.push_back({i, j});
            else
                cards.erase(a[i][j]);
        }
    }
}
bool good(int r, int c){
    set<char>rnk, sut;
    for(int i = r; i < r + 3; i++){
        for(int j = c; j < c + 3; j++){
            rnk.insert(a[i][j][0]);
            sut.insert(a[i][j][1]);
        }
    }
    return (rnk.size() == 9 || sut.size() == 1);
}
bool overlap(auto a, auto b){
    return abs(a.first - b.first < 3 && abs(a.second - b.second) < 3);
}
vector<pair<int, int>>get_ans(){
    vector<pair<int, int>>s, ans;
    for(int i = 0;  i < n - 2; i++){
        for(int j = 0; j < m - 2; j++)
            if(good(i, j))
                s.push_back({i, j});
    }
    for(auto i : s){
        for(auto j : s){
            if(!overlap(i, j) && ans.empty()){
                ans.push_back(i);
                ans.push_back(j);
            }
        }
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    get_input();
    vector<pair<int, int>>ans;
    if(joker.size() == 0){
        ans = get_ans();
        if(ans.empty())
            return cout << "No solution.", 0;
        cout << "Solution exists.\n";
        cout << "There are no jokers.\n";
        cout << "Put the first square to (" << ans.front().first << ", " << ans.front().second << ").\n";
        cout << "Put the second square to (" << ans.back().first << ", " << ans.back().second << ").\n";
    }
    else if(joker.size() == 1){
        int jx = joker.front().first, jy = joker.front().second;
        char x = a[jx][jy][1];
        string y;
        for(auto i : cards){
            a[jx][jy] = i;
            ans = get_ans();
            if(!ans.empty()){
                y = i;
                break;
            }
        }
        if(ans.empty())
            return cout << "No solution.", 0;
        cout << "Solution exists.\n";
        cout << "Replace J" << x << " with " << y << ".\n";
        cout << "Put the first square to (" << ans.front().first << ", " << ans.front().second << ").\n";
        cout << "Put the second square to (" << ans.back().first << ", " << ans.back().second << ").\n";
    }
    else{
        if(a[joker[0].first][joker[0].second][1] == '2')
            swap(joker[0], joker[1]);
        int jx = joker.front().first, jy = joker.front().second;
        int jxx = joker.back().first, jyy = joker.back().second;
        string x, y;
        for(auto i : cards){
            for(auto j : cards){
                if(i == j) continue;
                a[jx][jy] = i;
                a[jxx][jyy] = j;
                ans = get_ans();
                if(!ans.empty()){
                    x = i, y = j;
                    break;
                }
            }
        }
        if(ans.empty())
                return cout << "No solution.", 0;
        cout << "Solution exists.\n";
        cout << "Replace J1 with " << x << " and J2 with " << y << ".\n";
        cout << "Put the first square to (" << ans.front().first << ", " << ans.front().second << ").\n";
        cout << "Put the second square to (" << ans.back().first << ", " << ans.back().second << ").\n";
    }
    return 0;
}

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <string>

#define Forn(i, n) for(i = 0; i < (int)(n); ++i)
#define forn(i, n) for(int i = 0; i < (int)(n); ++i)
#define ford(i, n) for(int i = (int)(n-1); i >= 0; --i)

#define mp make_pair

using namespace std;

int n, m;

string map[17][17], repJ[2];
vector<string> allCard;
string FR = "23456789TJQKA", SD = "CDHS";
int SQ[2][2];
int Bmap[17][17];

bool check2(){
    forn(num, 2){
        bool f2 = 1;
        forn(di, 3)
            forn(dj, 3)
                f2 &= (map[SQ[num][0]+di][SQ[num][1]+dj][1] == map[SQ[num][0]][SQ[num][1]][1]);
        string tmp;
        forn(di, 3)
            forn(dj, 3)
                tmp += map[SQ[num][0]+di][SQ[num][1]+dj][0];
        sort(tmp.begin(), tmp.end());
        if(unique(tmp.begin(), tmp.end()) != tmp.end() && !f2)
            return 0;
    }
    return 1;
}

bool check(){
    Forn(SQ[0][0], n - 2)
        Forn(SQ[0][1], m - 2)
            Forn(SQ[1][0], n - 2)
                Forn(SQ[1][1], m - 2){
                    bool ok = 1;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                if(++Bmap[SQ[num][0]+di][SQ[num][1]+dj] == 2)
                                    ok = 0;
                    forn(num, 2)
                        forn(di, 3)
                            forn(dj, 3)
                                --Bmap[SQ[num][0]+di][SQ[num][1]+dj];
                    if(ok){
                        if(check2())
                            return 1;
                    }
                }
    return 0;

}

void f(int r, int c){
    if(r < n){
        if(c == m)
            f(r + 1, 0);
        else if(isdigit(map[r][c][1])){
            string J = map[r][c];
            forn(i, allCard.size()){
                swap(allCard[i], allCard[allCard.size()-1]);
                map[r][c] = allCard.back();
                allCard.pop_back();
                repJ[J[1]-'1'] = map[r][c];
                f(r, c + 1);
                allCard.push_back(map[r][c]);
                swap(allCard[i], allCard[allCard.size()-1]);
            }
        }else
            f(r, c + 1);
    }else{
        if(check()){
            cout << "Solution exists." << endl;
            if(repJ[0].length() == 0 && repJ[1].length() == 0 )
                cout << "There are no jokers." << endl;
            else if(repJ[0].length() == 0 || repJ[1].length() == 0 ){
                if(repJ[0].length() == 0)
                    cout << "Replace J2 with " << repJ[1] << "." << endl;
                else
                    cout << "Replace J1 with " << repJ[0] << "." << endl;
            }else
                cout << "Replace J1 with " << repJ[0] << " and J2 with " << repJ[1] << "." << endl;
            cout << "Put the first square to (" << SQ[0][0] + 1 << ", " << SQ[0][1] + 1 << ")." << endl;
            cout << "Put the second square to (" << SQ[1][0] + 1<< ", " << SQ[1][1] + 1 << ")." << endl;
            exit(0);
        }
    }
}

int main()
{
    forn(i, FR.length())
        forn(j, SD.length())
            allCard.push_back(string(1, FR[i]) + SD[j]);
    cin >> n >> m;
    forn(i, n)
        forn(j, m){
            cin >> map[i][j];
            if(map[i][j][0] != 'J')
                allCard.erase(find(allCard.begin(), allCard.end(), map[i][j]));
        }
    f(0, 0);
    cout << "No solution." << endl;
    return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
using namespace std;
static const double EPS = 1e-10;
typedef long long ll;

/*
6 3
J1 2S 3S
4S 5S 6S
7S 8S 9S
J2 2H 3H
4H 5H 6H
7H 8H 9H
*/

int n, m, j1x=-1, j1y=-1, j2x=-1, j2y=-1;
char S[17][17], R[17][17];
char A[4] = {'S', 'H', 'C', 'D'}, B[13] = {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'};

bool checkC(int x, int y){
	map<char, int> memo;
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < 3; j++){
			memo[S[i+y][j+x]]++;
		}
	}
	if(memo['S'] == 9 || memo['H'] == 9 || memo['C'] == 9 || memo['D'] == 9) return true;
	else return false;
}

bool checkR(int x, int y){
	map<char, int> memo;
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < 3; j++){
			memo[R[i+y][j+x]]++;
			if(memo[R[i+y][j+x]] == 2) return false;
		}
	}
	return true;
}

void print(){
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cout << R[i][j] << S[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

int main(){
	cin >> n >> m;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			char a, b;
			cin >> R[i][j] >> S[i][j];
			if(R[i][j] == 'J' && S[i][j] == '1'){
				j1x = j;
				j1y = i;
			}
			if(R[i][j] == 'J' && S[i][j] == '2'){
				j2x = j;
				j2y = i;
			}
		}
	}

	for(int i = 0; i < 52; i++){
		if(j1x != -1){
			S[j1y][j1x] = A[i/13];
			R[j1y][j1x] = B[i%13];
		}
		for(int j = 0; j < 52; j++){
			if(i == j) continue;
			if(j2x != -1){
				S[j2y][j2x] = A[j/13];
				R[j2y][j2x] = B[j%13];
			}
			for(int y = 0; y < n-2; y++){
				for(int x = 0; x < m-2; x++){
					for(int yy = 0; yy < n-2; yy++){
						for(int xx = 0; xx < m-2; xx++){
							if(abs(y-yy) < 3 && abs(x-xx) < 3) continue;
//							if(S[j1y][j1x] == 'C' && R[j1y][j1x] == 'T' && x == 0 && y == 0 && xx == 3 && yy == 1){
//								print();
//								cout << checkC(x, y) << ", " << checkR(x, y) << ", " << checkC(xx, yy) << ", " << checkR(xx, yy) << endl;
//								cout << 1 << endl;
//							}
							if((checkC(x, y) || checkR(x, y)) && (checkC(xx, yy) || checkR(xx, yy))){
								cout << "Solution exists." << endl;
								if(j1x == -1 && j2x == -1) cout << "There are no jokers." << endl;
								else if(j1x != -1 && j2x == -1){
									cout << "Replace J1 with " << R[j1y][j1x] << S[j1y][j1x] << "." << endl;
								}
								else if(j1x == -1 && j2x != -1){
									cout << "Replace J2 with " << R[j2y][j2x] << S[j2y][j2x] << "." << endl;
								}
								else if(j1x != -1 && j2x != -1){
									cout << "Replace J1 with " << R[j1y][j1x] << S[j1y][j1x] << " and J2 with " << R[j2y][j2x] << S[j2y][j2x] << "." << endl;
								}
								cout << "Put the first square to (" << y+1 << ", "<< x+1 << ")." << endl;
								cout << "Put the second square to (" << yy+1 << ", "<< xx+1 << ")." << endl;
								return 0;
							}
						}
					}
				}
			}
		}
	}
	cout << "No solution." << endl;
	return 0;
}

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
string A[18][18],s;
int n,m , U[101],us, J[3][3];
bool B[1001];
int r1,c1,r2,c2,size;

int tonum(char ch){
    if(ch=='C')return 1;
    if(ch=='D')return 2;
    if(ch=='H')return 3;
    if(ch=='S')return 4;
    if(ch=='T')return 8;
    if(ch=='J')return 9;
    if(ch=='Q')return 10;
    if(ch=='K')return 11;
    if(ch=='A')return 12;
    return (int)ch-50;
}

inline bool inside(int a,int b,int c){
    if(b>c)swap(b,c);
    return (b<=a&&a<=c);
}

inline bool ff(int r,int c){
    bool B[13];
    for(int i=0;i<=12;i++)B[i]=false;

    for(int i=r;i<=r+2;i++)
        for(int j=c;j<=c+2;j++){
            if(B[tonum(A[i][j][0])])return false;
            B[tonum(A[i][j][0])]=true;
        }
    return true;
}

inline bool check(){

    for(int i=1;i<=size;i++)
        for(int j=i+1;j<=size;j++){
            r1=(i%m)?i/m+1:i/m;
            c1=(i%m)?(i%m):m;
            r2=(j%m)?j/m+1:j/m;
            c2=(j%m)?(j%m):m;

            if(!(inside(r2,r1,r1+2)&&inside(c2,c1,c1+2) ) &&
               !(inside(r2,r1,r1+2)&&inside(c2+2,c1,c1+2) ) &&
               inside(r1+2,1,n)&&inside(r2+2,1,n) &&
               inside(c1+2,1,m) && inside(c2+2,1,m) ){

                    if(ff(r1,c1)&&ff(r2,c2))return true;

               }
        }
    return false;

}

char torank(int k){
    int r=(k%4)?k/4+1:k/4;
    if(r<=8)return (char)(r+49);
    if(r==9)return 'T';
    if(r==10)return 'J';
    if(r==11)return 'Q';
    if(r==12)return 'K';
    if(r==13)return 'A';
}

char tosuit(int k){
    int r=k%4;
    if(r==0)return 'S';
    if(r==1)return 'C';
    if(r==2)return 'D';
    if(r==3)return 'H';
}

inline bool replace(int j,int k){
    if(J[j][1]==0)return false;
    A[J[j][1]][J[j][2]][0]=torank(k);
    A[J[j][1]][J[j][2]][1]=tosuit(k);
    return true;
}

string print(int k){
    char A[2];
    A[0]=torank(k); A[1]=tosuit(k);
    string s(A);
    return s;
}

void printt(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<A[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}

int main()
{
    bool rep1 , rep2;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>s;
            A[i][j].assign(s);
            if(s[0]=='J'){
                if(s[1]=='1'){
                    J[1][1]=i; J[1][2]=j;
                }
                else{
                    J[2][1]=i; J[2][2]=j;
                }
            }
            B[tonum(s[0])*4+tonum(s[1])]=true;
        }

    size = n*m;
    for(int i=1;i<=52;i++)
        if( !B[i] )U[us++]=i;

    for(int i=0;i<us;i++)
        for(int j=0;j<us;j++)
            if(i!=j){

                rep1=replace(1,U[i]);
                rep2=replace(2,U[j]);

                //printt();

                if(check()){
                    cout<<"Solution exists."<<endl;
                    if(!rep1&&!rep2)cout<<"There are no jokers."<<endl;
                    else if(rep1&&rep2)cout<<"Replace J1 with "<<print(U[i])<<" and J2 with "<<print(U[j])<<"."<<endl;
                    else if(rep1)cout<<"Replace J1 with "<<print(U[i])<<"."<<endl;
                    else if(rep2)cout<<"Replace J2 with "<<print(U[j])<<"."<<endl;
                    cout<<"Put the first square to ("<<r1<<", "<<c1<<")."<<endl;
                    cout<<"Put the second square to ("<<r2<<", "<<c2<<")."<<endl;
                    return 0;
                }

            }

    cout<<"No solution."<<endl;

    return 0;
}

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <sstream>
#include <list>
using namespace std;
typedef long long LL;
//typedef __int64 LL;
typedef pair<int,int> PII;
typedef pair<int,char> PIC;
typedef vector<int> VI;
typedef vector<PII> VPI;
typedef vector<bool> VB;
typedef vector<string> VS;
typedef set<int> SI;
typedef list<string> LS;
typedef map<int, int> MII;
#define ALL(x) x.begin(),x.end()
#define REP(i,a,b) for(int i=(a);i<=(b);i++)
#define FOR(i,a) for(int i=0;i<(a);i++)
#define DEP(i,a,b) for(int i=(a);i>=(b);i--)
#define FORIT(it, c) for(__typeof(c.begin())it=c.begin();it!=c.end();it++)
#define CLR(x,a) memset(x,a,sizeof(x))
#define ALL(x) x.begin(),x.end()
#define LB(x) ((x)&(-(x)))
#define MP make_pair
#define PB push_back
#define oo 0x3f3f3f3f
#define X first
#define Y second
#define sqr(x) ((x)*(x))

const int MAXN = 17 + 10, MAXM = 17 + 10;
int n, m;
string gp[MAXN][MAXN];
vector<PII> res;
vector<string> ans1, ans2;
string str[] = {
"2C", "3C", "4C", "5C", "6C", "7C", "8C", "9C", "TC", "JC", "QC", "KC", "AC",
"2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D", "TD", "JD", "QD", "KD", "AD",
"2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "TH", "JH", "QH", "KH", "AH",
"2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "TS", "JS", "QS", "KS", "AS"
};
bool cnt[MAXN];

bool check(MII& d1, MII& d2){
    bool res1 = true, res2 = true;
    FORIT(it, d1){
        if(it -> Y > 1)res1 = false;
        if(!res1)break;
    }
    if(res1)return true;
    int ans = 0;
    FORIT(it, d2){
        if(it -> Y > 0)ans ++;
        if(ans > 1)res2 = false;
        if(!res2)break;
    }
    return res1 || res2;
}

bool calc(MII &d1, MII &d2, int x, int y, int d){
    //cout << d << endl;
    //if(d > 9)cout << d << endl;
    if(d == 9){
        if(!check(d1, d2))return false;
        MII d3, d4;
        REP(p, x , n - 1){
            if(p + 3 > n)break;
            REP(q, y, m - 1){
                if(q + 3 > m)break;
                if(p == x && q == y)continue;
                if(calc(d3, d4, p, q, d + 1)){
                    res.PB(MP(p, q));
                    return true;
                }
            }
        }
        return false;
    }
    if(d == 19){
        return check(d1, d2);
    }
    int td = d > 9 ? (d - 10) : d;
    string t = gp[x + td / 3][y + td % 3];
    if(t == "J1" || t == "J2"){
        FOR(i, 52){
            if(cnt[i] == 1){
                cnt[i] = 0;
                string tt = str[i];
                d1[tt[0]] ++;
                d2[tt[1]] ++;
                ans1.PB(t);
                ans2.PB(tt);
                if(calc(d1, d2, x, y, d + 1))return true;
                d1[tt[0]] --;
                d2[tt[1]] --;
                ans1.pop_back();
                ans2.pop_back();
                cnt[i] = 1;
            }
        }
    }
    else {
        d1[t[0]] ++;
        d2[t[1]] ++;
        if(calc(d1, d2, x, y, d + 1))return true;
        d1[t[0]] --;
        d2[t[1]] --;
    }
    return false;
}

bool solve(){
    CLR(cnt, 1);
    MII d1, d2;
    FOR(i, n)FOR(j, m)FOR(k, 52){
        if(gp[i][j] == str[k])cnt[k] = 0;
    }
    FOR(i, n){
        if(i + 3 > n)break;
        FOR(j, m){
            if(j + 3 > m)break;
            d1.clear(); d2.clear();
            if(calc(d1, d2, i, j, 0)){
                res.PB(MP(i, j));
                return true;
            }
        }
    }
    return false;
}

int main(){
    cin >> n >> m;
    FOR(i, n){
        FOR(j, m){
            cin >> gp[i][j];
        }
    }
    if(solve()){
        puts("Solution exists.");
        //cout<< ans2.size() << endl;
        if(ans1.size() == 0)puts("There are no jokers.");
        else if(ans1.size() == 1){
            printf("Replace %s with %s.\n",ans1[0].c_str(), ans2[0].c_str());
        }
        else if(ans1.size() ==2){
            if(ans1[0] == "J2") swap(ans2[0], ans2[1]);
            printf("Replace J1 with %s and J2 with %s.\n", ans2[0].c_str(), ans2[1].c_str());
        }
        printf("Put the first square to (%d, %d).\n", res[1].X + 1, res[1].Y + 1);
        printf("Put the second square to (%d, %d).\n", res[0].X + 1, res[0].Y + 1);
    }
    else puts("No solution.");
}

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int n, m;
string card;
int j1x = -1, j1y = -1;
int j2x = -1, j2y = -1;
int sq1x = -1, sq1y = -1;
int sq2x = -1, sq2y = -1;

vector<vector<int> >field(20);

string suits = "HCDS";
string faces = "AT23456789JQK";

void input() {
	cin>>n>>m;
	for(int x=0; x<n; ++x) {
		field[x].resize(m);
	}

	for(int x=0; x<n; ++x) {
		for(int y=0; y<m; ++y) {
			cin>>card;
			int i, j;
			if (card[0] == 'J') {
				if (card[1] == '1' || card[1] == '2') {
					if (card[1] == '1') {
						j1x = x;
						j1y = y;
					} else {
						j2x = x;
						j2y = y;
					}
					continue;
				}
			}

			for(i=0; i < 13; ++i) {
				if (card[0] == faces[i]) {
					break;
				}
			}
			for(j=0; j < 13; ++j) {
				if (card[1] == suits[j]) {
					break;
				}
			}
			field[x][y] = j*13 + i;
		}
	}
}

bool check() {
	int squares_found = 0;

	bool used[52] = {false};
	for(int x = 0; x < n; ++x) {
		for(int y = 0; y < m; ++y) {
			int code = field[x][y];
			if (used[code]) {
				return false;
			}
			used[code] = true;
		}
	}

	for(int x = 0; x + 2 < n; ++x) {
		for(int y = 0; y + 2 < m; ++y) {
			int suits[4] = {0};
			int faces[13] = {0};
			for(int i=0;i<3;++i) {
				for(int j=0;j<3;++j) {
					++suits[field[x+i][y+j] / 13];
					++faces[field[x+i][y+j] % 13];
				}
			}
			bool suit_valid = true;
			for(int f=0; f<4;++f) {
				if (suits[f] != 0 && suits[f] != 9) {
					suit_valid = false;
					break;
				}
			}
			bool faces_valid = true;
			for(int f=0; f<13;++f) {
				if (faces[f] > 1) {
					faces_valid = false;
					break;
				}
			}
			if (suit_valid || faces_valid) {
				++squares_found;
				if (squares_found == 1) {
					sq1x = x+1;
					sq1y = y+1;
				}
				if (squares_found == 2) {
					sq2x = x+1;
					sq2y = y+1;
					bool x_overlap = (sq2x >= sq1x && sq2x <= sq1x + 2) || (sq1x >= sq2x && sq1x <= sq2x + 2);
					bool y_overlap = (sq2y >= sq1y && sq2y <= sq1y + 2) || (sq1y >= sq2y && sq1y <= sq2y + 2);
					if (x_overlap && y_overlap) {
						squares_found -= 1;
						sq2x = -1;
						sq2y = -1;
					} else {
						return true;
					}
				}
			}
		}
	}

	return false;
}

string card_name(int i) {
	int suit = i / 13;
	int face = i % 13;
	string s;
	s += faces[face];
	s += suits[suit];
	return s;
}

void solve() {
	for(int i = 0; i < 52; ++i) {
		if (j1x == -1) {
			continue;
		}
		field[j1x][j1y] = i;
		for(int j = 0; j < 52; ++j) {
			if (j2x == -1) {
				continue;
			}
			field[j2x][j2y] = j;
			if (check()) {
				cout<<"Solution exists."<<endl;
				cout<<"Replace J1 with "<<card_name(i)<<"."<<endl;
				cout<<"Replace J2 with "<<card_name(j)<<"."<<endl;
				cout<<"Put the first square to ("<<sq1x<<", "<<sq1y<<")."<<endl;
				cout<<"Put the second square to ("<<sq2x<<", "<<sq2y<<")."<<endl;
				return;
			}
		}
		if (check()) {
			cout<<"Solution exists."<<endl;
			cout<<"Replace J1 with "<<card_name(i)<<"."<<endl;
			cout<<"Put the first square to ("<<sq1x<<", "<<sq1y<<")."<<endl;
			cout<<"Put the second square to ("<<sq2x<<", "<<sq2y<<")."<<endl;
			return;
		}
	}
	if (check()) {
		cout<<"Solution exists."<<endl;
		cout<<"There are no jokers."<<endl;
		cout<<"Put the first square to ("<<sq1x<<", "<<sq1y<<")."<<endl;
		cout<<"Put the second square to ("<<sq2x<<", "<<sq2y<<")."<<endl;
		return;
	}
	cout<<"No solution."<<endl;
}

int main() {
	//freopen("d.in","rt", stdin);
	input();
	solve();
	return 0;
}

//HACK ME, PLEASE! ^_^
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <math.h>
#include <cstdlib>
#include <memory.h>
#include <queue>
#include <assert.h>

#define pb push_back
#define i64 long long
#define mp make_pair
#define pii pair <int,int>
#define vi vector <int>
#define vii vector <pii>
#define f first
#define s second
#define foran(i,a,b) for (int i=a;i<(int)b;i++)
#define forn(i,n) for (int i=0;i<(int)n;i++)
#define ford(i,n) for (int i=(int)n-1;i>=0;i--)
#define sqr(x) (x) * (x)
#define y1 fucking_y1

const double eps = 1e-9;
const int int_inf = 1 << 31 - 1;
const i64 i64_inf = 1ll << 63 - 1;
const double pi = acos(-1.0);

using namespace std;

char dost[] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
char mast[] = { 'C', 'D', 'H', 'S' };
bool has[13][4];
int n, m;

char s[55][55][2];

bool in(int x, int y, int x1, int y1)
{
   return x1 >= x && x1 <= x + 2 && y1 >= y && y1 <= y + 2;
}

bool ok(int i, int j)
{
    int ok = 1;
    for (int ii = i; ii < i + 3; ii++)
     for (int jj = j; jj < j + 3; jj++)
      if  (s[ii][jj][1] != s[i][j][1]) ok = 0;
    if  (ok) return 1;

    string str = "";
    for (int ii = i; ii < i + 3; ii++)
     for (int jj = j; jj < j + 3; jj++)
      str += s[ii][jj][0];

    sort(str.begin(), str.end());
    str.resize( unique(str.begin(), str.end()) - str.begin());
    return (int)str.length() == 9;
}

int I1, J1, I2, J2;

bool check()
{
  for (int i1 = 0; i1 < n - 2; i1++)
   for (int j1 = 0; j1 < m - 2; j1++)
    for (int i2 = 0; i2 < n - 2; i2++)
     for (int j2 = 0; j2 < m - 2; j2++)
     {
         if  (in(i1, j1, i2, j2) || in(i1, j1, i2 + 2, j2) || in(i1, j1, i2, j2 + 2)
              || in(i1, j1, i2 + 2, j2 + 2))
          continue;

         if  (ok(i1, j1) && ok(i2,  j2)) { I1 = i1; J1 = j1; I2 = i2; J2 = j2; return 1; }
     }
  return 0;
}

void solve0()
{
    if  (!check()) return;
    puts("Solution exists.");
    puts("There are no jokers.");
    printf("Put the first square to (%d, %d).\n", I1 + 1, J1 + 1);
    printf("Put the second square to (%d, %d).\n", I2 + 1, J2 + 1);
    exit(0);
}

void solve1()
{
    bool ok = 0;
    int II, JJ;
    int joki, jokj;

    forn(i, n)
     forn(j, m)
      if  (s[i][j][0] == 'J')
        for (int ii = 0; ii < 13 && !ok; ii++)
         for (int jj = 0; jj < 4 && !ok; jj++)
          if  (!has[ii][jj])
          {
              joki = i; jokj = j;
              char prev = s[i][j][1];
              s[i][j][0] = dost[ii];
              s[i][j][1] = mast[jj];
              if  (check()) { ok = 1; II = ii; JJ = jj; }
              s[i][j][0] = 'J'; s[i][j][1] = prev;
          }

    if  (!ok) return;
    puts("Solution exists.");
    printf("Replace J%c with %c%c.\n", s[joki][jokj][1], dost[II], mast[JJ]);
    printf("Put the first square to (%d, %d).\n", I1 + 1, J1 + 1);
    printf("Put the second square to (%d, %d).\n", I2 + 1, J2 + 1);
    exit(0);
}

void solve2()
{
  int joki1, jokj1, joki2, jokj2;
  forn(i, n)
   forn(j, m)
    if  (s[i][j][0] == 'J')
     if  (s[i][j][1] == '1') joki1 = i, jokj1 = j; else
      joki2 = i, jokj2 = j;

 for (int ii1 = 0; ii1 < 13; ii1++)
  for (int jj1 = 0; jj1 < 4; jj1++)
   for (int ii2 = 0; ii2 < 13; ii2++)
    for (int jj2 = 0; jj2 < 4; jj2++)
    {
        if  (ii1 == ii2 && jj1 == jj2) continue;
        if  (has[ii1][jj1] || has[ii2][jj2]) continue;
        s[joki1][jokj1][0] = dost[ii1];
        s[joki1][jokj1][1] = mast[jj1];
        s[joki2][jokj2][0] = dost[ii2];
        s[joki2][jokj2][1] = mast[jj2];

        if  (check())
        {
           puts("Solution exists.");
           printf("Replace J1 with %c%c and J2 with %c%c.\n", dost[ii1], mast[jj1], dost[ii2], mast[jj2]);
           printf("Put the first square to (%d, %d).\n", I1 + 1, J1 + 1);
           printf("Put the second square to (%d, %d).\n", I2 + 1, J2 + 1);
           exit(0);
        }
    }
}

int main() {
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
  memset(has, 0, sizeof has);
  scanf("%d%d\n", &n, &m);

  bool was1 = 0; bool was2 = 0;
  forn(i, n)
   forn(j, m)
   {
      scanf("%c%c ", &s[i][j][0], &s[i][j][1]);
      if  (s[i][j][0] == 'J' && s[i][j][1] == '1') was1 = 1;
      if  (s[i][j][0] == 'J' && s[i][j][1] == '2') was2 = 1;
      for (int ii = 0; ii < 13; ii++)
       for (int jj = 0; jj < 4; jj++)
        if  (dost[ii] == s[i][j][0] && mast[jj] == s[i][j][1])
            has[ii][jj] = 1;
   }

  if  (!was1 && !was2) solve0(); else
   if  (was1 && was2) solve2(); else solve1();

  puts("No solution.");
  return 0;
}

#include<bits/stdc++.h>
#define j1 asdf
#define j2 ghjk
#define rank lzxc
using namespace std;
int n,m;
string rank="23456789TJQKA";
string suit="CDHS";
string tmp;
int cards[20][20];
bool vis[52];
vector<int> canid;
pair<int,int> j1,j2;
pair<int,int> s0,s1;
map<string,int> code;//(0~51) for normal,(-1,-2) for joker
int ecd(string s){//encode
	return code[s];
}
int gsuit(int x){
	return x%4;
}
int grank(int x){
	return x/4;
}
void put_square(){
	cout<<"Put the first square to ("<<s0.first<<", "<<s0.second<<")."<<endl;
	cout<<"Put the second square to ("<<s1.first<<", "<<s1.second<<")."<<endl;
}
string dcd(int x){
	string s="";
	s+=rank[grank(x)];
	s+=suit[gsuit(x)];
	return s;
}
bool ok(int x,int y){
	set<int> st,rk;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			st.insert(gsuit(cards[x+i][y+j]));
			rk.insert(grank(cards[x+i][y+j]));
		}
	}
	return ((st.size()==1)||(rk.size()==9));
}
bool has[20][20];
bool overlap(pair<int,int> a,pair<int,int> b){
	memset(has,false,sizeof(has));
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			has[a.first+i][a.second+j]=true;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			if(has[b.first+i][b.first+j])
				return false;
	return true;
}
bool solve(){
	int cnt=0;
	vector<pair<int,int> > po;
	for(int i=1;i<=n-2;i++){
		for(int j=1;j<=m-2;j++){
			if(ok(i,j)){
				po.push_back(make_pair(i,j));
			}
		}
	}
	if(po.size()<2)
		return false;
	for(int i=0;i<po.size();i++){
		for(int j=i+1;j<po.size();j++){
			if(!overlap(po[i],po[j])){
				s0=po[0];
				s1=po[j];
				return true;
			}
		}
	}
	return false;
}
int main(){
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	for(int i=0;i<13;i++){
		for(int j=0;j<4;j++){
			string s="";
			s+=rank[i];
			s+=suit[j];
			code[s]=i*4+j;
		}
	}
	code["J1"]=-1;
	code["J2"]=-2;
	cin>>n>>m;
	int jkh=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>tmp;
			cards[i][j]=ecd(tmp);
			if(cards[i][j]==-1){
				jkh+=1;
				j1=make_pair(i,j);
			}
			else if(cards[i][j]==-2){
				jkh+=2;
				j2=make_pair(i,j);
			}
			else{
				vis[cards[i][j]]=true;
			}
		}
	}
	for(int i=0;i<52;i++)
		if(!vis[i])
			canid.push_back(i);
	if(jkh==0){
		if(solve()){
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
			put_square();
			return 0;
		}
		else{
			cout<<"No solution."<<endl;
			return 0;
		}
	}
	else if(jkh==1||jkh==2){
		pair<int,int> at;
		if(jkh==1)
			at=j1;
		else
			at=j2;
		for(int ii=0;ii<canid.size();ii++){
			int i=canid[ii];
			cards[at.first][at.second]=i;
			if(solve()){
				cout<<"Solution exists."<<endl;
				cout<<"Replace J"<<jkh<<" with "<<dcd(i)<<"."<<endl;
				put_square();
				return 0;
			}
			cards[at.first][at.second]=-jkh;
		}
		cout<<"No solution."<<endl;
		return 0;
	}
	else{
		for(int ii=0;ii<canid.size();ii++){
			int i=canid[ii];
			for(int jj=0;jj<canid.size();jj++){
				int j=canid[jj];
				if(i==j)
					continue;
				cards[j1.first][j1.second]=i;
				cards[j2.first][j2.second]=j;
				if(solve()){
					cout<<"Solution exists."<<endl;
					cout<<"Replace J1 with "<<dcd(i)<<" and J2 with "<<dcd(j)<<"."<<endl;
					put_square();
					return 0;
				}
				cards[j1.first][j1.second]=-1;
				cards[j2.first][j2.second]=-2;
			}
		}
		cout<<"No solution."<<endl;
		return 0;
	}
	return 0;
}

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman010 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
int n , m;
vector<pair<int , int>> ans;
map<int , string> joker;
string s[20][20];
set<string> in;
bool done[20][20];
void mark(int i , int j , set<char> &st , set<char> &st2) {
    ans.push_back({i + 1 , j + 1});
    for(int p1 = 0;p1 < 3;p1++)
        for(int p2 = 0;p2 < 3;p2++)
            done[i + p1][j + p2] = true;
    for(auto &k : st2)
        st.erase(k);
}
int main() {
    abdelrahman010
    cin >> n >> m;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++)
            cin >> s[i][j] , in.insert(s[i][j]);
    for(int i = 0;i + 2 < n;i++)
        for(int j = 0;j + 2 < m;j++) {
            if(done[i][j])
                continue;
            set<char> st , st1 , st2;
            vector<int> v;
            for(int p1 = 0;p1 < 3;p1++)
                for(int p2 = 0;p2 < 3;p2++)
                    if(s[i + p1][j + p2][0] == 'J')
                        v.push_back(s[i + p1][j + p2][1] - '0');
                    else {
                        st1.insert(s[i + p1][j + p2][1]);
                        st2.insert(s[i + p1][j + p2][0]);
                    }
            for(char c = '2';c <= '9';c++)
                st.insert(c);
            st.insert('T') , st.insert('Q');
            st.insert('R') , st.insert('A');
            if(st1.size() == 1) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    string m = "";
                    for(char c = '2';c <= '9';c++) {
                        m += c;
                        m += *st1.begin();
                        if(!in.count(m))
                            break;
                        else
                            m = "";
                    }
                    if(m == "")
                        for(auto &c : {'A' , 'Q' , 'K' , 'T'}) {
                            m += c;
                            m += *st1.begin();
                            if(!in.count(m))
                                break;
                            else
                                m = "";
                        }
                    in.insert(m);
                    joker[k] = m;
                }
            } else if(st2.size() + v.size() == 9) {
                mark(i , j , st , st2);
                for(auto &k : v) {
                    string m = "";
                    for(auto &p1 : st) {
                        m = "";
                        for(auto &p2 : {'C' , 'D' , 'H' , 'S'}) {
                            m += p1 , m += p2;
                            if(!in.count(m))
                                break;
                            else
                                m = "";
                        }
                        if(m != "")
                            break;
                    }
                    in.insert(m);
                    joker[k] = m;
                }
            }
        }
    if(ans.size() < 2)
        return cout << "No solution." , 0;
    cout << "Solution exists.\n";
    vector<pair<string , string>> jr;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < m;j++)
                if(s[i][j][0] == 'J') {
                    int k = s[i][j][1] - '0';
                    jr.push_back({s[i][j] , joker[k]});
                }
    if(!jr.size())
        cout << "There are no jokers.\n";
    else if(jr.size() == 1)
        cout << "Replace " << jr[0].first << " with " << jr[0].second << ".\n";
    else
        cout << "Replace " << jr[0].first << " with " << jr[0].second << " and " << jr[1].first << " with " << jr[1].second << ".\n";
    cout << "Put the first square to (" << ans[0].first << ", " << ans[0].second << ").\n";
    cout << "Put the second square to (" << ans[1].first << ", " << ans[1].second << ").";
    return 0;
}

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
char a[20][20],b[20][20];
char A[20]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char B[5]={'C','D','H','S'};
int x1=0,y1=0,x2=0,y2=0,ans1,ans2,ans3,ans4;
int n,m,qwq=0;
int vis[500][500],va[100],vb[100];
inline bool pd()
{
	vector <pair<int,int> > v;
	for(int i=1;i<=n-2;i++)
	{
		for(int j=1;j<=m-2;j++)
		{
			int flag1=1,flag2=1;
			memset(va,0,sizeof va);
			memset(vb,0,sizeof vb);
			for(int k=i;k<i+3;k++)
			{
				for(int l=j;l<j+3;l++)
				{
					if(va[a[k][l]]) flag1=0;
					if(!vb[b[k][l]]&&(k>i||l>j))
						flag2=0;
					++va[a[k][l]],++vb[b[k][l]];
				}
			}
			if(flag1|flag2) v.push_back({i,j});
		}
	}
	for(int i=0;i<v.size();i++)
	{
		for(int j=i+1;j<v.size();j++)
		{
			if(v[i].first-v[j].first>2||v[j].first-v[i].first>2||v[i].second-v[j].second>2||v[j].second-v[i].second>2)
			{
				ans1=v[i].first,ans2=v[i].second;
				ans3=v[j].first,ans4=v[j].second;
				return 1;
			}
		}
	}
	return 0;
}
int main(int argc, char** argv) {
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin >> a[i][j] >> b[i][j];
			vis[a[i][j]][b[i][j]]=1;
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(b[i][j]<='2')
			{
				if(!x1) x1=i,y1=j,qwq=b[i][j]-'0';
				else x2=i,y2=j;
			}
		}
	}
	if(qwq==2&&x2) swap(x1,x2),swap(y1,y2);
	if(!x1)
	{
		if(pd())
		{
			cout << "Solution exists.\nThere are no jokers.\nPut the first square to (";
			cout << ans1 << ", " << ans2 << ").\n" << "Put the second square to (" << ans3 << ", " << ans4 << ").\n";
			return 0;
		}
		puts("No solution.");
	}
	else if(!x2)
	{
		for(int i=0;i<13;i++)
		{
			for(int j=0;j<5;j++)
			{
				if(vis[A[i]][B[j]]) continue;
				a[x1][y1]=A[i],b[x1][y1]=B[i];
				if(pd())
				{
					cout << "Solution exists.\nReplace J" << qwq << " with " << A[i] << B[j] << ".\n";
					cout << "Put the first square to (";
					cout << ans1 << ", " << ans2 << ").\n" << "Put the second square to (" << ans3 << ", " << ans4 << ").\n";
					return 0;
				}
			}
		}
		puts("No solution.");
	}
	else
	{
		for(int i=0;i<13;i++)
		{
			for(int j=0;j<5;j++)
			{
				if(vis[A[i]][B[j]]) continue;
				a[x1][y1]=A[i],b[x1][y1]=B[i];
				for(int k=0;k<13;k++)
				{
					for(int l=0;l<5;l++)
					{
						if(vis[A[k]][B[l]]) continue;
						if(A[i]==A[k]&&B[j]==B[l]) continue;
						a[x2][y2]=A[k],b[x2][y2]=B[l];
						if(pd())
						{
							cout << "Solution exists.\nReplace J1 with " << A[i] << B[j] << " and J2 with " << A[k] << B[l] << ".\n";
							cout << "Put the first square to (";
							cout << ans1 << ", " << ans2 << ").\n" << "Put the second square to (" << ans3 << ", " << ans4 << ").\n";
							return 0;
						}
					}
				}
			}
		}
	}
	return 0;
}

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <functional>
#include <cmath>
#include <sstream>
#include <memory.h>

#define forn(i,n) for (int i = 0; i < (int)(n); i++)
#define forv(i, a) for(int i=0; i<(int)a.size(); i++)
#define all(a) a.begin(),a.end()
#define mp make_pair
#define pb push_back
#define sz size()
#define VI vector< int >
#define VS vector< string >
#define PII pair< int,int >
#define PDD pair< double,double >
#define PIS pair< int, string >
#define sqr(a) ((a)*(a))
#define cube(a) ((a)*(a)*(a))
#define pi 3.1415926535897932384626433832795
const int inf=500*1000*1000;
#define eps 1e-7
using namespace std;

struct card{
	int m;
	int d;
	bool operator<(const card &c) const{
		if(m!=c.m) return m<c.m;
		else return d<c.d;
	}
};

int J;
int n, m;
card d[18][18];
PII jok[2];
char dost[13]={'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char mast[4]={'C', 'D', 'H', 'S'};
map<card, bool> used;

card read(){
	char str[3];
	card temp;
	cin>>str;

	temp.m=str[1];
	temp.d=str[0];
	used[temp]=true;

	return temp;
}

bool ok(int x, int y){
	if(x>n-3 || y>m-3) return false;

	int comm=d[x][y].m;
	bool cm=true, dd=true;
	for(int i=x; i<x+3; i++)
		for(int j=y; j<y+3; j++){
			if(d[i][j].m!=comm) cm=false;

			for(int i1=x; i1<x+3; i1++)
				for(int j1=y; j1<y+3; j1++)
					if(!(i==i1 && j==j1) && d[i][j].d==d[i1][j1].d) dd=false;

		}
	return (cm || dd);
}

bool win(int &x1, int &y1, int &x2, int &y2){
	forn(i, n)forn(j, m){
		forn(i1, n)forn(j1, m){
			if(i1>i+2 || j1>j+2)
				if(ok(i, j) && ok(i1, j1)){
					x1=i; y1=j; x2=i1; y2=j1;
					return true;
				}
		}
	}
	return false;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	J=0;
	int x1, x2, y2, y1;
	cin>>n>>m;

	forn(i, n)forn(j, m){
		d[i][j]=read();
		if(d[i][j].d=='J'){
			jok[d[i][j].m-'1']=mp(i, j);
			J++;
		}
	}

	if(J==0){
		if(win(x1, y1, x2, y2)){
		cout<<"Solution exists."<<endl;
		cout<<"There are no jokers."<<endl;
		cout<<"Put the first square to ("<<x1+1<<", "<<y1+1<<")."<<endl;
		cout<<"Put the second square to ("<<x2+1<<", "<<y2+1<<")."<<endl;
		}
		else cout<<"No solution.";
		return 0;
	}

	int px1, py1, px2, py2;
	bool b=false;

	for(px1=0; px1<13; px1++){
		for(py1=0; py1<4; py1++){
			d[jok[0].first][jok[0].second].d=dost[px1];
			d[jok[0].first][jok[0].second].m=mast[py1];
			if(used[d[jok[0].first][jok[0].second]]) continue;
			if(J>1){
				for(px2=0; px2<13; px2++){
					for(py2=0; py2<4; py2++){
						d[jok[1].first][jok[1].second].d=dost[px2];
						d[jok[1].first][jok[1].second].m=mast[py2];
						if(used[d[jok[1].first][jok[1].second]]) continue;
						if(win(x1, y1, x2, y2)){ b=true; break;}
					}
					if(b) break;
				}
			}
			else{
				if(win(x1, y1, x2, y2)) b=true;
			}
			if(b) break;
		}
		if(b) break;
	}

	if(!b){
		cout<<"No solution.";
	}
	else{
		cout<<"Solution exists."<<endl;
		if(J>1) cout<<"Replace J1 with "<<dost[px1]<<mast[py1]<<" and J2 with "<<dost[px2]<<mast[py2]<<"."<<endl;
		else cout<<"Replace J1 with "<<dost[px1]<<mast[py1]<<"."<<endl;
		cout<<"Put the first square to ("<<x1+1<<", "<<y1+1<<")."<<endl;
		cout<<"Put the second square to ("<<x2+1<<", "<<y2+1<<")."<<endl;
	}

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define iinf 2000000000
#define linf 1000000000000000000LL
#define ulinf 10000000000000000000ull
#define MOD1 1000000007LL
#define mpr make_pair
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned long UL;
typedef unsigned short US;
typedef pair < int , int > pii;
clock_t __stt;
inline void TStart(){__stt=clock();}
inline void TReport(){printf("\nTaken Time : %.3lf sec\n",(double)(clock()-__stt)/CLOCKS_PER_SEC);}
template < typename T > T MIN(T a,T b){return a<b?a:b;}
template < typename T > T MAX(T a,T b){return a>b?a:b;}
template < typename T > T ABS(T a){return a>0?a:(-a);}
template < typename T > void UMIN(T &a,T b){if(b<a) a=b;}
template < typename T > void UMAX(T &a,T b){if(b>a) a=b;}
char ss[5]="CDHS",rs[14]="23456789TJQKA";
int n,m,sct;
bool used[505][505],ok[20][20],occ[505];
char su[20][20],rk[20][20],str[10][105];
char readchar(){
	char c=getchar();
	while(c==' '||c=='\n') c=getchar();
	return c;
}
void output(){
	printf("Solution exists.\n");
	if(!sct){
		printf("There are no jokers.\n");
	}
	else{
		printf("Replace %s.\n",str[sct-1]);
	}
}
void check(){
	int i,j,k,l;
	for(i=0;i+2<n;++i){
		for(j=0;j+2<m;++j){
			bool okS=1,okR=1;
			for(k=0;k<3;++k){
				for(l=0;l<3;++l){
					if(su[i+k][j+l]!=su[i][j]) okS=0;
					if(occ[rk[i+k][j+l]]) okR=0;
					occ[rk[i+k][j+l]]=1;
				}
			}
			for(k=0;k<3;++k){
				for(l=0;l<3;++l){
					occ[rk[i+k][j+l]]=0;
				}
			}
			ok[i][j]=(okS||okR);
		}
	}
	for(i=0;i+2<n;++i){
		for(j=0;j+2<m;++j){
			for(k=i;k+2<n;++k){
				for(l=0;l+2<m;++l){
					if(ABS(k-i)>=3 || ABS(l-j)>=3){
						if(ok[i][j] && ok[k][l]){
							output();
							printf("Put the first square to (%d, %d).\n",i+1,j+1);
							printf("Put the second square to (%d, %d).\n",k+1,l+1);
							exit(0);
						}
					}
				}
			}
		}
	}
}
void go(int i,int j){
	int k,l;
	++j;
	for(;i<n;++i){
		for(;j<m;++j){
			if(rk[i][j]=='J'){
				char num=su[i][j];
				for(k=0;k<4;++k){
					for(l=0;l<13;++l){
						if(!used[ss[k]][rs[l]]){
							++sct;
							if(num=='2')
								sprintf(str[1],"%s and J%c with %c%c",str[0],num,rs[l],ss[k]);
							else
								sprintf(str[1],"J%c with %c%c and %s",num,rs[l],ss[k],str[0]);
							su[i][j]=ss[k];
							rk[i][j]=rs[l];
							check();
							--sct;
							su[i][j]=num;
							rk[i][j]='J';
						}
					}
				}
				return;
			}
		}
		j=0;
	}
	check();
}
int main(){
    // inputting start
    // 数据结构记得初始化！ n，m别写反！
    int i,j,k,l;
	scanf("%d%d",&n,&m);
	for(i=0;i<n;++i){
		for(j=0;j<m;++j){
			rk[i][j]=readchar();
			su[i][j]=readchar();
		}
	}
    #ifdef LOCAL
        TStart();
    #endif
    // calculation start
    // 数据结构记得初始化！ n，m别写反！
    for(i=0;i<n;++i){
		for(j=0;j<m;++j){
			used[su[i][j]][rk[i][j]]=1;
		}
	}
	bool meet=0;
	for(i=0;i<n;++i){
		for(j=0;j<m;++j){
			if(rk[i][j]=='J'){
				meet=1;
				char num=su[i][j];
				for(k=0;k<4;++k){
					for(l=0;l<13;++l){
						if(!used[ss[k]][rs[l]]){
							used[ss[k]][rs[l]]=1;
							sprintf(str[sct++],"J%c with %c%c",num,rs[l],ss[k]);
							su[i][j]=ss[k];
							rk[i][j]=rs[l];
							go(i,j);
							--sct;
							used[ss[k]][rs[l]]=0;
							su[i][j]=num;
							rk[i][j]='J';
						}
					}
				}
			}
		}
	}
	if(!meet) check();
	printf("No solution.\n");
    #ifdef LOCAL
        TReport();
    #endif
    return 0;
}

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;
int n,m;
string s[70][70];
vector <string> ve;
map <string,int> ma;
int klj[80][80];
int kla=0;
vector <pair<int,int> > votv;
int cnt[80][80];
int main() {
    string s1="23456789TJQKA";
    string s2="CDHS";
    int n,m;
    cin>>n>>m;
    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;
            ma[s3]=1;
        }int kljok=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            cin>>s[i][j];
            ma[s[i][j]]=0;
            if(s[i][j]=="J1" || s[i][j]=="J2") kljok++;
        }

    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;

            if (ma[s3]==1) ve.push_back(s3);

        }
    for (int i=0; i<n-2; i++)
        for (int j=0; j<m-2; j++) {
            map<char,int> mra;
            int f1=0,f2=0;
            int kj=0;
            for (int i1=0; i1<3; i1++)
                for (int j1=0; j1<3; j1++) {
                    if (s[i+i1][j+j1]!="J1" && s[i+i1][j+j1]!="J2") {
                        if (mra[s[i+i1][j+j1][0]]==0)
                            mra[s[i+i1][j+j1][0]]++;
                        else f1=1;
                        if (mra[s[i+i1][j+j1][1]]==0) {
                            mra[s[i+i1][j+j1][1]]=1;
                            f2++;
                        }

                    } else if (s[i+i1][j+j1]=="J1")kj++;
                    else if (s[i+i1][j+j1]=="J2") kj+=2;
                }
            //cout<<i<<' '<<j<<' '<<f1<<' '<<f2<<' '<<kj<<endl;
            klj[i][j]=kj;
            if (f1==0 || f2==1) {
                votv.push_back(make_pair(i,j));
            }
        }

    if (votv.size()<2) {
        cout<<"No solution.";
        return 0;
    }
                string jock1="",jock2="";
int nom1=-1,nom2=-1;
    for(int i=0; i<votv.size(); i++)
        for (int j=i+1; j<votv.size(); j++) {
             jock1="",jock2="";nom1=-1,nom2=-1;
             int x=votv[i].first;
            int y=votv[i].second;
            int x1=votv[j].first;
            int y1=votv[j].second;
            if (abs(x-x1)>2 || abs(y-y1)>2) {
            if (klj[x][y]==0 && klj[x1][y1]==0) {
                nom1=i;nom2=j;
                break;
            }

            if (klj[x][y]!=0 || klj[x][y]!=3) { int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++) {
                        if (mra[s[x+i1][y+j1][0]]==0)
                            mra[s[x+i1][y+j1][0]]++;
                        else f1=1;
                        if (mra[s[x+i1][y+j1][1]]==0) {
                            mra[s[x+i1][y+j1][1]]=1;
                            f2++;
                        }
                    }
                if (f2==1) {
                    char r=s[x][y][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            jock1=ve[l];
                            break;
                        }
                }
                if (f1==0) {
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                            jock1=ve[l];
                            break;
                        }

                }
            }
            if (klj[x1][y1]!=0 || klj[x1][y1]!=3) {int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++) {
                        if (mra[s[x1+i1][y1+j1][0]]==0)
                            mra[s[x1+i1][y1+j1][0]]++;
                        else f1=1;
                        if (mra[s[x1+i1][y1+j1][1]]==0) {
                            mra[s[x1+i1][y1+j1][1]]=1;
                            f2++;
                        }
                    }
                if (f2==1) {
                    char r=s[x1][y1][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            jock2=ve[l];
                            break;
                        }
                }
                if (f1==0) {
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                            jock2=ve[l];
                            break;
                        }
                }
            }
            if (klj[x][y]==3) {

                int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++) {
                        if(s[x+i1][y+y1]!="J1" && s[x+i1][y+y1]!="J2") {
                        if (mra[s[x+i1][y+j1][0]]==0)
                            mra[s[x+i1][y+j1][0]]++;
                        else f1=1;
                        if (mra[s[x+i1][y+j1][1]]==0) {
                            mra[s[x+i1][y+j1][1]]=1;
                            f2++;
                        }
                    }}
                if (f2==1) { int lrr=1;
                    char r=s[x][y][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            if (lrr==1)
                            jock1=ve[l];
                        else {jock2=ve[l];
                            break;}
                        }
                }
                if (f1==0) { int lrr=1;
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                                if (lrr==1)
                            jock1=ve[l];
                        else {jock2==ve[l];
                            break;}
                        }
                }
            }

if (klj[x1][y1]==3) {

                int f1=0,f2=0;            map<char,int> mra;

                for (int i1=0; i1<3; i1++)
                    for (int j1=0; j1<3; j1++)

                        { if (s[x1+i1][y1+j1]!="J1" && s[x1+i1][y1+j1]!="J2"){
                        if (mra[s[x1+i1][y1+j1][0]]==0)
                            mra[s[x1+i1][y1+j1][0]]++;
                        else f1=1;
                        if (mra[s[x1+i1][y1+j1][1]]==0) {
                            mra[s[x1+i1][y1+j1][1]]=1;
                            f2++;
                        }
                    }}
                if (f2==1) { int lrr=1;
                    char r=s[x1][y1][1];
                    for(int l=0; l<ve.size(); l++)
                        if (ve[l][1]==r) {
                            if (lrr==1)
                            jock1=ve[l];
                        else {jock2=ve[l];
                            break;}
                        }
                }
                if (f1==0) { int lrr=1;
                    for(int l=0; l<ve.size(); l++)
                        if (mra[ve[l][0]]==0) {
                                if (lrr==1)
                            jock1=ve[l];
                        else {jock2==ve[l];
                            break;}
                        }
                }
            }

            if (kljok==2 && jock1!="" && jock2!="") {nom1=i;nom2=j;break;}
            else if (kljok==1 && ((jock1!="") || jock2!="")) {nom1=i;nom2=j;break;}
            else if (kljok==0) {nom1=i;nom2=j;break;}
        }
        }
        if (nom1==-1 || nom2==-1) {cout<<"No solution.";return 0;}
        cout<<"Solution exists."<<endl;
        if (kljok==0) {cout<<"There are no jokers."<<endl;}
        if (kljok==1) {if (jock1=="") {string sr="";if (klj[votv[nom2].first][votv[nom2].second]==1) sr="J1";
        else sr="J2"; cout<<"Replace "<<sr<<" with "<<jock2<<'.'<<endl;}
        else  {string sr="";if (klj[votv[nom1].first][votv[nom1].second]==1) sr="J1";
        else sr="J2"; cout<<"Replace "<<sr<<" with "<<jock1<<'.'<<endl;}}
        if (kljok==2)
        cout<<"Replace J1 with "<<jock1<<" and J2 with "<<jock2<<'.'<<endl;
        cout<<"Put the first square to ("<<votv[nom1].first+1<<", "<<votv[nom1].second+1<<")."<<endl;
        cout<<"Put the second square to ("<<votv[nom2].first+1<<", "<<votv[nom2].second+1<<")."<<endl;

}

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    string s;
    char arr[n+1][m+1],arr2[n+1][m+1];
    int cnt=0,cnt1,x1=-1,x2=-1,y1=-1,y2=-1;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            cin>>s;
            if(s[0]=='J')
            {
                arr[i][j]='0';
                if(!cnt)
                {
                    x1=i;
                    y1=j;
                    cnt++;
                }
                else
                {
                    x2=i;
                    y2=j;
                    cnt++;
                }
            }
            else
                arr[i][j]=s[0];
            arr2[i][j]=s[1];
            if(s[0]=='J')
                arr2[i][j]='1';
        }
    }
    //cout<<cnt<<endl;
    cnt1=cnt;
    int rx1=-1,rx2=-1,ry1=-1,ry2=-1;
    int sx1,sx2,sy1,sy2;
    int vis[14],square=0;
    bool banned[n][m];
    string a,b;
    memset(banned,0,sizeof banned);
    for(int i=0; i<n-2; i++)
    {
        for(int j=0; j<m-2; j++)
        {
            if(banned[i][j])
                continue;
            memset(vis,0,sizeof vis);
            for(int k=i; k<i+3; k++)
            {
                for(int l=j; l<j+3; l++)
                {
                    if(arr[k][l]=='T')
                        vis[10]++;
                    else if(arr[k][l]=='A')
                        vis[11]++;
                    else if(arr[k][l]=='Q')
                        vis[12]++;
                    else if(arr[k][l]=='K')
                        vis[13]++;
                    else
                        vis[arr[k][l]-'0']++;
                }
            }
            bool flag=1;
            //cout<<i<<j<<endl;
            for(int k=2; k<14; k++)
            {
                if(vis[k]>1)
                    flag=0;
//                if(!i&&!j)
//                cout<<vis[k]<<" ";
                //if()
            }
            if(flag)
            {
                if(vis[0])
                {
                    cnt1--;
                    for(int k=2; k<=10; k++)
                    {
                        if(k==10)
                        {
                            vis[0]--;
                            a+='T';
                            a+='C';
                            break;
                        }
                        if(vis[k]==0)
                        {
                            vis[k]=1;
                            vis[0]--;
                            a+=(k+'0');
                            a+='C';
                            break;
                        }
                    }

                }
                if(vis[0])
                {
                    cnt1--;
                    for(int k=2; k<=10; k++)
                    {
                        if(k==10)
                        {
                            vis[0]--;
                            a+='T';
                            a+='C';
                            break;
                        }
                        if(vis[k]==0)
                        {
                            vis[k]=1;
                            vis[0]--;
                            b+=(k+'0');
                            b+='C';
                            break;
                        }
                    }
                }
                for(int k=i; k<i+3; k++)
                {
                    for(int l=j; l<j+3; l++)
                    {
                        banned[k][l]=1;
                    }
                }
                square++;
                if(square==1)
                {
                    sx1=i+1;
                    sy1=j+1;
                }
                else
                {
                    sx2=i+1;
                    sy2=j+1;
                    break;
                }
                continue;
            }
            char save;
            for(int k=i; k<i+3; k++)
            {
                for(int l=j; l<j+3; l++)
                {
                    if(arr2[k][l]!='1')
                    {
                        save=arr2[k][l];
                        break;
                    }
                }
            }
            for(int k=i; k<i+3; k++)
            {
                for(int l=j; l<j+3; l++)
                {
                    if(arr2[k][l]!=save&&arr2[k][l]!='1')
                    {
                        flag=0;
                        break;
                    }
                }
            }
            if(flag)
            {
                square++;
                if(square==1)
                {
                    sx1=i+1;
                    sy1=j+1;
                }
                else
                {
                    sx2=i+1;
                    sy2=j+1;

                }
                if(cnt1)
                {
                    for(int k=i; k<i+3; k++)
                    {
                        for(int l=j; l<j+3; l++)
                        {
                            if(arr2[k][l]=='1')
                            {
                                if(x1==k&&y1==l)
                                {
                                    cnt1--;
                                    a+='2';
                                    a+=save;
                                }
                                else if(x2==k&&y2==l)
                                {
                                    cnt1--;
                                    a+='2';
                                    a+=save;
                                }
                            }
                        }
                    }
                }
                if(square==2)
                    break;
                for(int k=i; k<i+3; k++)
                {
                    for(int l=j; l<j+3; l++)
                    {
                        banned[k][l]=1;
                    }
                }
            }
        }
        if(square==2)
            break;
    }
    if(cnt1)
    {
        if(a=="")
            a="2C";
        if(b=="")
            b="2C";
    }
    //cout<<square<<endl;
    //cout<<sx1<<" "<<sy1<<endl;
    if(square<2)
    {
        cout<<"No solution."<<endl;
    }
    else
    {
        cout<<"Solution exists."<<endl;
        if(cnt==1)
            cout<<"Replace J1 with "<<a<<"."<<endl;
        else if(cnt==2)
            cout<<"Replace J1 with "<<a<<" and J2 with "<<b<<"."<<endl;
        else
            cout<<"There are no jokers."<<endl;
        cout<<"Put the first square to ("<<sx1<<", "<<sy1<<")."<<endl;
        cout<<"Put the second square to ("<<sx2<<", "<<sy2<<")."<<endl;
    }
    return 0;
}

//
// Created by Allen Li on 7/22/18.
//

#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<double, double> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;

template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;

template<class T>
inline void MAX(T &a, T b) { if (a < b) a = b; }

template<class T>
inline void MIN(T &a, T b) { if (a > b) a = b; }

template<class T>
inline void MODA(T &a, T b) {
    a %= b;
    if (a < 0) a += b;
}

#define FAST_IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout.precision(20)
#define watch(x) cout << (#x) << " is " << (x) << endl
#define long ll
#define finish(x) return cout << (x) << '\n', 0
#define F0R(i, a) for(int (i)=0;(i)<(a);++(i))
#define FOR(i, a, b) for(int (i)=(a);(i)<(b);++(i))
#define F0Rd(i, a) for(int (i)=a;(i)>=0;--(i))
#define FORd(i, a, b) for(int (i)=a;(i)>=(b);--(i))
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

#define mp make_pair
#define pb push_back
#define pf push_front
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const int NINF = -0x3f3f3f40;
const int MAXN = 20;

int n, m;
vpi jokers;
vector<pair<char, char>> repl;
pair<char, char> grid[MAXN][MAXN];
bool overlaps(int i, int j, int k, int l) {
    bool used[n][m];
    memset(used, false, sizeof used);
    FOR(a, i-2, i+1)
        FOR(b, j-2, j+1)
            used[a][b] = true;
    FOR(a, k-2, k+1)
        FOR(b, l-2, l+1)
            if(used[a][b])
                return true;
    return false;
}
bool isValid() {
    FOR(i, 2, n) {
        FOR(j, 2, m) {
            FOR(k, 2, n) {
                FOR(l, 2, m) {
                    if(overlaps(i, j, k, l))
                        continue;
                    set<char> seen;
                    bool bad = false;
                    int currSuit = -1;
                    FOR(a, i - 2, i + 1)
                        FOR(b, j - 2, j + 1) {
                            pair<char, char> card = grid[a][b];
                            if (seen.count(card.f))
                                bad = true;
                            seen.insert(card.f);
                            if (currSuit == -1)
                                currSuit = card.s;
                            if (currSuit != card.s)
                                currSuit = -2;
                        }
                    if(currSuit == -2 && bad)
                        continue;
                    bad = false;
                    currSuit = -1;
                    seen.clear();
                    FOR(a, k - 2, k + 1)
                        FOR(b, l - 2, l + 1) {
                            pair<char, char> card = grid[a][b];
                            if (seen.count(card.f))
                                bad = true;
                            seen.insert(card.f);
                            if (currSuit == -1)
                                currSuit = card.s;
                            if (currSuit != card.s)
                                currSuit = -2;
                        }
                    if(currSuit == -2 && bad)
                        continue;
                    cout << "Solution exists." << '\n';
                    if (repl.size()) {
                        if (repl.size() == 1)
                            cout << "Replace J1 with " << repl[0].f << repl[0].s << ".\n";
                        else
                            cout << "Replace J1 with " << repl[0].f << repl[0].s
                                    << " and J2 with " << repl[1].f << repl[1].s << ".\n";
                    } else {
                        cout << "There are no jokers." << '\n';
                    }
                    cout << "Put the first square to (" << i-1 << ", " << j-1 << ")." << '\n';
                    cout << "Put the second square to (" << k-1 << ", " << l-1 << ")." << '\n';
                    exit(0);
                }
            }
        }
    }
    return false;
}
int main() {
    FAST_IO;
    cin >> n >> m;
    set<pair<char, char>> cards;
    set<char> suits{'C', 'D', 'H', 'S'};
    char type[]{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    for(char ty: type)
        for(char su: suits)
            cards.insert(mp(ty, su));
    F0R(i, n) {
        F0R(j, m) {
            string str; cin >> str;
            grid[i][j].f = str[0];
            grid[i][j].s = str[1];
            if(!suits.count(str[1]))
                jokers.pb(mp(i, j));
            cards.erase(mp(str[0], str[1]));
        }
    }
    if(jokers.size() == 0)
        isValid();
    if(jokers.size() == 1) {
        for(auto card: cards) {
            grid[jokers[0].f][jokers[0].s] = card;
            repl.pb(card);
            isValid();
            repl.clear();
        }
    }
    if(jokers.size() == 2) {
        for(auto card: cards) {
            for(auto card2: cards) {
                auto n1 = card;
                auto n2 = card2;
                if(grid[jokers[0].f][jokers[0].s] != mp('J', '1')) {
                    swap(n1, n2);
                }
                if(card == card2)
                    continue;
                grid[jokers[0].f][jokers[0].s] = card;
                grid[jokers[1].f][jokers[1].s] = card2;
                repl.pb(n1);
                repl.pb(n2);
                isValid();
                repl.clear();
            }

        }
    }
    cout << "No solution." << '\n';
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using ll = int64_t;
using ld = long double;
using ull = uint64_t;
using namespace std;
using namespace __gnu_pbds;
typedef vector <int> vi;
typedef pair <int, int> ii;

const int INF = (int)1e9;

#define maxn 100010

ii x, y;
int n, m;
vector <vector <string> > a;

bool solve() {
    set <char> va;
    set <char> cl;
    int cnt = 0;
    for(int i = 0; i < n - 2; i++) {
        for(int j = 0; j < m - 2; j++) {
            va.clear();
            cl.clear();
            for(int p = 0; p < 3; p++) {
                for(int q = 0; q < 3; q++) {
                    va.insert(a[i + p][j + q][0]);
                    cl.insert(a[i + p][j + q][1]);
                }
            }
            if(va.size() == 9 || cl.size() == 1) {
                if(cnt == 0) {
                    x.first = i + 1;
                    x.second = j + 1;
                    cnt++;
                }  else if(cnt == 1) {
                    y.first = i + 1;
                    y.second = j + 1;
                    cnt++;
                    return true;
                }
            }
        }
    }
    return false;
}

int main() {
#ifdef BZ
    freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cout.setf(ios::fixed); cout.precision(6);

    cin >> n >> m;
    a.resize(n, vector <string> (m));

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }

    ii j1, j2;

    int cnt = 0;

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(a[i][j][1] == '1' || a[i][j][1] == '2') {
                if(cnt == 0) {
                    j1.first = i, j1.second = j;
                    cnt++;
                } else {
                    j2.first = i, j2.second = j;
                    cnt++;
                }
            }
        }
    }

    vector <string> nud;
    set <string> used;

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            used.insert(a[i][j]);
        }
    }

    char va[15] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    char cl[4] = {'C', 'D', 'H', 'S'};

    for(int i = 0; i < 13; i++) {
        for(int j = 0; j < 4; j++) {
            string c = string(1, va[i]) + cl[j];
            if(!used.count(c)) {
                nud.push_back(c);
            }
        }
    }

    int q = nud.size();

    if(cnt == 0) {
        if(solve()) {
            cout << "Solution exists.\n" <<
                    "There are no jokers.\n" <<
                    "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                    "Put the second square to (" << y.first << ", " << y.second << ").\n";
        } else {
            cout << "No solution.\n";
        }
    } else if(cnt == 1) {
        for(int i = 0; i < q; i++) {
            a[j1.first][j1.second] = nud[i];
            if(solve()) {
                cout << "Solution exists.\n" <<
                    "Replace J1 with " << nud[i] << ".\n" <<
                    "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                    "Put the second square to (" << y.first << ", " << y.second << ").\n";
                return 0;
            }
        }
        cout << "No solution.\n";
    } else if(cnt == 2) {
        for(int i = 0; i < q; i++) {
            a[j1.first][j1.second] = nud[i];
            for(int j = 0; j < q; j++) {
                if(i == j) continue;
                a[j2.first][j2.second] = nud[j];
                if(solve()) {
                    cout << "Solution exists.\n" <<
                         "Replace J1 with " << nud[i] << ".\n" <<
                         "Replace J2 with " << nud[j] << ".\n" <<
                         "Put the first square to (" << x.first << ", " << x.second << ").\n" <<
                         "Put the second square to (" << y.first << ", " << y.second << ").\n";
                    return 0;
                }
            }

        }
        cout << "No solution.\n";
    }
}

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 5;

int n = 1000, m = 1000;
string s[60][60];

bool tmam(int i, int j){
    set<char> st, st2;
    for(int k = i; k < i + 3; k++){
        for(int l = j; l < j + 3; l++){
            st.insert(s[k][l][0]);
            st2.insert(s[k][l][1]);
        }
    }
    if(st.size() == 9 || st2.size() == 1) return 1;
    return 0;
}

bool valid(int i, int j, int k, int l){
    if(i + 3 > n || j + 3 >  m || k + 3 >  n || l + 3 > m) return 0;
    int r = i + 2, c = j + 2;
    if(k >= i && k <= r && l >= j && l <= c) return 0;
    r = k + 2, c = l + 2;
    if(i >= k && i <= r && j >= l && j <= c) return 0;
    return 1;
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    string ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
    string suits[] = {"C", "D", "H", "S"};
    vector<string> jokers;
    vector< pair<int, int> > pos;
    set<string> st;
    for(auto i: ranks){
        for(auto j: suits){
            st.insert(i + j);
        }
    }
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> s[i][j];
            if(st.find(s[i][j]) != st.end()) st.erase(st.find(s[i][j]));
            else{
                jokers.push_back(s[i][j]);
                pos.push_back({i, j});
            }
        }
    }
    if(pos.size() == 0){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                for(int k = i; k < n; k++){
                    for(int l = j; l < m; l++){
                        if(valid(i, j, k, l) && tmam(i, j) && tmam(k, l)){
                            cout << "Solution exists.\n";
                            cout << "There are no jokers.\n";
                            cout << "Put the first square to (" << i + 1 << ", " << j + 1 << ").\n";
                            cout << "Put the second square to (" << k + 1 << ", " << l + 1 << ").\n";
                            return 0;
                        }
                    }
                }
            }
        }
    }
    else if(pos.size() == 1){
        for(auto x: st){
            s[pos[0].first][pos[0].second] = x;
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    for(int k = 0; k < n; k++){
                        for(int l = 0; l < m; l++){
                            if(valid(i, j, k, l) && tmam(i, j) && tmam(k, l)){
                                cout << "Solution exists.\n";
                                cout << "Replace " << jokers[0] << " with " << x << ".\n";
                                cout << "Put the first square to (" << i + 1 << ", " << j + 1 << ").\n";
                                cout << "Put the second square to (" << k + 1 << ", " << l + 1 << ").\n";
                                return 0;
                            }
                        }
                    }
                }
            }
        }
    }
    else{
        for(auto x: st){
            for(auto y: st){
                if(x == y) continue;
                s[pos[0].first][pos[0].second] = x;
                s[pos[1].first][pos[1].second] = y;
                for(int i = 0; i < n; i++){
                    for(int j = 0; j < m; j++){
                        for(int k = i; k < n; k++){
                            for(int l = j; l < m; l++){
                                if(valid(i, j, k, l) && tmam(i, j) && tmam(k, l)){
                                    cout << "Solution exists.\n";
                                    cout << "Replace ";
                                    if(jokers[0] == "J1"){
                                        cout << jokers[0] << " with " << x << " and " << jokers[1] << " with " << y << ".\n";
                                    }
                                    else{
                                        cout << jokers[1] << " with " << y << " and " << jokers[0] << " with " << x << ".\n";
                                    }
                                    cout << "Put the first square to (" << i + 1 << ", " << j + 1 << ").\n";
                                    cout << "Put the second square to (" << k + 1 << ", " << l + 1 << ").\n";
                                    return 0;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout << "No solution.";

    return 0;

}

//I love natalia

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <string>

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 = l; j <= r+2; j++) {
            if (A[i][j].rank != 'J')
                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 = l; 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() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    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 (check1(l, r))
                V1.push_back(make_pair(l,r));

            if (l == 2 && r == 4)
                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 < V2.size(); j++) {
            int l1 = V1[i].first;
            int r1 = V1[i].second;
            int l2 = V2[i].first;
            int r2 = V2[i].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) && CHECK2(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) && CHECK2(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) && 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;
}

#define _CRT_SECURE_NO_WARNINGS
#ifdef ONLINE_JUDGE
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <utility>
#include <cstdlib>
#include <cstdio>
#include <cstdarg>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstring>
#endif
#include "stdio.h" // Pre-compiled header file.

#define len(C)                  int((C).size())
#define for_(I, M, N)           for(int I = int(M), CNT_##I = int(N); I < CNT_##I; ++I)
#define rep(I, N)               for_(I, 0, N)
#define elems(XS)               (XS).begin(), (XS).end()
#define tup                     make_pair
#define fst                     first
#define snd                     second

using namespace std;
template <typename S, typename T> void fill_(S& buf, T x){fill(reinterpret_cast<T*>(&buf), reinterpret_cast<T*>(&buf) + sizeof(buf) / sizeof(T), x);}
template <typename T, int N> inline int countof(const T (&)[N]){return N;}
template <typename T> inline vector<T>& operator +=(vector<T>& ret, const T& x){ret.push_back(x);return ret;}

struct Card
{
    int rank;
    int suit;
    Card(int rank = -1, int suit = -1) : rank(rank), suit(suit){}
    operator Card&(){return *this;}
    bool operator ==(const Card& x) const
    {
        return rank == x.rank && suit == x.suit;
    }
    bool operator !=(const Card& x) const
    {
        return !operator ==(x);
    }
    bool operator <(const Card& x) const
    {
        if(suit < x.suit) return true;
        if(suit > x.suit) return false;
        return rank < x.rank;
    }
    bool operator >=(const Card& x) const
    {
        return !operator <(x);
    }
    bool operator >(const Card& x) const
    {
        if(suit > x.suit) return true;
        if(suit < x.suit) return false;
        return rank > x.rank;
    }
    bool operator <=(const Card& x) const
    {
        return !operator >(x);
    }
    static int rank_to_int(const char c)
    {
        switch(c)
        {
        case 'T': return 10;
        case 'J': return 11;
        case 'Q': return 12;
        case 'K': return 13;
        case 'A': return 14;
        default:  return '2' <= c && c <= '9' ? c - '0' : -1;
        }
    }
    static int suit_to_int(const char c)
    {
        switch(c)
        {
        case 'H': return 0;
        case 'C': return 1;
        case 'D': return 2;
        case 'S': return 3;
        case '1': return 10;
        case '2': return 11;
        default:  return -1;
        }
    }
    static char int_to_rank(const int i)
    {
        switch(i)
        {
        case 10: return 'T';
        case 11: return 'J';
        case 12: return 'Q';
        case 13: return 'K';
        case 14: return 'A';
        default: return 2 <= i && i <= 9 ? i + '0' : '#';
        }
    }
    static char int_to_suit(const int i)
    {
        switch(i)
        {
        case 0:  return 'H';
        case 1:  return 'C';
        case 2:  return 'D';
        case 3:  return 'S';
        case 10: return '1';
        case 11: return '2';
        default: return '#';
        }
    }
    static vector<Card> get_all_cards()
    {
        vector<Card> xs;
        rep(suit, 4) rep(rank, 13) xs += Card(rank + 2, suit);
        return xs;
    }
    static bool has_same_suit(const vector<Card>& xs)
    {
        if(len(xs) == 0)
            return true;

        int suit = xs[0].suit;
        for_(i, 1, len(xs)) if(xs[i].suit != suit)
            return false;
        return true;
    }
};

istream& operator >>(istream& is, Card& x)
{
    string s; is >> s;
    x.rank = Card::rank_to_int(s[0]);
    x.suit = Card::suit_to_int(s[1]);
    return is;
}

ostream& operator <<(ostream& os, Card& x)
{
    return os << Card::int_to_rank(x.rank) << Card::int_to_suit(x.suit);
}

typedef pair<int, int> pair_t;

int N, M;
vector<vector<Card>> cards;
vector<Card> all_cards;
vector<Card> candidates;
vector<Card> jokers;
vector<pair_t> joker_positions;
vector<pair_t> squares;

inline bool is_joker(const Card& x)
{
    return x.suit >= 10;
}

inline bool is_in_square(const int y_, const int x_)
{
    rep(i, len(squares)){
        for_(y, y_, y_ + 3) for_(x, x_, x_ + 3){
            if(squares[i].fst <= y && y < squares[i].fst + 3 && squares[i].snd <= x && x < squares[i].snd + 3)
                return true;
        }
    }
    return false;
}

bool is_pairwise_different_ranks(const vector<Card>& xs)
{
    vector<int> is;
    rep(i, len(xs)) is += xs[i].rank;
    sort(elems(is));
    return unique(elems(is)) - is.begin() == 9;
}

bool check(const int number_of_squares, const int i_, const int j_)
{
    vector<Card> xs;

    if(number_of_squares == 0){
        return true;
    }else{
        for_(i, i_, N - 2) for_(j, i == i_ ? j_ : 0, M - 2){
            if(is_in_square(i, j))
                continue;
            xs.clear();
            for_(y, i, i + 3) for_(x, j, j + 3) xs += cards[y][x];
            if(!Card::has_same_suit(xs) && !is_pairwise_different_ranks(xs))
                continue;
            squares += tup(i, j);
            if(check(number_of_squares -1, i, j))
                return true;
            squares.pop_back();
        }
    }
    return false;
}

bool dfs(const int number_of_jokers)
{
    if(number_of_jokers == 0){
        rep(i, len(jokers))
            cout << cards[joker_positions[i].fst][joker_positions[i].snd];
        cout << endl;
        return check(2, 0, 0);
    }else{
        rep(i, N) rep(j, M) if(is_joker(cards[i][j])){
            jokers += cards[i][j];
            for_(k, 0, len(candidates)){
                Card old = candidates[k];
                joker_positions += tup(i, j);
                cards[i][j] = old;
                candidates.erase(candidates.begin() + k);
                if(dfs(number_of_jokers - 1))
                    return true;
                candidates.insert(candidates.begin() + k, old);
                joker_positions.pop_back();
            }
            cards[i][j] = jokers.back();
            jokers.pop_back();
            break;
        }
    }
    return false;
}

int main(int argc, char* argv[])
{
    cin >> N >> M;
    cards.assign(N, vector<Card>(M, Card()));
    rep(i, N) rep(j, M) cin >> cards[i][j];
    all_cards = Card::get_all_cards();

    vector<Card> temp;
    rep(i, N) copy(elems(cards[i]), back_inserter(temp));

    const int number_of_jokers = count_if(elems(temp), is_joker);

    sort(elems(temp));
    set_difference(elems(all_cards), elems(temp), back_inserter(candidates));

    if(!dfs(number_of_jokers)){
        cout << "No solution." << endl;
    }else{
        cout << "Solution exists." << endl;
        switch(len(jokers))
        {
        case 1:
            {
                const int y1 = joker_positions[0].fst, x1 = joker_positions[0].snd;
                cout << "Replace " << (jokers[0].suit == 10 ? "J1" : "J2") << " with " << cards[y1][x1] << "." << endl;
            }
            break;
        case 2:
            {
             if(jokers[0].suit == 11){
                swap(jokers[0], jokers[1]);
                swap(joker_positions[0], joker_positions[1]);
             }
             const int y1 = joker_positions[0].fst, x1 = joker_positions[0].snd;
             const int y2 = joker_positions[1].fst, x2 = joker_positions[1].snd;
             cout << "Replace J1 with " << cards[y1][x1] << " and J2 with " << cards[y2][x2] << "." << endl;
            }
            break;
        default:
            cout << "There are no jokers." << endl;
        }

        rep(i, len(squares))
            cout << "Put the " << (i ? "second" : "first") << " square to (" << squares[i].fst + 1 << ", " << squares[i].snd + 1 << ")." << endl;
    }

    return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 18;
string grid[N][N];

int n, m;

bool isGood(int i, int j)
{
	if (i + 2 > n || j + 2 > m) return 0;

	set<char> a, b;

	for (int x = i; x <= i + 2; ++x)
	{
		for (int y = j; y <= j + 2; ++y)
		{
			a.insert(grid[x][y][0]);
			b.insert(grid[x][y][1]);
		}
	}

	return (a.size() == 9) || (b.size() == 1);
}

bool flag;

pair< pair<int, int>, pair<int, int> > solve()
{
	vector< pair<int, int> > sq;

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			if (isGood(i, j))
			{
				sq.push_back(make_pair(i, j));
			}
		}
	}

	int k = (int) sq.size();

	for (int i = 0; i < k; ++i)
	{
		for (int j = i + 1; j < k; ++j)
		{
			const pair<int, int> &a = sq[i];
			const pair<int, int> &b = sq[j];

			int x1 = a.first, y1 = a.second;
			int x2 = b.first, y2 = b.second;

			if (x1 > x2 + 2 || y1 > y2 + 2 || x2 > x1 + 2 || y2 > y1 + 2)
			{
				flag = true;
				return make_pair(a, b);
			}
		}
	}

	return make_pair(make_pair(-1, -1), make_pair(-1, -1));
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	cin >> n >> m;

	vector< pair<int, int> > jokers;
	jokers.reserve(2);

	char ranks[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
	char suits[4] = { 'C', 'D', 'D', 'S' };

	set<string> rem;

	for (int i = 0; i < 13; i++)
	{
		for (int j = 0; j < 4; ++j)
		{
			string cur = "";
			cur += ranks[i];
			cur += suits[j];
			rem.insert(cur);
		}
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; ++j)
		{
			cin >> grid[i][j];

			if (grid[i][j][0] == 'J')
			{
				jokers.emplace_back(make_pair(i, j));
			}
			else
			{
				auto it = rem.find(grid[i][j]);
				if (it != rem.end()) rem.erase(it);
			}
		}
	}

	if (jokers.size() == 0)
	{
		pair< pair<int, int>, pair<int, int> > ans = solve();

		if (flag)
		{
			cout << "Solution exists.\nThere are no jokers.\n";
			cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
			cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
			return 0;
		}
	}
	else if (jokers.size() == 1)
	{
		for (const auto& cur : rem)
		{
			grid[jokers[0].first][jokers[0].second] = cur;
			pair< pair<int, int>, pair<int, int> > ans = solve();

			if (flag)
			{
				cout << "Solution exists.\n";
				cout << "Replace J1 with " << cur << ".\n";
				cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
				cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
				return 0;
			}
		}
	}
	else
	{
		vector< string > v(rem.begin(), rem.end());
		for (int i = 0; i < v.size(); i++)
		{
			for (int j = i + 1; j < v.size(); ++j)
			{
				grid[jokers[0].first][jokers[0].second] = v[i];
				grid[jokers[1].first][jokers[1].second] = v[j];
				pair< pair<int, int>, pair<int, int> > ans1 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace J1 with " << v[i] << " and J2 with " << v[j] << ".\n";
					cout << "Put the first square to (" << ans1.first.first << ", " << ans1.first.second << ").\n";
					cout << "Put the second square to (" << ans1.second.first << ", " << ans1.second.second << ").\n";
					return 0;
				}

				grid[jokers[0].first][jokers[0].second] = v[j];
				grid[jokers[1].first][jokers[1].second] = v[i];
				pair< pair<int, int>, pair<int, int> > ans2 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace J1 with " << v[j] << " and J2 with " << v[i] << ".\n";
					cout << "Put the first square to (" << ans2.first.first << ", " << ans2.first.second << ").\n";
					cout << "Put the second square to (" << ans2.second.first << ", " << ans2.second.second << ").\n";
					return 0;
				}
			}
		}
	}
	cout << "No solution.\n";
}

//#pragma GCC optimize ('O3')
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll,ll> pll;
typedef long double ld;
#define mp make_pair
#define f first
#define s second
#define pb push_back

const int N = 128 + 5;
const int M = 17 + 5;
const int W = 1000 + 5;
const int OO = 2e9;
const int mod = 1e9 + 7;

char rnk[] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char st[] = {'C','D','H','S'};

int n,m,vis[N][N],j1r=-1,j2r=-1,j1c,j2c;
char j1x;
string s[M][M];

struct Solution {

  bool exists;
  int r1,c1,r2,c2;

} no_sol, sol;

void solutionExists() {

    // LOL

    cout << "Solution exists.\n";

}

void printRectangles() {

    cout << "Put the first square to (" << sol.r1 << ", " << sol.c1 << ").\n";
    cout << "Put the second square to (" << sol.r2 << ", " << sol.c2 << ").\n";

}

bool intersect1D(int a, int b) {

    if(a<=b && b<=a+2) return 1;

    if(b<=a && a<=b+2) return 1;

    return 0;

}

bool intersect(int a, int b, int x, int y) {

    return intersect1D(a,x) && intersect1D(b,y);

}

Solution solved() {

    for (int i = 0; i < n-2; ++i) {
        for (int j = 0; j < m-2; ++j) {
            map<char,bool> ranks, suits;
            for (int row = i; row < i+3; ++row) {
                for (int col = j; col < j+3; ++col) {
                    ranks[s[row][col][0]] = 1;
                    suits[s[row][col][1]] = 1;
                }
            }
            if(ranks.size()!=9 && suits.size()!=1) continue;
            ranks.clear();
            suits.clear();
            for (int a = 0; a < n-2; ++a) {
                for (int b = 0; b < m-2; ++b) {
                    if(!intersect(i,j,a,b)) {
                        for (int row = a; row < a+3; ++row) {
                            for (int col = b; col < b+3; ++col) {
                                ranks[s[row][col][0]] = 1;
                                suits[s[row][col][1]] = 1;
                            }
                        }
                        if(ranks.size()!=9 && suits.size()!=1) continue;
                        return {1,i+1,j+1,a+1,b+1};
                    }
                }
            }
        }
    }

    return no_sol;

}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> s[i][j];
            char &curRank = s[i][j][0], &curSuit =  s[i][j][1];
            if(curRank!='J') vis[curRank][curSuit] = 1;
            else if(j1r==-1) {
                j1r = i;
                j1c = j;
                j1x = curSuit;
            } else {
                j2r = i;
                j2c = j;
            }
        }
    }

    if(j1r==-1) {
        sol = solved();
        if(sol.exists) {
            solutionExists();
            cout << "There are no jokers.\n";
            printRectangles();
            return 0;
        }
    } else if(j2r==-1) {
        for (int i = 0; i <= 12; ++i) {
            for (int j = 0; j <= 3; ++j) {
                if(!vis[rnk[i]][st[j]]) {
                    s[j1r][j1c] = rnk[i];
                    s[j1r][j1c] += st[j];
                    sol = solved();
                    if(sol.exists) {
                        solutionExists();
                        cout << "Replace J" << j1x << " with " << s[j1r][j1c] << ".\n";
                        printRectangles();
                        return 0;
                    }
                }
            }
        }
    } else {
        for (int i = 0; i <= 12; ++i) {
            for (int j = 0; j <= 3; ++j) {
                if (vis[rnk[i]][st[j]]) continue;
                s[j1r][j1c] = rnk[i] + st[j];
                for (int x = 0; x <= 12; ++x) {
                    for (int y = 0; y <= 3; ++y) {
                        if (x == i && y == j) continue;
                        if (vis[rnk[x]][st[y]]) continue;
                        s[j2r][j2c] = char(rnk[x]) + char(st[y]);
                        sol = solved();
                        if (sol.exists) {
                            solutionExists();
                            int a1 = i, b1 = j, a2 = x, b2 = y;
                            if (j1x != '1') swap(a1, a2), swap(b1, b2);
                            cout << "Replace J1 with " << char(rnk[a1]) + char(st[b1]);
                            cout << " and J2 with " << char(rnk[a2]) + char(st[b2]) << ".\n";
                            printRectangles();
                            return 0;
                        }
                    }
                }
            }
        }
    }

    cout << "No solution.\n";
    return 0;
}

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <vector>

const char kRank[] = "A23456789TJQK";
const char kSuit[] = "CDHS";

std::vector<std::pair<int, int> > pos;
std::vector<std::string> org;
std::vector<int> rep;
std::pair<int, int> ans[2];
int mask[13];
int map[52][52];
bool state[52][52];
bool used[52];
int n, m;

bool Check() {
  for (int i = 0; i + 3 <= n; ++i)
    for (int j = 0; j + 3 <= m; ++j) {
      bool same_suit = true, pairwise = true;
      memset(mask, 0, sizeof(mask));
      for (int k = 0; k < 3; ++k)
        for (int l = 0; l < 3; ++l) {
          if (map[i + k][j + l] / 13 != map[i][j] / 13) same_suit = false;
          if (++mask[map[i + k][j + l] % 13] > 1) pairwise = false;
        }
      state[i][j] = (same_suit || pairwise);
    }
  for (int i = 0; i + 3 <= n; ++i)
    for (int j = 0; j + 3 <= m; ++j) if (state[i][j])
      for (int k = 0; k + 3 <= n; ++k)
        for (int l = 0; l + 3 <= m; ++l) if (state[k][l])
          if (std::abs(i - k) >= 3 || std::abs(j - l) >= 3) {
            ans[0] = std::make_pair(i, j);
            ans[1] = std::make_pair(k, l);
            return true;
          }
  return false;
}

bool DFS(size_t step) {
  if (step == pos.size())
    return Check();
  for (int i = 0; i < 52; ++i)
    if (!used[i]) {
      map[pos[step].first][pos[step].second] = i;
      rep[step] = i;
      used[i] = true;
      if (DFS(step + 1)) return true;
      used[i] = false;
    }
  return false;
}

int main() {
  static char card[10];
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      scanf("%s", card);
      if (!strchr(kSuit, card[1]) || !strchr(kRank, card[0])) {
        pos.push_back(std::make_pair(i, j));
        org.push_back(card);
      } else {
        map[i][j] = (strchr(kSuit, card[1]) - kSuit) * 13 + (strchr(kRank, card[0]) - kRank);
        used[map[i][j]] = true;
      }
    }
  rep.resize(pos.size());
  if (!DFS(0)) {
    puts("No solution.");
  } else {
    puts("Solution exists.");
    if (pos.size() == 0) puts("There are no jokers.");
    else {
      printf("Replace %s with %c%c", org[0].c_str(), kRank[rep[0] % 13], kSuit[rep[0] / 13]);
      if (pos.size() == 2)
        printf("and %s with %c%c", org[1].c_str(), kRank[rep[1] % 13], kSuit[rep[1] / 13]);
      puts(".");
    }
    printf("Put the first square to (%d, %d).\n", ans[0].first + 1, ans[0].second + 1);
    printf("Put the second square to (%d, %d).\n", ans[1].first + 1, ans[1].second + 1);
  }
  return 0;
}

#include <algorithm>
#include <random>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <memory.h>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
const double eps = 1e-9;
const int BUFFER_SIZE = 1<<15;
const int MOD = 1000*1000*1000+7;
const int INF = 1<<30;
const LL LINF = 1ll<<60;

#define pb push_back
#define ALL(a) (a).begin(),(a).end()
#define CLR(a, v) memset((a),(v),sizeof(a))

// Sore input helpers
char BUFFER[BUFFER_SIZE];
int gi() { int x; scanf("%d", &x); return x; }
double gd() { double x; scanf("%lf", &x); return x; }
LL gll() { LL x; cin >> x; return x; }
VI gvi(int n) { VI a; while(n--) a.pb(gi()); return a;}
string gs() { scanf("%s", BUFFER); return string(BUFFER); }

// Some output helpers for stl
template <class T> struct forArray{ T *a; int n; forArray(T *a, int n): a(a),n(n) {} };
#define _dec1(a) template <class T> ostream& operator<<(ostream& os,const a<T> &d)
#define _dec2(a) template <class A,class B> ostream& operator<<(ostream& os,const a<A,B> &d)
#define _ipr {os<<"[";int f=0;for(auto x:d){if(f)os<<",";f=1;os << x;} return os<<"]";}
#define _imp1(a) _dec1(a) _ipr
#define _imp2(a) _dec2(a) _ipr
#define _FR(c) c##1(vector);c##1(queue);c##1(stack);c##1(set);c##1(multiset);c##1(unordered_set);c##2(map);c##2(multimap);c##2(unordered_map)
_dec2(pair);_FR(_dec);_FR(_imp);
_dec1(forArray){os<<"[";for(int i=0;i<d.n;++i){if(i)os<<",";os<<d.a[i];}return os<<"]";}
_dec2(pair) {return os<<"["<<d.first<<", "<<d.second<< "]";}
// ---------------------------------------------------------- //

int X1,Y1,X2,Y2;
int isgood(const vector<VS> &a) {
  for (int x1 = 1; x1+1 < a.size(); ++x1) {
    for (int y1 = 1; y1+1 < a[x1].size(); ++y1) {
      for (int x2 = x1; x2+1 < a.size(); ++x2) {
        for (int y2 = 1; y2 + 1 < a[x2].size(); ++y2) {
          if (x2-x1<3 && abs(y2-y1)<3) continue;
          set<char> r1,r2;
          set<char> s1,s2;
          for (int i = -1; i <= 1; ++i) {
            for (int j = -1; j <= 1; ++j) {
              r1.insert(a[x1+i][y1+j][0]);
              r2.insert(a[x2+i][y2+j][0]);
              s1.insert(a[x1+i][y1+j][1]);
              s2.insert(a[x2+i][y2+j][1]);
            }
          }
          if ((r1.size()==9 || s1.size()==1) && (r2.size()==9 || s2.size()==1)) {
            X1=x1;Y1=y1;
            X2=x2;Y2=y2;
            return 1;
          }
        }
      }
    }
  }
  return 0;
}

int ok(vector<VS> &a, vector<pair<string,string>> &path, set<string> &rem, int x, int y) {
  if (x>=a.size()) {
    if (isgood(a)) {
      return 1;
    }
    return 0;
  }
  if (y==a[0].size()) return ok(a,path,rem,x+1,0);
  if (a[x][y][0]=='J') {
    string orig = a[x][y];
    set<string> c = rem;
    for (string s : c) {
      rem.erase(s);
      path.push_back({orig, s});
      a[x][y] = s;
      if (ok(a,path,rem,x,y+1)) return 1;
      rem.insert(s);
    }
    a[x][y] = orig;
  } else {
    return ok(a,path,rem,x,y+1);
  }
  return 0;
}

int main() {
#ifdef DEAD_RABBIT
  clock_t start = clock();
  freopen("../in.txt","r",stdin);
  //freopen("../out.txt","w",stdout);
#endif

  set<string> rem;
  string R = "23456789AJQKT";
  string C = "CDHS";
  for (char r : R) for (char c : C) { string s = ""; s += r; s += c; rem.insert(s); }
  int n = gi();
  int m = gi();
  vector<VS> a;
  for (int i = 0; i < n; ++i) {
    a.pb(VS());
    for (int j = 0; j < m; ++ j) {
      string s = gs();
      rem.erase(s);
      a.back().pb(s);
    }
  }
  vector<pair<string,string>> path;
  if (ok(a,path,rem,0,0)) {
    printf("Solution exists.\n");
    sort(ALL(path));
    if (path.size()==2) printf("Replace J1 with %s and J2 with %s.\n", path[0].second.c_str(), path[1].second.c_str());
    else if (path.size()==1)  printf("Replace %s with %s.\n", path[0].first.c_str(), path[0].second.c_str());
    else printf("There are no jokers.\n");
    isgood(a);
    printf("Put the first square to (%d, %d).\n", X1, Y1);
    printf("Put the second square to (%d, %d).\n", X2, Y2);
  } else {
    printf("No solution.\n");
  }

#ifdef DEAD_RABBIT
  fprintf(stdout, "Time: %.3lf\n", 1.0*(clock()-start)/CLOCKS_PER_SEC);
#endif
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 18;
string grid[N][N];

int n, m;

bool isGood(int i, int j)
{
	if (i + 2 > n || j + 2 > m) return 0;

	set<char> a, b;

	for (int x = i; x <= i + 2; ++x)
	{
		for (int y = j; y <= j + 2; ++y)
		{
			a.insert(grid[x][y][0]);
			b.insert(grid[x][y][1]);
		}
	}

	return (a.size() == 9) || (b.size() == 1);
}

bool flag;

pair< pair<int, int>, pair<int, int> > solve()
{
	vector< pair<int, int> > sq;

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			if (isGood(i, j))
			{
				sq.push_back(make_pair(i, j));
			}
		}
	}

	int k = (int) sq.size();

	for (int i = 0; i < k; ++i)
	{
		for (int j = i + 1; j < k; ++j)
		{
			const pair<int, int> &a = sq[i];
			const pair<int, int> &b = sq[j];

			int x1 = a.first, y1 = a.second;
			int x2 = b.first, y2 = b.second;

			if (x1 > x2 + 2 || y1 > y2 + 2 || x2 > x1 + 2 || y2 > y1 + 2)
			{
				flag = true;
				return make_pair(a, b);
			}
		}
	}

	return make_pair(make_pair(-1, -1), make_pair(-1, -1));
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	cin >> n >> m;

	vector< pair<string, pair<int, int>> > jokers;
	jokers.reserve(2);

	char ranks[12] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A' };
	char suits[4] = { 'C', 'D', 'H', 'S' };

	set<string> rem;

	for (int i = 0; i < 12; i++)
	{
		for (int j = 0; j < 4; ++j)
		{
			string cur = "";
			cur += ranks[i];
			cur += suits[j];
			rem.insert(cur);
		}
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; ++j)
		{
			cin >> grid[i][j];

			if (grid[i][j][0] == 'J')
			{
				jokers.emplace_back(make_pair(grid[i][j], make_pair(i, j)));
			}
			else
			{
				auto it = rem.find(grid[i][j]);
				if (it != rem.end()) rem.erase(it);
			}
		}
	}

	sort(jokers.begin(), jokers.end());

	if (jokers.size() == 0)
	{
		pair< pair<int, int>, pair<int, int> > ans = solve();

		if (flag)
		{
			cout << "Solution exists.\nThere are no jokers.\n";
			cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
			cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
			return 0;
		}
	}
	else if (jokers.size() == 1)
	{
		for (const auto& cur : rem)
		{
			grid[jokers[0].second.first][jokers[0].second.second] = cur;
			pair< pair<int, int>, pair<int, int> > ans = solve();

			if (flag)
			{
				cout << "Solution exists.\n";
				cout << "Replace " << jokers[0].first << " with " << cur << ".\n";
				cout << "Put the first square to (" << ans.first.first << ", " << ans.first.second << ").\n";
				cout << "Put the second square to (" << ans.second.first << ", " << ans.second.second << ").\n";
				return 0;
			}
		}
	}
	else
	{
		vector< string > v(rem.begin(), rem.end());
		for (int i = 0; i < (int) v.size(); i++)
		{
			for (int j = i + 1; j < (int) v.size(); ++j)
			{
				grid[jokers[0].second.first][jokers[0].second.second] = v[i];
				grid[jokers[1].second.first][jokers[1].second.second] = v[j];
				pair< pair<int, int>, pair<int, int> > ans1 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace " << jokers[0].first << " with " << v[i] <<
						" and " << jokers[1].first << " with " << v[j] << ".\n";
					cout << "Put the first square to (" << ans1.first.first << ", " << ans1.first.second << ").\n";
					cout << "Put the second square to (" << ans1.second.first << ", " << ans1.second.second << ").\n";
					return 0;
				}

				grid[jokers[0].second.first][jokers[0].second.second] = v[j];
				grid[jokers[1].second.first][jokers[1].second.second] = v[i];
				pair< pair<int, int>, pair<int, int> > ans2 = solve();
				if (flag)
				{
					cout << "Solution exists.\n";
					cout << "Replace " << jokers[0].first << " with " << v[j] <<
						" and " << jokers[1].first << " with " << v[i] << ".\n";
					cout << "Put the first square to (" << ans2.first.first << ", " << ans2.first.second << ").\n";
					cout << "Put the second square to (" << ans2.second.first << ", " << ans2.second.second << ").\n";
					return 0;
				}
			}
		}
	}
	cout << "No solution.\n";
}

#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

#define all(x) x.begin(), x.end()
#define f(i,a,b) for(int i = (a); i <= (b); i++)
#define fd(i,a,b) for(int i = (a); i >= (b); i--)
#define mp make_pair
#define faster_io() ios_base::sync_with_stdio(false)
#define pb push_back
#define pii pair<int,int>
#define SZ(x) ((int)x.size())
#define vii vector<pair<int,int>>

const int INF = 1000000002;
const ll INFLL = 100000000000000001ll;
const ll MOD = 1000000007;

// ----------------------------------------------------------------------------------------------------------

bool U[6][15];
int H,W,S[18][18],N[18][18],I1,J1,I2,J2;
unordered_map<char,int> MN,MS;

bool overlap(pii p1, pii p2)
{
    int i1 = p1.first, j1 = p1.second;
    int i2 = p2.first, j2 = p2.second;
    bool overlap_i = (i1 <= i2 && i1+2 >= i2) || (i2 <= i1 && i2+2 >= i1);
    bool overlap_j = (j1 <= j2 && j1+2 >= j2) || (j2 <= j1 && j2+2 >= j1);
    return overlap_i && overlap_j;
}

bool ok()
{
    vii poss;

    f(i,1,H-2) f(j,1,W-2)
    {
        unordered_set<int> suits, nums;
        f(x,i,i+2) f(y,j,j+2)
        {
            suits.insert(S[x][y]);
            nums.insert(N[x][y]);
        }
        if(SZ(suits) == 1 || SZ(nums) == 9) poss.pb({i,j});
    }

    for(pii p1 : poss) for(pii p2 : poss) if(!overlap(p1,p2))
    {
        I1 = p1.first, J1 = p1.second;
        I2 = p2.first, J2 = p2.second;
        return true;
    }

    return false;
}

string getcard(int suit, int num)
{
    char s,n;
    for(pair<char,int> p : MS) if(p.second == suit) s = p.first;
    for(pair<char,int> p : MN) if(p.second == num) n = p.first;
    string ret = "";
    ret += s;
    ret += n;
    if(suit != 5) reverse(all(ret));
    return ret;
}

int main()
{
    MS['C'] = 1;
    MS['D'] = 2;
    MS['H'] = 3;
    MS['S'] = 4;
    MS['J'] = 5;
    MN['1'] = 0;
    MN['2'] = 1;
    MN['3'] = 2;
    MN['4'] = 3;
    MN['5'] = 4;
    MN['6'] = 5;
    MN['7'] = 6;
    MN['8'] = 7;
    MN['9'] = 8;
    MN['T'] = 9;
    MN['J'] = 10;
    MN['Q'] = 11;
    MN['K'] = 12;
    MN['A'] = 13;

    cin >> H >> W;
    int jokers = 0;

    f(i,1,H) f(j,1,W)
    {
        string s;
        cin >> s;
        if(s[1] == '1' || s[1] == '2') jokers++;
        if(s[1] != '1' && s[1] != '2') swap(s[0],s[1]);
        S[i][j] = MS[s[0]];
        N[i][j] = MN[s[1]];
        U[S[i][j]][N[i][j]] = true;
    }

    if(!jokers && ok())
    {
        cout << "Solution exists.\n";
        cout << "There are no jokers.\n";
        cout << "Put the first square to (" << I1 << ", " << J1 << ").\n";
        cout << "Put the second square to (" << I2 << ", " << J2 << ").\n";
        return 0;
    }

    if(jokers == 1)
    {
        f(i,1,H) f(j,1,W)
        {
            if(S[i][j] == 5)
            {
                f(suit,1,4) f(num,1,13) if(!U[suit][num])
                {
                    int ps = S[i][j];
                    int pn = N[i][j];
                    S[i][j] = suit, N[i][j] = num;
                    if(ok())
                    {
                        string now = getcard(ps,pn);
                        string rep = getcard(suit,num);
                        cout << "Solution exists.\n";
                        cout << "Replace " << now << " with " << rep << ".\n";
                        cout << "Put the first square to (" << I1 << ", " << J1 << ").\n";
                        cout << "Put the second square to (" << I2 << ", " << J2 << ").\n";
                        return 0;
                    }
                    S[i][j] = ps, N[i][j] = pn;
                }
            }
        }
    }

    if(jokers == 2)
    {
        f(i1,1,H) f(j1,1,W) if(S[i1][j1] == 5)
            f(i2,1,H) f(j2,1,W) if(S[i2][j2] == 5 && (i1!=i2 || j1!=j2))
            {
                f(suit1,1,4) f(num1,1,13) if(!U[suit1][num1]) f(suit2,1,4) f(num2,1,13) if(!U[suit2][num2] && (suit1 != suit2 || num1 != num2))
                {
                    int ps1 = S[i1][j1];
                    int pn1 = N[i1][j1];
                    int ps2 = S[i2][j2];
                    int pn2 = N[i2][j2];
                    S[i1][j1] = suit1, N[i1][j1] = num1;
                    S[i2][j2] = suit2, N[i1][j1] = num2;
                    if(ok())
                    {
                        string now1 = getcard(ps1,pn1);
                        string rep1 = getcard(suit1,num1);
                        string now2 = getcard(ps2,pn2);
                        string rep2 = getcard(suit2,num2);
                        if(now1[1] == '2') swap(now1,now2), swap(rep1,rep2);
                        cout << "Solution exists.\n";
                        cout << "Replace " << now1 << " with " << rep1 << " and " << now2 << " with " << rep2 << ".\n";
                        cout << "Put the first square to (" << I1 << ", " << J1 << ").\n";
                        cout << "Put the second square to (" << I2 << ", " << J2 << ").\n";
                        return 0;
                    }
                    S[i1][j1] = ps1, N[i1][j1] = pn1;
                    S[i2][j2] = ps2, N[i2][j2] = pn2;
                }
            }
    }

    cout << "No solution.";
}

/*
    Author - linpaws07
*/
#include <bits/stdc++.h>
using namespace std;
using namespace std::chrono;
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define inf (int)1e9
#define f first
#define s second
#define eps 1e-9
#define PI 3.1415926535897932384626433832795
#define scd(t) scanf("%d",&t)
#define sclld(t) scanf("%lld",&t)
#define scc(t) scanf("%c",&t)
#define scs(t) scanf("%s",t)
#define scf(t) scanf("%f",&t)
#define sclf(t) scanf("%lf",&t)
#define memst(a, b) memset(a, (b), sizeof(a))
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<pii> vii;
typedef vector<vi> vvi;
typedef map<int,int> mpii;
typedef set<int> seti;
typedef multiset<int> mseti;
typedef long int ii;
typedef unsigned long int uii;
typedef long long int ll;
typedef unsigned long long int ull;
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define rp(i,n) for(int i=0;i<(n);i++)
#define fr(i,a,b) for(int i=(a);i<(b);i++)
#define fre(i,a,b) for(int i=(a);i<=(b);i++)
#define frd(i,a,b) for(int i=(a);i>=(b);i--)
inline bool eq(double a, double b) { return fabs(a-b) < 1e-9; }
inline int two(int n) { return 1 << n; }
inline int test(int n, int b) { return (n>>b)&1; }
inline void set_bit(int & n, int b) { n |= two(b); }
inline void unset_bit(int & n, int b) { n &= ~two(b); }
inline int last_bit(int n) { return n & (-n); }
inline int ones(int n) { int res = 0; while(n && ++res) n-=n&(-n); return res; }
inline void check(ll & a){ a %= mod; if(a < 0) a += mod; }
auto start = high_resolution_clock::now();
inline void measure();

string str[20][20];
int st[256];
char rev[4], crank[15];
int n, m;
bool check(int i, int j, bool pr = false){
    int suit[4] = {0};
    int rank[15] = {0};
    fr(k, i , i + 3){
        fr(l, j, j + 3){
            suit[st[str[k][l][1]]]++;
            rank[st[str[k][l][0]]]++;
        }
    }
    if(pr){
        cout << suit[0] << " " << suit[1] << " " << suit[2] << " " << suit[3] << endl;
        fr(i, 2, 15){
            cout << i  << " " << rank[i] << endl;
        }
    }
    if(suit[0] == 9 || suit[1] == 9 || suit[2] == 9 || suit[3] == 9)    return 1;
    fre(i, 2, 14){
        if(rank[i] > 1) return 0;
    }
    return 1;
}
pair<bool, pair<pii, pii> > is_solvable(bool pr){
    vector<pii> vec;
    rp(i, n){
        rp(j, m){
            if(i + 3 > n || j + 3 > m)    continue;
            if(check(i, j, pr)) vec.pb({i, j});
        }
    }
    rp(i, vec.size()){
        fr(j, i + 1, vec.size()){
            if(abs(vec[i].f - vec[j].f) >= 3 || abs(vec[i].s - vec[j].s) >= 3)    return {true, {{vec[i].f, vec[i].s}, {vec[j].f, vec[j].s}}};
        }
    }
    return {false, {{0,0},{0,0}}};
}
int cards[4][15];
int main(){
    FAST
    //Do awesome things here
    cin >> n >> m;
    st['C'] = 0;
    st['D'] = 1;
    st['H'] = 2;
    st['S'] = 3;
    st['2'] = 2;
    st['3'] = 3;
    st['4'] = 4;
    st['5'] = 5;
    st['6'] = 6;
    st['7'] = 7;
    st['8'] = 8;
    st['9'] = 9;
    st['T'] = 10;
    st['J'] = 11;
    st['Q'] = 12;
    st['K'] = 13;
    st['A'] = 14;
    rev[0] = 'C';
    rev[1] = 'D';
    rev[2] = 'H';
    rev[3] = 'S';
    crank[2] = '2';
    crank[3] = '3';
    crank[4] = '4';
    crank[5] = '5';
    crank[6] = '6';
    crank[7] = '7';
    crank[8] = '8';
    crank[9] = '9';
    crank[10] = 'T';
    crank[11] = 'J';
    crank[12] = 'Q';
    crank[13] = 'K';
    crank[14] = 'A';
    bool joker = false;
    vector<pii> jpos;
    rp(i, n){
        rp(j, m){
            cin >> str[i][j];
            // cout << str[i][j] << " ";
            if(str[i][j][0] == 'J' && (str[i][j][1] == '1' || str[i][j][1] == '2')){
                joker = true;
                jpos.pb({i, j});
                continue;
            }
            cards[st[str[i][j][1]]][st[str[i][j][0]]]++;
        }
        // cout << endl;
    }
    vector<string> ms(0);
    rp(i, 4){
        fr(j, 2, 15){
            if(cards[i][j] == 0){
                // cout << crank[j] << " " << rev[i] << endl;
                string mis = "";
                mis += crank[j];
                mis += rev[i];
                ms.pb(mis);
            }
        }
    }
    // cout << "Missing cards." << endl;
    // rp(i, ms.size()){
    //     cout << ms[i] << endl;
    // }
    // cout << endl << endl;
    // cout << "Joker positions" << endl;
    // rp(i, jpos.size()){
    //     cout << jpos[i].f << " " << jpos[i].s << endl;
    // }
    // cout << endl;
    // cout << joker << endl;
    if(joker){
        if(jpos.size() == 1){
            string j1 = str[jpos[0].f][jpos[0].s];
            rp(i, ms.size()){
                str[jpos[0].f][jpos[0].s] = ms[i];
                bool pr = false;
                // if(ms[i] == "2H")   pr = true;
                pair<bool, pair<pii, pii > > ans = is_solvable(pr);
                if(ans.f){
                    cout << "Solution exists." << endl;
                    cout << "Replace " << j1 << " with " << ms[i] << "." << endl;
                    cout << "Put the first square to (" << ans.s.f.f << ", " << ans.s.f.s << ")." << endl;
                    cout << "Put the second square to (" << ans.s.s.f << ", " << ans.s.s.s << ")." << endl;
                    return 0;
                }
            }
            cout << "No solution." << endl;
            return 0;
        }
        else{
            string j1 = str[jpos[0].f][jpos[0].s];
            string j2 = str[jpos[1].f][jpos[1].s];
            rp(i, ms.size()){
                fr(j, i + 1, ms.size()){
                    str[jpos[0].f][jpos[0].s] = ms[i];
                    str[jpos[1].f][jpos[1].s] = ms[j];
                    pair<bool, pair<pii, pii > > ans = is_solvable(false);
                    if(ans.f){
                        cout << "Solution exists." << endl;
                        cout << "Replace " << j1 << " with " << ms[i] << " and " << j2 << " with " << ms[j] << "." << endl;
                        cout << "Put the first square to (" << ans.s.f.f << ", " << ans.s.f.s << ")." << endl;
                        cout << "Put the second square to (" << ans.s.s.f << ", " << ans.s.s.s << ")." << endl;
                        return 0;
                    }
                    str[jpos[1].f][jpos[1].s] = ms[i];
                    str[jpos[0].f][jpos[0].s] = ms[j];
                    ans = is_solvable(false);
                    if(ans.f){
                        cout << "Solution exists." << endl;
                        cout << "Replace " << j1 << " with " << ms[j] << "." << endl;
                        cout << "Replace " << j2 << " with " << ms[i] << "." << endl;
                        cout << "Put the first square to (" << ans.s.f.f << ", " << ans.s.f.s << ")." << endl;
                        cout << "Put the second square to (" << ans.s.s.f << ", " << ans.s.s.s << ")." << endl;
                        return 0;
                    }
                }
            }
            cout << "No solution." << endl;
        }
    }
    else{
        pair<bool, pair<pii, pii > > ans = is_solvable(false);
        if(ans.f){
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            cout << "Put the first square to (" << ans.s.f.f << ", " << ans.s.f.s << ")." << endl;
            cout << "Put the second square to (" << ans.s.s.f << ", " << ans.s.s.s << ")." << endl;
            return 0;
        }
        cout << "No solution." << endl;
    }
    return 0;
}

inline void measure(){
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(stop - start);
    cout << duration.count() << endl;
}

#include <bits/stdc++.h>
typedef long long ll ;
using namespace std;

string A = "23456789TJQKA" ;
string B = "CDHS" ;

int n , m ;
vector < vector < string > > grid;
map < char , vector < string > > suits ;
map < string , bool > vis ;
vector < pair < pair < int , int > , string >   > res ;

pair < bool , string >  solve(int x , int y) {

    bool diff = 1;
    int j1 = 0 , j2 = 0 ;
    map < char , bool > ok ;

    for(int i = x ; i < x + 3 ; i++) {
        for(int j = y ; j < y + 3 ; j++) {

            if(grid[i][j][0] == 'J') {
                if(grid[1][j][1] == '1') j1 = 1 ;
                else j2 = 1 ;
                continue ;
            }

            if(ok[grid[i][j][0]]) diff = 0 ;
            else ok[grid[i][j][0]] = 1 ;
        }
    }

    if(diff) {
        if(j1 && j2) {

            string s1 , s2 ;
            for(int i = 0 ; i < 4 ; i++) {
                for(auto s : suits[B[i]]) {
                    if(!vis[s]) {
                        if(s1.empty()) {
                            s1 = s ;
                            vis[s1] = 1;
                            continue ;
                        }
                        if(s2.empty()) {
                            s2 = s ;
                            vis[s2] = 1;
                            continue ;
                        }
                    }
                }
            }

            if(s1.empty() || s2.empty()) return {0 , "-1"};
            else return {1 , s1+s2} ;
        } else if(j1 || j2) {

            string ss ;
            for(int i = 0 ; i < 4 ; i++) {
                for(auto s : suits[B[i]]) {
                    if(!vis[s]) {
                        if(ss.empty()) {
                            vis[s] = 1;
                            if(j1) ss = s + "J1" ;
                            else ss = s + "J2" ;
                            continue ;
                        }
                    }
                }
            }
            if(ss.empty()) return {0 , "-1"} ;
            else return {1 , ss};
        }

        return {1 , "-1"};
    }

    return {0 , "-1"};
}

bool overlab(pair < int , int > p1 , pair < int , int > p2) {

    pair < int , int > l1 = p1 , l2 = p2 , r1 = make_pair(l1.first + 2 , l1.second + 2) , r2 = make_pair(l2.first + 2 , l2.second + 2);

    if (l1.first > r2.first || l2.first > r1.first)
        return false;

    if (l1.second < r2.second || l2.second < r1.second)
        return false;

    return true;
}

void output( pair < pair < int , int > , string >  sq1 , pair < pair < int , int > , string >  sq2) {

    if(!vis["J1"] && !vis["J2"]) cout << "There are no jokers." << endl ;

    else if(vis["J1"] && vis["J2"]) {

        if(sq1.second != "-1" && sq2.second != "-1") {
            string s1 = sq1.second ;
            string s2 = sq2.second ;
            if(s1.back() == '1')
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s2[0],s2[1]);
            else
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s2[0],s2[1],s1[0],s1[1]);

        } else if(sq1.second != "-1") {
            string s1 = sq1.second ;
            if(s1.back() != '1' && s1.back() != '2') {
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s1[2],s1[3]);
            } else {
                string s2 ;
                for(int i = 0 ; i < 4 && s2.empty() ; i++) {
                    for(int j = 0 ; j < 13 && s2.empty() ; j++) {
                        if(!vis[suits[B[i]][j]]) s2 = suits[B[i]][j] ;
                    }
                }
                if(s1.back() == '1') printf("Replace J1 with %c%c and J2 with %s.\n",s1[0],s1[1],s2.c_str());
                else printf("Replace J1 with %s and J2 with %c%c.\n",s2.c_str(),s1[0],s1[1]);
            }
        } else if(sq2.second != "-1") {
            string s1 = sq2.second ;
            if(s1.back() != '1' && s1.back() != '2') {
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s1[2],s1[3]);
            } else {
                string s2 ;
                for(int i = 0 ; i < 4 && s2.empty() ; i++) {
                    for(int j = 0 ; j < 13 && s2.empty() ; j++) {
                        if(!vis[suits[B[i]][j]]) s2 = suits[B[i]][j] ;
                    }
                }
                if(s1.back() == '1') printf("Replace J1 with %c%c and J2 with %s.\n",s1[0],s1[1],s2.c_str());
                else printf("Replace J1 with %s and J2 with %c%c.\n",s2.c_str(),s1[0],s1[1]);
            }

        } else {
            string s1 , s2 ;
            for(int i = 0 ; i < 4 ; i++){
                for(int j = 0 ; j < 13 ; j++){
                       if(vis[suits[B[i]][j]]) continue ;

                       if(s1.empty()){
                            s1 = suits[B[i]][j];
                            vis[s1] = 1;
                            continue ;
                       }
                       if(s2.empty()){
                            s2 = suits[B[i]][j];
                            vis[s2] = 1 ;
                            continue ;
                       }
                }
            }
            printf("Replace J1 with %s and J2 with %s.\n",s1.c_str(),s2.c_str());
        }
    }

    else if(vis["J1"] || vis["J2"]){

         if(sq1.second != "-1"){
              string s1 = sq1.second ;
              if(s1.back() == '1') printf("Replace J1 with %c%c.\n",s1[0],s1[1]);
              else  printf("Replace J2 with %c%c.\n",s1[0],s1[1]);
         }

         else if(sq2.second != "-1"){
              string s1 = sq2.second ;
              if(s1.back() == '1') printf("Replace J1 with %c%c.\n",s1[0],s1[1]);
              else  printf("Replace J2 with %c%c.\n",s1[0],s1[1]);
         }

         else{
              string s1 ;
              for(int i = 0 ; i < 4 ; i++){
                  for(int j = 0 ; j < 13 ; j++){
                        if(vis[suits[B[i]][j]]) continue ;
                        s1 = suits[B[i]][j] ;
                  }
              }
              if(vis["J1"]) printf("Replace J1 with %s.\n",s1.c_str());
              else printf("Replace J2 with %s.\n",s1.c_str());
         }
    }
    printf("Put the first square to (%d, %d).\n",sq1.first.first+1,sq1.first.second+1);
    printf("Put the second square to (%d, %d).\n",sq2.first.first+1,sq2.first.second+1);

    exit(0);
}

int main() {

    ios::sync_with_stdio(false);

    for(int i = 0 ; i < 4 ; i++) {
        for(int j = 0 ; j < 13 ; j++) {
            string s ;
            s.push_back(A[j]);
            s.push_back(B[i]);
            suits[B[i]].push_back(s);
        }
    }

    cin >> n >> m ;

    grid.resize(n + 1);

    for(int i = 0 ; i < n ; i++) {
        for(int j = 0 ; j < m ; j++) {
            string s ;
            cin >> s ;
            vis[s] = true ;
            grid[i].push_back(s);
        }
    }

    for(int i = 0 ; i + 2 < n ; i++) {
        for(int j = 0 ; j + 2 < m ; j++) {
            auto p = solve(i , j);
            if(p.first) res.push_back({ {i , j} , p.second });
        }
    }

    for(int i = 0 ; i < res.size() ; i++) {
        for(int j = i + 1 ; j < res.size() ; j++) {
            if(!overlab(res[i].first , res[j].first)) {
                cout << "Solution exists." << endl ;
                output(res[i] , res[j]);
            }
        }
    }

    cout << "No solution." << endl ;

    return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define x_ real()
#define y_ imag()
#define cross(a, b) (conj(a)*(b)).imag()
#define dot(a, b) (conj(a)*(b)).real()
#define PI acos(-1)
#define F first
#define S second
#define fastIO ios_base::sync_with_stdio(false), cin.tie(NULL)
#define fileIO freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout)
#define ordered_set tree<pair<int, int>, null_type,less<pair<int, int>>, rb_tree_tag,tree_order_statistics_node_update>
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef complex<ld> point;
typedef tuple<int, int, int> line;
typedef vector<point> polygon;
typedef pair<double, double> pd;
pair<int, int> dirs[] = { {1, 2}, {-1, 2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}, {1, -2}, {-1, -2} };
const ld eps = 1e-6;

const int N = 1e5 + 7;

string grid[20][20];
int n, m;
pair<int, int> ans1, ans2;

bool check_square(int sr, int sc) {
	set<char> suits;
	set<char> ranks;
	for (int i = sr; i < sr+3; i++) {
		for (int j = sc; j < sc+3; j++) {
			ranks.insert(grid[i][j][0]);
			suits.insert(grid[i][j][1]);
		}
	}
	bool valid = suits.size() == 1 || ranks.size() == 9;
	return valid;
}

bool check_solution() {
	for (int i = 0; i < n-2; i++) {
		for (int j = 0; j < m-2; j++) {
			if (check_square(i, j)) {
				for (int k = 0; k < n-2; k++) {
					for (int l = 0; l < m-2; l++) {
						if (k >= i && k < i+3 && l >= j && l < j+3)
							continue;
						if (check_square(k, l)) {
							ans1 = {i, j};
							ans2 = {k, l};
							return true;
						}
					}
				}
			}
		}
	}
	return false;
}

int main() {
	fastIO;
	string ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
	string suits[] = {"C", "H", "S", "D"};
	set<string> cards;
	for (int i = 0; i < 13; i++) {
		for (int j = 0; j < 4; j++) {
			cards.insert(ranks[i]+suits[j]);
		}
	}
	cin >> n >> m;
	pair<int, int> J1 = {-1, -1}, J2 = {-1, -1};
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> grid[i][j];
			cards.erase(grid[i][j]);
			if (grid[i][j] == "J1") {
				J1 = {i, j};
			}
			if (grid[i][j] == "J2") {
				J2 = {i, j};
			}
		}
	}
	for (auto c1 : cards) {
		for (auto c2: cards) {
			bool j1 = 0, j2 = 0;
			if (J1.first != -1) {
				grid[J1.first][J1.second] = c1;
				j1 = 1;
			}
			if (J2.first != -1) {
				grid[J2.first][J2.second] = c2;
				j2 = 1;
			}
			//cout << c1 << " " << check_square(J1.first, J1.second) << endl;
			if (check_solution()) {
				cout << "Solution exists.\n";
				if (!j1 && !j2) {
					cout << "There are no jokers.\n";
				}
				else {
					if (j1 && j2) {
						cout << "Replace J1 with " << c1 <<  " and J2 with " << c2 << ".\n";
					}
					else if (j1) {
						cout << "Replace J1 with " << c1 << ".\n";
					}
					else if (j2) {
						cout << "Replace J2 with " << c2 << ".\n";
					}
				}
				cout << "Put the first square to (" << ans1.first+1 << ", " << ans1.second+1 << ").\n";
				cout << "Put the second square to (" << ans2.first+1 << ", " << ans2.second+1 << ").\n";
				return 0;
			}
		}
	}

	cout << "No solution.";
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<char> Rank, suit;
vector<string> card, out;
vector<pair<int, int>> jokers;
map<string, bool> mapp;
void pre()
{
	for (char i = '2'; i <= '9'; i++)
		Rank.push_back(i);
	Rank.push_back('T');
	Rank.push_back('J');
	Rank.push_back('Q');
	Rank.push_back('K');
	Rank.push_back('A');
	suit.push_back('C');
	suit.push_back('D');
	suit.push_back('H');
	suit.push_back('S');
	string temp;
	for (int i = 0; i < (int) Rank.size(); i++)
		for (int j = 0; j < (int) suit.size(); j++)
		{
			temp = Rank[i];
			temp += suit[j];
			card.push_back(temp);
		}
}
vector<vector<string>> vec;

vector<pair<int, int>> sol(2);
bool check()
{
	vector<pair<int, int>> indx;
	for (int i = 0; i < (int) vec.size() - 2; i++)
	{
		for (int j = 0; j < (int) vec[i].size() - 2; j++)
		{
			set<char> ranks, suits;
			for (int k = i; k <= i + 2; k++)
			{
				for (int w = j; w <= j + 2; w++)
				{
					ranks.insert(vec[k][w][0]);
					suits.insert(vec[k][w][1]);
				}
			}
			if (ranks.size() == 9 || suits.size() == 1)
				indx.push_back(make_pair(i, j));
		}
	}
	for (int i = 0; i < (int) indx.size(); i++)
	{
		for (int j = 0; j < (int) indx.size(); j++)
		{
			if (indx[i].first - indx[j].first >= 3
					|| indx[i].second - indx[j].second >= 3)
			{
				sol[0] = indx[i], sol[1] = indx[j];
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	pre();
	int n, m;
	cin >> n >> m;
	vec.resize(n);
	for (int i = 0; i < (int) n; i++)
	{
		vec[i].resize(m);
		for (int j = 0; j < (int) m; j++)
		{
			cin >> vec[i][j];
			if (vec[i][j][0] == 'J'
					&& (vec[i][j][1] == '1' || vec[i][j][1] == '2'))
				jokers.push_back(make_pair(i, j));

			mapp[vec[i][j]] = 1;
		}
	}
	if (!mapp["J1"] && !mapp["J2"])
	{
		if (check())
		{
			cout << "Solution exists.\nThere are no jokers.\n";
			cout << "Put the first square to (" << sol[0].first + 1 << ", "
					<< sol[0].second + 1 << ").\n";
			cout << "Put the second square to (" << sol[1].first + 1 << ", "
					<< sol[1].second + 1 << ").\n";
		}
		else
		{
			cout << "No solution." << endl;
		}
		return 0;
	}
	for (int i = 0; i < (int) card.size(); i++)
		if (!mapp[card[i]])
			out.push_back(card[i]);

	string temp = vec[jokers[0].first][jokers[0].second];
	string temp1;
	if (jokers.size() > 1)
		temp1 = vec[jokers[1].first][jokers[1].second];
	for (int i = 0; i < (int) out.size(); i++)
	{
		vec[jokers[0].first][jokers[0].second] = out[i];
		if (jokers.size() == 2)
		{
			for (int j = 0; j < (int) out.size(); j++)
			{
				if (i == j)
					continue;
				vec[jokers[1].first][jokers[1].second] = out[j];
				if (check())
				{
					cout << "Solution exists.\nReplace " << temp << " with "
							<< out[i] << " and " << temp1 << " with " << out[j]
							<< ".\n";
					cout << "Put the first square to (" << sol[0].first + 1
							<< ", " << sol[0].second + 1 << ").\n";
					cout << "Put the second square to (" << sol[1].first + 1
							<< ", " << sol[1].second + 1 << ").\n";
					return 0;
				}
			}
		}
		else
		{
			if (check())
			{
				cout << "Solution exists.\nReplace " << temp << " with "
						<< out[i] << ".\n";
				cout << "Put the first square to (" << sol[0].first + 1 << ", "
						<< sol[0].second + 1 << ").\n";
				cout << "Put the second square to (" << sol[1].first + 1 << ", "
						<< sol[1].second + 1 << ").\n";
				return 0;
			}
		}
	}
	cout << "No solution." << endl;
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include<string>
#define REP(it,end) for (int it = 1; it <= (end); it++)
#define FOR(it,begin,end) for (int it = (begin); it <= (end); it++)
#define ROF(it,begin,end) for (int it = (begin); it >= (end); it--)
using namespace std;
string card[18][18];
set<string> used;
map<char,int> mp;
map<int,char> toc,tod;
int n,m;
struct state
{
    int x,y;
    string ans[2];
    state(){}
    state(int _x,int _y,string _str1,string _str2)
    {
        x=_x;y=_y;ans[0]=_str1;ans[1]=_str2;
    }
};
vector<state> sol;
int num[15];
bool col[4];
bool jhas[2];
string str[2];
void addcolor(int x,int y,int j,int col)
{
    if(j==2)
    {
        sol.push_back(state(x,y,str[0],str[1]));
        return;
    }
    str[j].clear();
    if(jhas[j])
    {
        for(int i=2;i<=14;i++)
        {
            str[j].push_back(tod[i]);
            str[j].push_back(toc[col]);
            if(used.find(str[j])==used.end())
            {
                used.insert(str[j]);
                addcolor(x,y,j+1,col);
                used.erase(str[j]);
            }
            str[j].clear();
        }
    }
    else addcolor(x,y,j+1,col);
}
void addnum(int x,int y,int j,int col)
{
    /*if(x==4&&y==1)
    {
        cout <<j<<" "<<jhas[j]<<" "<<col<<endl;
        for(int i=2;i<=14;i++)cout <<num[i]<<" ";cout <<endl;
        system("pause");
    }*/
    if(j==2)
    {
        sol.push_back(state(x,y,str[0],str[1]));
        return;
    }
    str[j].clear();
    if(jhas[j])
    {
        for(int i=2;i<=14;i++)
        {
            if(num[i]!=0)continue;
            str[j].push_back(tod[i]);
            str[j].push_back(toc[col]);
            if(used.find(str[j])==used.end())
            {
                used.insert(str[j]);
                num[i]++;
                addnum(x,y,j+1,col);
                num[i]--;
                used.erase(str[j]);
            }
            str[j].clear();
        }
    }
    else addnum(x,y,j+1,col);
}
void check(int x,int y)
{
    int i,j,dig,color,con;
    memset(num,0,sizeof(num));
    memset(col,false,sizeof(col));
    memset(jhas,false,sizeof(jhas));
    for(i=x;i<=x+2;i++)
        for(j=y;j<=y+2;j++)
        {
            //cout <<card[i][j]<<" "<<i<<" "<<j<<" "<<x<<" "<<y<<" "<<endl;system("pause");
            if(card[i][j][0]=='J'&&isdigit(card[i][j][1]))jhas[card[i][j][1]-'1']=true;
            else
            {
                dig=mp[card[i][j][0]];
                color=mp[card[i][j][1]];
                //cout <<color<<" "<<card[i][j]<<" "<<i<<" "<<j<<" "<<x<<" "<<y<<endl;system("pause");
                num[dig]++;
                col[color]=true;
            }
        }
    for(i=0,con=0;i<4;i++)
        if(col[i])
        {
            con++;color=i;
        }
    if(con==1)addcolor(x,y,0,color);
    for(i=2;i<=14;i++)if(num[i]>1)return;
    for(i=0;i<4;i++)addnum(x,y,0,i);
}
int main()
{
    int i,j,x,y;
    string joker[2];
    mp['2']=2;mp['3']=3;mp['4']=4;mp['5']=5;mp['6']=6;mp['7']=7;mp['8']=8;mp['9']=9;
    mp['T']=10;mp['J']=11;mp['Q']=12;mp['K']=13;mp['A']=14;
    mp['C']=0;mp['D']=1;mp['H']=2;mp['S']=3;
    toc[0]='C';toc[1]='D';toc[2]='H';toc[3]='S';
    tod[2]='2';tod[3]='3';tod[4]='4';tod[5]='5';tod[6]='6';tod[7]='7';tod[8]='8';tod[9]='9';
    tod[10]='T';tod[11]='J';tod[12]='Q';tod[13]='K';tod[14]='A';
    cin >>n>>m;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            cin >>card[i][j];
            used.insert(card[i][j]);
        }
    for(i=1;i<=n-2;i++)
        for(j=1;j<=m-2;j++)
            check(i,j);
    //for(i=0;i<(int)sol.size();i++)cout <<sol[i].x<<" "<<sol[i].y<<" "<<sol[i].ans[0]<<" "<<sol[i].ans[1]<<endl;
    for(i=0;i<(int)sol.size();i++)
    {
        for(j=i+1;j<(int)sol.size();j++)
        {
            if((sol[i].x+2<sol[j].x||sol[i].y+2<sol[j].y)&&(sol[i].ans[0]!=sol[j].ans[1]||sol[i].ans[1]!=sol[j].ans[0]))break;
        }
        if(j<(int)sol.size())break;
    }
    if(i>=(int)sol.size())
        printf("No solution.\n");
    else
    {
        //cout <<sol[i].x<<" "<<sol[i].y<<" "<<sol[i].type<<" "<<sol[i].ans<<endl;cout <<sol[j].x<<" "<<sol[j].y<<" "<<sol[j].type<<" "<<sol[j].ans<<endl;
        printf("Solution exists.\n");
        for(x=0;x<2;x++)
        if(sol[i].ans[x].size()>0u)joker[x]=sol[i].ans[x];
        for(x=0;x<2;x++)
        if(sol[j].ans[x].size()>0u)joker[x]=sol[j].ans[x];
        int color,dig;
        string temp;
        for(x=1;x<=n;x++)
            for(y=1;y<=m;y++)
            {
                if(card[x][y][0]=='J'&&isdigit(card[x][y][1]))
                {
                    if((int)joker[card[x][y][1]-'1'].size()>0)continue;
                    for(color=0;color<4;color++)
                    {
                        for(dig=2;dig<=14;dig++)
                        {
                            temp.clear();
                            temp.push_back(tod[dig]);
                            temp.push_back(toc[color]);
                            if(used.find(temp)==used.end())break;
                        }
                        if(dig<=14)break;
                    }
                joker[card[x][y][1]-'1']=temp;
                used.insert(temp);
                }
                //cout <<i<<" "<<j<<endl;
            }
        if(joker[0].size()==0&&joker[1].size()==0)printf("There are no jokers.\n");
        else if(joker[0].size()!=0&&joker[1].size()!=0)cout <<"Replace J1 with "<<joker[0]<<" and J2 with "<<joker[1]<<".\n";
        else if(joker[0].size()!=0)cout <<"Replace J1 with "<<joker[0]<<".\n";
        else cout <<"Replace J2 with "<<joker[1]<<".\n";
        //cout <<sol[i].x<<" "<<sol[i].y<<" "<<sol[i].type<<" "<<sol[i].ans<<endl;cout <<sol[j].x<<" "<<sol[j].y<<" "<<sol[j].type<<" "<<sol[j].ans<<endl;
        printf("Put the first square to (%d, %d).\n",sol[i].x,sol[i].y);
        printf("Put the second square to (%d, %d).\n",sol[j].x,sol[j].y);
    }
    return 0;
}

#include <bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;

vector<vector<string> > cards;
//vector<vector<bool> > cards;
map<char, set<char> > M;

vector<char> Ranks = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
vector<char> Suits = {'C', 'D', 'H', 'S'};

bool is_solved(int x, int y, vector<string> & C, int & jockers)
{
    set <char> S, S2;
    for (int i = 0; i < 3; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            char rank = cards[x+i][y+j][0];
            char suit = cards[x+i][y+j][1];
            if (suit != '1' && suit != '2') // not a Jocker
            {
                if (S.find(rank) != S.end())
                {
                    return false;
                }
                S.insert(rank);
            }
            else
            {
                jockers += int(suit - '0');
            }
        }
    }

    if (S.size() < 9)
    {
        for (char r: Ranks)
        {
            if (S.find(r) == S.end())
            {
                for (char s : Suits)
                {
                    if (M[r].find(s) == M[r].end())
                    {
                        string card = "";
                        C.push_back(card.append(1, r).append(1, s));
                        S2.insert(r);
                    }
                }
            }
        }
        return (S2.size() + S.size() >= 9);
    }

    return true;
}

void fill_string(vector<string> &C, string &s1, string &s2, bool & b1, bool &b2, int jockers)
{
    char r = '0';
    if (jockers & 1)
    {
        b1 = true;
        s1 = "J1 with " + C[0];
        M[C[0][0]].insert(C[0][1]);
        r = C[0][0];
    }

    if (jockers & 2)
    {
        b2 = true;
        int i = 0;
        while (C[i][0] == r) ++i;
        s2 = "J2 with " + C[i];
        M[C[i][0]].insert(C[i][1]);
    }

}

string next_card()
{
    for (char r : Ranks)
    {
        for (char s : Suits)
        {
            if (M[r].find(s) == M[r].end())
            {
                M[r].insert(s);
                string card = "";
                return card.append(1, r).append(1, s);
            }
        }
    }
}

void fill_string(string &s1, string &s2, bool & b1, bool &b2, int jockers)
{
    if (jockers & 1)
    {
        b1 = true;
        s1 = "J1 with " + next_card();
    }

    if (jockers & 2)
    {
        b2 = true;
        s2 = "J2 with " + next_card();
    }

}

bool solve()
{
    int n, m;
    cin >> n >> m;
    cards.resize(n, vector<string>(m));
    int jockers = 0;

    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            cin >> cards[i][j];
            M[cards[i][j][0]].insert(cards[i][j][1]);
            if (cards[i][j] == "J1")
            {
                jockers += 1;
            }
            if (cards[i][j] == "J2")
            {
                jockers += 2;
            }
        }
    }

    for (int i = 0; i < n - 2; ++i)
    {
        for (int j = 0; j < m - 2; ++j)
        {
            int jockers1  = 0;
            vector<string> C;
            if (is_solved(i, j, C, jockers1))
            {
                for (int k = 0; k < n - 2; ++k)
                {
                    for (int l = 0; l < m -2; ++l)
                    {
                        if ((k - i) < 3 && (l - j) < 3) continue;
                        vector<string> D;
                        int jockers2  = 0;
                        if (is_solved(k, l, D, jockers2))
                        {
                            if (D.size() == 0 || C.size() == 0 || D.size() > 1 || C.size() > 1 || D[0] != C[0]) // solution exists
                            {
                                if (D.size() > 0 && C.size() > 0 && D[0] == C[0])
                                {
                                    if (C.size() > 1)
                                    {
                                        C.erase(C.begin());
                                    }

                                    if (D.size() > 1)
                                    {
                                        D.erase(D.begin());
                                    }
                                }

                                string s1 = "";
                                string s2 = "";
                                bool b1 = false;
                                bool b2 = false;

                                fill_string(C, s1, s2, b1, b2, jockers1);
                                fill_string(D, s1, s2, b1, b2, jockers2);
                                fill_string(s1, s2, b1, b2, jockers);

                                // solution found
                                cout << "Solution exists." << endl;
                                if (b1 && b2)
                                {
                                    cout << "Replace " << s1 << " and " << s2 << "."<< endl;
                                }
                                else if (b1 || b2)
                                {
                                    cout << "Replace " << s1  << s2 << "."<< endl;
                                }
                                else
                                {
                                   cout << "There are no jokers." << endl;
                                }
                                cout << "Put the first square to ("<< i + 1 << ", " << j + 1 << ")."<< endl;
                                cout << "Put the second square to ("<< k + 1 << ", " << l + 1 << ")."<< endl;

                                return true;

                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
	cout.precision(10);

    if (!solve())
    {
       cout << "No solution." << endl;
    }

	return 0;
}

#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<climits>
using namespace std;
string a[100][100];
string f[]={"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" ,"A"};
string p[]={"C", "D", "H" , "S"};
int n,m,jk=0,ok=0;
set<string>st;
vector<string>out;
vector<string>cs;
string ff[]={"J1","J2"};
bool check(int x,int y)
{
    int i,j,k;
    int vis[130]={0};
    for (i=x;i<x+3;i++)
    {
        for (j=y;j<y+3;j++)
        {
            vis[a[i][j][0]]=1;
            //if (x==1&&y==0)printf("%c\n",a[i][j][0]);
        }
    }

    if (count(vis,vis+130,1)==9)return 1;
    memset(vis,0,sizeof(vis));
    for (i=x;i<x+3;i++)
    {
        for (j=y;j<y+3;j++)
        {
            vis[a[i][j][1]]=1;
        }
    }
    if (count(vis,vis+130,1)==1)return 1;
    return 0;
}
/*
7 3

3H J2 4H

5H 6H 7H

8H 9H TH

2S 3S TS

2D 3D 4D

5D 6D 7D

AD KD QD
*/
void dfs(int now)
{
    int i,j,k,l,u;
    //printf("%d\n",st.size());
    if (ok)return;
    if (now==jk)
    {
        for (i=0;i+2<n;i++)
        {
            for (j=0;j+2<m;j++)
            {
                if (check(i,j))
                {
                    for (k=0;k+2<n;k++)
                    {
                        for (l=0;l+2<m;l++)
                        {
                            if ((k<=i+2&&l<=j+2))continue;
                            if (check(k,l))
                            {
                                puts("Solution exists.");
                                if (!jk)
                                {
                                    puts("There are no jokers.");
                                }
                                else
                                {
                                    if (jk==1)
                                    {
                                        //cout<<out[0]<<endl;
                                        if (out[0].length()>3)
                                            printf("Replace J2 with %s.\n",out[0].substr(0,2).c_str());
                                        else
                                            printf("Replace J1 with %s.\n",out[0].c_str());
                                    }
                                    else
                                    {
                                        printf("Replace J1 with %s and J2 with %s.\n",out[0].c_str(),out[1].c_str());
                                    }
                                }
                                printf("Put the first square to (%d, %d).\n",i+1,j+1);
                                printf("Put the second square to (%d, %d).\n",k+1,l+1);
                                ok=1;
                                return;
                            }
                        }
                    }
                }
            }
        }
        return;
    }
    int x,y;
    for (i=0;i<n;i++)
    {
        for (j=0;j<m;j++)
        {
            if (a[i][j][0]=='J')
            {
                x=i,y=j;
            }
        }
    }
    int pos=a[x][y][1]-'0';
    //if (ok)return;

    for (i=0;i<cs.size();i++)
    {   //if (ok)return;
    //printf("%d\n",i);
        string tmp=cs[i];
        if (st.find(tmp)==st.end())continue;

        st.erase(tmp);
        string tt=a[x][y];
        a[x][y]=tmp;
        if (now==0&&pos==2)
        {
            out.push_back(tmp+"^^");}
        else
            out.push_back(tmp);
        dfs(now+1);
            //if (ok)return;
        out.pop_back();
        st.insert(tmp);
        a[x][y]=tt;
    }
}
int main()
{
    int i,j,k;
    for (i=0;i<13;i++)
    {
        for (j=0;j<4;j++)
        {
            st.insert(f[i]+p[j]);
        }
    }
    cin>>n>>m;
    for (i=0;i<n;i++)
    {
        for (j=0;j<m;j++)
        {
            cin>>a[i][j];
            if (a[i][j][0]!='J')st.erase(a[i][j]);
            else ++jk;
        }
    }
    for (set<string>::iterator ptr=st.begin();ptr!=st.end();++ptr)
    {
        cs.push_back(*ptr);
    }
    dfs(0);
    if (!ok)puts("No solution.");
    return 0;
}

#include <iostream>
#include <string>
#include <set>
#include <vector>

using namespace std;

string a[18][18],J1,J2;
int x1=-1,y1,x2,y2,k;
char ranks[13]={'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char suits[4]={'C', 'D', 'H', 'S'};
set <string> fall,dealed;
vector <string> all;

int equal(int x, int y)
{
    int i,j,j1=0,j2=0,J;
    char c;
    set <char> eq;
    set <char>:: iterator p;
    for (i=x; i<x+3; i++)
        for (j=y; j<y+3; j++)
            if (a[i][j]=="J1")j1=1;else
            if (a[i][j]=="J2")j2=1;else
            eq.insert(a[i][j][1]);
    if (eq.size()>1)return 0;
    p=eq.begin();
    c=(*p);
    J=j1+j2;
    int w=0;
    for (i=0; i<52 && w<J; i++)
       if (!(dealed.count(all[i])) && all[i][1]==c)
       {
          if(j1)J1=all[i],j1=0;else J2=all[i];
          w++;
       }
    if (i==52)return 0;
    if (J1.size())dealed.insert(J1);
    if (J2.size())dealed.insert(J2);
    if (k)x2=x,y2=y;else x1=x,y2=y;
    return 1;
}

int differ (int x, int y)
{
    int i,j,j1=0,j2=0,J;
    set <char> dif;
    for (i=x; i<x+3; i++)
        for (j=y; j<y+3; j++)
            if (a[i][j]=="J1")j1=1;else
            if (a[i][j]=="J2")j2=1;else
            if ((dif.count(a[i][j][0])))dif.insert(a[i][j][0]);else return 0;
    int w=0;
    for (i=0; i<52 && w<j1+j2; i++)
        if (!(dealed.count(all[i])) && !(dif.count(all[i][0])))
        {
           string qq;
           if(j1)J1=all[i],j1=0,qq=J1;else J2=all[i],qq=J2;
           dif.insert(qq[0]);
           w++;
        }
    if (dif.size()!=9)return 0;
    if (J1.size())dealed.insert(J1);
    if (J2.size())dealed.insert(J2);
    if (k)x2=x,y2=y;else x1=x,y2=y;
    return 1;
}

int main()
{
    int n,m,i,j;

    for (i=0; i<13; i++)
        for (j=0; j<4; j++)
        {
            string s="  ";
            s[0]=ranks[i],s[1]=suits[j];
            fall.insert(s);
        }

    vector <string> qqq(fall.begin() , fall.end());
    all=qqq;
    cin >> n >> m;

    for (i=0; i<n; i++)
        for (j=0; j<m; j++)
        {
            cin >> a[i][j];
            dealed.insert(a[i][j]);
        }

    for (i=0; i<n-2; i++)
        for (j=0; j<m-2; j++)
            if (x1!=-1 && j>=y1-2 && j<=y1+2 && i>=x1-2 && i<=x1+2)continue;else
               {
                  if (equal(i,j) || differ(i,j))k++;
                  if (k==2)
                  {
                     int j1=J1.size(),j2=J2.size();
                     cout << "Solution exists." << endl;
                     if (j1 && !j2)cout << "Replace J1 with " << J1 << "." << endl;
                     if (!j1 && j2)cout << "Replace J2 with " << J2 << "." << endl;
                     if (j1 && j2)cout << "Replace J1 with " << J1 << " and J2 with " << J2 << "." << endl;
                     if (!j1 && !j2)cout << "There are no jokers." << endl;
                     cout << "Put the first square to (" << x1+1 << ", " << y1+1 << ")." << endl;
                     cout << "Put the second square to (" << x2+1 << ", " << y2+1 << ")." << endl;
                 //    system("pause");
                     return 0;
                  }
               }
    cout << "No solution." << endl;
  //  system("pause");
}

//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//#pragma GCC target("avx,tune=native")
#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
const int inf=0x3f3f3f3f;
const double eps=1e-6;
const int mod=1000000007;
typedef long long ll;
int calc1(char c){
	if(c=='C')return 1;
	if(c=='D')return 2;
	if(c=='H')return 3;
	if(c=='S')return 4;
}
inline calc2(char c){
	if(isdigit(c))return c-'0';
	if(c=='T')return 10;
	if(c=='J')return 11;
	if(c=='Q')return 12;
	if(c=='K')return 13;
	if(c=='A')return 1;
}
inline char get1(int x){
	if(x==1)return 'C';
	if(x==2)return 'D';
	if(x==3)return 'H';
	if(x==4)return 'S';
}
inline char get2(int x){
	if(2<=x&&x<10)return '0'+x;
	if(x==10)return 'T';
	if(x==11)return 'J';
	if(x==12)return 'Q';
	if(x==13)return 'K';
	if(x==1)return 'A';
}
bool cross(int i1,int j1,int i2,int j2){
	vector<int>s1,s2;
	for(int i=i1;i<i1+3;i++){
		for(int j=j1;j<j1+3;j++){
			s1.push_back(i*100+j);
		}
	}
	for(int i=i2;i<i2+3;i++){
		for(int j=j2;j<j2+3;j++){
			s2.push_back(i*100+j);
		}
	}
	for(auto p:s1)for(auto q:s2)if(p==q)return true;
	return false;
}
bool ok(int x,int y,vector<vector<pair<int,int> > >&mat){
	bool samecolor=true;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(mat[i][j].first!=mat[x][y].first)samecolor=false;
		}
	}
	bool difranks=true;
	set<int>all;
	for(int i=x;i<x+3;i++){
		for(int j=y;j<y+3;j++){
			if(all.count(mat[i][j].second))difranks=false;
			all.insert(mat[i][j].second);
		}
	}
	return samecolor|difranks;
}
pair<pair<int,int>,pair<int,int> >check(vector<vector<pair<int,int> > >mat){
	int n=mat.size(),m=mat[0].size();
	for(int i1=0;i1<=n-3;i1++){
		for(int j1=0;j1<=m-3;j1++){
			for(int i2=0;i2<=n-3;i2++){
				for(int j2=0;j2<=m-3;j2++){
					if(!cross(i1,j1,i2,j2)&&ok(i1,j1,mat)&&ok(i2,j2,mat)){
						return make_pair(make_pair(i1+1,j1+1),make_pair(i2+1,j2+1));
					}
				}
			}
		}
	}
	return make_pair(make_pair(-1,-1),make_pair(-1,-1));
}
int n,m;
int main(){
	cin>>n>>m;
	vector<vector<pair<int,int> > >card(n,vector<pair<int,int> >(m,make_pair(0,0)));
	int cntj=0;
	vector<pair<int,int> >jokers;
	vector<string>vs;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			string s;
			cin>>s;
			if(s[0]=='J'&&isdigit(s[1])){
				cntj++;
				jokers.push_back(make_pair(i,j));
				vs.push_back(s);
				card[i][j]=make_pair(-1,-1);
				continue;
			}
			card[i][j]=make_pair(calc1(s[1]),calc2(s[0]));
			//color rank
		}
	}
	set<pair<int,int> >S;
	for(int i=1;i<=4;i++)for(int j=1;j<=13;j++)S.insert(make_pair(i,j));
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(card[i][j].first!=-1){
				S.erase(S.find(card[i][j]));
			}
		}
	}
	vector<pair<int,int> >restcards(S.begin(),S.end());
	if(cntj==0){
		auto p=check(card);
		if(p.first.first!=-1){
			puts("Solution exists.");
			puts("There are no jokers.");
			printf("Put the first square to (%d, %d).\n",p.first.first,p.first.second);
			printf("Put the second square to (%d, %d).\n",p.second.first,p.second.second);
			return 0;
		}else{
			puts("No solution.");
			return 0;
		}
	}else if(cntj==1){
		int x=jokers[0].first,y=jokers[0].second;
		for(auto p:restcards){
			card[x][y]=p;
			auto _p=check(card);
			if(_p.first.first!=-1){
				puts("Solution exists.");
				printf("Replace %s with %c%c.\n",vs[0].c_str(),get2(p.second),get1(p.first));
				printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
				printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
				return 0;
			}
			card[x][y]=make_pair(-1,-1);
		}
	}else{
		int x[2]={jokers[0].first,jokers[1].first},y[2]={jokers[0].second,jokers[1].second};
		for(auto p:restcards){
			for(auto q:restcards){
				if(p!=q){
					card[x[0]][y[0]]=p;
					card[x[1]][y[1]]=q;
					auto _p=check(card);
					if(_p.first.first!=-1){
						puts("Solution exists.");
						pair<char,char>c1,c2;
						if(vs[0]=="J1"){
							c1=make_pair(get2(p.second),get1(p.first));
							c2=make_pair(get2(q.second),get2(q.first));
						}else{
							c2=make_pair(get2(p.second),get1(p.first));
							c1=make_pair(get2(q.second),get2(q.first));
						}
						printf("Replace J1 with %c%c and J2 with %c%c.\n",c1.first,c1.second,c2.first,c2.second);
						printf("Put the first square to (%d, %d).\n",_p.first.first,_p.first.second);
						printf("Put the second square to (%d, %d).\n",_p.second.first,_p.second.second);
						return 0;
					}
					card[x[0]][y[0]]=make_pair(-1,-1);
					card[x[1]][y[1]]=make_pair(-1,-1);
				}
			}
		}
	}
	puts("No solution.");
	return 0;
}

#include <iostream>
#include <cmath>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#define REPN(i,a,N) for( int i = (int)a ; i < (int) N ; i++ )
#define REP(i,N) REPN(i,0,N)
#define all(x) x.begin(),x.end()

using namespace std;

typedef pair< int , int > pii;
int n , m;
int esta[130];
string suit = "CDHS";
int tab[20][20];
vector< pii > J;

int encode( string s ){
	char c = s[s.size()-1];
	s = s.substr(0,s.size()-1);
	int nat;
	if( s[0] == 'J' ) return '0'-c;
	if( s[0] == 'T' )  nat = 10;
	else if( s[0] == 'J' ) nat = 11;
	else if( s[0] == 'Q' ) nat = 12;
	else if( s[0] == 'K' ) nat = 13;
	else if( s[0] == 'A' )  nat = 1;
	else{
	istringstream is( s );
	is >> nat;
	}
	return nat*10 + suit.find(c);
}

bool inter( int a , int b , int i , int j ){
	int dx = abs( a - i );
	int dy = abs( b - j );
	if( dx < 3 and dy < 3 ) return 1;
	return 0;
}

bool solute( int i1 , int j1 ){
	int bien = true;
	REPN(i , i1 , i1+3 ){
		REPN( j , j1 , j1+3 ){
			if( tab[i][j] != tab[i1][j1] ){
				bien = false;
				goto fin;
			}
		}
	}
	if( bien ) return 1;
	fin:
	REPN( i , i1 , i1 + 3 ){
		REPN( j , j1 , j1+3 ){
			REPN( a , i1 , i1+3 ){
				REPN( b , j1 , j1+3 ){
					if( a ==i && b == j ) continue;
					if( tab[i][j]/10 == tab[a][b]/10) return 0;
				}
			}
		}
	}
	return 1;
}

vector< pii > solve( ){
	vector< pii > ans;
	REP( i1 , n-2 ){
		REP( j1 , m-2 ){
			REP( i2 , n-2  ){
				REP( j2 , m-2 ){
					if( inter( i1 , j1 , i2 , j2 ) ) continue;
					if( solute( i1, j1 ) && solute(i2,j2 ) ){
						ans.push_back( pii(i1,j1) );
						ans.push_back( pii(i2,j2) );
						return ans;
					}
				}
			}
		}
	}
	return ans;
}

int valid( int i ){
	char c = i%10;
	int rank = i/10;
	if( rank > 13 || rank <= 0 ) return 0;
	if( c > 3 || c < 0  ) return 0;
	return 1;
}

int decode( int a ){
	char c = suit[a%10];
	int peso = a/10;
	if( peso == 1 ) cout <<"A";
	else if( peso >= 10 ){
		string tmp = "TJQK";
		cout << tmp[peso-10];
	}
	else{
		cout << peso ;
	}
	cout << c ;
	return 1;
}

int main(){
	vector< int > ides;
	cin >> n >> m;
	memset( esta , 0 , sizeof( esta ) ) ;
	REP( i , n ) REP( j , m ){
		string str;
		cin >> str;
		int tmp = encode( str );
		if( tmp < 0 ){
			J.push_back( pii(i,j) );
			ides.push_back(-tmp);
		}
		else esta[tmp] = 1;
		tab[i][j] = tmp;
	}
	vector< pii > ans;
	if( J.empty() ){
		ans = solve();
		if( ans.empty() ) cout << "No solution." << endl;
		else{
			cout << "Solution exists." << endl;
			cout << "There are no jokers." << endl;
		}
	}
	else{
		if( J.size() == 1 ){
			REP( i , 130 ){
				if( valid(i) && esta[i] == 0 ){
					tab[J[0].first][J[0].second] = i;
					ans = solve();
					if( !ans.empty() ) break;
				}
			}
		}
		else{
			int i1 = J[0].first , i2 = J[1].first;
			int j1 = J[0].second , j2 = J[1].second;
			//cout << "----->>" << esta[81] << endl;
			REP( i , 130 ){
		//		cout << i << endl;
				if( i == 81 ) cout << " adjfhadkj " << endl;
				if( !valid(i) ) continue;
				if( esta[i] ) continue;
				REP( j , 130 ){
					if( esta[j] ) continue;
					if( !valid(j) ) continue;
					if( i == j ) continue;
		//			decode( i ); cout << endl;
		//			decode( j ); cout << endl;
					tab[i1][j1] = i;
					tab[i2][j2] = j;
					ans = solve();
					if( !ans.empty() ) break;
				}
		//		cout << ans.empty() << endl;
				if( !ans.empty() ) break;
			}
		}
		if( ans.empty() ) cout << "No solution." << endl;
		else  			  cout << "Solution exists." << endl;
	}

	if( !ans.empty() ){
		if( J.size() == 2 )
			if( ides[0] > ides[1] ) swap( J[0] , J[1] );
		if( !J.empty() ){
		REP(i  , 1 ){
			int a = J[i].first;
			int b = J[i].second;
			printf("Replace J%d with ",ides[0] );
			decode( tab[a][b] );
		}
		if( J.size() == 2 ){
			printf(" and J2 with ");
			decode( tab[J[1].first][J[1].second]);
		}
		}
		if( !J.empty() ) cout << "." << endl;
		printf("Put the first square to (%d, %d).\n",ans[0].first+1 , ans[0].second+1);
		printf("Put the second square to (%d, %d).\n",ans[1].first+1 , ans[1].second+1);
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 60;
string grid[N][N];
char suits[] = { 'C', 'D', 'H', 'S' };
char ranks[] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A', 'J'};
set<string> cards;
bool overlap(int r1, int c1, int r2, int c2) {
    if (r2 > r1 + 2 || r1 > r2 + 2) return false;
    if (c2 > c1 + 2 || c1 > c2 + 2) return false;
    return true;
}
bool check(int r, int c) {
    set<char> rank, suit;
    for (int i = r; i <= r + 2; i++) {
        for (int j = c; j <= c + 2; j++) {
            rank.insert(grid[i][j][0]);
            suit.insert(grid[i][j][1]);
        }
    }
    return (rank.size() == 9 || suit.size() == 1);
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for (int i = 0; i < 13; i++) {
        for (int j = 0; j < 4; j++) {
            string curr = "";
            curr += ranks[i];
            curr += suits[j];
            cards.insert(curr);
        }
    }
    vector<pair<int, int>> vec;
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> grid[i][j];
            if (grid[i][j] == "J1" || grid[i][j] == "J2") vec.emplace_back(i, j);
            cards.erase(grid[i][j]);
        }
    }
    if (vec.size() == 0) {
        for (int r1 = 1; r1 <= n - 2; r1++) {
            for (int c1 = 1; c1 <= m - 2; c1++) {
                for (int r2 = 1; r2 <= n - 2; r2++) {
                    for (int c2 = 1; c2 <= m - 2; c2++) {
                        if (overlap(r1, c1, r2, c2)) continue;
                        if (check(r1, c1) && check(r2, c2)) {
                            cout << "Solution exists.\n";
                            cout << "There are no jokers.\n";
                            cout << "Put the first square to (" << r1 << ", " << c1 << ").\n";
                            cout << "Put the second square to (" << r2 << ", " << c2 << ").\n";
                            return 0;
                        }
                    }
                }
            }
        }
    }
    if (vec.size() == 1) {
        string tmp = grid[vec[0].first][vec[0].second];
        for (auto x: cards) {
            grid[vec[0].first][vec[0].second] = x;
            for (int r1 = 1; r1 <= n - 2; r1++) {
                for (int c1 = 1; c1 <= m - 2; c1++) {
                    for (int r2 = 1; r2 <= n - 2; r2++) {
                        for (int c2 = 1; c2 <= m - 2; c2++) {
                            if (overlap(r1, c1, r2, c2)) continue;
                            if (check(r1, c1) && check(r2, c2)) {
                                cout << "Solution exists.\n";
                                cout << "Replace " << tmp << " with " << x << ".\n";
                                cout << "Put the first square to (" << r1 << ", " << c1 << ").\n";
                                cout << "Put the second square to (" << r2 << ", " << c2 << ").\n";
                                return 0;
                            }
                        }
                    }
                }
            }
        }
    }
    if (vec.size() == 2) {
        string tmp = grid[vec[0].first][vec[0].second];
        string tmp2 = grid[vec[1].first][vec[1].second];
        for (auto x: cards) {
            for (auto y: cards) {
                if (x == y) continue;
                grid[vec[0].first][vec[0].second] = x;
                grid[vec[1].first][vec[1].second] = y;
                for (int r1 = 1; r1 <= n - 2; r1++) {
                    for (int c1 = 1; c1 <= m - 2; c1++) {
                        for (int r2 = 1; r2 <= n - 2; r2++) {
                            for (int c2 = 1; c2 <= m - 2; c2++) {
                                if (overlap(r1, c1, r2, c2)) continue;
                                if (check(r1, c1) && check(r2, c2)) {
                                    cout << "Solution exists.\n";
                                    cout << "Replace " << tmp << " with " << x << " and " << tmp2 << " with " << y << ".\n";
                                    cout << "Put the first square to (" << r1 << ", " << c1 << ").\n";
                                    cout << "Put the second square to (" << r2 << ", " << c2 << ").\n";
                                    return 0;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout << "No solution.";
    return 0;
}

#include <stdio.h>
#include <string.h>

typedef struct
{
	int num;
	int suit;
}card;

typedef struct
{
	int x,y;
}point;

card a[20][20];
char str[20];
int vis[20][5];
point jok[2];
char suithash[4]={'C','D','H','S'};
char numhash[4]={'T','J','Q','K'};
point ret1,ret2;
int n,m;
int hash[15];
point res1[100];
point res2[100];

int abs(int t)
{
	return t>0?t:-t;
}

char Change(int t)
{
	char ret;
	if (t<=9 && t>1) ret=t+'0';
	else if (t==1) ret='A';
	else ret=numhash[t-10];
	return ret;
}

int ChangeSuit(char t)
{
	char ret;
	if (t=='C') ret=0;
	else if (t=='D') ret=1;
	else if (t=='H') ret=2;
	else ret=3;
	return ret;
}

int ChangeNum(char t)
{
	char ret;
	if (t>='2' && t<='9') ret=t-'0';
	else if (t=='A') ret=1;
	else if (t=='T') ret=10;
	else if (t=='J') ret=11;
	else if (t=='Q') ret=12;
	else ret=13;
	return ret;
}

bool Check1(int x,int y)
{
	int i,j,s;
	s=0;
	memset(hash,0,sizeof(hash));
	for (i=0;i<3;i++)
	{
		for (j=0;j<3;j++)
		{
			hash[a[x+i][y+j].suit]=1;
		}
	}
	for (i=0;i<4;i++)
	{
		s+=hash[i];
	}
	if (s==1) return true;
	return false;
}

bool Check2(int x,int y)
{
	int i,j,s;
	memset(hash,0,sizeof(hash));
	for (i=0;i<3;i++)
	{
		for (j=0;j<3;j++)
		{
			hash[a[x+i][y+j].num]=1;
		}
	}
	s=0;
	for (i=0;i<14;i++)
	{
		s+=hash[i];
	}
	if (s==9) return true;
	return false;
}

bool Check()
{
	int i,j,up1,up2;
	up1=up2=0;
	for (i=0;i<n;i++)
	{
		for (j=0;j<m;j++)
		{
			if (i+3>n || j+3>m) continue;
			if (Check1(i,j)==true)
			{
				res1[up1].x=i;
				res1[up1++].y=j;
			}
			if (Check2(i,j)==true)
			{
				res2[up2].x=i;
				res2[up2++].y=j;
			}
		}
	}
	for (i=0;i<up1;i++)
	{
		for (j=i+1;j<up1;j++)
		{
			if (abs(res1[i].x-res1[j].x)>=3 || abs(res1[i].y-res1[j].y)>=3)
			{
				ret1=res1[i];
				ret2=res1[j];
				return true;
			}
		}
	}
	for (i=0;i<up2;i++)
	{
		for (j=i+1;j<up2;j++)
		{
			if (abs(res2[i].x-res2[j].x)>=3 || abs(res2[i].y-res2[j].y)>=3)
			{
				ret1=res2[i];
				ret2=res2[j];
				return true;
			}
		}
	}
	return false;
}

int main()
{
	int i,j,up,t,t1,k,l;
	char s1,s;
	card tag,tag1,tagg;
	scanf("%d%d",&n,&m);
	up=0;
	memset(vis,0,sizeof(vis));
	for (i=0;i<n;i++)
	{
		for (j=0;j<m;j++)
		{
			scanf("%s",str);
			if (strcmp(str,"J1")==0 || strcmp(str,"J2")==0)
			{
				jok[up].x=i;
				jok[up].y=j;
				a[i][j].num=str[1]-'0';
				up++;
				continue;
			}
			a[i][j].suit=ChangeSuit(str[1]);
			a[i][j].num=ChangeNum(str[0]);
			vis[a[i][j].num][a[i][j].suit]=1;
		}
	}
	if (up==1)
	{
		tag=a[jok[0].x][jok[0].y];
		for (j=1;j<=13;j++)
		{
			for (k=0;k<4;k++)
			{
				if (vis[j][k]==false)
				{
					a[jok[0].x][jok[0].y].num=j;
					a[jok[0].x][jok[0].y].suit=k;
					if (Check()==true)
					{
						printf("Solution exists.\n");
						t=Change(j);
						printf("Replace J%d with %c%c.\n",tag.num,t,suithash[k]);
						printf("Put the first square to (%d, %d).\n",ret1.x+1,ret1.y+1);
						printf("Put the second square to (%d, %d).\n",ret2.x+1,ret2.y+1);
						return 0;
					}
				}
			}
		}
	}
	else if (up==2)
	{
		for (i=1;i<=13;i++)
		{
			for (j=0;j<4;j++)
			{
				for (k=1;k<=13;k++)
				{
					for (l=0;l<4;l++)
					{
						if (vis[i][j]==true || vis[k][l]==true || (i==k && j==l)) continue;
						a[jok[0].x][jok[0].y].num=i;
						a[jok[0].x][jok[0].y].suit=j;
						a[jok[1].x][jok[1].y].num=k;
						a[jok[1].x][jok[1].y].suit=l;
						if (Check()==true)
						{
							printf("Solution exists.\n");
							if (a[ret1.x][ret1.y].num==1)
							{
								t=Change(i);
								s=suithash[j];
								t1=Change(k);
								s1=suithash[l];
							}
							else
							{
								t1=Change(i);
								s1=suithash[j];
								t=Change(k);
								s=suithash[l];
							}
							printf("Replace J1 with %c%c and J2 with %c%c.\n",t,s,t1,s1);
							printf("Put the first square to (%d, %d).\n",ret1.x+1,ret1.y+1);
							printf("Put the second square to (%d, %d).\n",ret2.x+1,ret2.y+1);
							return 0;
						}

					}
				}
			}
		}
	}
	else
	{
		if (Check()==true)
		{
			printf("Solution exists.\n");
			printf("There are no jokers.\n");
			printf("Put the first square to (%d, %d).\n",ret1.x+1,ret1.y+1);
			printf("Put the second square to (%d, %d).\n",ret2.x+1,ret2.y+1);
			return 0;
		}
	}
	printf("No solution.\n");
	return 0;
}

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define li		long long
#define rep(i,to)	for(li i=0;i<((li)to);i++)
#define pb		push_back
#define sz(v)		((li)v.size())

string board[100];
map<string,int> mp;
map<int,string> rev;
map<char,int> num;
int w,h;
int res[4];
int ok=0;
int rj1,rj2,a1=-1,a2=-1;
void check2(int x,int y){
	rep(i,w-3)rep(j,h-3)if((x<i || i+3<=x) && (y<j || j+3<=y)){
		char suit=board[i+w*j][0];
		int s=0;
		int n=0;
		int used[13];
		rep(k,13) used[k]=0;
		rep(a,3)rep(b,3){
			if(used[num[board[i+a+w*(j+b)][1]]]) n=1;
			used[num[board[i+a+w*(j+b)][1]]]=1;
			if(suit!=board[i+a+w*(j+b)][0]) s=1;
		}
		if(s==0 || n==0){
			ok=1;
			rj1=a1;
			rj2=a2;
			res[0]=x+1;
			res[1]=y+1;
			res[2]=i+1;
			res[3]=j+1;
		}
	}
}
void check(){
	rep(i,w-3)rep(j,h-3){
		char suit=board[i+w*j][0];
		int s=0;
		int n=0;
		int used[13];
		rep(k,13) used[k]=0;
		rep(a,3)rep(b,3){
			if(used[num[board[i+a+w*(j+b)][1]]]) n=1;
			used[num[board[i+a+w*(j+b)][1]]]=1;
			if(suit!=board[i+a+w*(j+b)][0]) s=1;
		}
		if(s==0 || n==0) check2(i,j);
	}
}
int main(){
	string s="A23456789TJQK";
	rep(i,sz(s)) num[s[i]]=i;
	string str[]={"JA","J2","J3","J4","J5","J6","J7","J8","J9","JT","JJ","JQ","JK","SA","S2","S3","S4","S5","S6","S7","S8","S9","ST","SJ","SQ","SK","HA","H2","H3","H4","H5","H6","H7","H8","H9","HT","HJ","HQ","HK","CA","C2","C3","C4","C5","C6","C7","C8","C9","CT","CJ","CQ","CK"};
	rep(i,52) rev[i]=str[i];
	rep(i,52) mp[str[i]]=i;
	cin>>h>>w;
	rep(i,w*h) cin>>board[i];
	rep(i,w*h) swap(board[i][0],board[i][1]);
	int deck[52];
	rep(i,52) deck[i]=0;
	rep(i,w*h) deck[mp[board[i]]]=1;
	rep(i,w*h){
		if(board[i]=="J1") a1=i;
		if(board[i]=="J2") a2=i;
	}
	if(a2==-1 && a1==-1){
		check();
		if(ok){
			cout<<"Solution exists."<<endl;
			cout<<"There are no jokers."<<endl;
			cout<<"Put the first square to ("<<res[0]<<", "<<res[1]<<")."<<endl;
			cout<<"Put the second square to ("<<res[2]<<", "<<res[2]<<")."<<endl;
		}else{
			cout<<"No solution."<<endl;
		}
	}else if(a2==-1 && a1!=-1){

		rep(i,52)if(deck[i]==0){
			board[a1]=rev[i];
			check();
		}
		if(ok){
			cout<<"Solution exists."<<endl;
			cout<<"Replace J1 with "<<rj1<<"."<<endl;
			cout<<"Put the first square to ("<<res[0]<<", "<<res[1]<<")."<<endl;
			cout<<"Put the second square to ("<<res[2]<<", "<<res[2]<<")."<<endl;
		}else{
			cout<<"No solution."<<endl;
		}

	}else{
		rep(i,52)rep(j,52)if(deck[i]==0 && deck[j]==0 && i!=j){
			board[a1]=rev[i];
			board[a2]=rev[i];
			check();
		}
		if(ok){
			cout<<"Solution exists."<<endl;
			cout<<"Replace J1 with "<<rj1<<" and J2 with "<<rj2<<"."<<endl;
			cout<<"Put the first square to ("<<res[0]<<", "<<res[1]<<")."<<endl;
			cout<<"Put the second square to ("<<res[2]<<", "<<res[2]<<")."<<endl;
		}else{
			cout<<"No solution."<<endl;
		}
	}
}

/**
 *
 */
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef long long LL;

template<typename T> inline int sz(const T& x) { return (int)x.size(); }

pair<ii,ii> solve( vector<vector<string> > tab ) {
	int n = sz(tab); int m = sz(tab[0]);
	for(int i1 = 0; i1 < n-2; ++i1) {
		for(int j1 = 0; j1 < m-2; ++j1) {
			for(int i2 = 0; i2 < n-2; ++i2) {
				for(int j2 = 0; j2 < m-2; ++j2) {

					if( abs(i1-i2) < 3 && abs(j1-j2) < 3 )
						continue;

					set<char> sa, sb;
					for(int i = 0; i < 3; ++i) {
						for(int j = 0; j < 3; ++j) {
							sa.insert( tab[i1+i][j1+j][0] );
							sb.insert( tab[i1+i][j1+j][1] );
						}
					}

					if( sz(sa) != 9 && sz(sb) != 1 )
						continue;
					int q = sz(sa), w = sz(sb);

					sa.clear(); sb.clear();
					for(int i = 0; i < 3; ++i) {
						for(int j = 0; j < 3; ++j) {
							sa.insert( tab[i2+i][j2+j][0] );
							sb.insert( tab[i2+i][j2+j][1] );
						}
					}

					//if( sz(sa) != 9 && sz(sb) != 1 )
					//	continue;
					if((q == 9 && sz(sa) == 9) || (w == 1 && sz(sb) == 1) )
						return make_pair( ii(i1,j1), ii(i2,j2) );
				}
			}
		}
	}

	return make_pair(ii(-1,0), ii(0,0));
}

void out_sol( pair<ii,ii> res ) {
	cout << "Put the first square to (" << (res.first.first+1) << ", " << (res.first.second+1) << ").\n";
	cout << "Put the second square to (" << (res.second.first+1) << ", " << (res.second.second+1) << ").\n";
}

int main() {
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);

	char a[13] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
	char b[4] = {'C','D','H','S'};

	set<string> cards;

	for(int i = 0; i < 13; ++i) {
		for(int j = 0; j < 4; ++j) {
			string s("  ");
			s[0] = a[i];
			s[1] = b[j];
			cards.insert( s );
		}
	}

	int n,m;
	cin >> n >> m;

	vector<vector<string> > table(n, vector<string>(m));
	int jokers = 0;
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < m; ++j) {
			string s;
			cin >> s;
			table[i][j] = s;
			cards.erase(s);
			if( s == "J1" || s == "J2" )
				++jokers;
		}
	}

	if( jokers == 0 ) {
		pair<ii,ii> res = solve(table);
		if( res.first.first == -1 )
			cout << "No solution.\n";
		else {
			cout << "Solution exists.\nThere are no jokers.\n";
			out_sol(res);
		}
		return 0;
	}

	vector<string> free;
	for(set<string>::iterator it = cards.begin(); it != cards.end(); ++it) {
		free.push_back( *it );
	}

	if( jokers == 1 ) {
		int i,j;
		for(i = 0; i < n; ++i) {
			for(j = 0; j < m; ++j) {
				if( table[i][j] == "J1" || table[i][j] == "J2" )
					goto BB;
			}
		}
		BB:
		string t = table[i][j];
		for(int k = 0; k < sz(free); ++k) {
			table[i][j] = free[k];
			pair<ii,ii> res = solve(table);
			if( res.first.first >= 0 ) {
				cout << "Solution exists.\n";
				cout << "Replace " << t << " with " << table[i][j] << ".\n";
				out_sol(res);
				return 0;
			}
		}

		cout << "No solution.\n";
		return 0;
	}

	if( jokers == 2 ) {
		int i1=-1,i2=-1,j1,j2;
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < m; ++j) {
				if( table[i][j] == "J1" || table[i][j] == "J2" ) {
					if( i1 < 0 ) {
						i1 = i; j1 = j;
					} else {
						i2 = i; j2 = j;
					}
				}
			}
		}

		string x = table[i1][j1];
		string y = table[i2][j2];
		for(int i = 0; i < sz(free); ++i) {
			for(int j = 0; j < sz(free); ++j) {
				if( i == j ) continue;

				table[i1][j1] = free[i];
				table[i2][j2] = free[j];

				pair<ii,ii> res = solve(table);
				if( res.first.first >= 0 ) {
					cout << "Solution exists.\n";
					cout << "Replace " << x << " with " << table[i1][j1] << ".\n";
					cout << "Replace " << y << " with " << table[i2][j2] << ".\n";
					out_sol(res);
					return 0;
				}
			}
		}
	}
	cout << "No solution.\n";

	return 0;
}

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <ctime>
#include <fstream>
#include <cmath>

using namespace std;

#ifndef LOCAL
#define cerr if(0)cerr
#endif
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define RT fprintf(stderr, "\nTIME = %lf\n", 1.0 * clock()/CLOCKS_PER_SEC);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii > vpii;
typedef vector<vi > vvi;

const int INFint = 1147483547;
const ll INF = 9223372036854775807ll;
const ll MOD = 1000000007ll;
const ld EPS = 1e-13;

#define FILE "paren"

char dost[13] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char mast[4] = {'C', 'D', 'H', 'S'};

int b1, b2, a1, a2;

bool isPasians(vector< vector< pair<char, char> > > & cur, int x, int y) {
    set<char > ferathorn;
    set<char > masha;
    for (int i = x; i < x + 3; i++) {
        for (int j = y; j < y + 3; j++)  {
            ferathorn.insert(cur[i][j].F);
            masha.insert(cur[i][j].S);
        }
    }
    return (ferathorn.size() == 9 || masha.size() == 1);
}

bool in(int x1, int y1, int x2, int y2) {
    return abs(x1 - x2) > 2 || abs(y1 - y2) > 2;
}

int check(vector< vector< pair<char, char> > > & cur) {
    int n = cur.size();
    int m = cur[0].size();
    for (int i = 0; i < n - 2; i++) {
        for (int j = 0; j < m - 2; j++) {
            if (isPasians(cur, i, j)) {
                for (int a = i + 1; a < n; a++)
                    for (int b = j + 1; b < m; b++) {
                   //     cerr << i << ' ' << j << ' ' << a << ' ' << b << ' ' <<  in(i, j, a, b) << endl;
                        if (a + 2 < n && b + 2 < m && in(i, j, a, b) && isPasians(cur, a, b)) {
                            a1 = i;
                            a2 = a;
                            b1 = j;
                            b2 = b;
                            return 1;
                        }
                    }
            }
        }
    }
    return 0;
}

int main(){
    ios_base::sync_with_stdio(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
//    freopen(FILE".in", "r", stdin); freopen(FILE".out", "w", stdout);
//    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif
    set<pair<char, char > > available;
    for (int i = 0; i < 13; i++) {
        for (int j = 0; j < 4; j++) {
            available.insert(mp(dost[i], mast[j]));
        }
    }
    int n, m;
    cin >> n >> m;
    vector< vector< pair<char, char> > > f(n, vector< pair<char, char> > (m));
    pii j1 = {-1, -1}, j2 = {-1, -1};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            string c;
            cin >> c;
            if (c[0] == 'J') {
                if (c[1] == '1') {
                    j1 = mp(i, j);
                } else j2 = mp(i, j);
                continue;
            }
            f[i][j].F = c[0];
            f[i][j].S = c[1];
            available.erase(available.find(mp(c[0], c[1])));
        }
    }
    for (auto it : available) {
        for (auto it1 : available) {
            pair <char, char > c1 = it, c2 = it1;
            vector< vector< pair<char, char> > > cur = f;
            if (c1 == c2) continue;
            bool replaced1 = 0, replaced2 = 0;
            if (j1 != mp(-1, -1)) {
                replaced1 = 1;
                cur[j1.F][j1.S] = c1;
            }
            if (j2 != mp(-1, -1)) {
                replaced2 = 1;
                cur[j2.F][j2.S] = c2;
            }
            if (check(cur)) {
                cout << "Solution exists.\n";
                if (replaced1) {
                    cout << "Replace J1 with " << c1.F << c1.S << ".\n";
                }
                if (replaced2) {
                    cout << "Replace J2 with " << c2.F << c2.S << ".\n";
                }
                if (!replaced1 && !replaced2) {
                    cout << "There are no jokers.\n";
                }
                cout << "Put the first square to (" << a1 + 1 << ", " << b1 + 1 << ").\n";
                cout << "Put the second square to (" << a2 + 1 << ", " << b2 + 1 << ").\n";
                return 0;
            }
        }
    }
    cout << "No solution.   ";
    //RT;
    return 0;
}

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <bitset>
#include <random>
#include <cassert>

using std::ios_base;
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::fixed;

using std::vector;
using std::string;
using std::stack;
using std::queue;
using std::deque;
using std::map;
using std::set;
using std::unordered_map;
using std::unordered_set;
using std::bitset;

using std::tuple;
using std::make_tuple;
using std::pair;
using std::make_pair;

using std::sort;
using std::reverse;
using std::nth_element;

#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()

#define forn(i, n) for (int i = 0; i < (n); i++)
#define fornr(i, n) for (int i = (n) - 1; i >= 0; i--)
#define forab(i, a, b) for (int i = (a); i < (b); i++)

int n, m;
char x[13] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
char y[4] = {'C', 'D', 'H', 'S'};

string f[20][20];
int used[20][20], useda[256], C = 0;
bool diff[20][20], cont[20][20];
bool inter[20][20][20][20];

bool intersect(int i, int j, int k, int l) {
    ++C;
    int cnt = 0;
    for (int a = i; a < i + 3; ++a) {
        for (int b = j; b < j + 3; ++b) {
            if (used[a][b] != C) {
                used[a][b] = C;
                cnt++;
            }
        }
    }
    for (int a = k; a < k + 3; ++a) {
        for (int b = l; b < l + 3; ++b) {
            if (used[a][b] != C) {
                used[a][b] = C;
                cnt++;
            }
        }
    }
    return cnt != 18;
}

bool check(int i, int j) {
    bool eq = true;
    for (int a = i; a < i + 3; ++a) {
        for (int b = j; b < j + 3; ++b) {
            eq &= f[a][b][1] == f[i][j][1];
        }
    }
    if (eq) return true;

    C++;
    int cnt = 0;
    for (int a = i; a < i + 3; ++a) {
        for (int b = j; b < j + 3; ++b) {
            if (useda[f[a][b][0]] != C) {
                useda[f[a][b][0]] = C;
                ++cnt;
            }
        }
    }
    return cnt == 9;
}

int sol1i, sol2i, sol1j, sol2j;

bool check() {
    for (int i = 0; i < n - 2; ++i) {
        for (int j = 0; j < m - 2; ++j) {
            diff[i][j] = check(i, j);
        }
    }

    for (int i = 0; i < n - 2; ++i) {
        for (int j = 0; j < m - 2; ++j) {
            if (!diff[i][j])
                continue;
            for (int k = 0; k < n - 2; ++k) {
                for (int l = 0; l < m - 2; ++l) {
                    if (inter[i][j][k][l])
                        continue;
                    if (diff[i][j] && diff[k][l]) {
                        sol1i = i + 1;
                        sol1j = j + 1;
                        sol2i = k + 1;
                        sol2j = l + 1;
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

vector<pair<int, int> > aa;
vector<string> bb;
set<string> fr;
vector<string> fr2;

void print() {
    cout << "Solution exists.\n";
    if (bb.empty()) {
        cout << "There are no jokers.\n";
    } else {
        for (int i = 0; i < (int) bb.size(); ++i) {
            int k = aa[i].first, l = aa[i].second;
            if (i == 0) {
                cout << "Replace " << bb[i] << " with " << f[k][l];
            } else {
                cout << " and " << bb[i] << " with " << f[k][l];
            }
        }
        cout << ".\n";
    }
    cout << "Put the first square to (" << sol1i << ", " << sol1j << ").\n";
    cout << "Put the second square to (" << sol2i << ", " << sol2j << ").\n";
    exit(0);
}

void setj(int i) {
    if (i == (int) aa.size()) {
        if (check()) {
            print();
        }
        return;
    }

    for (auto& s : fr2) {
        if (s[0] == 'J')
            continue;
        if (i && f[aa[i - 1].first][aa[i - 1].second] == s)
            continue;
        f[aa[i].first][aa[i].second][0] = s[0];
        f[aa[i].first][aa[i].second][1] = s[1];
        setj(i + 1);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.precision(10);
    cout << fixed;

    for (int i = 0; i < 13; ++i) {
        for (int j = 0; j < 4; ++j) {
            string s = "";
            s += x[i];
            s += y[j];
            fr.insert(s);
        }
    }

    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> f[i][j];
            fr.erase(f[i][j]);
            if (f[i][j] == "J1" || f[i][j] == "J2") {
                aa.emplace_back(i, j);
                bb.pb(f[i][j]);
            }
        }
    }

    for (auto& s : fr)
        fr2.pb(s);

    if ((int) bb.size() == 2 && bb[0] > bb[1]) {
        std::swap(bb[0], bb[1]);
        std::swap(aa[0], aa[1]);
    }

    for (int i = 0; i < n - 2; ++i)
        for (int j = 0; j < m - 2; ++j)
            for (int k = 0; k < n - 2; ++k)
                for (int l = 0; l < m - 2; ++l)
                    inter[i][j][k][l] = intersect(i, j, k, l);

    setj(0);

    cout << "No solution.\n";

#ifdef LOCAL
    cerr << "\n== " << 1.0 * clock() / CLOCKS_PER_SEC << " sec.\n";
#endif
    return 0;
}

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;
int n,m;
string s[70][70];
vector <string> ve;
map <string,int> ma;
int klj[80][80];
int kla=0;
vector <pair<int,int> > votv;
int cnt[80][80];
int main() {
    string s1="23456789TJQKA";
    string s2="CDHS";
    int n,m;
    cin>>n>>m;
    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;
            ma[s3]=1;
        }
    int kljok=0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            cin>>s[i][j];
            ma[s[i][j]]=0;
            if(s[i][j]=="J1" || s[i][j]=="J2") kljok++;
        }

    for (int i=0; i<s1.size(); i++)
        for (int j=0; j<s2.size(); j++) {
            string s3;
            s3=s1[i];
            string s4;
            s4=s2[j];
            s3=s3+s4;

            if (ma[s3]==1) ve.push_back(s3);

        }
    for (int i=0; i<n-2; i++)
        for (int j=0; j<m-2; j++) {
            map<char,int> mra;
            int f1=0,f2=0;
            int kj=0;
            for (int i1=0; i1<3; i1++)
                for (int j1=0; j1<3; j1++) {
                    if (s[i+i1][j+j1]!="J1" && s[i+i1][j+j1]!="J2") {
                        if (mra[s[i+i1][j+j1][0]]==0)
                            mra[s[i+i1][j+j1][0]]++;
                        else f1=1;
                        if (mra[s[i+i1][j+j1][1]]==0) {
                            mra[s[i+i1][j+j1][1]]=1;
                            f2++;
                        }

                    } else if (s[i+i1][j+j1]=="J1")kj++;
                    else if (s[i+i1][j+j1]=="J2") kj+=2;
                }
            //cout<<i<<' '<<j<<' '<<f1<<' '<<f2<<' '<<kj<<endl;
            klj[i][j]=kj;
            if (f1==0 || f2==1) {
                votv.push_back(make_pair(i,j));
            }
        }

    if (votv.size()<2) {
        cout<<"No solution.";
        return 0;
    }
    string jock1="",jock2="";
    int nom1=-1,nom2=-1;
    for(int i=0; i<votv.size(); i++){if (nom1!=-1 && nom2!=-1) break;
        for (int j=i+1; j<votv.size(); j++) {
                if (nom1!=-1 && nom2!=-1) break;
            jock1="",jock2="";

            nom1=-1;nom2=-1;
            int x=votv[i].first;
            int y=votv[i].second;
            int x1=votv[j].first;
            int y1=votv[j].second;
            if (abs(x-x1)>2 || abs(y-y1)>2) {
                if (klj[x][y]==0 && klj[x1][y1]==0) {
                    nom1=i;
                    nom2=j;
                    break;
                }
                if (klj[x][y]!=0 && klj[x][y]!=3) {
                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if (s[x+i1][y+j1]!="J1" && s[x+i1][y+j1]!="J2") {
                                if (mra[s[x+i1][y+j1][0]]==0)
                                    mra[s[x+i1][y+j1][0]]++;
                                else f1=1;
                                if (mra[s[x+i1][y+j1][1]]==0) {
                                    mra[s[x+i1][y+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) { char r;
                        if (s[x][y]!="J1" && s[x][y]!="J2")
                            r=s[x][y][1];
                        else if (s[x][y+1]!="J1" && s[x][y]!="J2")
                             r=s[x][y+1][1];
                        else  r=s[x+1][y][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                jock1=ve[l];
                                break;
                            }
                    }
                    if (f1==0) {
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                jock1=ve[l];
                                break;
                            }

                    }
                }
                if (klj[x1][y1]!=0  && klj[x1][y1]!=3) {
                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if (s[x1+i1][y1+j1]!="J1" && s[x1+i1][y1+j1]!="J2") {

                                if (mra[s[x1+i1][y1+j1][0]]==0)
                                    mra[s[x1+i1][y1+j1][0]]++;
                                else f1=1;
                                if (mra[s[x1+i1][y1+j1][1]]==0) {
                                    mra[s[x1+i1][y1+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        if (s[x1][y1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1][1];
                        else if (s[x1][y1+1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1+1][1];
                        else r=s[x1+1][y1][1];
                         r=s[x1][y1][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                jock2=ve[l];
                                break;
                            }
                    }
                    if (f1==0) {
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                jock2=ve[l];
                                break;
                            }
                    }
                }
                if (klj[x][y]==3) {

                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++) {
                            if(s[x+i1][y+y1]!="J1" && s[x+i1][y+j1]!="J2") {
                                if (mra[s[x+i1][y+j1][0]]==0)
                                    mra[s[x+i1][y+j1][0]]++;
                                else f1=1;
                                if (mra[s[x+i1][y+j1][1]]==0) {
                                    mra[s[x+i1][y+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        int lrr=1;
                        if (s[x][y]!="J1" && s[x][y]!="J2")
                             r=s[x][y][1];
                        else if (s[x][y+1]!="J1" && s[x][y]!="J2")
                             r=s[x][y+1][1];
                        else  r=s[x+1][y][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                } else {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                    if (f1==0) {
                        int lrr=1;
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                    mra[ve[l][0]]=1;
                                } else  {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                }
                if (klj[x1][y1]==3) {

                    int f1=0,f2=0;
                    map<char,int> mra;

                    for (int i1=0; i1<3; i1++)
                        for (int j1=0; j1<3; j1++)

                        {
                            if (s[x1+i1][y1+j1]!="J1" && s[x1+i1][y1+j1]!="J2") {
                                if (mra[s[x1+i1][y1+j1][0]]==0)
                                    mra[s[x1+i1][y1+j1][0]]++;
                                else f1=1;
                                if (mra[s[x1+i1][y1+j1][1]]==0) {
                                    mra[s[x1+i1][y1+j1][1]]=1;
                                    f2++;
                                }
                            }
                        }
                    if (f2==1) {char r;
                        int lrr=1;
                        if (s[x1][y1]!="J1" && s[x1][y1]!="J2")
                            r=s[x1][y1][1];
                        else if (s[x1][y1+1]!="J1" && s[x1][y1]!="J2")
                             r=s[x1][y1+1][1];
                        else r=s[x1+1][y1][1];
                        for(int l=0; l<ve.size(); l++)
                            if (ve[l][1]==r) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                } else {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                    if (f1==0) {
                        int lrr=1;
                        for(int l=0; l<ve.size(); l++)
                            if (mra[ve[l][0]]==0) {
                                if (lrr==1) {
                                    jock1=ve[l];
                                    lrr++;
                                    mra[ve[l][0]]=1;
                                } else  {
                                    jock2=ve[l];
                                    break;
                                }
                            }
                    }
                }

if (kljok==2 && jock1!="" && jock2!="") {
                    nom1=i;
                    nom2=j;
                    break;
                } else if (kljok==1 && ((jock1!="") || jock2!="")) {
                    nom1=i;
                    nom2=j;
                    break;
                } else if (kljok==0) {
                    nom1=i;
                    nom2=j;
                    break;
                }
            }

        }}
    if (nom1==-1 || nom2==-1) {
        cout<<"No solution.";
        return 0;
    }
    cout<<"Solution exists."<<endl;
    if (kljok==0) {
        cout<<"There are no jokers."<<endl;
    }
    if (kljok==1) {
        if (jock1=="") {
            string sr="";
            if (klj[votv[nom2].first][votv[nom2].second]==1) sr="J1";
            else sr="J2";
            cout<<"Replace "<<sr<<" with "<<jock2<<'.'<<endl;
        } else  {
            string sr="";
            if (klj[votv[nom1].first][votv[nom1].second]==1) sr="J1";
            else sr="J2";
            cout<<"Replace "<<sr<<" with "<<jock1<<'.'<<endl;
        }
    }string sr;string srr;
    if (kljok==2) {if (klj[votv[nom1].first][votv[nom2].second]==1) sr="J1";
    else sr="J2";if (sr=="J2") srr="J1";
    else srr="J2";
    if (sr=="J1")
        cout<<"Replace "<<sr<<" with "<<jock1<<" and "<<srr<<" with "<<jock2<<'.'<<endl;
        else cout<<"Replace "<<srr<<" with "<<jock2<<" and "<<sr<<" with "<<jock1<<'.'<<endl;

        }
    cout<<"Put the first square to ("<<votv[nom1].first+1<<", "<<votv[nom1].second+1<<")."<<endl;
    cout<<"Put the second square to ("<<votv[nom2].first+1<<", "<<votv[nom2].second+1<<")."<<endl;

}

//
// Created by Allen Li on 7/22/18.
//

#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<double, double> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;

template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;

template<class T>
inline void MAX(T &a, T b) { if (a < b) a = b; }

template<class T>
inline void MIN(T &a, T b) { if (a > b) a = b; }

template<class T>
inline void MODA(T &a, T b) {
    a %= b;
    if (a < 0) a += b;
}

#define FAST_IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout.precision(20)
#define watch(x) cout << (#x) << " is " << (x) << endl
#define long ll
#define finish(x) return cout << (x) << '\n', 0
#define F0R(i, a) for(int (i)=0;(i)<(a);++(i))
#define FOR(i, a, b) for(int (i)=(a);(i)<(b);++(i))
#define F0Rd(i, a) for(int (i)=a;(i)>=0;--(i))
#define FORd(i, a, b) for(int (i)=a;(i)>=(b);--(i))
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

#define mp make_pair
#define pb push_back
#define pf push_front
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const int NINF = -0x3f3f3f40;
const int MAXN = 20;

int n, m, num;
vpi jokers;
vector<pair<char, char>> repl;
pair<char, char> grid[MAXN][MAXN];
bool overlaps(int i, int j, int k, int l) {
    bool used[n][m];
    memset(used, false, sizeof used);
    FOR(a, i-2, i+1)
        FOR(b, j-2, j+1)
            used[a][b] = true;
    FOR(a, k-2, k+1)
        FOR(b, l-2, l+1)
            if(used[a][b])
                return true;
    return false;
}
bool isValid() {
    FOR(i, 2, n) {
        FOR(j, 2, m) {
            FOR(k, 2, n) {
                FOR(l, 2, m) {
                    if(overlaps(i, j, k, l))
                        continue;
                    set<char> seen;
                    bool bad = false;
                    int currSuit = -1;
                    FOR(a, i - 2, i + 1)
                        FOR(b, j - 2, j + 1) {
                            pair<char, char> card = grid[a][b];
                            if (seen.count(card.f))
                                bad = true;
                            seen.insert(card.f);
                            if (currSuit == -1)
                                currSuit = card.s;
                            if (currSuit != card.s)
                                currSuit = -2;
                        }
                    if(currSuit == -2 && bad)
                        continue;
                    bad = false;
                    currSuit = -1;
                    seen.clear();
                    FOR(a, k - 2, k + 1)
                        FOR(b, l - 2, l + 1) {
                            pair<char, char> card = grid[a][b];
                            if (seen.count(card.f))
                                bad = true;
                            seen.insert(card.f);
                            if (currSuit == -1)
                                currSuit = card.s;
                            if (currSuit != card.s)
                                currSuit = -2;
                        }
                    if(currSuit == -2 && bad)
                        continue;
                    cout << "Solution exists." << '\n';
                    if (repl.size()) {
                        if (repl.size() == 1)
                            cout << "Replace J" << num << " with " << repl[0].f << repl[0].s << ".\n";
                        else
                            cout << "Replace J1 with " << repl[0].f << repl[0].s
                                    << " and J2 with " << repl[1].f << repl[1].s << ".\n";
                    } else {
                        cout << "There are no jokers." << '\n';
                    }
                    cout << "Put the first square to (" << i-1 << ", " << j-1 << ")." << '\n';
                    cout << "Put the second square to (" << k-1 << ", " << l-1 << ")." << '\n';
                    exit(0);
                }
            }
        }
    }
    return false;
}
int main() {
    FAST_IO;
    cin >> n >> m;
    set<pair<char, char>> cards;
    set<char> suits{'C', 'D', 'H', 'S'};
    char type[]{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
    for(char ty: type)
        for(char su: suits)
            cards.insert(mp(ty, su));
    F0R(i, n) {
        F0R(j, m) {
            string str; cin >> str;
            grid[i][j].f = str[0];
            grid[i][j].s = str[1];
            if(!suits.count(str[1]))
                jokers.pb(mp(i, j));
            cards.erase(mp(str[0], str[1]));
        }
    }
    if(jokers.size() == 0)
        isValid();
    if(jokers.size() == 1) {
        num = grid[jokers[0].f][jokers[0].s].s - '0';
        for(auto card: cards) {
            grid[jokers[0].f][jokers[0].s] = card;
            repl.pb(card);
            isValid();
            repl.clear();
        }
    }
    if(jokers.size() == 2) {
        for(auto card: cards) {
            for(auto card2: cards) {
                auto n1 = card;
                auto n2 = card2;
                if(grid[jokers[0].f][jokers[0].s] != mp('J', '1')) {
                    swap(n1, n2);
                }
                if(card == card2)
                    continue;
                grid[jokers[0].f][jokers[0].s] = n1;
                grid[jokers[1].f][jokers[1].s] = n2;
                repl.pb(n1);
                repl.pb(n2);
                isValid();
                repl.clear();
            }

        }
    }
    cout << "No solution." << '\n';
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define all(a) a.begin(),a.end()
#define fst first
#define snd second

int n,m;
pii joker[2]={{-1,-1},{-1,-1}};
pair<int,int>s1={-1,-1},s2={-1,-1};
string ranks="23456789TJQKA",suits="CDHS",a[64][64];
set<string>deck;
vector<string>left_cards;
void gen_deck() {
  for(char r:ranks)for(char s:suits) {
    string res="";
    res=res+r;
    res=res+s;
    deck.insert(res);
  }
}

bool can(int ii,int jj) {
  set<char>cur_ranks;
  set<char>cur_suits;
  fore(i,0,3)fore(j,0,3) {
    cur_ranks.insert(a[ii+i][jj+j][0]);
    cur_suits.insert(a[ii+i][jj+j][1]);
  }
  // cout<<ii<<" "<<jj<<" : "<<SZ(cur_ranks)<<" "<<SZ(cur_suits)<<endl;
  return ((SZ(cur_ranks)==9)||(SZ(cur_suits)==1));
}

bool check() {
  // cout<<"check for: "<<endl;
  // fore(i,0,n){fore(j,0,m)cout<<a[i][j]<<" ";cout<<endl;}
  fore(lr,0,n-2)fore(lc,0,m-2)fore(rr,0,n-2)fore(rc,0,m-2) {
    // cout<<"view: "<<lr<<" "<<lc<<" "<<rr<<" "<<rc<<endl;
    if(rr<lr+3 && rc<lc+3)continue;
    // cout<<"really view: "<<lr<<" "<<lc<<" "<<rr<<" "<<rc<<endl;
    if(can(lr,lc) && can(rr,rc)) {
      s1={lr,lc};
      s2={rr,rc};
      return 1;
    }
  }
  return 0;
}

int main() {
  ios::sync_with_stdio(false);
  gen_deck();
  cin>>n>>m;
  fore(i,0,n)fore(j,0,m) {
    cin>>a[i][j];
    if(a[i][j][0]=='J')joker[a[i][j][1]-'1']={i,j};
    deck.erase(a[i][j]);
  }
  for(auto it:deck)left_cards.pb(it);
  fore(i,0,SZ(left_cards))fore(j,0,SZ(left_cards)) {
    if(i==j)continue;
    if(joker[0].fst!=-1)a[joker[0].fst][joker[0].snd]=left_cards[i];
    if(joker[1].fst!=-1)a[joker[1].fst][joker[1].snd]=left_cards[j];

    // cout<<"check for: "<<endl;
    // fore(i,0,n){fore(j,0,m)cout<<a[i][j]<<" ";cout<<endl;}

    if(check()) {
      cout<<"Solution exists."<<endl;
      if(joker[0].fst<0 && joker[1].fst<0) {
        cout<<"There are no jokers."<<endl;
      } else if (!((joker[0].fst<0)||(joker[1].fst<0))) {
        cout<<"Replace J1 with "<<left_cards[i]<<" and J2 with "<<left_cards[j]<<"."<<endl;
      } else {
        if(joker[0].fst<0) {
          cout<<"Replace J2 with "<<left_cards[j]<<"."<<endl;
        } else {
          cout<<"Replace J1 with "<<left_cards[i]<<"."<<endl;
        }
      }
      cout<<"Put the first square to ("<<s1.fst+1<<","<<s1.snd+1<<")."<<endl;
      cout<<"Put the second square to ("<<s2.fst+1<<","<<s2.snd+1<<")."<<endl;
      return 0;
    }
  }
  cout<<"No solution."<<endl;
}

#include <iostream>
#include <string>
#include <set>
#include <cstdio>
#include <cstring>
using namespace std;

string rank[15] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
string suit[5] = {"C", "D", "H", "S"};

int ans1i, ans1j, ans2i, ans2j;

int check(string str[100][100], int m, int n)
{
	int ret[100][100];
	int used[500];
	char st;
	int flag = 0;
	int i, j, k, l;
	int ok = 0;

	memset(ret, 0, sizeof(ret));
	for(i = 2;i < m;i++)
		for(j = 2;j < n;j++)
		{
			flag = 1;
			st = str[i - 2][j - 2][1];
			memset(used, 0, sizeof(used));
			for(k = i - 2;k <= i;k++)
			{
				for(l = j - 2;l <= j;l++)
					if (str[k][l][1] != st && used[str[k][l][0]])
					{
						flag = 0;
						break;
					}
					else
						used[str[k][l][0]]++;
				if (flag == 0)
					break;
			}
			ret[i][j] = flag;
		}

	for(i = 2;i < m;i++)
	{
		for(j = 2;j < n;j++)
		{
			if (ret[i][j])
			{
				for(k = i + 3;k < m;k++)
				{
					for(l = 0;l < n;l++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				for(l = j + 3;j < n;j++)
				{
					for(k = i;k < m;k++)
						if (ret[k][l])
						{
							ok = 1;
							ans1i = i - 1;
							ans1j = j - 1;
							ans2i = k - 1;
							ans2j = l - 1;
							break;
						}
					if (ok)
						break;
				}
				if (ok)
					break;
			}
		}
		if (ok)
			break;
	}

	return ok;
}

int main()
{
	int m, n;
	int rk, st, rk2, st2;
	int pi1, pj1, pi2, pj2;
	int i, j;
	int flag;
	string arr[100][100];
	set <string> used;
	cin>>m>>n;

	pi1 = pj1 = pi2 = pj2 = -1;
	for(i = 0;i < m;i++)
		for(j = 0;j < n;j++)
		{
			cin>>arr[i][j];
			if (arr[i][j] == "J1" && arr[i][j] == "J2")
				used.insert(arr[i][j]);
			if (arr[i][j] == "J1")
			{
				pi1 = i;
				pj1 = j;
			}
			if (arr[i][j] == "J2")
			{
				pi2 = i;
				pj2 = j;
			}
		}

	flag = 0;
	for(rk = 0;rk < 13;rk++)
		for(st = 0;st < 4;st++)
		{
			if (pi1 != -1)
				arr[pi1][pj1] = rank[rk] + suit[st];
			if (used.find(arr[pi1][pj1]) != used.end())
				continue;

	//		cout<< arr[pi1][pj1] << endl;

	//		if (arr[pi1][pj1] == "2H")
	//					cout<<"fdafd"<<endl;
			for(rk2 = 0;rk2 < 13;rk2++)
				for(st2 = 0;st2 < 4;st2++)
				{
					if (pi1 != -1 && rk == rk2 && st == st2)
						continue;
					if (pi2 != -1)
						arr[pi2][pj2] = rank[rk2] + suit[st2];

					if (used.find(arr[pi2][pj2]) != used.end())
						continue;

			//		if (arr[pi1][pj1] == "2H")
			//			cout<<"fdafd"<<endl;
					if (check(arr, m, n))
					{
						flag = 1;
						break;
					}
				}
			if (flag == 1)
				break;
		}

	if (flag)
	{
		printf("Solution exists.\n");
		if (pi1 == -1 && pi2 == -1)
			printf("There are no jokers.\n");
		else if (pi1 != -1)
			printf("Replace J1 with %s.\n", arr[pi1][pj1].c_str());
		if (pi2 != -1)
			printf("Replace J1]2 with %s.\n", arr[pi2][pj2].c_str());

		printf("Put the first square to (%d, %d).\n", ans1i, ans1j);
		printf("Put the second square to (%d, %d).\n", ans2i, ans2j);
	}
	else
		printf("No solution.\n");

	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using ordered_set_rev = tree<T, null_type, greater<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using dijkstra = priority_queue<T, vector<T>, greater<T>>;

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define fbo find_by_order //k th index
#define ook order_of_key // strictly smaller than k
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define max_ull 18446744073709551615
#define max_ll 9223372036854775807
#define min3(a, b, c) min(a, min(b, c))
#define max3(a, b, c) max(a, max(b, c))
#define min4(a, b, c, d) min(min(a, b), min(c, d))
#define max4(a, b, c, d) max(max(a, b), max(c, d))
#define max5(a, b, c, d, e) max(max3(a, b, c), max(d, e))
#define min5(a, b, c, d, e) min(min3(a, b, c), min(d, e))
#define lead_zero(x) __builtin_clzll(x)
#define trail_zero(x) __builtin_ctzll(x)
#define total_1s(x) __builtin_popcountll(x)
#define first_1(x) __builtin_ffsll(x)
#define log2_(x) __builtin_clz(1) - __builtin_clz(x)
#define isLeap(x) ((x % 400 == 0) || (x % 100 ? x % 4 == 0 : false))
#define QUERY int test;scanf("%d", &test);for (int _T = 1; _T <= test; _T++)
#define FAST ios_base::sync_with_stdio(0), cin.tie(0)
#define all(v) v.begin(), v.end()
#define reunique(v) v.resize(std::unique(all(v)) - v.begin())
#define pii pair<int, int>
#define pll pair<ll, ll>
#define ff first
#define ss second
#define MERGE(v1, v2, v) merge(all(v1), all(v2), back_inserter(v))
#define MP make_pair
#define EB emplace_back
#define read freopen("input.txt", "r", stdin)
#define write freopen("output.txt", "w", stdout)
#define in_range(v, r, l) upper_bound(all(v), r) - lower_bound(all(v), l)
#define LCM(a,b) (a/__gcd(a,b))*b;
template<typename T1,typename T2>
ostream& operator<<(ostream &fout,const pair<T1,T2>&ps) {
    fout<<ps.ff<<" "<<ps.ss;
    return fout;
}
template<typename T1,typename T2>
ostream& operator<<(ostream &fout,const map<T1,T2>&mp) {
    for(pair<T1,T2> i:mp)
        fout<<i.first<<" : "<<i.second<<endl;
    return fout;
}
template<typename T>
ostream& operator<<(ostream& fout,const vector<T>&v) {
    for(T i:v)
        fout<<i<<"\n";
    return fout;
}
template<typename T>
ostream& operator<<(ostream& fout,const set<T>&v) {
    for(T i:v)
        fout<<i<<" ";
    return fout;
}
template<typename T>
ostream& operator<<(ostream& fout,const ordered_set<T>&v) {
    for(T i:v)
        fout<<i<<" ";
    return fout;
}
ll rdn(int y, int m, int d) {
    /* Rata Die day one is 0001-01-01 */
    if (m < 3)
        y--, m += 12;
    return 365 * y + y / 4 - y / 100 + y / 400 + (153 * m - 457) / 5 + d - 306;
}
/* Direction arrays */
/* int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};      */                   // 4 Direction
/*int dx[] = {1,-1,0,0,1,1,-1,-1}, dy[] = {0,0,1,-1,1,-1,1,-1};       */ // 8 Direction
/* int dx[] = {1,-1,1,-1,2,2,-2,-2} , dy[] = {2,2,-2,-2,1,-1,1,-1}; */ // Knight Direction
/* int dx[] = {2,-2,1,1,-1,-1} , dy[] = {0,0,1,-1,1,-1}; */            // Hexagonal Direction
/* int dx[] = {2,-2,1,1,-1,-1} , dy[] = {0,0,1,-1,1,-1}; */            // Hexagonal Direction
/* int day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; */
int rank_to_int(char x) {
    if(x=='J')
        return -1;
    if(x=='2')
        return 0;
    if(x=='3')
        return 1;
    if(x=='4')
        return 2;
    if(x=='5')
        return 3;
    if(x=='6')
        return 4;
    if(x=='7')
        return 5;
    if(x=='8')
        return 6;
    if(x=='9')
        return 7;
    if(x=='T')
        return 8;
    if(x=='J')
        return 9;
    if(x=='Q')
        return 10;
    if(x=='K')
        return 11;
    if(x=='A')
        return 12;
}
char int_to_rank(int x) {
    if(x==-1)
        return 'J';
    if(x==0)
        return '2';
    if(x==1)
        return '3';
    if(x==2)
        return '4';
    if(x==3)
        return '5';
    if(x==4)
        return '6';
    if(x==5)
        return '7';
    if(x==6)
        return '8';
    if(x==7)
        return '9';
    if(x==8)
        return 'T';
    if(x==9)
        return 'J';
    if(x==10)
        return 'Q';
    if(x==11)
        return 'K';
    if(x==12)
        return 'A';
}
int suit_to_int(char x) {
    if(x=='1')
        return -1;
    if(x=='2')
        return -2;
    if(x=='C')
        return 0;
    if(x=='D')
        return 1;
    if(x=='H')
        return 2;
    if(x=='S')
        return 3;
}
char int_to_suit(int x) {
    if(x==0)
        return 'C';
    if(x==1)
        return 'D';
    if(x==2)
        return 'H';
    if(x==3)
        return 'S';
    if(x==-1)
        return '1';
    if(x==-2)
        return '2';
}
pii ara[60][60];
int mark[60][60];
bool check_differnet(vector<pii>&x) {
    for(int i=0; i<x.size(); i++) {
        for(int j=i+1; j<x.size(); j++) {
            if(x[i].ff==x[j].ff)
                return 0;
        }
    }
    return 1;
}
bool check_suit(vector<pii>&x) {
    for(int i=0; i<x.size(); i++) {
        if(x[i].ss!=x[0].ss)
            return 0;
    }
    return 1;
}
pair<pii,pii> checkans(int n,int m) {
    vector< pii >tmp;
    vector<pii>mybe;
    for(int i=0; i<n; i++) {
        if(i+2>=n)
            break;
        for(int j=0; j<m; j++) {
            if(j+2>=m)
                break;
            tmp.clear();
            tmp.emplace_back(ara[i][j]);
            tmp.emplace_back(ara[i][j+1]);
            tmp.emplace_back(ara[i][j+2]);
            tmp.emplace_back(ara[i+1][j]);
            tmp.emplace_back(ara[i+1][j+1]);
            tmp.emplace_back(ara[i+1][j+2]);
            tmp.emplace_back(ara[i+2][j]);
            tmp.emplace_back(ara[i+2][j+1]);
            tmp.emplace_back(ara[i+2][j+2]);
            if(check_differnet(tmp)|| check_suit(tmp)) {
                mybe.emplace_back(MP(i+1,j+1));
            }
        }
    }
    for(int i=0; i<mybe.size(); i++) {
        pii x=mybe[i];
        x.ss+=3;
        auto idx=lower_bound(all(mybe),x);
        if(idx!=mybe.end())
            return MP(mybe[i],*idx);
        x.ss-=3;
        x.ff+=3;
        idx=lower_bound(all(mybe),x);
        if(idx!=mybe.end()){
            return MP(mybe[i],*idx);
        }
    }
    return MP(MP(-1,-1),MP(-1,-1));
}
int main() {
    FAST;
    int n,m;
    char x,y;
    cin>>n>>m;
    vector<pii>pos;
    for(int i=0; i<13; i++) {
        for(int j=0; j<4; j++)
            mark[i][j]=1;
    }
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            cin>>x>>y;
            ara[i][j]=MP(rank_to_int(x),suit_to_int(y));
            if(x=='J') {
                pos.emplace_back(MP(i,j));
                continue;
            }
            mark[rank_to_int(x)][suit_to_int(y)]=0;

        }
    }
    vector<pii>have;
    for(int i=0; i<13; i++) {
        for(int j=0; j<4; j++) {
            if(mark[i][j])
                have.emplace_back(MP(i,j));
        }
    }
    sort(all(have));
    if(pos.empty()) {
        auto ans=checkans(n,m);
        if(ans.ff.ff!=-1)
            cout<<"Solution exists.\nThere are no jokers.\nPut the first square to ("<<ans.ff.ff<<", "<<ans.ff.ss<<").\nPut the second square to ("<<ans.ss.ff<<", "<<ans.ss.ss<<").\n";

        else
            cout<<"No solution.\n";
        return 0;
    } else if(pos.size()==1) {
        for(int i=0; i<have.size(); i++) {
            auto tmp1=ara[pos[0].ff][pos[0].ss];
            ara[pos[0].ff][pos[0].ss]=have[i];
            auto ans=checkans(n,m);
            ara[pos[0].ff][pos[0].ss]=tmp1;
            if(ans.ff.ff!=-1) {
                cout<<"Solution exists.\nReplace "<<int_to_rank(ara[pos[0].ff][pos[0].ss].ff)<<int_to_suit(ara[pos[0].ff][pos[0].ss].ss)<<" with "<<int_to_rank(have[i].ff)<<int_to_suit(have[i].ss)<<".\nPut the first square to ("<<ans.ff.ff<<", "<<ans.ff.ss<<").\nPut the second square to ("<<ans.ss.ff<<", "<<ans.ss.ss<<").\n";
                return 0;
            }
        }
        cout<<"No solution.\n";
        return 0;

    } else if(pos.size()==2) {
        int s1=int_to_suit(ara[pos[0].ff][pos[0].ss].ss);
        int s2=int_to_suit(ara[pos[1].ff][pos[1].ss].ss);
        if(s1>s2)swap(pos[0],pos[1]);
        for(int i=0; i<have.size(); i++) {
            for(int j=i+1; j<have.size(); j++) {
                auto tmp1=ara[pos[0].ff][pos[0].ss];
                auto tmp2=ara[pos[1].ff][pos[1].ss];
                ara[pos[0].ff][pos[0].ss]=have[i];
                ara[pos[1].ff][pos[1].ss]=have[j];
                auto ans=checkans(n,m);
                ara[pos[0].ff][pos[0].ss]=tmp1;
                ara[pos[1].ff][pos[1].ss]=tmp2;
                if(ans.ff.ff!=-1) {
                    cout<<"Solution exists.\nReplace "<<int_to_rank(ara[pos[0].ff][pos[0].ss].ff)<<int_to_suit(ara[pos[0].ff][pos[0].ss].ss)<<" with "<<int_to_rank(have[i].ff)<<int_to_suit(have[i].ss)<<" and "<<int_to_rank(ara[pos[1].ff][pos[1].ss].ff)<<int_to_suit(ara[pos[1].ff][pos[1].ss].ss)<<" with "<<int_to_rank(have[j].ff)<<int_to_suit(have[j].ss)<<".\nPut the first square to ("<<ans.ff.ff<<", "<<ans.ff.ss<<").\nPut the second square to ("<<ans.ss.ff<<", "<<ans.ss.ss<<").\n";
                    return 0;
                }
            }
        }
        cout<<"No solution.\n";
        return 0;
    }
}

#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <bitset>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <sstream>
#include <cmath>
#include <fstream>
#include <list>
using namespace std;
#define rp(i,n) for(int (i)=0;(i)<(n);++(i))
#define pb push_back
#define L(s) (int)s.size()
#define mp make_pair
#define pii pair<int,int>
#define x first
#define y second
#define inf 1000000000
#define VI vector<int>
#define ll long long
#define all(s) (s).begin(),(s).end()
#define C(u) memset((u),0,sizeof((u)))
#define ull unsigned ll
#define uint unsigned int
pair<char,char> a[55][55];
int u[255][255];
int n,m,c;
pii p1,p2;
bool dos[255];
inline bool can(int i,int j)
{
	bool mas=1;
	for(int k=0;k<3 && mas;++k)
		for(int l=0;l<3 && mas;++l)
			if (a[i+k][j+l].y!=a[i][j].y)
				mas=0;
	if (mas)
		return 1;
	mas=1;
	for(int k=0;k<3;++k)
		for(int l=0;l<3;++l)
			if (!dos[a[i+k][j+l].x])
				dos[a[i+k][j+l].x]=1;
			else
			{
				rp(t,3)
					rp(tt,3)
					dos[a[i+t][j+tt].x]=0;
				return 0;
			}
	return 1;
}
pii a1,a2;
inline bool good()
{
	int u[55][55];
	C(u);
	rp(i1,n-2)
		rp(j1,m-2)
			if (can(i1,j1))
				u[i1][j1]=1;
	int mar[55][55];
	C(mar);
	rp(i1,n-2)
		rp(j1,m-2)
		if (u[i1][j1])
		{
			rp(i,3)
				rp(j,3)
				mar[i1+i][j1+j]=1;
			rp(i2,n-2)
				rp(j2,m-2)
				if (u[i2][j2])
				{
					bool ok=1;
					rp(i,3)
						rp(j,3)
						if (mar[i2+i][j2+j])
							ok=0;
					if (ok)
					{
						a1=mp(i1,j1);
						a2=mp(i2,j2);
						return 1;
					}
				}
			rp(i,3)
				rp(j,3)
					mar[i1+i][j1+j]=0;
		}
	return 0;
}
int main()
{
	cin>>n>>m;
	rp(i,n)
		rp(j,m)
		{
			cin>>a[i][j].x>>a[i][j].y;
			if (a[i][j].y=='1' || a[i][j].y=='2')
			{
				if (!c)
				{
					p1=mp(i,j);
					++c;
				}
				else
					if (c==1)
					{
						p2=mp(i,j);
						c++;
					}
			}
			else
				u[a[i][j].x][a[i][j].y]=1;
		}
	if(!c)
	{
		if (good())
		{
			cout<<"Solution exists.\n";
			cout<<"There are no jokers.\n";
			cout<<"Put the first square to ("<<a1.x+1<<", "<<a1.y+1<<").\n";
			cout<<"Put the second square to ("<<a2.x+1<<", "<<a2.y+1<<").\n";
		}
		else
			cout<<"No solution.\n";
		return 0;
	}
	vector<pair<char,char> > v;
	vector<char> let(0);
	let.pb('C');
	let.pb('D');
	let.pb('H');
	let.pb('S');
	vector<char> sec(0);
	sec.pb('2');
	sec.pb('3');
	sec.pb('4');
	sec.pb('5');
	sec.pb('6');
	sec.pb('7');
	sec.pb('8');
	sec.pb('9');
	sec.pb('T');
	sec.pb('J');
	sec.pb('Q');
	sec.pb('K');
	sec.pb('A');
	rp(i,L(sec))
		rp(j,L(let))
		if (!u[sec[i]][let[j]])
			v.pb(mp(sec[i],let[j]));
	random_shuffle(all(v));
	bool one=1;
	if (a[p1.x][p1.y].y=='2')
		one=0;
	if (c==1)
	{
		rp(i,L(v))
		{
			a[p1.x][p1.y]=v[i];
			if (good())
			{
				cout<<"Solution exists.\n";
				if (one)
					cout<<"Replace J1 ";
				else
					cout<<"Replace J2 ";
				cout<<"with "<<v[i].x<<v[i].y<<".\n";
				cout<<"Put the first square to ("<<a1.x+1<<", "<<a1.y+1<<").\n";
				cout<<"Put the second square to ("<<a2.x+1<<", "<<a2.y+1<<").\n";
				return 0;
			}
		}
		cout<<"No solution.\n";
		return 0;
	}
	if (a[p1.x][p1.y].y=='2')
		swap(p1,p2);
	rp(i,L(v))
		rp(j,i)
		{
			a[p1.x][p1.y]=v[i];
			a[p2.x][p2.y]=v[j];
			if (good())
			{
				cout<<"Solution exists.\n";
				cout<<"Replace J1 with "<<v[i].x<<v[i].y<<" and J2 with "<<v[j].x<<v[j].y<<".\n";
				cout<<"Put the first square to ("<<a1.x+1<<", "<<a1.y+1<<").\n";
				cout<<"Put the second square to ("<<a2.x+1<<", "<<a2.y+1<<").\n";
				return 0;
			}
	}
	cout<<"No solution.\n";
}

#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
struct card {
    int num , hua;
    card () {}
    card (int n,int h) {
        num = n;
        hua = h;
    }
    string getName() {
        string ret;
        ret.clear();
        if (num == 1) {
            ret += "A";
        }
        else if (num < 10 && num > 1) {
            ret += num + '0';
        }
        else if (num == 10) {
            ret += 'T';
        }
        else if (num == 11) {
            ret += 'J';
        }
        else if (num == 12) {
            ret += 'Q';
        }
        else if (num == 13) {
            ret += 'K';
        }
        else {
            ret += 'J';//"C", "D", "H" and "S
        }

        if (hua == 0) {
            ret += 'C';
        }
        else if (hua == 1 && num != 0) {
            ret += 'D';
        }
        else if (hua == 2 && num != 0) {
            ret += 'H';
        }
        else if (hua == 3) {
            ret += 'S';
        }
        else ret += '0' + hua;
        return ret;
    }
    void check(
        string &str
        ) {
        if (str[0] == 'T') {
            num = 10;
        }
        else if (str[0] == 'J' && (str[1] < '1' && str[1] > '2')) {
            num = 11;
        }
        else if (str[0] == 'Q') {
            num = 12;
        }
        else if (str[0] == 'K') {
            num = 13;
        }
        else if (str[0] == 'A') {
            num = 1;
        }
        else if (str[0] == 'J') {
            num = 0;
        }
        else {
            num = str[0]  - '0'; //"C", "D", "H" and "S
        }

        if (str[1] == 'C')
            hua = 0;
        else if (str[1] == 'D')
            hua = 1;
        else if (str[1] == 'H')
            hua = 2;
        else if (str[1] == 'S')
            hua = 3;
        else hua = str[1] - '0';
    }
};

card list[60][60];

bool Hash[4][20];

vector<card> canUse;

int xx1 , yy1;
int xx2 , yy2;
int Cnt = 0;

bool mark[100];

bool success;

string first , second , third , forth;

int ansx1 , ansy1, ansx2 ,ansy2;

card joker1 , joker2;

int n , m;

void check() {
    for (int i = 1;i <= n - 2;i ++) {
        for (int j = 1;j <= m - 2;j ++) {

            bool flag = false;
            if (list[i][j].hua == list[i][j + 1].hua &&
                list[i][j].hua == list[i][j + 2].hua &&
                list[i][j].hua == list[i + 1][j].hua &&
                list[i][j].hua == list[i + 1][j + 1].hua &&
                list[i][j].hua == list[i + 1][j + 2].hua &&
                list[i][j].hua == list[i + 2][j].hua &&
                list[i][j].hua == list[i + 2][j + 1].hua &&
                list[i][j].hua == list[i + 2][j + 2].hua) {
                    flag = true;
            }
            bool mark[20] = {false};

            if (flag == false) {
                flag = true;
                for (int h = 0;h < 3;h ++) {
                    for (int k = 0;k < 3;k ++) {
                        if (mark[ list[i + h][j + k].num]) {
                            flag = false;
                            h = 1000;
                            break;
                        }
                        else {
                            mark[ list[i + h][j + k].num ] = true;
                        }
                    }
                }
            }

            if (flag) {
                for (int h = 1;h <= n - 2;h ++) {
                    for (int k = 1;k <= m - 2;k ++) {
                        if ( (h - i < 3 && h - i > -3) && (k - j < 3 && k - j > -3) ) {
                            continue;
                        }

                        bool flag = false;
                        if (list[h][k].hua == list[h][k + 1].hua &&
                            list[h][k].hua == list[h][k + 2].hua &&
                            list[h][k].hua == list[h + 1][k].hua &&
                            list[h][k].hua == list[h + 1][k + 1].hua &&
                            list[h][k].hua == list[h + 1][k + 2].hua &&
                            list[h][k].hua == list[h + 2][k].hua &&
                            list[h][k].hua == list[h + 2][k + 1].hua &&
                            list[h][k].hua == list[h + 2][k + 2].hua) {
                                flag = true;
                        }
                        bool mark[20] = {false};

                        if (flag == false) {
                            flag = true;
                            for (int hh = 0;hh < 3;hh ++) {
                                for (int kk = 0;kk < 3;kk ++) {
                                    if (mark[ list[h + hh][k + kk].num]) {
                                        flag = false;
                                        hh = 1000;
                                        break;
                                    }
                                    else {
                                        mark[ list[h + hh][k + kk].num ] = true;
                                    }
                                }
                            }
                        }

                        if (flag == true) {
                            success = true;
                            ansx1 = i;
                            ansy1 = j;
                            ansx2 = h;
                            ansy2 = k;
                            return;
                        }

                    }
                }
            }

        }
    }
}
card replace1 , replace2;
void DFS(int cnt) {
    if (cnt == 0) {
        check();
        if (success) {
            first += "Solution exists.";
            if (Cnt == 0) {
                second += "There are no jokers.";
            }
            else {
                second += "Replace ";
                second += joker1.getName();
                second += " with ";
                second += replace1.getName();
            }
            if (Cnt == 2) {
                second += " and J2 with ";
                second += replace2.getName();
            }

            third += "Put the first square to (";
            char tempx[20],tempy[20];
            itoa(ansx1,tempx,10);
            itoa(ansy1,tempy,10);
            third += tempx;
            third += ", ";
            third += tempy;
            third += ").";

            forth += "Put the second square to (";
            itoa(ansx2,tempx,10);
            itoa(ansy2,tempy,10);
            forth += tempx;
            forth += ", ";
            forth += tempy;
            forth += ").";
        }
        else {
            return;
        }
    }
    else {
        for (int i = 0;i < canUse.size();i ++) {
            if (mark[i]) continue;

            if (cnt == 2) {
                list[xx2][yy2] = canUse[i];
                mark[i] = true;
                replace2 = canUse[i];
                DFS(cnt - 1);
                if (success) return;
                mark[i] = false;
            }
            else {
                list[xx1][yy1] = canUse[i];
                replace1 = canUse[i];
                mark[i] = true;
                DFS(cnt - 1);
                if (success) return;
                mark[i] = false;
            }
        }
    }
}
int main () {
    scanf ("%d%d",&n,&m);
    for (int i = 1;i <= n;i ++) {
        for (int j = 1;j <= m;j ++) {
            char temp[1010];
            scanf ("%s",temp);
            string str(temp);
            list[i][j].check(str);
        }
    }
    memset (Hash,false,sizeof(Hash));

    for (int i = 1;i <= n;i ++) {
        for (int j = 1;j <= m;j ++) {
            if (list[i][j].num != 0) {
                Hash[ list[i][j].hua ][ list[i][j].num ] = true;
            }
            else {
                Cnt ++;
                if (Cnt == 1) {
                    xx1 = i;yy1 = j;
                    joker1 = list[i][j];
                }
                else {
                    xx2 = i;yy2 = j;
                    joker2 = list[i][j];
                }
            }
        }
    }
    if (Cnt == 2 && joker1.hua > joker2.hua) {
        swap(joker1,joker2);
        swap(xx1 , xx2);
        swap(yy1 , yy2);
    }
    canUse.clear();
    for (int i = 0;i <= 3;i ++) {
        for (int j = 1;j <= 13;j ++) {
            if (Hash[i][j] == false) {
                canUse.push_back(card(j,i));
            }
        }
    }
    memset (mark,false,sizeof(mark));
    success = false;
    first.clear();
    second.clear();
    third.clear();
    forth.clear();
    DFS(Cnt);
    if (success == false) {
        puts("No solution.");
    }
    else {
        puts(first.c_str());
        puts(second.c_str());
        puts(third.c_str());
        puts(forth.c_str());
    }
    return 0;
}

#include<stdio.h>
int a[52][52],joke[2][2],used[64],n,m;
int abs(int x){return x<0?-x:x;}
bool Test2(int x,int y){
    int i,j,d[4],e[14],cnt1=0,cnt2=0;
    for(i=0;i<4;i++)d[i]=0;
    for(i=0;i<14;i++)e[i]=0;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++){
            if(d[a[x+i][y+j]>>4]==0){
                cnt1++;
                d[a[x+i][y+j]>>4]++;
            }
            if(e[a[x+i][y+j]&15]==0){
                cnt2++;
                e[a[x+i][y+j]&15]++;
            }
        }
    return cnt1==1||cnt2==9;
}
bool Test(int &x1,int &y1,int &x2,int &y2){
    int i,j,ii,jj;
    for(i=0;i<n-2;i++)
        for(j=0;j<m-2;j++){
            for(ii=0;ii<n-2;ii++)
                for(jj=0;jj<m-2;jj++){
                    if(abs(i-ii)<3&&abs(j-jj)<3)continue;
                    if(Test2(i,j)&&Test2(ii,jj)){
                        x1=i;
                        y1=j;
                        x2=ii;
                        y2=jj;
                        return 1;
                    }
                }
        }
    return 0;
}
void print(int x){
    int y=x&15;
    if(y==1)printf("A");
    else if(y>1&&y<10)printf("%c",'0'+y);
    else if(y==10)printf("T");
    else if(y==11)printf("J");
    else if(y==12)printf("Q");
    else if(y==13)printf("K");
    switch(x>>4){
        case 0:
            printf("C");
            break;
        case 1:
            printf("D");
            break;
        case 2:
            printf("H");
            break;
        case 3:
            printf("S");
            break;
    }
}
bool dfs(int x){
    int i,j,x1,y1,x2,y2;
    if(x==2){
        if(Test(x1,y1,x2,y2)){
            puts("Solution exists.");
            if(joke[0][0]==-1&&joke[1][0]==-1)puts("There are no jokers.");
            else{
                if(joke[0][0]!=-1&&joke[1][0]==-1){
                    printf("Replace J1 with ");
                    print(a[joke[0][0]][joke[0][1]]);
                    puts(".");
                }
                else if(joke[0][0]==-1){
                    printf("Replace J2 with ");
                    print(a[joke[1][0]][joke[1][1]]);
                    puts(".");
                }
                else {
                    printf("Replace J1 with ");
                    print(a[joke[0][0]][joke[0][1]]);
                    printf("and J2 with ");
                    print(a[joke[1][0]][joke[1][1]]);
                    puts(".");
                }
            }
            printf("Put the first square to (%d, %d).\n",x1+1,y1+1);
            printf("Put the second square to (%d, %d).\n",x2+1,y2+1);

            return 1;
        }
        return 0;
    }
    if(joke[x][0]==-1){
        return dfs(x+1);
    }
    for(i=0;i<4;i++)
        for(j=1;j<=13;j++){

            if(used[(i<<4)+j])continue;
            used[(i<<4)+j]=1;
            a[joke[x][0]][joke[x][1]]=(i<<4)+j;
            if(dfs(x+1))return 1;
            used[(i<<4)+j]=0;
        }
    return 0;
}
main(){
    int i,j;
    scanf("%d%d",&n,&m);
    joke[0][0]=joke[1][0]=-1;
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            char s[8];
            int tmp=0;
            scanf("%s",s);
            if(s[0]=='J'&&s[1]>='0'&&s[1]<='2')tmp=-(s[1]-'1');
            else{
                if(s[1]=='C')tmp=0;
                else if(s[1]=='D')tmp=16;
                else if(s[1]=='H')tmp=32;
                else if(s[1]=='S')tmp=48;
                if(s[0]=='A')tmp+=1;
                if(s[0]=='T')tmp+=10;
                if(s[0]=='J')tmp+=11;
                if(s[0]=='Q')tmp+=12;
                if(s[0]=='K')tmp+=13;
                if(s[0]>='1'&&s[0]<='9')tmp+=s[0]-'0';
            }
            a[i][j]=tmp;
            if(a[i][j]>=0)used[a[i][j]]=1;
            if(a[i][j]<=0){
                joke[-a[i][j]][0]=i;
                joke[-a[i][j]][1]=j;
            }
        }
    }
    if(!dfs(0))puts("No solution.");
}

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <algorithm>
using std::cout;
using std::swap;
using std::vector;
using std::cin;
using std::pair;
using std::string;
using std::max;
using std::min;
using std::endl;

int n, m;
string card[20][20];
vector< pair<int, int> > jcoord;

bool good(int x, int y) {
    std::set<char> type, value;
    for(int i = x; i < x + 3; i++)
        for(int j = y; j < y + 3; j++) {
            type.insert(card[i][j][1]);
            value.insert(card[i][j][0]);
        }
    return type.size() == 1 or value.size() == 9;
}

void insert(std::set<string> &x, const string &beg) {
    x.insert(beg + "C");
    x.insert(beg + "D");
    x.insert(beg + "H");
    x.insert(beg + "S");
}

void put(int r1, int c1, int r2, int c2) {
    cout << "Put the first square to (" << r1 << ", " << c1 << ")."
        << endl;
    cout << "Put the second square to (" << r2 << ", " << c2 << ")."
        << endl;
}

bool solve(int &x1, int &y1, int &x2, int &y2) {
    for(int i = 0; i < n - 2; i++) {
        for(int j = 0; j < m - 2; j++) {
            if(!good(i, j))
                continue;
            for(int k = 0; k < n - 2; k++)
                for(int r = 0; r < m - 2; r++) {
                    if(max(i, k) <= min(i + 2, k + 2) and
                            max(j, r) <= min(j + 2, r + 2))
                        continue;
                    if(good(k, r)) {
                        x1 = i + 1;
                        y1 = j + 1;
                        x2 = k + 1;
                        y2 = r + 1;
                        return true;
                    }
                }
        }
    }
    return false;
}

int main() {
    std::set<string> avail;
    for(int i = 2; i <= 9; i++) {
        string t(1, i + '0');
        insert(avail, t);
    }
    insert(avail, "T");
    insert(avail, "J");
    insert(avail, "Q");
    insert(avail, "K");
    insert(avail, "A");
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) {
            cin >> card[i][j];
            if(card[i][j][0] == 'J' and (card[i][j][1] == '1'
                        or card[i][j][1] == '2'))
                jcoord.push_back(std::make_pair(i, j));
            avail.erase(card[i][j]);
        }

    int r1, c1, r2, c2;
    string fj, sj;
    if(jcoord.size() == 0) {
        if(solve(r1, c1, r2, c2)) {
            cout << "Solution exists." << endl;
            cout << "There are no jokers." << endl;
            put(r1, c1, r2, c2);
            return 0;
        }
    } else if(jcoord.size() == 1) {
        fj = card[jcoord[0].first][jcoord[0].second];
        for(const string &t: avail) {
            card[jcoord[0].first][jcoord[0].second] = t;
            if(solve(r1, c1, r2, c2)) {
                cout << "Solution exists." << endl;
                cout << "Replace " << fj << " with " << t << "." << endl;
                put(r1, c1, r2, c2);
                return 0;
            }
        }
    } else {
        fj = card[jcoord[0].first][jcoord[0].second];
        sj = card[jcoord[1].first][jcoord[1].second];
        if(fj[0] == '2') {
            swap(fj, sj);
            swap(jcoord[0], jcoord[1]);
        }
        for(const string &t1: avail) {
            for(const string &t2: avail) {
                if(t1 == t2)
                    continue;
                card[jcoord[0].first][jcoord[0].second] = t1;
                card[jcoord[1].first][jcoord[1].second] = t2;
                if(solve(r1, c1, r2, c2)) {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with " << t1 << " and J2 with " <<
                        t2 << "." << endl;
                    put(r1, c1, r2, c2);
                    return 0;
                }
            }
        }
    }
    cout << "No solution." << endl;
    return 0;
}

#include <iostream>
#include <vector>
#include <set>
#include <map>
using namespace std;

const string ssuit[4] = { "C", "D", "H", "S" };
const string rrank[13] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J",
		"Q", "K", "A" };

set<string> cards, jok1, jok2;
set<char> suit, Rank;
map<char, int> mp;
string card[100][100];
int n, m, ci, cj, ck, cl;
void get_cards() {
	for (int i = 0; i < 4; ++i)
		for (int j = 0; j < 13; ++j)
			cards.insert(rrank[j] + ssuit[i]);
}
bool square(int i, int j) {
	return i + 2 < n && j + 2 < m;
}
bool overlap(int i, int j) {
	int ci2 = ci + 2, cj2 = cj + 2, ni, nj;
	for (int l = 0; l <= 2; l += 2)
		for (int k = 0; k <= 2; k += 2) {
			ni = i + l;
			nj = j + k;
			if (ni >= ci && ni <= ci2 && nj >= cj && nj <= cj2) {
				return 1;
			}
		}
	return 0;
}

bool valid_square(int r, int c, string jak1, string jak2) {
	suit.clear();
	Rank.clear();
	for (int i = r; i <= r + 2; i++) {
		for (int j = c; j <= c + 2; j++) {
			string cur = card[i][j];
			if (cur == "J1")
				cur = jak1;
			if (cur == "J2")
				cur = jak2;
			Rank.insert(cur[0]);
			suit.insert(cur[1]);
		}
	}
	return Rank.size() == 9 || suit.size() == 1;
}
bool check(string jak1, string jak2) {

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (square(i, j) && valid_square(i, j, jak1, jak2)) {
				ci = i;
				cj = j;
				for (int k = 0; k < n; k++) {
					for (int l = 0; l < m; l++) {
						if (square(k, l) && !overlap(k, l)
								&& valid_square(k, l, jak2, jak2)) {
							ck = k;
							cl = l;

							return 1;
						}
					}
				}
			}
		}
	}
	return 0;
}
int main() {

	get_cards();
	cin >> n >> m;
	bool j1 = 0, j2 = 0;
	jok1.insert("a");
	jok2.insert("b");
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			cin >> card[i][j];
			if (card[i][j] == "J1")
				j1 = 1;
			if (card[i][j] == "J2")
				j2 = 1;
			cards.erase(card[i][j]);
		}
	if (j1)
		jok1 = cards;
	if (j2)
		jok2 = cards;
	for (auto a : jok1) {
		for (auto b : jok2) {
			if (a != b && check(a, b)) {
				cout << "Solution exists." << endl;
				if (j1 && j2)
					cout << "Replace J1 with " << a << " and J2 with " << b
							<< "." << endl;
				else if (j1)
					cout << "Replace J1 with " << a << "." << endl;
				else if (j2)
					cout << "Replace J2 with " << b << "." << endl;
				else
					cout << "There are no jokers." << endl;
				cout << "Put the first square to (" << ci + 1 << ", " << cj + 1
						<< ")." << endl;
				cout << "Put the second square to (" << ck + 1 << ", " << cl + 1
						<< ")." << endl;
				return 0;
			}
		}
	}
	cout << "No solution." << endl;

	return 0;
}

#include <bits/stdc++.h>
typedef long long ll ;
using namespace std;

string A = "23456789TJQKA" ;
string B = "CDHS" ;

int n , m ;
vector < vector < string > > grid;
map < char , vector < string > > suits ;
map < string , bool > vis ;
vector < pair < pair < int , int > , string >   > res ;

pair < bool , string >  solve(int x , int y) {

    bool diff = 1;
    int j1 = 0 , j2 = 0 ;
    map < char , bool > ok ;

    for(int i = x ; i < x + 3 ; i++) {
        for(int j = y ; j < y + 3 ; j++) {

            if(grid[i][j][0] == 'J') {
                if(grid[i][j][1] == '1') j1 = 1 ;
                else j2 = 1 ;
                continue ;
            }

            if(ok[grid[i][j][0]]) diff = 0 ;
            else ok[grid[i][j][0]] = 1 ;
        }
    }

    if(diff) {

        if(j1 && j2) {

            string s1 , s2 ;
            for(int i = 0 ; i < 4 ; i++) {
                for(auto s : suits[B[i]]) {
                    if(ok[s[0]]) continue ;

                    if(!vis[s]) {
                        if(s1.empty()) {
                            s1 = s ;
                            ok[s[0]] = 1 ;
                            vis[s1] = 1;
                            continue ;
                        }
                        if(s2.empty()) {
                            s2 = s ;
                            ok[s[0]] = 1;
                            vis[s2] = 1;
                            continue ;
                        }
                    }
                }
            }

            if(s1.empty() || s2.empty()) return {0 , "-1"};
            else return {1 , s1+s2} ;
        } else if(j1 || j2) {

            string ss ;
            for(int i = 0 ; i < 4 ; i++) {
                for(auto s : suits[B[i]]) {
                    if(ok[s[0]]) continue ;

                    if(!vis[s]) {

                        if(ss.empty()) {
                            vis[s] = 1;
                            if(j1 == 1) ss = s + "J1" ;
                            else ss = s + "J2" ;
                            continue ;
                        }
                    }
                }
            }
            if(ss.empty()) return {0 , "-1"} ;
            else return {1 , ss};
        }

        return {1 , "-1"};
    }

    return {0 , "-1"};
}

bool overlab(pair < int , int > p1 , pair < int , int > p2) {

    pair < int , int > l1 = p1 , l2 = p2 , r1 = make_pair(l1.first + 2 , l1.second + 2) , r2 = make_pair(l2.first + 2 , l2.second + 2);

    if (l1.first > r2.first || l2.first > r1.first)
        return false;

    if (l1.second < r2.second || l2.second < r1.second)
        return false;

    return true;
}

void output( pair < pair < int , int > , string >  sq1 , pair < pair < int , int > , string >  sq2) {

    if(!vis["J1"] && !vis["J2"]) cout << "There are no jokers." << endl ;

    else if(vis["J1"] && vis["J2"]) {

        if(sq1.second != "-1" && sq2.second != "-1") {
            string s1 = sq1.second ;
            string s2 = sq2.second ;
            if(s1.back() == '1')
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s2[0],s2[1]);
            else
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s2[0],s2[1],s1[0],s1[1]);

        } else if(sq1.second != "-1") {
            string s1 = sq1.second ;
            if(s1.back() != '1' && s1.back() != '2') {
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s1[2],s1[3]);
            } else {
                string s2 ;
                for(int i = 0 ; i < 4 && s2.empty() ; i++) {
                    for(int j = 0 ; j < 13 && s2.empty() ; j++) {
                        if(!vis[suits[B[i]][j]]) s2 = suits[B[i]][j] ;
                    }
                }
                if(s1.back() == '1') printf("Replace J1 with %c%c and J2 with %s.\n",s1[0],s1[1],s2.c_str());
                else printf("Replace J1 with %s and J2 with %c%c.\n",s2.c_str(),s1[0],s1[1]);
            }
        } else if(sq2.second != "-1") {
            string s1 = sq2.second ;
            if(s1.back() != '1' && s1.back() != '2') {
                printf("Replace J1 with %c%c and J2 with %c%c.\n",s1[0],s1[1],s1[2],s1[3]);
            } else {
                string s2 ;
                for(int i = 0 ; i < 4 && s2.empty() ; i++) {
                    for(int j = 0 ; j < 13 && s2.empty() ; j++) {
                        if(!vis[suits[B[i]][j]]) s2 = suits[B[i]][j] ;
                    }
                }
                if(s1.back() == '1') printf("Replace J1 with %c%c and J2 with %s.\n",s1[0],s1[1],s2.c_str());
                else printf("Replace J1 with %s and J2 with %c%c.\n",s2.c_str(),s1[0],s1[1]);
            }

        } else {
            string s1 , s2 ;
            for(int i = 0 ; i < 4 ; i++) {
                for(int j = 0 ; j < 13 ; j++) {
                    if(vis[suits[B[i]][j]]) continue ;

                    if(s1.empty()) {
                        s1 = suits[B[i]][j];
                        vis[s1] = 1;
                        continue ;
                    }
                    if(s2.empty()) {
                        s2 = suits[B[i]][j];
                        vis[s2] = 1 ;
                        continue ;
                    }
                }
            }
            printf("Replace J1 with %s and J2 with %s.\n",s1.c_str(),s2.c_str());
        }
    }

    else if(vis["J1"] || vis["J2"]) {

        if(sq1.second != "-1") {
            string s1 = sq1.second ;
            if(s1.back() == '1') printf("Replace J1 with %c%c.\n",s1[0],s1[1]);
            else  printf("Replace J2 with %c%c.\n",s1[0],s1[1]);
        }

        else if(sq2.second != "-1") {
            string s1 = sq2.second ;
            if(s1.back() == '1') printf("Replace J1 with %c%c.\n",s1[0],s1[1]);
            else  printf("Replace J2 with %c%c.\n",s1[0],s1[1]);
        }

        else {
            string s1 ;
            for(int i = 0 ; i < 4 ; i++) {
                for(int j = 0 ; j < 13 ; j++) {
                    if(vis[suits[B[i]][j]]) continue ;
                    s1 = suits[B[i]][j] ;
                }
            }
            if(vis["J1"]) printf("Replace J1 with %s.\n",s1.c_str());
            else printf("Replace J2 with %s.\n",s1.c_str());
        }
    }
    printf("Put the first square to (%d, %d).\n",sq1.first.first+1,sq1.first.second+1);
    printf("Put the second square to (%d, %d).\n",sq2.first.first+1,sq2.first.second+1);

    exit(0);
}

int main() {

    ios::sync_with_stdio(false);

    for(int i = 0 ; i < 4 ; i++) {
        for(int j = 0 ; j < 13 ; j++) {
            string s ;
            s.push_back(A[j]);
            s.push_back(B[i]);
            suits[B[i]].push_back(s);
        }
    }

    cin >> n >> m ;

    grid.resize(n + 1);

    for(int i = 0 ; i < n ; i++) {
        for(int j = 0 ; j < m ; j++) {
            string s ;
            cin >> s ;
            vis[s] = true ;
            grid[i].push_back(s);
        }
    }

    for(int i = 0 ; i + 2 < n ; i++) {
        for(int j = 0 ; j + 2 < m ; j++) {
            auto p = solve(i , j);
            if(p.first) res.push_back({ {i , j} , p.second });
        }
    }

    for(int i = 0 ; i < res.size() ; i++) {
        for(int j = i + 1 ; j < res.size() ; j++) {
            if(!overlab(res[i].first , res[j].first)) {
                cout << "Solution exists." << endl ;
                output(res[i] , res[j]);
            }
        }
    }

    cout << "No solution." << endl ;

    return 0;
}

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

#define FAST_READER ios::sync_with_stdio(false); cin.tie(nullptr);
#define ALL(v) (v).begin(), (v).end()
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
#define SZ(v) ((int)(v).size())
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef long double LD;
template<class T> T sqr(T a) {return a * a;}

using namespace std;

int valuesamt = 13, mastamt = 4;
char values[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
char mast[] = {'C', 'D', 'H', 'S'};
int n, m;
pair<int, int> jokerpos[2];
string v[20][20];
set<string> st;
vector<string> cards;

bool isjoker(const string& s) {
	return s[0] == 'J' && ('1' <= s[1] && s[1] <= '2');
}

void nojoker() {
	cout << "There are no jokers." << endl;
}

void nosol() {
	cout << "No solution." << endl;
}

void solexists() {
	cout << "Solution exists." << endl;
}

void replacewith(const string& from, const string& to) {
	cout << "Replace " << from << " with " << to << "." << endl;
}

int ipos[2], jpos[2];

void putfirst() {
	cout << "Put the first square to (" << ipos[0] + 1 << ", " << jpos[0] + 1  << ")." << endl;
}

void putsecond() {
	cout << "Put the second square to (" << ipos[1] + 1 << ", " << jpos[1] + 1  << ")." << endl;
}

bool intersect() {
	if (ipos[0] + 3 <= ipos[1] || ipos[1] + 3 <= ipos[0]) return false;
	if (jpos[0] + 3 <= jpos[1] || jpos[1] + 3 <= jpos[0]) return false;
	return true;
}

bool allequal(int i, int j) {
	FOR(a, i, i + 3) {
		FOR(b, j, j + 3) {
			if (v[a][b][1] != v[i][j][1]) return false;
		}
	}
	return true;
}

set<char> mid;

bool allvarious(int i, int j) {
	mid.clear();
	FOR(a, i, i + 3) {
		FOR(b, j, j + 3) {
			mid.insert(v[a][b][0]);
		}
	}
	return mid.size() == 9;
}

bool good(int i, int j) {
	return allequal(i, j) || allvarious(i, j);
}

bool offer() {
	for(ipos[0] = 0; ipos[0] <= n - 3; ++ipos[0]) {
		for(jpos[0] = 0; jpos[0] <= m - 3; ++jpos[0]) {
			for(ipos[1] = 0; ipos[1] <= n - 3; ++ipos[1]) {
				for(jpos[1] = 0; jpos[1] <= m - 3; ++jpos[1]) {
					if (intersect()) continue;
					if (good(ipos[0], jpos[0]) && good(ipos[1], jpos[1])) {
						return true;
					}
				}
			}
		}
	}
	return false;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif

	FAST_READER;

	cin >> n >> m;
	jokerpos[0].first = jokerpos[0].second = -1;
	jokerpos[1] = jokerpos[0];

	FOR(i, 0, valuesamt) {
		FOR(j, 0, mastamt) {
			string s;
			s.PB(values[i]);
			s.PB(mast[j]);
			st.insert(s);
		}
	}

	FOR(i, 0, n) {
		FOR(j, 0, m) {
			cin >> v[i][j];
			if (isjoker(v[i][j])) {
				if (v[i][j][1] == '1') {
					jokerpos[0].first = i, jokerpos[0].second = j;
				} else {
					jokerpos[1].first = i, jokerpos[1].second = j;
				}
			}
			st.erase(v[i][j]);
		}
	}
	while (!st.empty()) {
		cards.PB(*st.begin());
		st.erase(st.begin());
	}

	if (jokerpos[0].first == -1 && jokerpos[1].first == -1) {
		if (offer()) {
			solexists();
			nojoker();
			putfirst();
			putsecond();
			return 0;
		} else {
			nosol();
			return 0;
		}
	}
	//if (offer()) {
	//	solexists();
	//	putfirst();
	//	putsecond();
	//	return 0;
	//}
	if (jokerpos[0].first != -1 && jokerpos[1].first == -1) {
		FOR(i, 0, SZ(cards)) {
			v[jokerpos[0].first][jokerpos[0].second] = cards[i];
			if (offer()) {
				solexists();
				replacewith("J1", cards[i]);
				putfirst();
				putsecond();
				return 0;
			}
		}
		if (jokerpos[1].first == -1) {
			nosol();
			return 0;
		}
	}
	if (jokerpos[1].first != -1 && jokerpos[0].first == -1) {
		FOR(i, 0, SZ(cards)) {
			v[jokerpos[1].first][jokerpos[1].second] = cards[i];
			if (offer()) {
				solexists();
				replacewith("J2", cards[i]);
				putfirst();
				putsecond();
				return 0;
			}
		}
		if (jokerpos[0].first == -1) {
			nosol();
			return 0;
		}
	}
	FOR(i, 0, SZ(cards)) {
		FOR(j, 0, SZ(cards)) {
			if (i == j) continue;
			v[jokerpos[0].first][jokerpos[0].second] = cards[i];
			v[jokerpos[1].first][jokerpos[1].second] = cards[j];
			if (offer()) {
				solexists();
				replacewith("J1", cards[i]);
				replacewith("J2", cards[j]);
				putfirst();
				putsecond();
				return 0;
			}
		}
	}

	return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
#define REP(i,a,b) for (int i = a ; i <= b ; i++)
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;

const int OO = 1e9+7;
const int MOD = 1e9+7;
const int N = 52+7;

pair<char,char> a[N][N];
map<pair<char,char> ,int> c;
int n,m;
pi w1,w2;
bool check()
{
    vector<pi> vec;
    REP(i,0,n-3) REP(j,0,m-3)
    {
        set<char> st;
        bool oks = 1;
        char suit = '\0';
        REP(ki,0,2) REP(kj,0,2)
        {
            st.insert( a[i+ki][j+kj].F );
            if (suit == '\0') suit = a[i+ki][j+kj].S;
            else if (suit != a[i+ki][j+kj].S) oks = 0;
        }
        if (oks || st.size() == 9) vec.PB({i,j});
    }

    int sz = vec.size();
    REP(i,0,sz-1) REP(j,0,sz-1)
    {
        if (i==j)continue;
        if (vec[j].F+2 < vec[i].F || vec[j].S+2 < vec[i].S) {w1 = vec[i];w2 = vec[j];return 1;}
        else if (vec[j].F > vec[i].F+2 || vec[j].S > vec[i].S+2) {w1 = vec[i];w2 = vec[j];return 1;}
    }

    return 0;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    string r = "23456789TKA";
    string s = "CDHS";

    cin >> n >> m;
    int J1i = -1,J1j = -1,J2i = -1,J2j = -1;

    REP(i,0,n-1) REP(j,0,m-1)
    {
        cin >> a[i][j].F >> a[i][j].S;
        if (a[i][j].F == 'J')
        {
            if (a[i][j].S == '1') {J1i = i;J1j = j;}
            else {J2i = i;J2j = j;}
        }
        c[a[i][j]]++;
    }

    //cout << J2i << endl;
    if (J1i != -1 && J2i != -1)
    {
        REP(i1,0,10) REP(j1,0,3)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            REP(i2,0,10) REP(j2,0,3)
            {
                if (c[{r[i2],s[j2]}] > 0) continue;
                c[{r[i2],s[j2]}]++;
                a[J2i][J2j] = {r[i2],s[j2]};
                if (check())
                {
                    cout << "Solution exists." << endl;
                    cout << "Replace J1 with "<< r[i1]<<s[j1] <<" and J2 with " << r[i2]<<s[j2] << "." << endl;
                    cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                    cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                    return 0;
                }
                a[J2i][J2j] = {'J','2'};
                c[{r[i2],s[j2]}]--;
            }
            a[J1i][J1j] = {'J','1'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J1i != -1)
    {
        REP(i1,0,10) REP(j1,0,3)
        {
            if (c[{r[i1],s[j1]}] > 0) continue;
            c[{r[i1],s[j1]}]++;
            a[J1i][J1j] = {r[i1],s[j1]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J1 with "<< r[i1]<<s[j1] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J1i][J1j] = {'J','2'};
            c[{r[i1],s[j1]}]--;
        }
    }
    else if (J2i != -1)
    {
        REP(i2,0,10) REP(j2,0,3)
        {
            if (c[{r[i2],s[j2]}] > 0) continue;
            c[{r[i2],s[j2]}]++;
            a[J2i][J2j] = {r[i2],s[j2]};
            if (check())
            {
                cout << "Solution exists." << endl;
                cout << "Replace J2 with " << r[i2]<<s[j2] << "." << endl;
                cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
                cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
                return 0;
            }
            a[J2i][J2j] = {'J','2'};
            c[{r[i2],s[j2]}]--;
        }
    }
    else if (check())
    {
        cout << "Solution exists." << endl;
        cout << "There are no jokers." << endl;
        cout << "Put the first square to (" << w1.F+1 <<  ", " << w1.S+1 << ")." << endl;
        cout << "Put the second square to (" << w2.F+1 <<  ", " << w2.S+1 << ")." << endl;
        return 0;
    }

    cout << "No solution." << endl;

    return 0;
}