Problem: This is yet another problem dealing with regular bracket sequences.

We should remind you that a bracket sequence is called regular, if by inserting «+» and «1» into it we can get a correct mathematical expression. For example, sequences «(())()», «()» and «(()(()))» are regular, while «)(», «(()» and «(()))(» are not. 

You are given a string of «(» and «)» characters. You are to find its longest substring that is a regular bracket sequence. You are to find the number of such substrings as well.

Input

The first line of the input file contains a non-empty string, consisting of «(» and «)» characters. Its length does not exceed 106.

Output

Print the length of the longest substring that is a regular bracket sequence, and the number of such substrings. If there are no such substrings, write the only line containing "0 1".

Examples

Input

)((())))(()())


Output

6 2


Input

))(


Output

0 1

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Scanner;
import java.util.TreeMap;

public class Solution{
	
	///////////////////////////////////////////////////////////////////////////
	static class FastScanner{
		BufferedReader s;
		StringTokenizer st;
		
		public FastScanner(){
			st = new StringTokenizer("");
			s = new BufferedReader(new InputStreamReader(System.in));
		}
		
		public FastScanner(File f) throws FileNotFoundException{
			st = new StringTokenizer("");
			s = new BufferedReader (new FileReader(f));
		}
		
		public int nextInt() throws IOException{
			if(st.hasMoreTokens())
				return Integer.parseInt(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextInt();
			}
		}
		
		public double nextDouble() throws IOException{
			if(st.hasMoreTokens())
				return Double.parseDouble(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextDouble();
			}
		}
		
		public long nextLong() throws IOException{
			if(st.hasMoreTokens())
				return Long.parseLong(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextLong();
			}
		}
		
		public String nextString() throws IOException{
			if(st.hasMoreTokens())
				return st.nextToken();
			else{
				st = new StringTokenizer(s.readLine());
				return nextString();
			}
			
		}
		public String readLine() throws IOException{
			return s.readLine();
		}
		
		public void close() throws IOException{
			s.close();
		}
		
	}
	
	////////////////////////////////////////////////////////////////////
	//		Number Theory
	
	public static int divisor(int x){
	    int limit = x;
	    int numberOfDivisors = 0;

	    for (int i=1; i < limit; ++i) {
	        if (x % i == 0) {
	            limit = x / i;
	            if (limit != i) {
	                numberOfDivisors++;
	            }
	            numberOfDivisors++;
	        }
	    }

	    return numberOfDivisors;
    }
	
	
	public static long gcd(long a, long b){
		return b == 0 ? a : gcd(b,a%b);
	}
	
  
	public static long lcm(long a,long b, long c){
		return lcm(lcm(a,b),c);
	}
	
	public static long lcm(long a, long b){
		return a*b/gcd(a,b);
	}
	
	
	////////////////////////////////////////////////////////////////////
	
	
//	  private static  	FastScanner s = new FastScanner(new File("input.txt"));
//	  private static PrintWriter ww = new PrintWriter(new FileWriter("output.txt"));
	  private static FastScanner s = new FastScanner();   
      private static PrintWriter ww = new PrintWriter(new OutputStreamWriter(System.out));
//    private static Scanner s = new Scanner(System.in);
      @SuppressWarnings("unused")
	private static Map<Integer,Integer> mm = new HashMap<Integer,Integer>();
      @SuppressWarnings("unused")
	private static Map<Integer,node> mn = new HashMap<Integer,node>();
	@SuppressWarnings("unused")
	private static int[][] states = { {-1,0} , {1,0} , {0,-1} , {0,1} };
	
      
    //////////////////////////////////////////////////////////////////// 
      
     static class node implements Comparable<node>{
      	int a;
      	int b;
      	public node(int x, int y){
      		this.a  = x;
      		this.b = y;
      	}
		@Override
		public int compareTo(node arg0) {
			// TODO Auto-generated method stub
			return Integer.compare(arg0.b, b);
		}
      }
     
    public static void main(String[] args) throws IOException{
 		Solution so = new Solution();
 		so.solve();
 	}
   
    
    ////////////////////////////////////////////////////////////////////
     
   
     void solve() throws IOException{
    	
    	char[] arr = s.nextString().toCharArray();
    	int len = arr.length;
    	int[] dp = new int[len];
    	Stack<Integer> st = new Stack<Integer>();
    	int ans = Integer.MIN_VALUE;
    	int count = 0;
    	
    	for(int i=0;i<len;i++){
    		
    		if(arr[i] == '(')
    			st.push(i);
    		else if(!st.isEmpty()){
    			
    			int pre_index = st.pop();
    			dp[i] = i - pre_index + 1;
    			if(dp[i] < i+1)
    				dp[i] += dp[i-dp[i]];
    			if(dp[i] > ans){
    				ans = dp[i];
    				count = 0;
    			}
    			if(ans == dp[i]) count++;
    		}
    		
    	}
    	
    	if(ans == Integer.MIN_VALUE) ww.print(0+" "+1);
    	else ww.print(ans+" "+count);
        s.close();
 	    ww.close(); 
    
     }
}