Problem:
Score : 400 points

Problem Statement

You are given a tree with N vertices.

Here, a tree is a kind of graph, and more specifically, a connected undirected graph with N-1 edges, where N is the number of its vertices.

The i-th edge (1≤i≤N-1) connects Vertices a_i and b_i, and has a length of c_i.

You are also given Q queries and an integer K. In the j-th query (1≤j≤Q):

find the length of the shortest path from Vertex x_j and Vertex y_j via Vertex K.

Constraints

3≤N≤10^5

1≤a_i,b_i≤N (1≤i≤N-1)

1≤c_i≤10^9 (1≤i≤N-1)

The given graph is a tree.

1≤Q≤10^5

1≤K≤N

1≤x_j,y_j≤N (1≤j≤Q)

x_j≠y_j (1≤j≤Q)

x_j≠K,y_j≠K (1≤j≤Q)

Input

Input is given from Standard Input in the following format:

N
a_1 b_1 c_1
:
a_{N-1} b_{N-1} c_{N-1}
Q K
x_1 y_1
:
x_{Q} y_{Q}

Output

Print the responses to the queries in Q lines.

In the j-th line j(1≤j≤Q), print the response to the j-th query.

Sample Input 1

5
1 2 1
1 3 1
2 4 1
3 5 1
3 1
2 4
2 3
4 5

Sample Output 1

3
2
4

The shortest paths for the three queries are as follows:

Query 1: Vertex 2 → Vertex 1 → Vertex 2 → Vertex 4 : Length 1+1+1=3

Query 2: Vertex 2 → Vertex 1 → Vertex 3 : Length 1+1=2

Query 3: Vertex 4 → Vertex 2 → Vertex 1 → Vertex 3 → Vertex 5 : Length 1+1+1+1=4

Sample Input 2

7
1 2 1
1 3 3
1 4 5
1 5 7
1 6 9
1 7 11
3 2
1 3
4 5
6 7

Sample Output 2

5
14
22

The path for each query must pass Vertex K=2.

Sample Input 3

10
1 2 1000000000
2 3 1000000000
3 4 1000000000
4 5 1000000000
5 6 1000000000
6 7 1000000000
7 8 1000000000
8 9 1000000000
9 10 1000000000
1 1
9 10

Sample Output 3

17000000000

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Math;
using static System.Console;
using static CS_Contest.Utils;

namespace CS_Contest {
	using Li = List<int>;
	using LLi = List<List<int>>;
	class Program {
        static void Main(string[] args) {
			new Calc().Solve();
			return;
        }

		private class Calc {
			long[,] Cost;
			public void Solve() {
				int N = ReadInt();
				Cost = new long[N, N];
				REP(N, x => REP(N, y => { Cost[x, y] = INF; }));
				REP(N-1, x => {
					int a, b, c;
					ReadTriple(out a, out b, out c);
					a--;b--;
					Cost[a, b] = c;
					Cost[b, a] = c;
				});
				int Q, K;
				ReadMulti(out Q, out K);
				var toK = new List<long>();
				REP(N, x => {
					toK.Add(Dijkstra(x, N, K - 1));
				});
				REP(Q, _ => {
					int x, y;
					ReadMulti(out x, out y);
					x--;y--;
					 (toK[x] + Dijkstra(K-1, N, y)).WL();
				});
				return;
			}
			private long Dijkstra(int s,int N,int g) {
				Li prev = new Li();
				var dist = new List<long>();
				PriorityQueue<Tuple<long, int>> Q = new PriorityQueue<Tuple<long, int>>((x, y) => {
					if (x.Item1 == y.Item1) return 0;
					else if (x.Item1 < y.Item1) return -1;
					else return 1;
				});
				Q.Enqueue(new Tuple<long, int>(0,s));
				REP(N, x => {
					if (x == s) dist.Add(0);
					else dist.Add(INF);
					prev.Add(-1);
				});
				while (Q.Count!=0) {
					var src = Q.Dequeue();
					if (dist[src.Item2] < src.Item1) {
						continue;
					}

					for (int dest = 0; dest < N; dest++) {
						var cost = Cost[src.Item2, dest];
						if(cost!=INF&& dist[dest] > dist[src.Item2] + cost) {
							dist[dest] = dist[src.Item2] + cost;
							Q.Enqueue(new Tuple<long, int>(dist[dest], dest));
							prev[dest] = src.Item2;
						}
					}
				}
				return dist[g];
			}
		}
    }

	
	
