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.Collections.Generic;
using System.Linq;

namespace contest_Csharp
{
    class Program
    {
        static long power(long a, long b, long modulo)
        {
            long result = 1;
            long buff = a;
            for (long i = 1; i <= b; i *= 2)
            {
                result = result * ((b / i % (2) == 1) ? buff : 1) % modulo;
                buff = (buff * buff) % modulo;
            }
            return result % modulo;
        }
        static long binomal(long n, long r, long modulo)
        {
            long result = 1;
            for (long i = 0; i < r; i++)
            {
                result = (result * (n - i)) % modulo;
                result = (result * power(i+1, modulo - 1, modulo)) % modulo;
            }
            return result;
        }
        static void Main(string[] args)
        {
            var vals = Console.ReadLine().Split(' ')
               .Select(x => long.Parse(x)).ToList();
            var N = vals[0];
            PriorityQueue<(int, int)> up = new PriorityQueue<(int, int)>();
            PriorityQueue<(int, int)> down = new PriorityQueue<(int, int)>();
            for (int i = 0; i < N; i++)
            {
                var S = Console.ReadLine();
                int left = 0, right = 0;
                foreach (var item in S)
                {
                    if (item == ')')
                    {
                        if (right>0)
                        {
                            right--;
                        }
                        else
                        {
                            left++;
                        }
                    }
                    else if(item=='(')
                    {
                        right++;
                    }
                }
                if (right-left>0)
                {
                    up.Enqueue((left, right));
                }
                else
                {
                    down.Enqueue((right, left));
                }
            }
            //Console.WriteLine(ans);
            bool flg = (up.Count()==0||up.Peek().Item1 == 0) 
                && (down.Count() == 0 || down.Peek().Item1 == 0);
            int uright = 0,dleft=0;
            while (up.Count()!=0)
            {
                var v = up.Dequeue();
                flg = flg && (uright - v.Item1 >= 0);
                uright = uright - v.Item1 + v.Item2;
            }
            while (down.Count() != 0)
            {
                var v = down.Dequeue();
                flg = flg && (dleft - v.Item1 >= 0);
                dleft = dleft - v.Item1 + v.Item2;
            }
            flg = flg && (uright == dleft);
            Console.WriteLine(flg ? "Yes" : "No");
        }



    }
    class PriorityQueue<T> where T : IComparable<T>
    {
        private List<T> heap = new List<T>();
        private int lastindex = -1;
        private void swap(int n, int m)
        {
            T wait = heap[n];
            heap[n] = heap[m];
            heap[m] = wait;
        }
        public int Count()
        {
            return lastindex + 1;
        }
        public void Enqueue(T data)
        {
            int p;
            if (lastindex + 1 < heap.Count())
            {
                heap[lastindex + 1] = data;
            }
            else
            {
                heap.Add(data);
            }
            lastindex++;
            p = lastindex;

            while (true)
            {
                if (p > 0 && heap[p].CompareTo(heap[(p - 1) / 2]) <= -1)
                {
                    swap(p, (p - 1) / 2);
                    p = (p - 1) / 2;
                }
                else
                {
                    break;
                }
            }
        }
        public T Peek()
        {
            return heap[0];
        }
        public T Dequeue()
        {
            T result = Peek();
            heap[0] = default(T);
            swap(0, lastindex);
            lastindex--;
            int p = 0;
            while (true)
            {
                int np;
                if (2 * p + 1 > lastindex)
                {
                    break;
                }
                else
                {
                    np = ((2 * p + 1 == lastindex) || heap[2 * p + 1].CompareTo(heap[2 * p + 2]) <= -1)
                        ? (2 * p + 1) : (2 * p + 2);
                }
                if (heap[p].CompareTo(heap[np]) >= 1)
                {
                    swap(p, np);
                    p = np;
                }
                else
                {
                    break;
                }
            }

            return result;
        }





    }
}