unittest
{
	assert( [ "2", ")", "(()" ].parse.expand.solve == "Yes" );
	assert( [ "2", ")(", "()" ].parse.expand.solve == "No" );
	assert( [ "4", "((()))", "((((((", "))))))", "()()()" ].parse.expand.solve == "Yes" );
	assert( [ "3", "(((", ")", ")" ].parse.expand.solve == "No" );
	
	assert( [ "4", "((", "))((((((", "))))))((", "))" ].parse.expand.solve == "Yes" );		// 追加ケース
	assert( [ "4", "((", "))((((((", ")))))", "))(" ].parse.expand.solve == "Yes" );		// 追加ケース
}



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

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

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = input.front.to!( long );
	auto ss = new dchar[][ n ];
	foreach( ref s; ss )
	{
		input.popFront;
		s = input.front.to!( dchar[] );
	}
	return tuple( ss );
}

auto solve( dchar[][] ss )
{
	// 括弧の群れを前提条件と変化量に変換
	Tuple!( long, long )[] ls;
	Tuple!( long, long )[] rs;
	foreach( s; ss )
	{
		auto m = 0L;
		auto d = 0L;
		
		// 左括弧と右括弧のどちらが多いかで分類
		if( s.length <= s.count( '(' ) * 2 )
		{
			foreach( c; s )
			{
				if( c == '(' )
				{
					d++;
				}
				else
				{
					d--;
					m = min( m, d );
				}
			}
			ls ~= tuple( -m, d );
		}
		else
		{
			foreach_reverse( c; s )
			{
				if( c == ')' )
				{
					d++;
				}
				else
				{
					d--;
					m = min( m, d );
				}
			}
			rs ~= tuple( -m, d );
		}
	}
	
	// 左括弧のやつ同士で前提条件が緩いやつから順番にくっつける
	auto lt = 0L;
	foreach( l; ls.sort() )
	{
		if( lt < l[ 0 ] ) return "No";
		lt += l[ 1 ];
	}
	
	// 右括弧のやつ同士で前提条件が緩いやつから順番にくっつける
	auto rt = 0L;
	foreach( r; rs.sort() )
	{
		if( rt < r[ 0 ] ) return "No";
		rt += r[ 1 ];
	}
	
	// 左括弧と右括弧をくっつけて対応が取れているか判定
	return ( lt == rt ) ? "Yes" : "No";
}
