#include <stdio.h>
#include <stdlib.h>

const int maxr = 128;
const int maxc = 128;
const int maxSteck = 5000;


int maxSearch = 5000;
int nSearch;



int maxRound = 20000;
int nRound;

int row[maxr][maxc/2];
int col[maxc][maxr/2];
bool best[maxr][maxc];
int bestPoint;

int nRow, nCol;


int field[maxr][maxc];
signed char fields[maxSteck+5][maxr][maxc];

bool updateds[maxSteck][2][maxc];
bool updated[2][maxc];

int cell[maxc];
int length;
int block[maxc/2];
int nblock;

bool left[maxc/2][maxc];
bool right[maxc/2][maxc];
bool canstart[maxc/2][maxc];

void RestoreLine();
int CalcLine();
int Calc();
int CalcRow(int i);
int CalcCollumn(int i);
void Analize();


int blockType;// 0  for Rows, 1 for Columns
int iLineBlock, iBlock;
int position[maxc];// position[i] > 0  -- first cell
double bestBlock;
int blockLength;

bool OutCalcState = false;

double blockPoint(int type, int i, int l, int npos)
{
	double res = 1.0;
	if (npos <2) return 0;
	if (i==0) res*=2;
	if ((type==0)&&(i==nRow-1)) res *=2;
	if ((type==1)&&(i==nCol-1)) res *=2;
	if (i<3) res *=1.5;
	if ((type==0)&&(i>nRow-4)) res *=1.5;
	if ((type==1)&&(i>nCol-4)) res *=1.5;
	return l*res/npos;
}

void SelectBlock(int type, int iLine)
{
	int i,j,k;
	double d;
	for(i=0;i<nblock;i++)
	{
		k=0;
		for(j=0;j<=length;j++)
			if (canstart[i][j]) k++;
		d = blockPoint(type, iLine, block[i], k);
		if (d > bestBlock)
		{
			blockLength = block[i];
			bestBlock = d;
			blockType = type;
			iLineBlock = iLine;
			iBlock = i;
			k=0;
			for(j=0;j<=length;j++)
				if (canstart[i][j]) position[k++] = j-1;
			position[k] = -1;
		}
	}

}

void Analize()
{
	int i,j,k,nc = 0, nr = 0;
	for(i=0;i<nRow;i++)
	{
		for(j=0;j<nCol;j++)
			if (field[i][j] == 0) break;
		if (j<nCol) nr++;
	}

	for(j=0;j<nCol;j++)
	{
		for(i=0;i<nRow;i++)
			if (field[i][j] == 0) break;
		if (i<nRow) nc++;
	}

	if (nc+nr==0)
	{
		for(i=0;i<nRow;i++)
			for(j=0;j<nCol;j++)
				best[i][j] = field[i][j] > 0;
		bestPoint = (nRow+nCol)*2;
		return;
	}

	bestBlock = -1;

	if (nc > nr)
	{
//		for(i=0;i<nRow;i++)
//			CalcRow(i);

		for(int ic=0;ic<nCol;ic++)
		{
			length = nRow;
			nblock = col[ic][0];
			for(i=0;i<nblock;i++)
				block[i] = col[ic][i+1];
			for(i=0;i<length;i++)
				cell[i+1] = field[i][ic];
			cell[0] = cell[length+1] = -1;

			RestoreLine();

			for(i=0;i<length;i++)
				field[i][ic] = cell[i+1];
		}

	}else
	{
//		for(i=0;i<nCol;i++)
//			CalcCollumn(i);
		for(int ir=0;ir<nRow;ir++)
		{
			length = nCol;
			nblock = row[ir][0];
			for(i=0;i<nblock;i++)
				block[i] = row[ir][i+1];
			for(i=0;i<length;i++)
				cell[i+1] = field[ir][i];
			cell[0] = cell[length+1] = -1;

			RestoreLine();

			for(i=0;i<length;i++)
				field[ir][i] = cell[i+1];
		}
	}
// check;
	nc = 0;

	for(i=0;i<nRow;i++)
	{
		nr = 0;
		k=1;
		for(j=0;j<nCol;j++)
			if (field[i][j] > 0)
			{
				nr++;
			}else
			{
				if (nr > 0)
					if (row[i][k++] != nr) break;
				nr = 0;
			}
		if (nr > 0)
			if (row[i][k++] != nr) continue;
		if ((k > row[i][0])&&(j>= nCol)) nc++;
		
	}

	for(i=0;i<nCol;i++)
	{
		nr = 0;
		k=1;
		for(j=0;j<nRow;j++)
			if (field[j][i] > 0)
			{
				nr++;
			}else
			{
				if (nr > 0)
					if (col[i][k++] != nr) break;
				nr = 0;
			}
		if (nr > 0)
			if (col[i][k++] != nr) continue;
		if ((k > col[i][0])&&(j>= nRow)) nc++;
		
	}

	if (nc > bestPoint)
	{
		for(i=0;i<nRow;i++)
			for(j=0;j<nCol;j++)
				best[i][j] = field[i][j] > 0;
		bestPoint = nc;
	}


}

