// Arup Guha
// 2/16/2015
// Solution to 2007 MCPC Problem A: Typesetting

import java.util.*;

public class a {

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int R = Integer.parseInt(stdin.nextLine());
		int loop = 1;

		// Go through each case.
		while (R != 0) {

			// Read in the data and form tile objects.
			String[] data = new String[R];
			for (int i=0; i<R; i++)
				data[i] = stdin.nextLine();
			tile[] myTiles = makeTiles(data);

			// Merge into one tile.
			tile ans = myTiles[0];
			for (int i=1; i<myTiles.length; i++)
				ans = ans.merge(myTiles[i]);

			// Print result and go to next case.
			System.out.println(loop);
			System.out.print(ans);
			loop++;
			R = Integer.parseInt(stdin.nextLine());
		}
	}

	public static tile[] makeTiles(String[] data) {

		// Set up parsing data.
		StringTokenizer tok = new StringTokenizer(data[0]);
		int numTiles = tok.countTokens();
		int rows = data.length;
		char[][][] all = new char[numTiles][rows][];

		// Parse out each 2D char grid we care about.
		for (int i=0; i<rows; i++) {
			for (int j=0; j<numTiles; j++) {
				all[j][i] = tok.nextToken().toCharArray();
			}
			if (i < rows-1) tok = new StringTokenizer(data[i+1]);
		}

		// Copy into tile form.
		tile[] res = new tile[numTiles];
		for (int i=0; i<numTiles; i++)
			res[i] = new tile(all[i]);
		return res;
	}
}

class tile {

	// I stored more than I needed to for ease.
	final public static int NONE = 1000;
	public char[][] grid;
	public int rows;
	public int cols;
	public int[] min;
	public int[] max;
	public int startC;
	public int endC;
	public int startPrint;
	public int endPrint;
	public tile(char[][] oneTile) {

		// Calculate all of these.
		rows = oneTile.length;
		cols = oneTile[0].length;
		grid = oneTile;
		min = new int[rows];
		Arrays.fill(min, NONE);
		max = new int[rows];
		Arrays.fill(max, -NONE);
		startC = cols;
		endC = 0;
		startPrint = cols;
		endPrint = 0;

		// Fill in row min's and max's and total min's and max's.
		for (int i=0; i<rows; i++) {
			for (int j=0; j<cols; j++) {
				if (grid[i][j] != '.') {
					min[i] = Math.min(min[i], j);
					max[i] = Math.max(max[i], j);
					startC = Math.min(startC, min[i]);
					endC = Math.max(endC, max[i]);
				}
				if (grid[i][j] == '#') {
					startPrint = Math.min(startPrint, j);
					endPrint = Math.max(endPrint, j);
				}
			}
		}
	}

	public tile merge(tile other) {

		int gap = cols+other.cols;
		for (int i=0; i<rows; i++)
			gap = Math.min(gap, other.min[i] + this.cols - this.max[i] - 1);


		// Regular case, starting column for each tile.
		int leftStart = 0;
		int rightStart = this.cols + 1 - gap;
		int size = Math.max(Math.max(this.cols, this.cols+other.cols+1-gap), other.cols);

		// Right tile has "crossed over" left, so translate...
		if (rightStart < 0) {
			size = Math.max(other.cols,-rightStart + this.cols);
			leftStart -= rightStart;
			rightStart = 0;
		}

		// Copy answer into res.
		char[][] res = new char[rows][size];

		for (int i=0; i<rows; i++) {

			// Default, at first.
			Arrays.fill(res[i], '.');

			// Fill in everything we need to from left tile.
			for (int j=0, k=leftStart; j<this.cols; j++,k++)
				if (this.grid[i][j] != '.')
					res[i][k] = this.grid[i][j];

			// And from right tile.
			for (int j=0, k=rightStart; j<other.cols && k<size; j++,k++)
				if (other.grid[i][j] != '.')
					res[i][k] = other.grid[i][j];

		}

		// Get rid of blank columns on left and right.
		return new tile(res);
	}

	// String representation of a tile.
	public String toString() {
		String res = "";
		for (int i=0; i<rows; i++)
			res = res + (new String(grid[i])).substring(startPrint, endPrint+1) + "\n";
		res = res.replaceAll("0",".");
		return res;
	}
}