Problem:
Score : 600 points

Problem Statement

A bracket sequence is a string that is one of the following:

An empty string;

The concatenation of (, A, and ) in this order, for some bracket sequence A ;

The concatenation of A and B in this order, for some non-empty bracket sequences A and B /

Given are N strings S_i. Can a bracket sequence be formed by concatenating all the N strings in some order?

Constraints

1 \leq N \leq 10^6

The total length of the strings S_i is at most 10^6.

S_i is a non-empty string consisting of ( and ).

Input

Input is given from Standard Input in the following format:

N
S_1
:
S_N

Output

If a bracket sequence can be formed by concatenating all the N strings in some order, print Yes; otherwise, print No.

Sample Input 1

2
)
(()

Sample Output 1

Yes

Concatenating (() and ) in this order forms a bracket sequence.

Sample Input 2

2
)(
()

Sample Output 2

No

Sample Input 3

4
((()))
((((((
))))))
()()()

Sample Output 3

Yes

Sample Input 4

3
(((
)
)

Sample Output 4

No

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder.Contest.F
{
	class Program
	{
		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);

			Scanner cin = new Scanner();

			int n = cin.nextInt();
			string[] s = new string[n];
			for (int i = 0; i < n; i++)
			{
				s[i] = cin.next();
			}

			var aaa = new List<lr>();
			for (int i = 0; i < n; i++)
			{
				aaa.Add(new lr(0, 0));
			}
			int[] a = new int[n];
			int[] b = new int[n];


			int azero = 0;
			int bzero = 0;
			int doublezero = 0;

			for (int i = 0; i < n; i++)
			{
				int left = 0;
				int right = 0;
				for (int j = 0; j < s[i].Length; j++)
				{
					if (s[i][j] == ')') left++;
					else break;
				}
				for (int j = s[i].Length - 1; j >= 0; j--)
				{
					if (s[i][j] == '(') right++;
					else break;
				}

				// # of '(' in the middle
				int num1 = s[i].Replace(')'.ToString(), "").Length - right;
				int num2 = s[i].Replace('('.ToString(), "").Length - left;
				if (num1 > num2) right += (num1 - num2);
				else if (num1 == num2) { }
				else left += (num2 - num1);

				aaa[i].a = left;
				aaa[i].b = right;


				if (right == 0) azero++;
				if (left == 0) bzero++;
				if (right == 0 && left == 0) doublezero++;

			}

			var bbb = new List<lr>();
			var ddd = new List<lr>();
			var ccc = new List<lr>();

			for (int i = 0; i < n; i++)
			{
				if (aaa[i].b - aaa[i].a > 0) bbb.Add(aaa[i]);
				else if (aaa[i].b == aaa[i].a) ddd.Add(aaa[i]);
				else ccc.Add(aaa[i]);
			}

			bbb.Sort(lr.Compare);
			ccc.Sort(lr.Compare2);
			/*for (int i = ccc.Count - 1; i >= 0; i--)
			{
				if (ccc[i].b == 0)
				{
					var x = ccc[i];
					ccc[i] = ccc[ccc.Count - 1];
					ccc[ccc.Count - 1] = x;
				}
			}*/

			int high = 0;
			int bottom = 0;
			int now = 0;
			for (int i = 0; i < bbb.Count; i++)
			{
				now -= bbb[i].a;
				if (bottom > now) bottom = now;
				now += bbb[i].b;
				if (high < now) high = now;
			}
			for (int i = 0; i < ddd.Count; i++)
			{
				now -= ddd[i].a;
				if (bottom > now) bottom = now;
				now += ddd[i].b;
				if (high < now) high = now;
			}
			for (int i = 0; i < ccc.Count; i++)
			{
				now -= ccc[i].a;
				if (bottom > now) bottom = now;
				now += ccc[i].b;
				if (high < now) high = now;
			}
			bool sad = (doublezero == 1 && azero == 1 && bzero == 1);

			int asum = 0;
			int bsum = 0;
			for (int i = 0; i < n; i++)
			{
				asum += aaa[i].a;
				bsum += aaa[i].b;
			}

			//if (azero >= 1 && bzero >= 1 && (asum == bsum) && !sad) Console.WriteLine("Yes");
			if (now == 0 && bottom == 0) Console.WriteLine("Yes");
			else Console.WriteLine("No");

			Console.Out.Flush();
		}
	}

	class lr
	{
		public int a { get; set; }
		public int b { get; set; }
		public lr(int a, int b) { this.a = a; this.b = b; }

		public static int Compare(lr x, lr y)
		{
			if (x.a > y.a) return 1;
			else if (x.a < y.a) return -1;
			else if (x.b > y.b) return -1;
			else if (x.b < y.b) return 1;
			else return 0;
		}
		public static int Compare2(lr x, lr y)
		{
			if (x.b < y.b) return 1;
			else if (x.b > y.b) return -1;
			else if (x.a < y.a) return -1;
			else if (x.a > y.a) return 1;
			else return 0;
		}
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] cs = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string next()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return next();
			i = 0;
			return s[i++];
		}

		public int nextInt()
		{
			return int.Parse(next());
		}

		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextInt() + add;
			}
			return Array;
		}

		public long nextLong()
		{
			return long.Parse(next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextLong() + add;
			}
			return Array;
		}

		public double nextDouble()
		{
			return double.Parse(next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = nextDouble() + add;
			}
			return Array;
		}
	}
}