void RestoreLine()
{
	int i,j,k;
	CalcLine();
	i=0;
	j=1;
	while((i<nblock)&&(j<=length))
	{
		if (canstart[i][j])
		{
			for(k=0;k<block[i];k++)
				cell[j+k] = 1;
			j+=block[i];
			i++;
		}
		cell[j++] = -1;

	}
	for(;j<=length;j++)
		cell[j] = -1;

}

int Calc()
{
	int i,res, lres;
	do{
		
		res = 0;
		for(i=0;i<nRow;i++)
		{
			lres = CalcRow(i);
			if (lres < 0) 
				return -1;
			res += lres;
		}
		for(i=0;i<nCol;i++)
		{
			lres = CalcCollumn(i);
			if (lres < 0) 
				return -1;
			res += lres;
		}


		if(++nRound > maxRound) return 0;	
	}while(res > 0);
	return 0;

}


int CalcRow(int ir)
{
	int i, res;
	bool up = true;
	if (!updated[0][ir]) return 0;
	length = nCol;
	nblock = row[ir][0];
	for(i=0;i<nblock;i++)
		block[i] = row[ir][i+1];
	for(i=0;i<length;i++)
		cell[i+1] = field[ir][i];
	cell[0] = cell[length+1] = -1;

	if ( (res = CalcLine()) < 0) return -1;

//	SelectBlock(0, ir);

	for(i=0;i<length;i++)
		if (field[ir][i] != cell[i+1])
		{
			field[ir][i] = cell[i+1];
			updated[0][ir] = true;
			updated[1][i] = true;
			up = false;
		}
	if (up) updated[0][ir] = false;
	return res;
	

}

int CalcCollumn(int ic)
{
	int i, res;
	bool up = true;
	if (!updated[1][ic]) return 0;
	length = nRow;
	nblock = col[ic][0];
	for(i=0;i<nblock;i++)
		block[i] = col[ic][i+1];
	for(i=0;i<length;i++)
		cell[i+1] = field[i][ic];
	cell[0] = cell[length+1] = -1;

	if ( (res = CalcLine()) < 0) return -1;

//	SelectBlock(1, ic);

	for(i=0;i<length;i++)
	{
		if (field[i][ic] != cell[i+1])
		{
			updated[1][ic] = true;
			updated[0][i] = true;
			field[i][ic] = cell[i+1];
			up = false;
		}
	}

	if (up) updated[1][ic] = false;

	return res;
	


}

