One day, Yuhao came across a problem about checking if some bracket sequences are correct bracket sequences.

A bracket sequence is any non-empty sequence of opening and closing parentheses. A bracket sequence is called a correct bracket sequence if it's possible to obtain a correct arithmetic expression by inserting characters "+" and "1" into this sequence. For example, the sequences "(())()", "()" and "(()(()))" are correct, while the bracket sequences ")(", "(()" and "(()))(" are not correct.

Yuhao found this problem too simple for him so he decided to make the problem harder. You are given many (not necessarily correct) bracket sequences. The task is to connect some of them into ordered pairs so that each bracket sequence occurs in at most one pair and the concatenation of the bracket sequences in each pair is a correct bracket sequence. The goal is to create as many pairs as possible.

This problem unfortunately turned out to be too difficult for Yuhao. Can you help him and solve it?

Input

The first line contains one integer n (1 ≤ n ≤ 10^5) — the number of bracket sequences.

Each of the following n lines contains one bracket sequence — a non-empty string which consists only of characters "(" and ")".

The sum of lengths of all bracket sequences in the input is at most 5 ⋅ 10^5.

Note that a bracket sequence may appear in the input multiple times. In this case, you can use each copy of the sequence separately. Also note that the order in which strings appear in the input doesn't matter.

Output

Print a single integer — the maximum number of pairs which can be made, adhering to the conditions in the statement.

Examples

Input


7
)())
)
((
((
(
)
)


Output


2


Input


4
(
((
(((
(())


Output


0


Input


2
(())
()


Output


1

Note

In the first example, it's optimal to construct two pairs: "(( )())" and "( )".
/*
 * Remember a 7.0 student can know more than a 10.0 student.
 * Grades don't determine intelligence, they test obedience. 
 * I Never Give Up.
 */
import java.util.*;
import java.util.Map.Entry;
import java.io.*;
import java.text.*;

import static java.lang.System.out;
import static java.util.Arrays.*;
import static java.lang.Math.*;
public class ContestMain {
	private static Reader in=new Reader();
	private static StringBuilder ans=new StringBuilder();
	private static long MOD=1000000000+7;//10^9+7
	private static final int N=100000+7; //10^5+7
	private static final double EPS=1e-9;
//	private static final int LIM=26;
//	private static final double PI=3.1415;
//	private static ArrayList<Integer> v[]=new ArrayList[N];
//	private static int color[]=new int[N];
//	private static boolean mark[]=new boolean[N];
//	private static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//	private static void dfs(int node){mark[node]=true;for(int x:v[node]){if(!mark[x]){dfs(x);}}}
	private static long powmod(long x,long n){
		if(n==0||x==0)return 1;
		else if(n%2==0)return(powmod((x*x)%MOD,n/2));
		else return (x*(powmod((x*x)%MOD,(n-1)/2)))%MOD;
	}
//	private static void shuffle(long [] arr) {
//		for (int i = arr.length - 1; i >= 2; i--) {
//			int x = new Random().nextInt(i - 1);
//	        long temp = arr[x];
//	        arr[x] = arr[i];
//	        arr[i] = temp;
//	    }
//	 }
	private static long gcd(long a, long b){
		if(b==0)return a;
		return gcd(b,a%b);
	}
//	private static boolean check(int x,int y){
//		if((x>=0&&x<n)&&(y>=0&&y<m)&&mat[x][y]!='X'&&!visited[x][y])return true;
//		return false;
//	}
//	static class Node{
//		int x,y,c;
//		Node(int x,int y,int c){
//			this.x=x;
//			this.y=y;
//			this.c=c;
//		}
//	}
	public static void main(String[] args) throws IOException{
		int n=in.nextInt();
		String ar[]=new String[n];
		int c[][]=new int[2][500007];
		Stack<Character> st=new Stack();
		String temp;
		int cnt,res=0;
		int ext=0;
		for(int i=0;i<n;i++)
			ar[i]=in.next();
		int open,close;
		for(int i=0;i<n;i++){
			open=0;close=0;
			for(int j=0;j<ar[i].length();j++){
				if(st.size()==0)st.push(ar[i].charAt(j));
				else if(ar[i].charAt(j)==')'&&st.peek()=='(')st.pop();
				else st.push(ar[i].charAt(j));
			}
			while(!st.isEmpty()){
				if(st.peek()=='(')open++;
				else close++;
				st.pop();
			}
			if(open!=0&&close!=0)continue;
			else if(open==0&&close==0)ext++;
			else if(open!=0)c[0][open]+=1;
			else c[1][close]+=1;
		}
		res+=ext/2;
		for(int i=1;i<=500000;i++){
			res+=min(c[0][i],c[1][i]);
		}
		out.println(res);
	}
	static class Pair<T> implements Comparable<Pair>{
		int l;
		int r;
		int ind;
		Pair(){
			l=0;
			r=0;
		}
		Pair(int k,int v,int i){
			l=k;
			r=v;
			ind=i;
		}
		@Override
		public int compareTo(Pair o) {
			if(o.l!=l)return (int) (l-o.l);
			else return (r-o.r);
		}
		
	}
	static class Reader{
        BufferedReader br;
        StringTokenizer st;
        public Reader()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }
 
        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
     
                	st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int nextInt()
        {
            return Integer.parseInt(next());
        }
 
        long nextLong()
        {
            return Long.parseLong(next());
        }
 
        double nextDouble()
        {
            return Double.parseDouble(next());
        }
 
        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }
}