#include<stdio.h>
#include<iostream>
#include<string>
#include<set>
#include<vector>
#include<map>
using namespace std;
string c[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
string s[] = {"C", "D", "H", "S"};
string sol[60][60];
map<string,int> used;
vector<string> card;
vector<string> not_used;
int m,n;
bool check(int x,int y)
{
     set<char> a;
     set<char> b;
     for(int i=x;i<x+3;i++)
      for(int j=y;j<y+3;j++)
      {
           a.insert(sol[i][j][0]);
           b.insert(sol[i][j][1]);
      }
     return  a.size()==9 || b.size()==1;
}
int main()
{
     int i,j;
     int i1,i2,j1,j2;
     int x1,x2,y1,y2;
     for(int i=0;i<13;i++)
      for(int j=0;j<4;j++)
       card.push_back(c[i]+s[j]);
     x1=x2=y1=y2=-1;
     scanf("%d%d",&m,&n);
     for(i=0;i<m;i++)
          for(j=0;j<n;j++)
          {
               cin>>sol[i][j];
               if(sol[i][j]=="J1")
                  {x1=i; y1=j;}
               else if(sol[i][j]=="J2")
                  {x2=i;y2=j;}
               used[sol[i][j]]=1;
          }
   // printf("%d %d\n",x1,x2);
 for(i=0;i<card.size();i++)
      if(!used[card[i]])
       not_used.push_back(card[i]);
    int Size=not_used.size();
 for(i=0;i<Size;i++)
  for(j=0;j<Size;j++)
  {
      if(i==j) continue;
      if(x1>=0) sol[x1][y1]=not_used[i];
      if(x2>=0) sol[x2][y2]=not_used[j];
      for(i1=0;i1<m-2;i1++)
        for(j1=0;j1<n-2;j1++)
            for(i2=0;i2<m-2;i2++)
                for(j2=0;j2<n-2;j2++)
                {
                    if(j2-j1>=3 || i2-i1>=3)
                    {
                        if(check(i1,j1)&& check(i2,j2))
                        {
                            cout<<"Solution exists."<<endl;
                            if(x1<0 && x2<0)
                                cout<<"There are no jokers."<<endl;
                            else if(x1>=0 && x2>=0)
                                cout<<"Replace J1 with "<<not_used[i]<<" and J2 with "<<not_used[j]<<"."<<endl;
                            else
                            {
                                if(x1>=0)
                                    cout<<"Replace J1 with "<<not_used[i]<<"."<<endl;
                                if(x2>=0)
                                    cout<<"Replace J2 with "<<not_used[j]<<"."<<endl;
                            }
                            cout<<"Put the first square to "<<"("<<i1+1<<", "<<j1+1<<")."<<endl;
                            cout<<"Put the second square to "<<"("<<i2+1<<", "<<j2+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<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;
}

#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;
}

#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;

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;
}

#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 <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 <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 <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 <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>
#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;
}

#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 <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 <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 <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>
#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;
}

#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 <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 <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>
#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 <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 <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 <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>

#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;

#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 <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 <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;

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 <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 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<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;
}

#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<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 <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 <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";
    }
}

#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 <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 <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 ;
}

#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>
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 <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 <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

*/

#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;
}

#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>
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>
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);
}

///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>
//#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 <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>
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 <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;
}

//#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;
}

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

#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<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 <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 <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 <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;
}

#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;
}

#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 <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 <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 <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;
}

#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 <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;
}

#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 <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 <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 <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 <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 <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 <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 <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;
        }

//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 <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>
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 <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<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 <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 <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<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;
}

//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;
}

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

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

#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;
}