int CalcLine_0()
{
	int i,j,ll;
	int iLastEmpty;
// left
	if ((nblock == 3)&&(block[0] == 1)&&(block[1]==1)&&(length==5))
		i=0;
	iLastEmpty = -1;
	for(j=0;j<=length;j++)
	{
		if (cell[j] > 0) iLastEmpty = j;
		left[0][j] = iLastEmpty < 0;
	}
	ll=0;
	for(i=1;i<=nblock;i++)
	{
		iLastEmpty = -1;
		ll += block[i-1];
		for(j=0;j<=ll;j++)
		{
			left[i][j] = false;
			if (cell[j] < 0) iLastEmpty = j;
		}
		for(;j<=length+1;j++)
		{
			left[i][j] = left[i][j-1] || 
				((iLastEmpty <= j-block[i-1])&&(cell[j-block[i-1]-1] <=0)
				&&(left[i-1][j-block[i-1]-1]));
			if (cell[j] < 0) iLastEmpty = j;
		}
		ll++;
	}
// right
	iLastEmpty = -1;
	for(j=length+1;j>0;j--)
	{
		right[nblock][j] = iLastEmpty < 0;
		if (cell[j] > 0) iLastEmpty = j;
	}
	ll=0;
	for(i=nblock-1;i>=0;i--)
	{
		iLastEmpty = length+1;
		ll += block[i];
		right[i][length+1] = false;
		right[i][length+2] = false;
		for(j=0;j<ll;j++)
		{
			right[i][length-j] = false;
			if (cell[length-j] < 0) iLastEmpty = length-j;
		}
		for(j=length-ll+1;j>=0;j--)
		{
			right[i][j] = right[i][j+1] || 
				((iLastEmpty > j+block[i])&&(cell[j+block[i]+1] <=0)
				&&(right[i+1][j+block[i]+1]));
			if (cell[j] < 0) iLastEmpty = j;
		}
		ll++;
	}

	if (!right[0][0]) return -1;
// can start
	bool ok;
	iLastEmpty = length+1;
	for(j=length;j>0;j--)
	{
		if (cell[j] < 0) iLastEmpty = j;
		for(i=0;i<nblock;i++)
		{
			int j1 = j+block[i];
			if ((ok = (iLastEmpty >= j+block[i])&&(cell[j-1] <=0)))

			{
				ok &= ((cell[j1] <=0)&&(right[i+1][j1]));
				if (j>1) ok &= left[i][j-1];
				else ok &= i==0;
			}
			canstart[i][j] = ok;
		}
	}
	int res = 0;
	iLastEmpty = -1;
	for(j=1;j<=length;j++)
	{
		for(i=0;i<nblock;i++)
			if (canstart[i][j])
				if (j+block[i] > iLastEmpty) iLastEmpty = j+block[i];
		if (cell[j] == 0)
		{

			for(i=0;i<=nblock;i++)
				if ((left[i][j])&&(right[i][j])) break;
			if (i>nblock)
			{
				cell[j] = 1;
				res++;
			}else
			{
				if (iLastEmpty <= j)
				{
					cell[j] = -1;
					res++;
				}
			}
		}
	}
	return res;

}



void Search(int level)
{
	int i,j;
	int pos[maxc];
	int line[maxc];
	int bt, il, ib, lb;

	if (nSearch++ > maxSearch) return;
	if (bestPoint >= nCol + nRow) return;
	if (level >= maxSteck-1) return;
	if (nRound >= maxRound) return;


if (OutCalcState)
{
printf("------- level %d ----------\n", level);

for(i=0;i<nRow;i++)
{
	for(j=0;j<nCol;j++)
	{
		if(field[i][j] > 0) printf("*");
		if(field[i][j] < 0) printf(".");
		if(field[i][j] == 0) printf("x");
	}
	printf("\n");
}

}
	if ( Calc() < 0) 
	{ 
//		Analize();
		return;
	}
if (OutCalcState)
{
printf("\n");

for(i=0;i<nRow;i++)
{
	for(j=0;j<nCol;j++)
	{
		if(field[i][j] > 0) printf("*");
		if(field[i][j] < 0) printf(".");
		if(field[i][j] == 0) printf("x");
	}
	printf("\n");
}

}



	for(i=0;i<nRow+4;i++)
		for(j=0;j<nCol+4;j++)
			fields[level][i][j] = (signed char)field[i][j];

	for(i=0;i<nRow;i++)
		updateds[level][0][i] = updated[0][i];
	for(i=0;i<nCol;i++)
		updateds[level][1][i] = updated[1][i];

	Analize();

	for(i=0;i<nRow+4;i++)
		for(j=0;j<nCol+4;j++)
			field[i][j] = fields[level][i][j];

	for(i=0;i<nRow;i++)
		updated[0][i] = updateds[level][0][i];
	for(i=0;i<nCol;i++)
		updated[1][i] = updateds[level][1][i];

	for(i=0;i<nRow;i++)
	{
		for(j=0;j<nCol;j++)
			if (field[i][j] == 0) break;
		if (j<nCol) break;
	}
	updated[0][i] = true;
	updated[1][j] = true;

	field[i][j] = 1;
	Search(level+1);
	


	for(i=0;i<nRow+4;i++)
		for(j=0;j<nCol+4;j++)
			field[i][j] = fields[level][i][j];

	for(i=0;i<nRow;i++)
		updated[0][i] = updateds[level][0][i];
	for(i=0;i<nCol;i++)
		updated[1][i] = updateds[level][1][i];

	for(i=0;i<nRow;i++)
	{
		for(j=0;j<nCol;j++)
			if (field[i][j] == 0) break;
		if (j<nCol) break;
	}

	updated[0][i] = true;
	updated[1][j] = true;

	field[i][j] = -1;
	Search(level+1);

	return;

	

}



