// UFU + IZHSTU
// AlexFetisov
// pew pew

#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

const int HEIGHT = 16;
const int WIDTH = 8;
const int NCOLORS = 6;
const int maxX = 100000; // amount of Xs;

struct C {
	int x, y;
	C() {}
	C(int x, int y) {
		this->x = x;
		this->y = y;
	}
};

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
bool mark[HEIGHT][WIDTH];
int comp_size = 0;
int SCORE_LAVIN[] = {0, 0, 3, 6, 12, 24, 50, 100};
bool flag[HEIGHT][WIDTH];
//FILE * f;

class Field {
public:
	int f[HEIGHT][WIDTH];
	vector < C > color_positions[NCOLORS];
	
	void dfs(int x, int y, int col) {
		if (x < 0 || y < 0 || x >= HEIGHT || y >= WIDTH) {
			return;
		}
		if (mark[x][y]) {
			return;
		}
		if (f[x][y] != col) {
			return;
		}
		mark[x][y] = true;
		++comp_size;
		for (int i = 0; i < 4; ++i) {
			dfs(x + dx[i], y + dy[i], col);
		}
	}

	void dfsKillBlack(int x, int y, int col) {
		if (x < 0 || y < 0 || x >= HEIGHT || y >= WIDTH) {
			return;
		}
		if (flag[x][y]) {
			return;
		}
		if (f[x][y] != col) {
			if (f[x][y] == 6) {
				flag[x][y] = true;
			}
			return;
		}
		flag[x][y] = true;
		for (int i = 0; i < 4; ++i) {
			dfsKillBlack(x + dx[i], y + dy[i], col);
		}
	}

	bool findAndDelComponents(int & amountBurnBalls, int & amountBurnComps) {
		amountBurnBalls = 0;
		amountBurnComps = 0;
		memset(mark, false, sizeof mark);
		memset(flag, false, sizeof flag);
		bool ok = false;
		for (int i = 0; i < HEIGHT; ++i) {
			for (int j = 0; j < WIDTH; ++j) {
				if (f[i][j] >= 1 && f[i][j] <= 5) {
					if (!mark[i][j]) {
						comp_size = 0;
						dfs(i, j, f[i][j]);
						if (comp_size >= 4) {
							ok = true;
							dfsKillBlack(i, j, f[i][j]);
							++amountBurnComps;
							amountBurnBalls += comp_size;
						}
					}
				}
			}
		}
		if (!ok) {
			return false;
		}
		for (int i = 0; i < HEIGHT; ++i) {
			for (int j = 0; j < WIDTH; ++j) {
				if (flag[i][j]) {
					f[i][j] = 0;
				}
			}
		}
		return true;
	}

	void goDown() {
		for (int c = 0; c < WIDTH; ++c) {
			int lastEmpty = HEIGHT-1;
			for (int r = HEIGHT - 1; r >= 0; --r) {
				if (f[r][c] != 0) {
					while (lastEmpty > r && f[lastEmpty][c] != 0) {
						--lastEmpty;
					}
					if (f[lastEmpty][c] == 0) {
						f[lastEmpty][c] = f[r][c];
						f[r][c] = 0;
					}
				}
			}
		}
	}

	Field() {
		memset(f, 0, sizeof f);
		for (int i = 0; i < NCOLORS; ++i) {
			color_positions[i].clear();
		}
	}

	void readField() {
		char s[WIDTH + WIDTH];
		for (int i = 0; i < HEIGHT; ++i) {
			scanf("%s", s);
		//	fprintf(::f, "%s\n", s);
		//	fflush(::f);
			for (int j = 0; j < WIDTH; ++j) {
				char c = s[j];
				int whatIsThis = 0; // it is empty, 1-5 - color, 6 - black hole
				if (isdigit(c)) {
					whatIsThis = c - '0';
				} else if (c == '*') {
					whatIsThis = 6;
				} 
				f[i][j] = whatIsThis;
				if (whatIsThis > 0) {
					color_positions[whatIsThis].push_back(C(i, j));
				}
			}
		}                   
	}



