// Arup Guha
// 2/27/2024
// Solution to 2023 SER D1/D2 Problem B: Balanced Tree Path

import java.util.*;

public class b {

	public static int n;
	public static char[] str;
	public static ArrayList<Integer>[] g;
	public static int[] map;

	public static void main(String[] args) {
	
		// Store matching characters in map.
		map = new int[256];
		map[')'] = '(';
		map[']'] = '[';
		map['}'] = '{';

		// Set up graph.
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		str = stdin.next().toCharArray();
		g = new ArrayList[n];
		for (int i=0; i<n; i++)
			g[i] = new ArrayList<Integer>();
			
		// Add edges.
		for (int i=0; i<n-1; i++) {
			int u = stdin.nextInt()-1;
			int v = stdin.nextInt()-1;
			g[u].add(v);
			g[v].add(u);
		}
		
		// Add all paths.
		int res = 0;
		for (int i=0; i<n; i++) 
			res += solve(i);
			
		// Ta da!
		System.out.println(res);
	}
	
	// Wrapper function to run DFS from vertex v.
	public static int solve(int v) {
		Stack<Character> s = new Stack<Character>();
		boolean[] visited = new boolean[n];
		return dfs(v, visited, s);
	}
	
	// Return the number of solutions for the dfs from v.
	public static int dfs(int v, boolean[] visited, Stack<Character> s) {
	
		// Mark it.
		visited[v] = true;
		char c = str[v];
		
		int res = 0;
		
		// If open, push onto stack.
		if (c == '(' || c == '[' || c == '{')
			s.push(c);
			
		// Can't go this way.
		else if (s.size() == 0)
			return 0;
			
		// This close doesn't match, can't pop off.
		else if (map[c] != s.peek())
			return 0;
			
		// Must be a matching close.
		else {
			char tmp = s.pop();
			if (s.size() == 0) res++;
		}
		
		// Go to unvisited neighbors.
		for (Integer x: g[v]) {
			if (visited[x]) continue;
			res += dfs(x, visited, s);
		}
		
		// This is important, undo the initial operation so that we can try a new path.
		if (c == ')' || c == ']' || c == '}') s.push((char)map[c]);
		else s.pop();
		
		return res;
	}
}