    public static class Utils {
		public static int ModValue = (int)(1e9+7);
		public static long INF = long.MaxValue;
		public static long Mod(long x) => x % ModValue;
		public static long ModPow(long x,long n) { long tmp = 1; while (n != 0) { if (n % 2 == 1) { tmp = Mod(tmp * x); }x = Mod(x * x);n /= 2; }return tmp; }
		public static long DivMod(long x, long y) => Mod(x * ModPow(y, (long)(1e9 + 5)));
        public static void WL(this object obj) => WriteLine(obj);
        public static void WL(this string obj) => WriteLine(obj);
        public static void WL<T>(this IEnumerable<T> list) => list.ToList().ForEach(x => x.WL());
		public static int ReadInt() => int.Parse(ReadLine());
		public static List<int> ReadInt(char s) => ReadLine().Split(s).Select(int.Parse).ToList();
		public static long ReadLong() => long.Parse(ReadLine());
		public static List<long> ReadLong(char s) => ReadLine().Split(s).Select(long.Parse).ToList();
		public static void ReadMulti(out int x, out int y) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1];

		}
		public static void ReadMulti(out long x, out long y) {
			var i = ReadLong(' ');
			x = i[0];y = i[1];
		}
		public static void ReadTriple(out int x, out int y, out int z) {
			var i = ReadInt(' ');
			x = i[0];y = i[1];z = i[2];
		}

		public static long GCD(long m,long n) {
			long tmp;
			while(m%n!=0) {
				tmp = n;
				n = m % n;
				m = tmp;
			}
			return n;
		}
		public static long LCM(long m, long n) => m * (n / GCD(m, n));

		public static void REP(int n,Action<int> act) {
			for (int i = 0; i < n; i++) {
				act(i);
			}
		}
		public static void RREP(int n,Action<int> act) {
			for (int i = n-1; i >=0; i--) {
				act(i);
			}
		}
		public static void REP(long n, Action<int> act) => REP((int)n, act);
		public static void RREP(long n, Action<int> act) => RREP((int)n, act);

		public static void Yes() => "Yes".WL();
		public static void No() => "No".WL();
		public static void YES() => "YES".WL();
		public static void NO() => "NO".WL();


		public static int ManhattanDistance(int x1, int y1, int x2, int y2) => Abs(x2 - x1) + Abs(y2 - y1);


		public class Tree {
			public LLi Graph;
			public Tree(int nodes) {
				Graph = new LLi();
				REP(nodes, x => {
					Graph.Add(new Li());
				});
			}
			public void Add(int x,int y) {
				Graph[x].Add(y);
				Graph[y].Add(x);
			}
		}

		public class Vector2 {
			public int X { get; set; }
			public int Y { get; set; }
			public Vector2() { X = 0;Y = 0; }
			public Vector2(int x,int y) { X = x;Y = y; }
			public int ManhattanDistance(Vector2 v2) {
				return Utils.ManhattanDistance(X, Y, v2.X, v2.Y);
			}
			public static int ManhattanDistance(Vector2 v1, Vector2 v2) => v2.ManhattanDistance(v2);
			public double Distance(Vector2 v2) => Sqrt(Pow(X - v2.X, 2) + Pow(Y - v2.Y, 2));
			public static Vector2 Zero { get { return new Vector2(); } }
			public void Clear() { X = 0;Y = 0; }

		}

		public class PriorityQueue<T> {
			private readonly List<T> heap;
			private readonly Comparison<T> compare;
			private int size;
			public PriorityQueue() : this(Comparer<T>.Default) { }
			public PriorityQueue(IComparer<T> comparer) : this(16, comparer.Compare) { }
			public PriorityQueue(Comparison<T> comparison) : this(16, comparison) { }
			public PriorityQueue(int capacity, Comparison<T> comparison) {
				this.heap = new List<T>(capacity);
				this.compare = comparison;
			}
			public void Enqueue(T item) {
				this.heap.Add(item);
				var i = size++;
				while (i > 0) {
					var p = (i - 1) >> 1;
					if (compare(this.heap[p], item) <= 0)
						break;
					this.heap[i] = heap[p];
					i = p;
				}
				this.heap[i] = item;

			}
			public T Dequeue() {
				var ret = this.heap[0];
				var x = this.heap[--size];
				var i = 0;
				while ((i << 1) + 1 < size) {
					var a = (i << 1) + 1;
					var b = (i << 1) + 2;
					if (b < size && compare(heap[b], heap[a]) < 0) a = b;
					if (compare(heap[a], x) >= 0)
						break;
					heap[i] = heap[a];
					i = a;
				}
				heap[i] = x;
				heap.RemoveAt(size);
				return ret;
			}
			public T Peek() { return heap[0]; }
			public int Count { get { return size; } }
			public bool Any() { return size > 0; }
		}
	}
}