	int burnField() {
		int score = 0;
		int step = 0;
		for (step = 1; ; ++step) {
			int amountofBalls = 0;
			int amountOfComps = 0;
			bool ok = findAndDelComponents(amountofBalls, amountOfComps);
			score += amountofBalls - amountOfComps - 2;
			if (step > 7) {
				step = 7;
			}
			score += SCORE_LAVIN[step];
			if (!ok) {
				break;
			}
			goDown();
		}
		return score;
	}

	bool addBlock(int y1, int c1, int y2, int c2) {
		int x;
		for (x = 0; x < HEIGHT && f[x][y1] == 0; ++x);
		if (x == HEIGHT) --x;
		if (x == 0 && f[x][y1] > 0) {
			return false;
		}
		f[x][y1] = c1;
		for (x = 0; x < HEIGHT && f[x][y2] == 0; ++x);
		if (x == HEIGHT) --x;
		if (x == 0 && f[x][y1] > 0) {
			return false;
		}
		f[x][y2] = c2;
		return true;
	}
};


// Func that finds the color by the X_i
int doColor(int x) {
	return (x % 5) + 1;
}

//Func that finds next X by the previous two
int nextX(int px) {
	long long A = (long long)px * 17235617LL;
	A += 4311271LL;
	A %= 87465851LL;
	return (int)A;
}

Field ourField, enemyField;		// Fields of the game
int X[maxX];					// Xs of balls
int curPtr = 0;					// this is the pointer of start the current ball in X
int lastPtr = 0;				// this is the last ball in Xs
Field tmpField;					// temp field

int prev(int i, int mod) {		// gets previous i in mod 
	--i;
	if (i < 0) {
		i += mod;
	}
	return i;
}

int next(int i, int mod) {		// gets next i in mod 
	++i;
	if (i >= mod) {
		i -= mod;
	}
	return i;
}

void findScoreForOneBlock(int & best, int & bi, int & bj) {
	int c1 = doColor(X[curPtr]);
	int c2 = doColor(X[next(curPtr, maxX)]);
	best = 0;
	bi = -1;
	bj = -1;
	// find Horisontal 
	for (int i = 0; i < WIDTH - 1; ++i) {
		int j = i + 1;
		tmpField = ourField;
		tmpField.addBlock(i, c1, j, c2);
		int cur = tmpField.burnField();
		if (cur > best) {
			best = cur;
			bi = i;
			bj = j;
		}
		if (c1 != c2) {
			tmpField = ourField;
			tmpField.addBlock(j, c1, i, c2);
			int cur = tmpField.burnField();
			if (cur > best) {
				best = cur;
				bi = j;
				bj = i;
			}
		}
	}

	// find Vertical 
	
	for (int i = 0; i < WIDTH; ++i) {
		int j = i;
		tmpField = ourField;
		tmpField.addBlock(i, c1, j, c2);
		int cur = tmpField.burnField();
		if (cur > best) {
			best = cur;
			bi = i;
			bj = 1000;
		}
		if (c1 != c2) {
			tmpField = ourField;
			tmpField.addBlock(j, c1, i, c2);
			int cur = tmpField.burnField();
			if (cur > best) {
				best = cur;
				bi = 1000;
				bj = i;
			}
		}
	}
}

int memi = -1, memj = -1;
int memret = 0;

