The ancient Berlanders believed that the longer the name, the more important its bearer is. Thus, Berland kings were famous for their long names. But long names are somewhat inconvenient, so the Berlanders started to abbreviate the names of their kings. They called every king by the first letters of its name. Thus, the king, whose name was Victorious Vasily Pupkin, was always called by the berlanders VVP.

In Berland over its long history many dynasties of kings replaced each other, but they were all united by common traditions. Thus, according to one Berland traditions, to maintain stability in the country, the first name of the heir should be the same as the last name his predecessor (hence, the first letter of the abbreviated name of the heir coincides with the last letter of the abbreviated name of the predecessor). Berlanders appreciate stability, so this tradition has never been broken. Also Berlanders like perfection, so another tradition requires that the first name of the first king in the dynasty coincides with the last name of the last king in this dynasty (hence, the first letter of the abbreviated name of the first king coincides with the last letter of the abbreviated name of the last king). This tradition, of course, has also been always observed.

The name of a dynasty is formed by very simple rules: we take all the short names of the kings in the order in which they ruled, and write them in one line. Thus, a dynasty of kings "ab" and "ba" is called "abba", and the dynasty, which had only the king "abca", is called "abca".

Vasya, a historian, has recently found a list of abbreviated names of all Berland kings and their relatives. Help Vasya to find the maximally long name of the dynasty that could have existed in Berland.

Note that in his list all the names are ordered by the time, that is, if name A is earlier in the list than B, then if A and B were kings, then king A ruled before king B.

Input

The first line contains integer n (1 ≤ n ≤ 5·105) — the number of names in Vasya's list. Next n lines contain n abbreviated names, one per line. An abbreviated name is a non-empty sequence of lowercase Latin letters. Its length does not exceed 10 characters.

Output

Print a single number — length of the sought dynasty's name in letters.

If Vasya's list is wrong and no dynasty can be found there, print a single number 0.

Examples

Input

3
abc
ca
cba


Output

6


Input

4
vvp
vvp
dam
vvp


Output

0


Input

3
ab
c
def


Output

1

Note

In the first sample two dynasties can exist: the one called "abcca" (with the first and second kings) and the one called "abccba" (with the first and third kings). 

In the second sample there aren't acceptable dynasties.

