unittest
{
	assert( [ "4 4", "##.#", "....", "##.#", ".#.#" ].parse.expand.solve == "###\n###\n.##" );
	assert( [ "3 3", "#..", ".#.", "..#" ].parse.expand.solve == "#..\n.#.\n..#" );
	assert( [ "4 5", ".....", ".....", "..#..", "....." ].parse.expand.solve == "#" );
	assert( [ "7 6", "......", "....#.", ".#....", "..#...", "..#...", "......", ".#..#." ].parse.expand.solve == "..#\n#..\n.#.\n.#.\n#.#" );
}



import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto hw = input.front.split.to!( long[] );

	auto ass = new char[][ hw[ 0 ] ];
	foreach( ref as; ass )
	{
		input.popFront;
		as = input.front.strip.dup;
	}
	
	return tuple( hw[ 0 ], hw[ 1 ], ass );
}

auto solve( long h, long w, char[][] ass )
{
	auto hb = new bool[ h ];
	auto wb = new bool[ w ];
	
	// 黒がある行と列をマーキング
	foreach( y, as; ass )
	{
		foreach( x, a; as )
		{
			if( a == '#' )
			{
				hb[ y ] = true;
				wb[ x ] = true;
			}
		}
	}
	
	// 白のみの行を削除
	foreach_reverse( y; 0 .. h )
	{
		if( hb[ y ] ) continue;
		
		ass = ass[ 0 .. y ] ~ ass[ y + 1 .. $ ];
	}
	
	// 白のみの列を削除
	foreach_reverse( x; 0 .. w )
	{
		if( wb[ x ] ) continue;
		
		foreach( ref as; ass )
		{
			as = as[ 0 .. x ] ~ as[ x + 1 .. $ ];
		}
	}
	
	return ass.join( "\n" );
}