void Solve()
{
	int i,j,k,l;
	bestPoint = -1;

	nRound = 0;
	for(i=0;i<nRow+4;i++)
		for(j=0;j<nCol+4;j++)
			field[i][j] = 0;

	for(i=0;i<nRow;i++)
		updated[0][i] = true;
	for(i=0;i<nCol;i++)
		updated[1][i] = true;

	nRound = 0;


	nSearch = 0;
	Search(0);
}

int random(int k)
{
	int v = 0;
	for(int i=0;i<128;i++)
		v = (v*2+(rand()&1))%k;
	return v;
}

void InitField(int ii, int unit)
{
	int i,j;
	for(i=0;i<nRow;i++)
		fields[ii][i][nCol] = -1;
	for(i=0;i<nCol;i++)
		fields[ii][nRow][i] = -1;

	for(i=0;i<nRow;i++)
		for(j=0;j<nCol;j++)
			if (random(1000) < unit)
				 fields[ii][i][j] = 1;
			else fields[ii][i][j] = -1;

}

void InitBlocks(int ii)
{
	int i,j,k, nr;

	for(i=0;i<nRow;i++)
	{
		nr = 0;
		k=1;
		for(j=0;j<=nCol;j++)
			if (fields[ii][i][j] > 0)
			{
				nr++;
			}else
			{
				if (nr > 0)
					row[i][k++] = nr;
				nr = 0;
			}
		row[i][0] = k-1;
		
	}

	for(i=0;i<nCol;i++)
	{
		nr = 0;
		k=1;
		for(j=0;j<=nRow;j++)
			if (fields[ii][j][i] > 0)
			{
				nr++;
			}else
			{
				if (nr > 0)
					col[i][k++] = nr;
				nr = 0;
			}
		col[i][0] = k-1;
		
	}


}



int main()
{
	int ii,i,j,n;
	FILE *f;
/*
	CheckLine(4);

	n = 2000;
	srand(45694521);
	for(ii=0;ii<n;ii++)

	{
		nRow = 4 + random(1);
		nCol = 4 + random(1);
		InitField(maxSteck+1,500);
		InitBlocks(maxSteck+1);
		Solve();
		if (bestPoint < nRow+nCol) break;
	}

	if (ii >=n)
	{
		printf("ok\n");
		return 0;
	}



	printf("Bad field(%d) %d, %d ->%d:\n", ii, nRow, nCol, bestPoint);
	for(i=0;i<nRow;i++)
	{
		for(j=0;j<nCol;j++)
//			if (fields[maxSteck-2][i][j] == 1) printf("*");
			if (best[i][j] == 1) printf("*");
			else printf(".");
		printf("\n");
	}

	printf("\nInitial\n", nRow, nCol, bestPoint);
	for(i=0;i<nRow;i++)
	{
		for(j=0;j<nCol;j++)
			if (fields[maxSteck+1][i][j] == 1) printf("*");
			else printf(".");
		printf("\n");
	}

	OutCalcState = true;
	Solve();
	InitBlocks(maxSteck+1);
	Solve();


	return 0;
	         */


	if ((f = fopen("01.in", "rt"))== NULL)	f = stdin;

	fscanf(f, "%d",&n);
	for(ii=0;ii<n;ii++)
	{
		fscanf(f,"%d%d",&nRow, &nCol);
		for(i=0;i<nRow;i++)
		{
			j=0;
			while(fscanf(f,"%d",row[i] + j+1) > 0)
			{
				if (row[i][j+1] < 1) break;
				j++;
			}
			row[i][0] = j;
		}
		for(i=0;i<nCol;i++)
		{
			j=0;
			while(fscanf(f,"%d",col[i] + j+1) > 0)
			{
				if (col[i][j+1] < 1) break;
				j++;
			}
			col[i][0] = j;
		}

		Solve();

		for(i=0;i<nRow;i++)
		{
			for(j=0;j<nCol;j++)
				if(best[i][j]) printf("#");
				else printf(".");
			printf("\n");
		}
	}
	return 0;
}


