#include <stdio.h>
#include <stdlib.h>

#define NOPOS (48*48*8*8*2)

const int lShape[48]={
	0x088C,0x0446,0x0223,0x88C0,0x4460,0x2230,
	0x044C,0x0226,0x0113,0x44C0,0x2260,0x1130,
	0xC440,0x6220,0x3110,0x0C44,0x0622,0x0311,
	0xC880,0x6440,0x3220,0x0C88,0x0644,0x0322,
	0xE800,0x0E80,0x00E8,0x7400,0x0740,0x0074,
	0x8E00,0x08E0,0x008E,0x4700,0x0470,0x0047,
	0xE200,0x0E20,0x00E2,0x7100,0x0710,0x0071,
	0x2E00,0x02E0,0x002E,0x1700,0x0170,0x0017,
};

struct TMove
{
	int mv;
	struct TMove *next;
};

struct TPos
{
	char n;    // Number of moves from this position
	char eval; // Evaluation (100 = W mates 0, 99 = W mates 1, 0 = draw, -96 = B mates 4)
	struct TMove *move,*premove;
} *pos;

int movelist[500],nomoves;
int head,tail,queue[20000];

void getL(void)
{
	int i,j,k,v;
	char s[10];

	for(i=0;i<48;i++) {
		v=0;
		for(j=0;j<4;j++) {
			scanf("%s",s);
			for(k=0;k<4;k++)
				v=(v<<1)+(s[k]=='#');
		}
		printf("0x%04X,",v);
	}
	exit(0);
}

/* Encode a position (0<=l1,l2<48, 0<=c1,c2<16, turn = player to move (0-1) */
int encode(int l1, int l2, int c1, int c2, int turn)
{
	int i,j,v1=-1,v2=-1,mask;
	if (c2<c1) { i=c1; c1=c2; c2=i; }
	mask=~(lShape[l1]|lShape[l2]);
	for(i=j=0;i<16;i++) {
		if (c1==i) v1=j;
		if (c2==i) v2=j;
		if ((1<<i)&mask) j++;
	}
	if ((v1<0) || (v2<0) || (v1>7) || (v2>7))
		exit(0);
	return (((l1*48+l2)*8+v1)*8+v2)*2+turn;
}

void decode(int pos, int *l1, int *l2, int *c1, int *c2, int *turn)
{
	int i,j,v1,v2,mask;
	*turn=pos&1;
	pos>>=1;
	v2=pos&7;
	pos>>=3;
	v1=pos&7;
	pos>>=3;
	*l2=pos%48;
	pos/=48;
	*l1=pos;
	mask=~(lShape[*l1]|lShape[*l2]);
	for(i=j=0;i<16;i++) {
		if (v1==j) *c1=i;
		if (v2==j) *c2=i;
		if ((1<<i)&mask) j++;
	}
}

int legal(int l1, int l2, int c1, int c2)
{
	int mask;
	if (lShape[l1]&lShape[l2])
		return 0;
	mask=lShape[l1]|lShape[l2];
	if ((1<<c1)&mask) return 0;
	if ((1<<c2)&mask) return 0;
	if (c1==c2) return 0;
	return 1;
}

void showpos(int l1, int l2, int c1, int c2)
{
	int i,j;
	char pos[16];
	if (!legal(l1,l2,c1,c2)) {
		printf("Illegal position!\n");
		return;
	}
	memset(pos,'.',sizeof(pos));
	for(i=0;i<16;i++) {
		if ((1<<i)&lShape[l1]) pos[i]='#';
		if ((1<<i)&lShape[l2]) pos[i]='*';
	}
	pos[c1]='x';
	pos[c2]='x';
	for(i=0;i<4;i++) {
		for(j=0;j<4;j++)
			printf("%c",pos[i*4+j]);
		printf("\n");
	}
}

void addmove(int l1, int l2, int c1, int c2, int turn)
{
	movelist[nomoves++]=encode(l1,l2,c1,c2,turn);
}

