Parsa has a humongous tree on n vertices.

On each vertex v he has written two integers l_v and r_v.

To make Parsa's tree look even more majestic, Nima wants to assign a number a_v (l_v ≤ a_v ≤ r_v) to each vertex v such that the beauty of Parsa's tree is maximized.

Nima's sense of the beauty is rather bizarre. He defines the beauty of the tree as the sum of |a_u - a_v| over all edges (u, v) of the tree.

Since Parsa's tree is too large, Nima can't maximize its beauty on his own. Your task is to find the maximum possible beauty for Parsa's tree.

Input

The first line contains an integer t (1≤ t≤ 250) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer n (2≤ n≤ 10^5) — the number of vertices in Parsa's tree.

The i-th of the following n lines contains two integers l_i and r_i (1 ≤ l_i ≤ r_i ≤ 10^9).

Each of the next n-1 lines contains two integers u and v (1 ≤ u , v ≤ n, u≠ v) meaning that there is an edge between the vertices u and v in Parsa's tree.

It is guaranteed that the given graph is a tree.

It is guaranteed that the sum of n over all test cases doesn't exceed 2 ⋅ 10^5.

Output

For each test case print the maximum possible beauty for Parsa's tree.

Example

Input


3
2
1 6
3 8
1 2
3
1 3
4 6
7 9
1 2
2 3
6
3 14
12 20
12 19
2 12
10 17
3 17
3 2
6 5
1 5
2 6
4 6


Output


7
8
62

Note

The trees in the example:

<image>

In the first test case, one possible assignment is a = \{1, 8\} which results in |1 - 8| = 7.

In the second test case, one of the possible assignments is a = \{1, 5, 9\} which results in a beauty of |1 - 5| + |5 - 9| = 8
import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class tr0 {
	static PrintWriter out;
	static StringBuilder sb;
	static long mod = (long) 1e9 + 7;
	static long inf = (long) 1e16;
	static int n, m, k;
	static ArrayList<Integer>[] ad;
	static int[][] remove, add;
	static long[][] memo;
	static boolean vis[];
	static long[] inv, ncr[];
	static HashMap<Integer, Integer> hm;
	static int[] pre, suf, Smax[], Smin[];
	static int idmax, idmin;
	static ArrayList<Integer> av;
	static HashMap<Integer, Integer> mm;
	static boolean[] msks;
	static int[] lazy[], lazyCount;
	static int[] dist;
	static int[] g;
	static int st, ed;
	static ArrayList<Integer> gl;
	static int[] l, r;

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		int t = sc.nextInt();
		while (t-- > 0) {
			int n = sc.nextInt();
			l = new int[n];
			r = new int[n];
			ad = new ArrayList[n];
			for (int i = 0; i < n; i++)
				ad[i] = new ArrayList<>();
			for (int i = 0; i < n; i++) {
				l[i] = sc.nextInt();
				r[i] = sc.nextInt();
			}
			for (int i = 0; i < n - 1; i++) {
				int a = sc.nextInt() - 1;
				int b = sc.nextInt() - 1;
				ad[a].add(b);
				ad[b].add(a);
			}
			memo = new long[n][3];
			for (long[] i : memo)
				Arrays.fill(i, -1);
	//		System.out.println(Arrays.toString(l));
	//		System.out.println(Arrays.toString(r));
			out.println(dp(0, -1, 0));
		}
		out.flush();
	}

	static long dp(int u, int p, int last) {
		if (memo[u][last] != -1)
			return memo[u][last];
		long ans = 0;
		if (last == 1)
			ans += Math.abs(l[u] - l[p]);
		if (last == 2)
			ans += Math.abs(l[u] - r[p]);
		for (int v : ad[u])
			if (v != p) {
				ans += dp(v, u, 1);
			
			}
		long ans1 = 0;
		if (last == 1)
			ans1 += Math.abs(r[u] - l[p]);
		if (last == 2)
			ans1 += Math.abs(r[u] - r[p]);
		for (int v : ad[u])
			if (v != p) {
				ans1 += dp(v, u, 2);
			
			}
	//	System.err.println(u+" "+last+" "+ans+" "+ans1);
		ans = Math.max(ans, ans1);
		return memo[u][last] = ans;
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public int[] nextArrInt(int n) throws IOException {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public long[] nextArrLong(int n) throws IOException {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		public int[] nextArrIntSorted(int n) throws IOException {
			int[] a = new int[n];
			Integer[] a1 = new Integer[n];
			for (int i = 0; i < n; i++)
				a1[i] = nextInt();
			Arrays.sort(a1);
			for (int i = 0; i < n; i++)
				a[i] = a1[i].intValue();
			return a;
		}

		public long[] nextArrLongSorted(int n) throws IOException {
			long[] a = new long[n];
			Long[] a1 = new Long[n];
			for (int i = 0; i < n; i++)
				a1[i] = nextLong();
			Arrays.sort(a1);
			for (int i = 0; i < n; i++)
				a[i] = a1[i].longValue();
			return a;
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}