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 Java (OpenJDK 11.0.6) (judge verdict: Wrong Answer)


import java.util.*;
import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main {
	int N;
	List<String> S;

	public static void main(String[] args) throws IOException {
		InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
		BufferedReader in = new BufferedReader(reader);
		Main ins = new Main(in);
		ins.calc();
		ins.showResult();
	}

	static int[] count(String s) {
		int[] result = new int[2];
		result[0] = 0;
		result[1] = 0;
		for (int i = 0; i < s.length(); ++i) {
			if (s.charAt(i) == '(') {
				result[0]++;
			} else {
				result[1]++;
			}
		}
		return result;
	}

	Main(BufferedReader in) throws IOException {
		N = Integer.parseInt(in.readLine());
		S = new ArrayList<>(N);
		for (int i = 0; i < N; ++i) {
			S.add(in.readLine());
		}
		Collections.sort(S, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				if (isPositive(o1) && isPositive(o2)) {
					int[] ro1 = count(o1);
					int[] ro2 = count(o2);
					return -1 * Integer.compare(ro1[0] - ro1[1], ro2[0] - ro2[1]);
				} else if (isPositive(o1)) {
					return -1;
				} else if (isPositive(o2)) {
					return 1;
				} else {
					int[] ro1 = count(o1);
					int[] ro2 = count(o2);
					return -1 * Integer.compare(ro1[0] - ro1[1], ro2[0] - ro2[1]);
				}
			}
		});
	}

	static boolean isPositive(String s) {
		int count = 0;
		for (int i = 0; i < s.length(); ++i) {
			if (s.charAt(i) == '(') {
				++count;
			} else {
				--count;
			}
			if (count < 0) {
				return false;
			}
		}
		return true;
	}

	int eval(String s, int score) {
		int val = score;
		for (int i = 0; i < s.length(); ++i) {
			if (s.charAt(i) == '(') {
				++val;
			} else {
				--val;
			}
			if (val < 0) {
				return -1;
			}
		}
		return val;
	}

	void calc() {
		int score = 0;
		for (int i = 0; i < S.size(); ++i) {
			score = eval(S.get(i), score);
			if (score < 0) {
				break;
			}
		}
		if (score == 0) {
			System.out.println("Yes");
		} else {
			System.out.println("No");
		}
	}

	void showResult() {
	}

}