void getmoves(int pos)
{
	int i,j,l1,l2,c1,c2,turn,opl,myl;
	nomoves=0;
	decode(pos,&l1,&l2,&c1,&c2,&turn);
	opl=turn?l1:l2;
	myl=turn?l2:l1;
	for(i=0;i<48;i++)
		if (i!=myl)
			if (legal(i,opl,c1,c2)) {
				addmove(turn?opl:i,turn?i:opl,c1,c2,1-turn);
				for(j=0;j<16;j++) {
					if ((j!=c1) && legal(i,opl,j,c2)) addmove(turn?opl:i,turn?i:opl,j,c2,1-turn);
					if ((j!=c2) && legal(i,opl,c1,j)) addmove(turn?opl:i,turn?i:opl,c1,j,1-turn);
				}
			}
}

void addqueue(int p, int eval)
{
	pos[p].eval=eval;
	queue[tail++]=p;
}

int readpos(void)
{
	int i,j,k,l1,l2,c1,c2;
	char s[20],turn[4];

	for(i=0;i<4;i++)
		scanf("%s",s+(i<<2));			
	j=k=0;
	c1=c2=-1;
	for(i=0;i<16;i++) {
		if (s[i]=='#') j|=(1<<i);
		if (s[i]=='*') k|=(1<<i);
		if (s[i]=='x') {
			if (c1<0) c1=i;
			else if (c2<0) c2=i;
			else return -1;
		}
	}
	l1=l2=-1;
	for(i=0;i<48;i++) {
		if (j==lShape[i]) l1=i;
		if (k==lShape[i]) l2=i;
	}
	if ((l1<0) || (l2<0))
		return -1;
	return encode(l1,l2,c1,c2,0);
}

int solve(int i)
{
	int j,dir,l1,l2,c1,c2;

	decode(i,&l1,&l2,&c1,&c2,&j);
	if (pos[i].eval<=0) {
		printf("No winning move exist\n");
		if (!pos[i].eval)
			printf("Draw\n");
		else
			printf("Losing\n");
	}	
	getmoves(i);
	for(i=0;i<nomoves;i++) {
		if (pos[movelist[i]].eval>0) {
			decode(movelist[i],&l1,&l2,&c1,&c2,&dir);
			showpos(l1,l2,c1,c2);
		}				
	}
}

int main(void)
{
	int i,j,k,cnt,matecnt;
	int l1,l2,c1,c2;
	struct TMove *m;

	if (!(pos=calloc(NOPOS,sizeof(struct TPos)))) {
		fprintf(stderr,"Out of memory!\n");
		exit(-1);
	}

	head=tail=0;
	cnt=matecnt=0;
	for(l1=0;l1<48;l1++)
		for(l2=0;l2<48;l2++) {
			if (lShape[l1]&lShape[l2])
				continue;
			for(c1=0;c1<16;c1++)
				for(c2=c1+1;c2<16;c2++)
					if (legal(l1,l2,c1,c2)) {
						for(i=0;i<2;i++) {
							j=encode(l1,l2,c1,c2,i);
							getmoves(j);
							pos[j].n=nomoves;
							for(k=0;k<nomoves;k++) {
								m=malloc(sizeof(struct TMove));
								m->mv=movelist[k];
								m->next=pos[j].move;
								pos[j].move=m;
								m=malloc(sizeof(struct TMove));
								m->mv=j;
								m->next=pos[movelist[k]].premove;
								pos[movelist[k]].premove=m;
							}
							cnt++;
							if (!nomoves) {
								addqueue(j,i?100:-100);
								matecnt++;
							}
						}
					}
		}

	while (head<tail) {
		i=queue[head++];
		m=pos[i].premove;
		if (((i&1) && (pos[i].eval>0)) || (!(i&1) && (pos[i].eval<0))) {
			k=pos[i].eval;
			if (k>0) k--; else k++;
			while (m) {
				if (!pos[m->mv].eval)
					addqueue(m->mv,k);
				m=m->next;
			}
		} else if (((i&1) && (pos[i].eval<0)) || (!(i&1) && (pos[i].eval>0))) {
			while (m) {
				if (!pos[m->mv].eval && !--pos[m->mv].n)
					addqueue(m->mv,pos[i].eval);
				m=m->next;
			}
		}
	}

	i=readpos();
	solve(i);
}

