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++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}
 
template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const ll INF = 1e18;
const ll MOD = 998244353;
const ll MX = 1000001;

ll N;

struct Comp1 {
	bool operator()(const l_l &a, const l_l &b) {
		if (a.first != b.first) {
			return a.first < b.first;
		}
		return a.second > b.second;
	}
};

struct Comp2 {
	bool operator()(const l_l &a, const l_l &b) {
		if (a.first != b.first) {
			return a.first > b.first;
		}
		return a.second > b.second;
	}
};

void solve() {
    cin >> N;
    vector<string> a(N);
    vector<l_l> adds, subs;
    
	int tlc = 0, trc = 0;

    for (int i = 0; i < N; i++) {
		int lc = 0, rc = 0;
		cin >> a[i];
		for (auto& c : a[i]) {
			if (c == '(') {
				lc++;
			} else {
				if (lc) lc--;
				else rc++;
			}
		}
		if (lc && !rc) tlc += lc;
		else if (!lc && rc) trc += rc;
		else if (lc && rc) {
			if (lc >= rc) adds.push_back({rc, lc});
			else subs.push_back({rc, lc});
		}
	}
    sort(adds.begin(), adds.end(), Comp1());
    sort(subs.begin(), subs.end(), Comp2());
    
    bool pos = true;
    for (auto& i : adds) {
		if (i.first > tlc) {
			pos = false;
			break;
		} else {
			tlc -= i.first;
			tlc += i.second;
		}
	}
	
	for (auto& i : subs) {
		if (i.first > tlc) {
			pos = false;
			break;
		} else {
			tlc -= i.first;
			tlc += i.second;
		}
	}
    
    if (pos && tlc == trc) cout << "Yes";
    else cout << "No";
}

int main() {
	cin.sync_with_stdio(0); cin.tie(0);
    ll T = 1; // cin >> T;
    while (T--) solve();
    return 0;
    // You should actually read the stuff at the bottom
}

/* Stuff to Look For
 * -----------------
 * Int overflow, array bounds
 * Initializing all variables, avoid weird behavior
 * Edge cases(n = 0, n = 1)
 * Just return 0 after result
 */