int CalcLine()
{
	int i,j,ll;
	int iLastEmpty;
// left
	if ((nblock == 3)&&(block[0] == 1)&&(block[1]==1)&&(length==5))
		i=0;
	iLastEmpty = -1;
	for(j=0;j<=length+1;j++)
	{
		left[0][j] = iLastEmpty < 0;
		if (cell[j] > 0) iLastEmpty = j;
	}
	ll=0;
	for(i=1;i<=nblock;i++)
	{
		iLastEmpty = -1;
		ll += block[i-1];
		for(j=0;j<=ll;j++)
		{
			left[i][j] = false;
			if (cell[j] < 0) iLastEmpty = j;
		}
		for(;j<=length+1;j++)
		{
			left[i][j] = 
				((iLastEmpty < j-block[i-1])&&(cell[j-block[i-1]-1] <=0)
				&&(left[i-1][j-block[i-1]-1]));
			if (cell[j-1] <= 0) left[i][j] |= left[i][j-1];
			if (cell[j] < 0) iLastEmpty = j;
		}
		ll++;
	}
// right
	iLastEmpty = -1;
	for(j=length+1;j>=0;j--)
	{
		right[nblock][j] = iLastEmpty < 0;
		if (cell[j] > 0) iLastEmpty = j;
	}
	ll=0;
	for(i=nblock-1;i>=0;i--)
	{
		iLastEmpty = length+1;
		ll += block[i];
		right[i][length+1] = false;
		right[i][length+2] = false;
		for(j=0;j<ll;j++)
		{
			right[i][length-j] = false;
			if (cell[length-j] < 0) iLastEmpty = length-j;
		}
		for(j=length-ll+1;j>=0;j--)
		{
			right[i][j] = 
				((iLastEmpty > j+block[i])&&(cell[j+block[i]+1] <=0)
				&&(right[i+1][j+block[i]+1]));
			if (cell[j+1] <= 0) right[i][j] |= right[i][j+1];
			if (cell[j] < 0) iLastEmpty = j;
		}
		ll++;
	}

	if (!right[0][0]) return -1;
// can start
	bool ok;
	iLastEmpty = length+1;
	for(j=length;j>0;j--)
	{
		if (cell[j] < 0) iLastEmpty = j;
		for(i=0;i<nblock;i++)
		{
			int j1 = j+block[i];
			if ((ok = (iLastEmpty >= j+block[i])&&(cell[j-1] <=0)))

			{
				ok &= ((cell[j1] <=0)&&(right[i+1][j1]));
				if (j>1) ok &= left[i][j-1];
				else ok &= i==0;
			}
			canstart[i][j] = ok;
		}
	}
	int res = 0;
	iLastEmpty = -1;
	for(j=1;j<=length;j++)
	{
		for(i=0;i<nblock;i++)
			if (canstart[i][j])
				if (j+block[i] > iLastEmpty) iLastEmpty = j+block[i];
		if (cell[j] == 0)
		{

			for(i=0;i<=nblock;i++)
				if ((left[i][j])&&(right[i][j])) break;
			if (i>nblock)
			{
				cell[j] = 1;
				res++;
			}else
			{
				if (iLastEmpty <= j)
				{
					cell[j] = -1;
					res++;
				}
			}
		}
	}
	return res;

}