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 Haskell (GHC 8.8.3) (judge verdict: Accepted)

{-# LANGUAGE BangPatterns        #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE MultiWayIf          #-}
{-# LANGUAGE ScopedTypeVariables #-}

import           Control.Monad
import           Control.Monad.ST
import           Control.Monad.State
import           Control.Monad.Trans.State
import           Data.Array.IArray
import           Data.Array.ST
import           Data.Array.Unboxed
import           Data.Bits
import qualified Data.ByteString.Char8       as BS
import           Data.Char
import           Data.Int                    (Int64)
import           Data.List
import           Data.Maybe
import           Data.Proxy
import           Data.Sequence               (Seq, (<|), (><), (|>))
import qualified Data.Sequence               as Seq
import qualified Data.Set                    as S
import           Data.STRef
import qualified Data.Vector                 as V
import qualified Data.Vector.Mutable         as VM
import qualified Data.Vector.Unboxed         as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import           Debug.Trace
import           Numeric

main :: IO ()
main = do
  n <- readLn
  abcs <- readLnAsUVecWith3Tuple unconsInt (n-1)
  (q,k) <- (\vec -> (vec VU.! 0, vec VU.! 1)) <$> readLnAsUVecWith unconsInt 2
  xys <- readLnAsUVecWith2Tuple unconsInt q
  let graph = generateGraph abcs n
      distvec = treeDfs (k-1) graph
  VU.forM_ xys $ \(x,y) -> do
    print $ distvec VU.! (x-1) + distvec VU.! (y-1)



type Graph a = V.Vector [(Int, a)]

treeDfs :: forall a. (Num a, VUM.Unbox a) => Int -> Graph a -> VU.Vector a
treeDfs r graph = VU.create $ do
  distance <- VUM.replicate (V.length graph) (0::a)
  go distance (-1) r
  return distance
  where go :: VUM.MVector s a -> Int -> Int -> ST s ()
        go dist p n = forM_ (graph V.! n) $ \(m, x) -> do
          if p == m
            then return ()
            else do d <- VUM.read dist n
                    VUM.write dist m (d + x)
                    go dist n m

treeDfs' :: forall a. Int -> Graph a -> ()
treeDfs' r graph = runST $ do
  go (-1) r
  where go :: Int -> Int -> ST s ()
        go p n = forM_ (graph V.! n) $ \(m, _) -> do
          if p == m
            then return ()
            else do go n m


dfs :: (Num a) => [Int] -> Graph a -> ()
dfs ns graph = runST $ do
  seen <- VUM.replicate (V.length graph) False
  mapM_ (go seen) ns
  where go :: VUM.MVector s Bool -> Int -> ST s ()
        go seen n = forM_ (graph V.! n) $ \(m, _) -> do
          VUM.read seen m >>= \s -> if not s
            then return ()
            else do VUM.write seen m True
                    go seen m


generateGraph :: (Num a, VU.Unbox a) => VU.Vector (Int, Int, a) -> Int -> Graph a
generateGraph vec n = V.create $ do
  graph <- VM.replicate n []
  let l = VU.length vec
  forM_ [0..l-1] $ \i -> do
    let (from,to,w) = vec VU.! i
        f = from - 1
        t = to - 1
    VM.modify graph ((t,w):) f
    VM.modify graph ((f,w):) t
  return graph

readLnAsUVecWith3Tuple :: VU.Unbox a => StateT BS.ByteString Maybe a -> Int -> IO (VU.Vector (a,a,a))
readLnAsUVecWith3Tuple !st !n = VU.replicateM n $ (\vec -> (vec VU.! 0, vec VU.! 1, vec VU.! 2)) <$> readLnAsUVecWith st 3



-- converter
unconsChar :: StateT BS.ByteString Maybe Char
unconsChar = StateT BS.uncons

unconsInt :: StateT BS.ByteString Maybe Int
unconsInt = StateT $ BS.readInt . BS.dropWhile isSpace

unconsInteger :: StateT BS.ByteString Maybe Integer
unconsInteger = StateT $ BS.readInteger . BS.dropWhile isSpace

-- 1D Data
-- for list
readLnAsListWith :: StateT BS.ByteString Maybe a -> IO [a]
readLnAsListWith !st = unfoldr (runStateT st) <$> BS.getLine

-- for boxed array
readLnAsArrayWith :: StateT BS.ByteString Maybe a -> Int -> IO (Array Int a)
readLnAsArrayWith !st !n = listArray (1,n) <$> readLnAsListWith st

-- for unboxed array
readLnAsUArrayInt :: Int -> IO (UArray Int Int)
readLnAsUArrayInt !n = listArray (1,n) <$> readLnAsListWith unconsInt

readLnAsUArrayChar :: Int -> IO (UArray Int Char)
readLnAsUArrayChar !n = listArray (1,n) <$> readLnAsListWith unconsChar

-- for boxed vector
readLnAsVecWith :: StateT BS.ByteString Maybe a -> Int -> IO (V.Vector a)
readLnAsVecWith !st !n = V.unfoldrN n (runStateT st) <$> BS.getLine

-- for unboxed vector
readLnAsUVecWith :: VU.Unbox a => StateT BS.ByteString Maybe a -> Int -> IO (VU.Vector a)
readLnAsUVecWith !st !n = VU.unfoldrN n (runStateT st) <$> BS.getLine

-- example: 1D tuple vector
readLnAsUVecWith2Tuple :: VU.Unbox a => StateT BS.ByteString Maybe a -> Int -> IO (VU.Vector (a,a))
readLnAsUVecWith2Tuple !st !n = VU.replicateM n $ (\vec -> (vec VU.! 0, vec VU.! 1)) <$> readLnAsUVecWith st 2


-- 2D Data
-- n: number of lines
-- m: number of values per a line

-- for boxed array
readLnAs2DArrayWith :: StateT BS.ByteString Maybe a -> Int -> Int -> IO (Array (Int,Int) a)
readLnAs2DArrayWith !st !n !m = listArray ((1,1),(n,m)) . unfoldr (runStateT st) . BS.concat <$> replicateM n BS.getLine

-- for boxed vector
readLnAs2DVecWith :: StateT BS.ByteString Maybe a -> Int -> Int -> IO (V.Vector (V.Vector a))
readLnAs2DVecWith !st !n !m = V.replicateM n $ V.unfoldrN m (runStateT st) <$> BS.getLine

-- for unboxed vector
readLnAs2DUVecWith :: VU.Unbox a => StateT BS.ByteString Maybe a -> Int -> Int -> IO (V.Vector (VU.Vector a))
readLnAs2DUVecWith !st !n !m = V.replicateM n $ VU.unfoldrN m (runStateT st) <$> BS.getLine