Problem:
Score : 600 points

Problem Statement

There is a tree with N vertices numbered 1 to N.
The i-th edge in this tree connects Vertex a_i and Vertex b_i, and the color and length of that edge are c_i and d_i, respectively.
Here the color of each edge is represented by an integer between 1 and N-1 (inclusive). The same integer corresponds to the same color, and different integers correspond to different colors.

Answer the following Q queries:

Query j (1 \leq j \leq Q): assuming that the length of every edge whose color is x_j is changed to y_j, find the distance between Vertex u_j and Vertex v_j. (The changes of the lengths of edges do not affect the subsequent queries.)

Constraints

2 \leq N \leq 10^5

1 \leq Q \leq 10^5

1 \leq a_i, b_i \leq N

1 \leq c_i \leq N-1

1 \leq d_i \leq 10^4

1 \leq x_j \leq N-1

1 \leq y_j \leq 10^4

1 \leq u_j < v_j \leq N

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N Q
a_1 b_1 c_1 d_1
:
a_{N-1} b_{N-1} c_{N-1} d_{N-1}
x_1 y_1 u_1 v_1
:
x_Q y_Q u_Q v_Q

Output

Print Q lines. The j-th line (1 \leq j \leq Q) should contain the answer to Query j.

Sample Input 1

5 3
1 2 1 10
1 3 2 20
2 4 4 30
5 2 1 40
1 100 1 4
1 100 1 5
3 1000 3 4

Sample Output 1

130
200
60

The graph in this input is as follows:

Here the edges of Color 1 are shown as solid red lines, the edge of Color 2 is shown as a bold green line, and the edge of Color 4 is shown as a blue dashed line.

Query 1: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 4 is 100 + 30 = 130.

Query 2: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 5 is 100 + 100 = 200.

Query 3: Assuming that the length of every edge whose color is 3 is changed to 1000 (there is no such edge), the distance between Vertex 3 and Vertex 4 is 20 + 10 + 30 = 60. Note that the edges of Color 1 now have their original lengths.

Solution in Haskell (GHC 7.10.3) (judge verdict: Accepted)

-- https://github.com/minoki/my-atcoder-solutions
{-# LANGUAGE BangPatterns #-}
import Data.Char (isSpace)
import Data.List (unfoldr)
import Data.Monoid
import Control.Monad
import Control.Monad.ST
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VM
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntMap.Strict as IntMap
import qualified Data.Sequence as Seq

strictAppend :: (Monoid a, Monoid b) => (a, b) -> (a, b) -> (a, b)
strictAppend (x, y) (x', y') = let !xx = x <> x'
                                   !yy = y <> y'
                               in (xx, yy)

main = do
  [n,q] <- unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
  edges <- U.replicateM (n-1) $ do
    [a,b,c,d] <- unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
    return (a-1,b-1,c,d)
  let edges' :: V.Vector [(Int,Int,Int)]
      edges' = V.create $ do
        vec <- VM.replicate n []
        U.forM_ edges $ \(i,j,c,d) -> do
          VM.modify vec ((j,c,d) :) i
          VM.modify vec ((i,c,d) :) j
        return vec
  let depthMap :: U.Vector Int
      routes :: V.Vector (Seq.Seq Int)
      distances :: U.Vector Int
      distancesMap :: V.Vector (IntMap.IntMap (Sum Int, Sum Int))
      (depthMap, routes, distances, distancesMap) = runST $ do
        depthVec <- UM.new n
        routes <- VM.new n
        distances <- UM.new n
        distancesMap <- VM.new n
        let go !i0 !i !d route !dt dtm = do
              UM.write depthVec i d
              VM.write routes i route
              UM.write distances i dt
              VM.write distancesMap i dtm
              forM_ (edges' V.! i) $ \(j,col,dist) -> do
                when (j /= i0) $ do
                  go i j (d+1) (route Seq.|> j) (dt + dist) (IntMap.insertWith strictAppend col (Sum 1, Sum dist) dtm)
        go (-1) 0 0 (Seq.singleton 0) 0 IntMap.empty
        liftM4 (,,,) (U.unsafeFreeze depthVec) (V.unsafeFreeze routes) (U.unsafeFreeze distances) (V.unsafeFreeze distancesMap)
      lowestCommonAncestor :: Int -> Int -> Int
      lowestCommonAncestor !i !j =
        let ri = routes V.! i
            rj = routes V.! j
            search !l !u | l + 1 == u = ri `Seq.index` l
            search !l !u = let d = (l + u) `quot` 2 -- l < d < u
                               pi = ri `Seq.index` d
                               pj = rj `Seq.index` d
                           in if pi == pj
                              then search d u
                              else search l d
        in search 0 (min (Seq.length ri) (Seq.length rj))
  forM_ [0..q-1] $ \_ -> do
    [x,y,up1,vp1] <- unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
    let u = up1 - 1
        v = vp1 - 1
        w = lowestCommonAncestor u v
        modifiedDistanceFromRoot :: Int -> Int
        modifiedDistanceFromRoot !i = distances U.! i + case IntMap.lookup x (distancesMap V.! i) of
                                                          Just (Sum n, Sum origDist) -> y * n - origDist
                                                          Nothing -> 0
    print $ modifiedDistanceFromRoot u + modifiedDistanceFromRoot v - 2 * modifiedDistanceFromRoot w