void rec(int depth, Field cur, int cret, int pi, int pj, int startPtr) {
	
	if (depth == 2) {
		if (cret > memret) {
			memret = cret;
			memi = pi;
			memj = pj;
		}
		return;
	}
	int c1 = doColor(X[startPtr]);
	int c2 = doColor(X[next(startPtr, maxX)]);
	// find Horisontal 
	for (int i = 0; i < WIDTH - 1; ++i) {
		int j = i + 1;
		tmpField = cur;
		bool ok = tmpField.addBlock(i, c1, j, c2);
		if (ok) {
			int curScore = tmpField.burnField();
			if (depth == 0) {
				rec(depth + 1, tmpField, cret + curScore, i, j, next(next(startPtr, maxX), maxX));
			} else {
				rec(depth + 1, tmpField, cret + curScore, pi, pj, next(next(startPtr, maxX), maxX));
			}
			if (c1 != c2) {
				tmpField = cur;
				bool ok = tmpField.addBlock(j, c1, i, c2);
				if (ok) { 	
					int curScore = tmpField.burnField();
					if (depth == 0) {
						rec(depth + 1, tmpField, cret + curScore, j, i, next(next(startPtr, maxX), maxX));
					} else {
						rec(depth + 1, tmpField, cret + curScore, pi, pj, next(next(startPtr, maxX), maxX));
					}
				}
			}
		}
	}

	// find Vertical 
	
	for (int i = 0; i < WIDTH; ++i) {
		int j = i;
		tmpField = cur;
		bool ok = tmpField.addBlock(i, c1, j, c2);
		if (ok) {
			int curScore = tmpField.burnField();
			if (depth == 0) {
				rec(depth + 1, tmpField, cret + curScore, i, 1000, next(next(startPtr, maxX), maxX));
			} else {
				rec(depth + 1, tmpField, cret + curScore, pi, pj, next(next(startPtr, maxX), maxX));
			}
			if (c1 != c2) {
				tmpField = cur;
				bool ok = tmpField.addBlock(j, c1, i, c2);
				if (ok) {
					int curScore = tmpField.burnField();
					if (depth == 0) {
						rec(depth + 1, tmpField, cret + curScore, 1000, i, next(next(startPtr, maxX), maxX));
					} else {
						rec(depth + 1, tmpField, cret + curScore, pi, pj, next(next(startPtr, maxX), maxX));
					}
				}
			}
		}
	}
}

void lookForward(int & best, int & bi, int & bj) {
	memret = 0;
	memi = memj = -1;
	//fprintf(f, "Start\n");
	//fflush(f);
	rec(0, ourField, 0, -1, -1, curPtr);
	//fprintf(f, "Finish\n");
	//fflush(f);
	best = memret;
	bi = memi;
	bj = memj;
}

void outIt(int bi, int bj) {
	if (bi != 1000 && bj != 1000) {
		// this is Horisontal
		if (bi < bj) {
			printf("%d %d\n", bi, 0);
		} else {
			printf("%d %d\n", bj, 2);
		}
	} else {
		if (bi == 1000) {
			printf("%d %d\n", bj, 1);
		} else {
			printf("%d %d\n", bi, 3);
		}
	}
}


int main()
{
//	f = fopen("log.txt", "w");
	//freopen("game.txt", "r", stdin);
	char str[100];
	int x0;
	for (int step = 0; ; ++step) {
		scanf("%s", str);
	//	fprintf(f, "%s\n", str);
	//	fflush(f);
		if (str[0] == 'Q') {
			break;
		}
		if (str[0] == 'S') {
			scanf("%d", &x0);
	//		fprintf(f, "%d\n", x0);
	//		fflush(f);
			X[lastPtr] = (x0);
			lastPtr = next(lastPtr, maxX);
			for (int i = 1; i <= 100; ++i) {
				X[lastPtr] = (nextX(X[prev(lastPtr, maxX)]));
				lastPtr = next(lastPtr, maxX);
			}
			printf("Destroy That Ball\n");
			fflush(stdout);
		} else if (str[0] == 'M') {
			ourField.readField();
			enemyField.readField();
			int score = 0, bi, bj;
			findScoreForOneBlock(score, bi, bj);
			if (bi != -1) {
				outIt(bi, bj);
			} else {
				lookForward(score, bi, bj);
				if (bi != -1) {
					outIt(bi, bj);
				} else {
					bi = step % (WIDTH-1);
					bj = bi + 1;
					outIt(bi, bj);
				}
			}
			fflush(stdout);
			for (int i = 1; i <= 2; ++i) {
				X[lastPtr] = doColor(nextX(X[prev(lastPtr, maxX)]));
				lastPtr = next(lastPtr, maxX);
				curPtr = next(curPtr, maxX);
			}
		}
	}
	
	return 0;
}