The only dynasty in the third sample consists of one king, his name is "c".
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.ObjectInputStream.GetField;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.io.BufferedReader;

 
 
			public class Q2 {
				
				static long MOD = 1000000007;
				static boolean b1,b[],bc[];
				static boolean boo[][][];
				static int ans1 = -1,ans2 = -1, root, BLOCK = 350;
				static ArrayList<Integer>[] amp,amp1;
				static ArrayList<Pair>[] pmp;
				static int sum[],cnt[],ans[],size[],col[][],left[], right[];
				static int p = 0,cnt1 =0 ,cnt2 = 0;
				//static ArrayList<Pair3>[][][] pmp;
				static FasterScanner sc = new FasterScanner(System.in);
				static Queue<Integer> q = new LinkedList<>();
				static int arr[],start[],end[],color[],parent[];
				static PriorityQueue<Pair> pq;
				//static ArrayList<Integer> parent = new ArrayList<>();
				static LinkedList<Integer> fa;
				static BufferedWriter log;
				static TreeMap<Integer,Integer> tm = new TreeMap<>();
			//	static HashMap<Integer,Pair> hs;
				static Stack<Integer> stack = new Stack<>();
				static Pair prr[];
				static int dp[][];
				static int parent1[],parent2[],size1[],size2[],value[];
				static long Ans,dist[];
				public static void main(String[] args) throws Exception {
					/*new Thread(null, new Runnable() {
						public void run() {
							try {
								soln();
							} catch (Exception e) {
								System.out.println(e);
							}
						}
					}, "1", 1<<27).start();*/
					soln();
			    }
				static int MAX = 10000001;
				static int N , m ,K, max, x1, x2;
				static HashSet<Pair> hs;
				static long DP[];
				static ArrayList<Integer> amp2 = new ArrayList<>();
				static int c1, c2, two[];
				
				public static void soln() throws IOException {
					//FasterScanner in = new FasterScanner(new FileInputStream("C:\\Users\\Admin\\Desktop\\QCL.txt"));
					//PrintWriter out = new PrintWriter("C:\\Users\\Admin\\Desktop\\A1.txt");
					log = new BufferedWriter(new OutputStreamWriter(System.out));
					int n = sc.nextInt();
					int ch[][] = new int[n+1][3];
					for(int i = 0; i< n ;i++){
						String str = sc.nextLine();
						ch[i+1][0] = str.charAt(0)-'a';
						ch[i+1][1] = str.charAt(str.length()-1)-'a';
						ch[i+1][2] = str.length();
					}
					int dp[][] = new int[26][26];
					boolean b[][] = new boolean[26][26];
					for(int i = 1 ;i <= n ;i++){
						int x = ch[i][0], y = ch[i][1];
						for(int j = 0; j< 26;j++){
							if(dp[j][x]>0){
								dp[j][y]=Math.max(dp[j][x]+ch[i][2],dp[j][y]);
								if(y==j) b[j][y] = true;
							}
						}
						dp[x][y] = Math.max(dp[x][y], ch[i][2]);
						if(x==y) b[x][y] = true;
					}
					int ans = 0;
					for(int i = 0; i< 26;i++){
						for(int j = 0; j< 26;j++){
							if(b[i][j])
							ans = Math.max(dp[i][j], ans);
						}
					}
					System.out.println(ans);
					//out.close();
					log.close();
				}
				public static void djistkra(){
					while(!pq.isEmpty()){
						Pair y = pq.poll();
						//System.out.println(y);
						long u = y.u;
						int v = y.v;
						if(b[v]) continue;
						b[v] = true;
						for(Pair p : pmp[v]){
							if(dist[(int) p.u]>(u+p.v)){
								dist[(int) p.u] = u+p.v;
								//pq.add(new Pair(dist[(int) p.u],(int)p.u));
							}
						}
					}
				}
				
				public static void buildWeightedGraph(int m){
					for(int i = 0; i< m; i++){
						int x = sc.nextInt()-1, y = sc.nextInt() -1, z = sc.nextInt();
						//pmp[x].add(new Pair(y,z));
						//pmp[y].add(new Pair(x,z));
					}
				}
				public static class FenwickTree {

				    int[] array; // 1-indexed array, In this array We save cumulative information to perform efficient range queries and updates

				    public FenwickTree(int size) {
				        array = new int[size + 1];
				    }

				    /**
				     * Range Sum query from 1 to ind
				     * ind is 1-indexed
				     * <p>
				     * Time-Complexity:    O(log(n))
				     *
				     * @param  ind index
				     * @return sum
				     */
				    public int rsq(int ind) {
				        assert ind > 0;
				        int sum = 0;
				        while (ind > 0) {
				            sum += array[ind];
				            //Extracting the portion up to the first significant one of the binary representation of 'ind' and decrementing ind by that number
				            ind -= ind & (-ind);
				        }

				        return sum;
				    }

				    /**
				     * Range Sum Query from a to b.
				     * Search for the sum from array index from a to b
				     * a and b are 1-indexed
				     * <p>
				     * Time-Complexity:    O(log(n))
				     *
				     * @param  a left index
				     * @param  b right index
				     * @return sum
				     */
				    public int rsq(int a, int b) {
				        assert b >= a && a > 0 && b > 0;

				        return rsq(b) - rsq(a - 1);
				    }

				    /**
				     * Update the array at ind and all the affected regions above ind.
				     * ind is 1-indexed
				     * <p>
				     * Time-Complexity:    O(log(n))
				     *
				     * @param  ind   index
				     * @param  value value
				     */
				    public void update(int ind, int value) {
				        assert ind > 0;
				        while (ind < array.length) {
				            array[ind] += value;
				            //Extracting the portion up to the first significant one of the binary representation of 'ind' and incrementing ind by that number
				            ind += ind & (-ind);
				        }
				    }

				    public int size() {
				        return array.length - 1;
				    }
				}
				static int dfs(int x, int cnt){
					b[x] = true;
					for(int i : amp[x]){
						if(!b[i]){
							cnt= Math.max(dfs(i,0), cnt);
						}
					}
					cnt++;
					return cnt;
				}
				public static void bfs(int x){
					b[x] = true;
					q = new LinkedList<Integer>();
					q.add(x);
					while(!q.isEmpty()){
						int y = q.poll();
						for(int i:amp[y]){
							if(!b[i]){
								parent[i] = y;
								q.add(i);
								b[i] = true;
								dist[i] = dist[y]+1;
							}
						}
					}
				}
				static int countBytes(int x){
					int cnt = 0;
					for(int i = 0;i<20;i++){
						if((two[i]&x)!=0) cnt++;
					}
					//System.out.println(cnt);
					return cnt;
				}
				 static long maxSubArraySum(long a[])
				    {
				        int size = a.length;
				        long max_so_far = Long.MIN_VALUE/2, max_ending_here = 0;
 
				        for (int i = 0; i < size; i++)
				        {
				            max_ending_here = max_ending_here + a[i];
				            if(max_so_far < max_ending_here)
				                max_so_far = max_ending_here;
				            if(max_ending_here < 0)
				                max_ending_here = 0;
				        }
				        return max_so_far;
				    }
				public class TrieNode{
					TrieNode[] t = new TrieNode[2];
					int cnt = 0;
				}
				public class Trie{
					TrieNode root;
					Trie(){
						root = new TrieNode();
					}
					public void insert(String s){
						TrieNode temp = root;
						for(int i = 0; i< s.length();i++){
							if(temp.t[s.charAt(i)-'0']==null){
								TrieNode n = new TrieNode();
								temp.t[s.charAt(i)-'0'] = n;
							}
							temp = temp.t[s.charAt(i)-'0'];
						}
						temp.cnt++;
					}
					public void delete(String s, TrieNode temp){
						
					}
					public String get(String s){
						StringBuilder sb = new StringBuilder();
						TrieNode temp = root;
						for(int i = 0; i< s.length();i++){
							int x = (s.charAt(i)-'0'+1)%2;
							if(temp.t[x]!=null){
								temp = temp.t[x];
								sb.append(1);
							}
							else{
								temp = temp.t[(x+1)%2];
								sb.append(0);
							}
						}
						return sb.toString();
					}
				}
				
				static class Pair implements Comparable<Pair> {
					int u;
					int v;
					int k;
					int i;
					public Pair(){
						u = 0;
						v = 0;
					}
					public Pair(int u, int v, int k, int i) {
						this.u = u;
						this.v = v;
						this.k = k;
						this.i = i;
					}
					public int hashCode() {
						int hu = (int) (u ^ (u >>> 32));
						int hv = (int) (v ^ (v >>> 32));
						return 31*hu + hv;
					}
			 
					public boolean equals(Object o) {
						Pair other = (Pair) o;
						return (u == other.u && v == other.v);
					}
			 
					/*public int compareTo(Pair other) {
						return Long.compare(u, other.u);// != 0 ? (Long.compare(u, other.u)) : (Long.compare(v, other.v));
					}*/
					public int compareTo(Pair other) {
						return Integer.compare(u/BLOCK, other.u/BLOCK)!=0?Integer.compare(u/BLOCK, other.u/BLOCK):Integer.compare(v, other.v);
					}
					public String toString() {
						return "[u=" + u + ", v=" + v + "]";
					}
				}
				
				public static long gcd(long gc, long m){
					if(m!=0) return gcd(m,gc%m);
					else return gc;
				}
				
				static int CeilIndex(int A[], int l, int r, int key)
			    {
			        while (r - l > 1)
			        {
			            int m = l + (r - l)/2;
			            if (A[m]>=key)
			                r = m;
			            else
			                l = m;
			        }
			 
			        return r;
			    }
			/*	public static Pair recur(int N, int K, int C){
					if(K>k) return new Pair(Long.MAX_VALUE/2,-1);
					if(N>=n && k<K) return new Pair(Long.MAX_VALUE/2,-1);
					if(N>=n && k==K) return new Pair(0,k);
					if(N>=n) return new Pair(0,0);
					if(dp[N][C][K]!=null){
						//System.out.println(dp[N][C][K]);
						return dp[N][C][K];
					} 
					Pair ans = new Pair(Long.MAX_VALUE/2,-1);
					if(arr[N]>0){
						Pair p;
						if(arr[N]==C) p = recur(N+1,K,arr[N]);
						else p = recur(N+1,K+1,arr[N]);
						if((p.u)<ans.u){
							ans = p;
						}
						if(p.u==ans.u){
							if(p.v>ans.v){
								ans = p;
							}
						}
					}
					else{
					for(int i = 1 ;i <= m; i++){
						Pair p;
						if(i==C)
						p = recur(N+1,K,i);
						else p = recur(N+1,K+1,i);
						p.u+=col[N][i-1];
						if((p.u)<ans.u){
							ans = p;
						}
						if(p.u==ans.u){
							if(p.v>ans.v){
								ans = p;
							}
						}
					}
					//System.out.println(ans);
					}
					return dp[N][C][K] = ans;
				}*/
				public static void mergeSort(int[] arr2, int l ,int r){
					if((r-l)>=1){
						int mid = (l+r)/2;
						mergeSort(arr2,l,mid);
						mergeSort(arr2,mid+1,r);
						merge(arr2,l,r,mid);
						//System.out.println(Ans);
					}
				}
				public static void merge(int arr[], int l, int r, int mid){
					int n1 = (mid-l+1), n2 = (r-mid);
					int left[] = new int[n1];
					int right[] = new int[n2];
					for(int i =0 ;i<n1;i++) left[i] = arr[l+i];
					for(int i =0 ;i<n2;i++) right[i] = arr[mid+1+i];
					int i =0, j =0, k = l;
					while(i<n1 && j<n2){
						if(left[i]>right[j]){
							cnt[right[j]]+=(n1-i);
							arr[k++] = right[j++];
						}
						else{
							arr[k++] = left[i++];
						}
					}
					while(i<n1) arr[k++] = left[i++];
					while(j<n2) arr[k++] = right[j++];
				}
				public static void buildGraph(int n){
					for(int i =0;i<n;i++){
						int x = sc.nextInt()-1, y = sc.nextInt()-1;
						amp[x].add(y);
						amp[y].add(x);
					}
				}
				
				
 
				public static int getParent(int x){
					while(parent[x]!=x){
						parent[x] = parent[ parent[x]];
						x = parent[ x];
					}
					return x;
				}
				
				static int min(int a, int b, int c){
					if(a<b && a<c) return a;
					if(b<c) return b;
					return c;
				}
				private static void permutation(String prefix, String str) {
				    int n = str.length();
				    if (n == 0){
				    	amp2.add(Integer.parseInt(prefix));
				    }
				    else {
				        for (int i = 0; i < n; i++)
				            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
				    }
				}
				static class Graph{
					int vertex;
					long weight;
				}
				public static void buildTree(int n){
					int arr[] = sc.nextIntArray(n);
					for(int i = 0;i<n;i++){
						int x = arr[i]-1;
						amp[i+1].add(x);
						amp[x].add(i+1);
					}
				}
				static class Node{
					long max = 0, pre = 0, suf = 0, sum = 0;
					Node(long max, long pre, long suf, long sum){
						this.max = max;
						this.pre = pre;
						this.suf = suf;
						this.sum = sum;
					}
					Node(){};
				}
				static class SegmentTree {
					ArrayList<Integer> st[];
				//	long lazy[];
					SegmentTree(int n) {
						int size = 4 * n;
						st = (ArrayList<Integer>[])new ArrayList[size];
						for(int i = 0; i< size;i++) st[i] = new ArrayList<>();
					//	lazy = new long[size];
						build(0, n - 1, 1);
					}
					ArrayList<Integer> merge(ArrayList<Integer> l,  ArrayList<Integer> r){
						ArrayList<Integer> ans = new ArrayList<>();
						int i = 0, j = 0;
						while(i<l.size() && j<r.size()){
							if(l.get(i)<r.get(j)){
								ans.add(l.get(i));
								i++;
							}
							else{
								ans.add(r.get(j));
								j++;
							}
						}
						while(i<l.size()){
							ans.add(l.get(i++));
						}
						while(j<r.size()){
							ans.add(r.get(j++));
						}
						return ans;
					}
					ArrayList<Integer> build(int ss, int se, int si) {
						if(ss==se){
							st[si].add(arr[ss]);
							return st[si];
						}
						int mid = (ss+se)/2;
						ArrayList<Integer> a1 = build(ss, mid, si*2), a2 = build(mid+1, se, si*2+1);
						return st[si] = merge(a1,a2);
					}
 /*
					void update(int si, int ss, int se, int idx, int val) {
						if (ss == se) {
							arr[ss] = val;
							st[si] = new Node(arr[ss],arr[ss],arr[ss],arr[ss]);
						} 
						else {
							int mid = (ss + se) / 2;
							if(ss <= idx && idx <= mid)
					        {
					             update(2*si, ss, mid, idx, val);
					        }
					        else
					        { update(2*si+1, mid+1, se, idx, val);
					        }
							st[si] = comb(st[si*2],st[si*2+1]);
						}
					}*/
					void get(int qs, int qe, int ss, int se, int si, int k){
						if(qs>se || qe<ss){
							return ;
						}
						if (qs <= ss && qe >= se) {
							int x = Collections.binarySearch(st[si], k);
							if(x<0) x = -x-1;
							p+=(st[si].size()-x);
							return ;
						}
						int mid = (ss+se)/2;
						get(qs, qe, ss, mid, si * 2, k);get(qs, qe, mid + 1, se, si * 2 + 1, k);
						return ;
					}
					/*void updateRange(int node, int start, int end, int l, int r, long val)
					{
					    if(lazy[node] != 0)
					    { 
					        // This node needs to be updated
					        st[node] += (end - start + 1) * lazy[node];    // Update it
					        if(start != end)
					        {
					            lazy[node*2] += lazy[node];                  // Mark child as lazy
					            lazy[node*2+1] += lazy[node];                // Mark child as lazy
					        }
					        lazy[node] = 0;                                  // Reset it
					    }
					    if(start > end || start > r || end < l)              // Current segment is not within range [l, r]
					        return;
					    if(start >= l && end <= r)
					    {
					        // Segment is fully within range
					        st[node] += (end - start + 1) * val;
					        if(start != end)
					        {
					            // Not leaf node
					            lazy[node*2] += val;
					            lazy[node*2+1] += val;
					        }
					        return;
					    }
					    int mid = (start + end) / 2;
					    updateRange(node*2, start, mid, l, r, val);        // Updating left child
					    updateRange(node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
					    st[node] = st[node*2] + st[node*2+1];        // Updating root with max value 
					}
 
					long queryRange(int node, int start, int end, int l, int r)
					{
					    if(start > end || start > r || end < l)
					        return 0L;         // Out of range
					    if(lazy[node] != 0)
					    {
					        // This node needs to be updated
					        st[node] += (end - start + 1) * lazy[node];            // Update it
					        if(start != end)
					        {
					            lazy[node*2] += lazy[node];         // Mark child as lazy
					            lazy[node*2+1] += lazy[node];    // Mark child as lazy
					        }
					        lazy[node] = 0L;                 // Reset it
					    }
					    if(start >= l && end <= r)             // Current segment is totally within range [l, r]
					        return  st[node];
					    int mid = (start + end) / 2;
					    long p1 = queryRange(node*2, start, mid, l, r);         // Query left child
					    long p2 = queryRange(node*2 + 1, mid + 1, end, l, r); // Query right child
					    return (p1 + p2);
					}*/
					void print() {
						for (int i = 0; i < st.length; i++) {
							//System.out.print(st[i].u+" "+st[i].v+" "+st[i].z+"\n");
						}
						System.out.println();
					}
				}
				
				static class Tree {
					ArrayList<Integer>[] g ;
					int T[]; // parent
					int L[]; // level
					int P[][]; // P[i][j] = 2^j th parent of i
 
					public Tree(int n) {
						T = new int[n];
						L = new int[n];
						P = new int[n][log2(n) + 1];
						g = (ArrayList<Integer>[])new ArrayList[n];
						L[0] = 0;
						T[0] = -1;
						for (int i = 0; i < n; i++) {
							g[i] = new ArrayList<>();
						}
						for (int i = 0; i < n ; i++) {
							int a = sc.nextInt();
							for(int j = 0; j<a; j++){
								int b = sc.nextInt()-1;
								g[i].add(b);
								g[b].add(i);
							}
						}
						dfs(0, -1);
						for (int j = 0; (1 << j) <= n; j++)
							pre(0, j,-1);
					}
 
					public int log2(int n) {
						return (int) (Math.log10(n) / Math.log10(2));
					}
 
					public void dfs(int node, int p) {
						for (int k : g[node]) {
							if (k != p) {
								T[k] = node;
								L[k] = L[node] + 1;
								dfs(k, node);
							}
						}
					}
					public void pre(int node, int j,int p) {
						if (j == 0) {
							P[node][j] = T[node];
						} else {
							P[node][j] = P[P[node][j - 1]][j - 1];
						}
						for (int k : g[node]) {
							if(k!=p)
								pre(k, j,node);
						}
					}
					public int lca(int u, int v) {
						if (L[u] > L[v]) {
							int temp = u;
							u = v;
							v = temp;
						}
						int log;
						for (log = 0; (1 << log) <= L[v]; log++)
							; // convert level into log
						log--;
 
						for (int i = log; i >= 0; i--) {
							if ((1 << i) <= L[v] - L[u]) // make both node's level same
								v = P[v][i];
						}
						if (u == v)
							return u;
						for (int i = log; i >= 0; i--) {
							if (P[u][i] != -1 && P[u][i] != P[v][i]) // shift up both u and v
							{
								u = P[u][i];
								v = P[v][i];
							}
						}
						return T[u];
					}
				}
				public static long max(long x, long y, long z){
					if(x>=y && x>=z) return x;
					if(y>=x && y>=z) return y;
					return z;
				}
				
				public static void seive(long n){
					b = new boolean[(int) (n+1)];
					Arrays.fill(b, true);
					for(int i = 2;i*i<=n;i++){
						if(b[i]){
							for(int p = 2*i;p<=n;p+=i){
								b[p] = false;
							}
						}
					}
				}
				static long modInverse(long a, long mOD2){
				            return  power(a, mOD2-2, mOD2);
				}
				static long power(long x, long y, long m)
				{
				    if (y == 0)
				        return 1;
				    long p = power(x, y/2, m) % m;
				    p = (p * p) % m;
				 
				    return (y%2 == 0)? p : (x * p) % m;
				}
				static long d,x,y;
				public static void extendedEuclidian(long a, long b){
					if(b == 0) {
				        d = a;
				        x = 1;
				        y = 0;
				    }
				    else {
				        extendedEuclidian(b, a%b);
				        int temp = (int) x;
				        x = y;
				        y = temp - (a/b)*y;
				    }
				}
				
				
				static class FasterScanner {
 
					private final InputStream stream;
					private final byte[] buf = new byte[8192];
					private int curChar, snumChars;
					private SpaceCharFilter filter;
					public int read() {
						if (snumChars == -1)
							throw new InputMismatchException();
						if (curChar >= snumChars) {
							curChar = 0;
							try {
								snumChars = System.in.read(buf);
							} catch (IOException e) {
								throw new InputMismatchException();
							}
							if (snumChars <= 0)
								return -1;
						}
						return buf[curChar++];
					}
					public FasterScanner(InputStream stream) {
						this.stream = stream;
					}
					public String nextString() {
						int c = read();
						while (isSpaceChar(c))
							c = read();
						StringBuilder res = new StringBuilder();
						do {
							res.appendCodePoint(c);
							c = read();
						} while (!isSpaceChar(c));
						return res.toString();
					}
					public int snext() {
						if (snumChars == -1)
							throw new InputMismatchException();
						if (curChar >= snumChars) {
							curChar = 0;
							try {
								snumChars = stream.read(buf);
							} catch (IOException e) {
								throw new InputMismatchException();
							}
							if (snumChars <= 0)
								return -1;
						}
						return buf[curChar++];
					}
 
					public int nextInt() {
						int c = snext();
						while (isSpaceChar(c)) {
							c = snext();
						}
						int sgn = 1;
						if (c == '-') {
							sgn = -1;
							c = snext();
						}
						int res = 0;
						do {
							if (c < '0' || c > '9')
								throw new InputMismatchException();
							res *= 10;
							res += c - '0';
							c = snext();
						} while (!isSpaceChar(c));
						return res * sgn;
					}
 
					public long nextLong() {
						int c = snext();
						while (isSpaceChar(c)) {
							c = snext();
						}
						int sgn = 1;
						if (c == '-') {
							sgn = -1;
							c = snext();
						}
						long res = 0;
						do {
							if (c < '0' || c > '9')
								throw new InputMismatchException();
							res *= 10;
							res += c - '0';
							c = snext();
						} while (!isSpaceChar(c));
						return res * sgn;
					}
 
					public int[] nextIntArray(int n) {
						int a[] = new int[n];
						for (int i = 0; i < n; i++) {
							a[i] = nextInt();
						}
						return a;
					}
 
					public long[] nextLongArray(int n) {
						long a[] = new long[n];
						for (int i = 0; i < n; i++) {
							a[i] = nextInt();
						}
						return a;
					}
			                
					public String readString() {
						int c = snext();
						while (isSpaceChar(c)) {
							c = snext();
						}
						StringBuilder res = new StringBuilder();
						do {
							res.appendCodePoint(c);
							c = snext();
						} while (!isSpaceChar(c));
						return res.toString();
					}
 
					public String nextLine() {
						int c = snext();
						while (isSpaceChar(c))
							c = snext();
						StringBuilder res = new StringBuilder();
						do {
							res.appendCodePoint(c);
							c = snext();
						} while (!isEndOfLine(c));
						return res.toString();
					}
 
					public boolean isSpaceChar(int c) {
						if (filter != null)
							return filter.isSpaceChar(c);
						return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
					}
 
					private boolean isEndOfLine(int c) {
						return c == '\n' || c == '\r' || c == -1;
					}
 
					public interface SpaceCharFilter {
						public boolean isSpaceChar(int ch);
					}
				}
			}  