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 Common Lisp (SBCL 1.1.14) (judge verdict: Runtime Error)

#-swank
(unless (member :child-sbcl *features*)
  (quit
   :unix-status
   (process-exit-code
    (run-program *runtime-pathname*
                 `("--control-stack-size" "64MB"
                   "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                   "--eval" "(push :child-sbcl *features*)"
                   "--script" ,(namestring *load-pathname*))
                 :output t :error t :input t))))

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (ql:quickload '(:cl-debug-print :fiveam))
  #-swank (set-dispatch-macro-character #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil (values) t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(defmacro with-output-buffer (&body body)
  "Buffers all outputs to *STANDARD-OUTPUT* in BODY and flushes them to
*STANDARD-OUTPUT* after BODY has been done (without error). Note that only
BASE-CHAR is allowed."
  (let ((out (gensym)))
    `(let ((,out (make-string-output-stream :element-type 'base-char)))
       (let ((*standard-output* ,out))
         ,@body)
       (write-string (get-output-stream-string ,out)))))

(declaim (inline bisect-right))
(defun bisect-right (target value &key (start 0) end (predicate #'<) (key #'identity))
  "TARGET := vector | function
PREDICATE := strict order

Returns the smallest index (or input) i that fulfills TARGET[i] > VALUE. TARGET
must be monotonically non-decreasing with respect to PREDICATE. This function returns
END if VALUE exceeds TARGET[END-1]. Note that the range [START, END) is
half-open. END must be explicitly specified if TARGET is function. KEY is
applied to each element of TARGET before comparison."
  (declare (function key predicate)
           ((integer 0 #.most-positive-fixnum) start)
           ((or null (integer 0 #.most-positive-fixnum)) end))
  (macrolet
      ((body (accessor &optional declaration)
         `(cond ((assert (<= start end)))
                ((= start end) end)
                ((funcall predicate value (funcall key (,accessor target (- end 1))))
                 (labels ((%bisect-right (l r)
                            ,@(list declaration)
                            (let ((mid (ash (+ l r) -1)))
                              (if (= mid l)
                                  (if (funcall predicate value (funcall key (,accessor target l)))
                                      l
                                      r)
                                  (if (funcall predicate value (funcall key (,accessor target mid)))
                                      (%bisect-right l mid)
                                      (%bisect-right mid r))))))
                   
                   (%bisect-right start (- end 1))))
                (t end))))
    (etypecase target
      (vector
       (when (null end)
         (setf end (length target)))
       (body aref (declare ((integer 0 #.most-positive-fixnum) l r))))
      (function
       (assert end)
       (body funcall)))))

;;;
;;; Lowest common anscestor of tree (binary lifting)
;;; build: O(nlog(n))
;;; query: O(log(n))
;;;

;; PAY ATTENTION TO THE STACK SIZE! BUILD-LCA-TABLE does DFS.

(deftype lca-vertex-number () '(signed-byte 32))

(defstruct (lca-table
            (:constructor make-lca-table
                (size
                 &aux
                 (depths (make-array size :element-type 'lca-vertex-number))
                 ;; requires 1 + log_2{size-1}
                 (parents (make-array (list size (+ 1 (integer-length (- size 2))))
                                      :element-type 'lca-vertex-number))))
            (:conc-name lca-))
  (depths nil :type (simple-array lca-vertex-number (*)))
  (parents nil :type (simple-array lca-vertex-number (* *))))

(defun build-lca-table (root graph &key (key #'identity))
  (declare (optimize (speed 3))
           ((simple-array list (*)) graph)
           (function key))
  (let* ((size (length graph))
         (lca-table (make-lca-table size))
         (depths (lca-depths lca-table))
         (parents (lca-parents lca-table))
         (max-log-v (array-dimension parents 1)))
    (labels ((dfs (v prev-v depth)
               (declare (lca-vertex-number v prev-v))
               (setf (aref depths v) depth)
               (setf (aref parents v 0) prev-v)
               (dolist (node (aref graph v))
                 (let ((dest (funcall key node)))
                   (declare (lca-vertex-number dest))
                   (unless (= dest prev-v)
                     (dfs dest v (+ 1 depth)))))))
      (dfs root -1 0)
      (dotimes (k (- max-log-v 1))
        (dotimes (v size)
          (if (= -1 (aref parents v k))
              (setf (aref parents v (+ k 1)) -1)
              (setf (aref parents v (+ k 1)) (aref parents (aref parents v k) k)))))
      lca-table)))

(defun get-lca (u v lca-table)
  (declare (optimize (speed 3))
           (lca-vertex-number u v))
  (let* ((depths (lca-depths lca-table))
         (parents (lca-parents lca-table))
         (max-log-v (array-dimension parents 1)))
    ;; Ensures depth[u] <= depth[v]
    (when (> (aref depths u) (aref depths v)) (rotatef u v))
    (dotimes (k max-log-v)
      (when (logbitp k (- (aref depths v) (aref depths u)))
        (setf v (aref parents v k))))
    (if (= u v)
        u
        (loop for k from (- max-log-v 1) downto 0
              unless (= (aref parents u k) (aref parents v k))
              do (setf u (aref parents u k)
                       v (aref parents v k))
              finally (return (aref parents u 0))))))

(defun distance-on-tree (u v lca-table)
  (declare (optimize (speed 3)))
  (let ((depths (lca-depths lca-table))
        (lca (get-lca u v lca-table)))
    (+ (- (aref depths u) (aref depths lca))
       (- (aref depths v) (aref depths lca)))))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  (declare #.OPT)
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (sb-impl::ansi-stream-read-byte in nil #.(char-code #\Nul) nil))))
    (let* ((minus nil)
           (result (loop (let ((byte (%read-byte)))
                           (cond ((<= 48 byte 57)
                                  (return (- byte 48)))
                                 ((zerop byte) ; #\Nul
                                  (error "Read EOF or #\Nul."))
                                 ((= byte #.(char-code #\-))
                                  (setf minus t)))))))
      (declare ((integer 0 #.most-positive-fixnum) result))
      (loop
        (let* ((byte (%read-byte)))
          (if (<= 48 byte 57)
              (setq result (+ (- byte 48) (* 10 (the (integer 0 #.(floor most-positive-fixnum 10)) result))))
              (return (if minus (- result) result))))))))

;; unfinished.

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;; Body

(defun make-dfs-order (graph &key (key #'identity))
  (declare #.OPT
           ((simple-array list (*)) graph)
           (function key))
  (let* ((n (length graph))
         (res (make-array n :element-type 'uint32 :initial-element 0))
         (index 0))
    (declare (fixnum index))
    (labels ((dfs (v parent)
               (dolist (node (aref graph v))
                 (let ((neighbor (funcall key node)))
                   (declare ((integer 0 #.most-positive-fixnum) neighbor))
                   (unless (= neighbor parent)
                     (incf index)
                     (setf (aref res neighbor) index)
                     (dfs neighbor v)
                     (incf index))))))
      (dfs 0 -1)
      res)))

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (q (read))
         ;; (to color dist)
         (graph (make-array n :element-type 'list :initial-element nil)))
    (declare (uint32 n q))
    (dotimes (i (- n 1))
      (let ((a (- (read-fixnum) 1))
            (b (- (read-fixnum) 1))
            (c (- (read-fixnum) 1))
            (d (read-fixnum)))
        (push (list a c d) (aref graph b))
        (push (list b c d) (aref graph a))))
    (let ((lca-table (build-lca-table 0 graph :key #'car))
          (tours (make-array n :element-type '(vector list)))
          (dist-table (make-array n :element-type 'uint32 :initial-element 0))
          (dfsord (make-dfs-order graph :key #'car))
          (index 0)
          (colordist-table (make-array n :element-type 'uint32 :initial-element 0))
          (colorsum-table (make-array n :element-type 'uint32 :initial-element 0)))
      (declare (uint32 index)
               ((simple-array uint32 (*)) dfsord))
      (dotimes (i n) (setf (aref tours i) (make-array 0 :fill-pointer 0)))
      (labels ((dfs (v parent dist)
                 (setf (aref dist-table v) dist)
                 (dolist (neighbor (aref graph v))
                   (destructuring-bind (to color cost) neighbor
                     (declare (uint32 to color cost))
                     (unless (= to parent)
                       (incf (aref colorsum-table color))
                       (incf (aref colordist-table color) cost)
                       (incf index)
                       (vector-push-extend (list* index
                                                  (aref colorsum-table color)
                                                  (aref colordist-table color))
                                           (aref tours color))
                       (dfs to v (+ dist cost))
                       (decf (aref colordist-table color) cost)
                       (decf (aref colorsum-table color))
                       (incf index)
                       (vector-push-extend (list* index
                                                  (aref colorsum-table color)
                                                  (aref colordist-table color))
                                           (aref tours color))))))
               (get-data (ordv color)
                 (declare (uint32 ordv color))
                 (let* ((color-tour (array-storage-vector (aref tours color)))
                        (pos+1 (bisect-right color-tour ordv
                                             :key (lambda (node) (the uint32 (car node))))))
                   (declare ((simple-array list (*)) color-tour))
                   (if (zerop pos+1)
                       '(0 . 0)
                       (let ((node (aref color-tour (- pos+1 1))))
                         (cdr node))))))
        (dfs 0 -1 0)
        (with-output-buffer
          (dotimes (_ q)
            (let* ((x (- (read-fixnum) 1))
                   (y (read-fixnum))
                   (u (- (read-fixnum) 1))
                   (v (- (read-fixnum) 1))
                   (p (get-lca u v lca-table))
                   (dist-u (aref dist-table u))
                   (dist-v (aref dist-table v))
                   (dist-p (aref dist-table p)))
              (declare (uint32 dist-u dist-v dist-p)
                       (uint16 y))
              (destructuring-bind (u-ccount . u-cdist) (get-data (aref dfsord u) x)
                (destructuring-bind (v-ccount . v-cdist) (get-data (aref dfsord v) x)
                  (destructuring-bind (p-ccount . p-cdist) (get-data (aref dfsord p) x)
                    (declare (uint32 u-ccount u-cdist v-ccount v-cdist p-ccount p-cdist))
                    (let ((res-dist-u (+ dist-u (- (* u-ccount y) u-cdist)))
                          (res-dist-v (+ dist-v (- (* v-ccount y) v-cdist)))
                          (res-dist-p (+ dist-p (- (* p-ccount y) p-cdist))))
                      (println (- (+ res-dist-u res-dist-v) (* 2 res-dist-p))))))))))))))

#-swank(main)