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 Go (1.14.1) (judge verdict: Wrong Answer)

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"sort"
	"strconv"
)

const mod = 998244353
const facNum = 300001

func main() {
	sc := newScanner(os.Stdin)
	N := sc.i()
	firstHarf := make([]Bar, 0, N)
	secondHarf := make([]Bar, 0, N)
	up := '('
	down := ')'
	for i := 0; i < N; i++ {
		s := sc.s()
		m := 0
		p := 0
		//b := 0
		for _, r := range s {
			if r == up {
				p += 1
			} else if r == down {
				p -= 1
				if p < m {
					m = p
				}
			}
		}
		if p == 0 && m == 0 {
			continue
		}
		if p >= 0 {
			b := Bar{-1 * m, p - m}
			firstHarf = append(firstHarf, b)
		} else {
			b := Bar{m, p - m}
			secondHarf = append(secondHarf, b)
		}
	}
	// sort
	sort.Slice(firstHarf, func(i, j int) bool {
		return firstHarf[i].A < firstHarf[j].A
	})
	sort.Slice(secondHarf, func(i, j int) bool {
		return secondHarf[i].B > secondHarf[j].B
	})
	total := 0
	for len(firstHarf) > 0 {
		bar := firstHarf[0]
		firstHarf = firstHarf[1:]
		total += bar.B + bar.A
		if total < 0 {
			fmt.Println("No")
			return
		}
	}
	for len(secondHarf) > 0 {
		bar := secondHarf[0]
		secondHarf = secondHarf[1:]
		total += bar.B + bar.A
		if total < 0 {
			fmt.Println("No")
			return
		}
	}
	if total != 0 {
		fmt.Println("No")
		return
	}
	fmt.Println("Yes")
}

type Bar struct {
	A int // -
	B int // +
}

// I/O
type scanner struct {
	sc *bufio.Scanner
}

func newScanner(input io.Reader) *scanner {
	sc := bufio.NewScanner(input)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &scanner{sc}
}

func (s *scanner) s() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *scanner) i() int {
	i, e := strconv.Atoi(s.s())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *scanner) f() float64 {
	f, e := strconv.ParseFloat(s.s(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *scanner) bs() []byte {
	return []byte(s.s())
}

func (s *scanner) is(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.i()
	}
	return res
}

func (s *scanner) fs(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.f()
	}
	return res
}

//const factorial = new
func Pow(a, n int) int {
	ans := 1
	for n > 0 {
		if (n & 1) == 1 {
			ans = ans * a % mod
		}
		a = a * a % mod
		n = n >> 1
	}
	return ans
}

func Gcd(a, b int) int {
	if a < b {
		return Gcd(b, a)
	}
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func combination(n, k int, fac, ifac []int) int {
	if n < k || n < 0 {
		return 0
	}
	if k == 0 {
		return 1
	}
	//while n != 0
	ans := ifac[k] * ifac[n-k] % mod
	return ans * fac[n] % mod
}

// 階乗: factorial
// コンビネーションを計算する際に前もって計算しておく
// fac[k] => k! (mod M)
// ifac[k] => k!^(M-2) (mod M)
// n: ex. 2 * 10^5 => 200001
// fac, ifac := factorial()
func factorial() (fac []int, ifac []int) {
	fac = make([]int, facNum)
	fac[0] = 1
	ifac = make([]int, facNum)
	ifac[0] = 1
	for i := 1; i < facNum; i++ {
		fac[i] = fac[i-1] * i % mod
		ifac[i] = ifac[i-1] * Pow(i, mod-2) % mod
	}
	return
}