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 Rust (1.15.1) (judge verdict: Wrong Answer)

macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( iter = $ iter : ident , $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut $ iter = s . split_whitespace ( ) ; input_inner ! { $ iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , mut $ var : usize $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , $ var : usize $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , { chars : $ base : expr } ) => { read_value ! ( $ iter , String ) . chars ( ) . map ( | c | ( c as u8 - $ base as u8 ) as usize ) . collect ::< Vec < usize >> ( ) } ; ( $ iter : expr , { char : $ base : expr } ) => { read_value ! ( $ iter , { chars : $ base } ) [ 0 ] } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , char ) => { read_value ! ( $ iter , chars ) [ 0 ] } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
pub struct SegmentTree<M: Monoid> {
    n: usize,
    seg: Vec<M::T>,
    m: M,
}
impl<M: Monoid> SegmentTree<M> {
    pub fn new(n: usize, m: M) -> SegmentTree<M> {
        let n = 1 << format!("{:b}", n - 1).len();
        let seg = vec![m.mempty(); 2 * n - 1];
        SegmentTree {
            n: n,
            seg: seg,
            m: m,
        }
    }
    pub fn from_vec(v: Vec<M::T>, m: M) -> SegmentTree<M> {
        let n = 1 << format!("{:b}", v.len() - 1).len();
        let mut seg = vec![m.mempty(); 2 * n - 1];
        for (i, x) in v.into_iter().enumerate() {
            seg[i + n - 1] = x;
        }
        for i in (0..n - 1).rev() {
            seg[i] = m.mappend(&seg[2 * i + 1], &seg[2 * i + 2]);
        }
        SegmentTree {
            n: n,
            seg: seg,
            m: m,
        }
    }
    pub fn update(&mut self, k: usize, x: M::T) {
        let mut k = k + self.n - 1;
        self.seg[k] = x;
        while k > 0 {
            k = (k - 1) / 2;
            self.seg[k] = self.m.mappend(&self.seg[2 * k + 1], &self.seg[2 * k + 2]);
        }
    }
    pub fn query(&self, l: usize, r: usize) -> M::T {
        let mut l = l + self.n - 1;
        let mut r = r + self.n - 1;
        let mut res = self.m.mempty();
        while l < r {
            if r & 1 == 0 {
                r -= 1;
                res = self.m.mappend(&res, &self.seg[r]);
            }
            if l & 1 == 0 {
                res = self.m.mappend(&res, &self.seg[l]);
                l += 1;
            }
            l = (l - 1) / 2;
            r = (r - 1) / 2;
        }
        res
    }
}
pub trait Monoid {
    type T: Clone + PartialEq;
    fn mempty(&self) -> Self::T;
    fn mappend(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
pub struct MinMonoid<T: Ord + Clone> {
    min: T,
}
impl<T: Ord + Clone> MinMonoid<T> {
    pub fn new(min: T) -> MinMonoid<T> {
        MinMonoid { min: min }
    }
}
impl<T: Ord + Clone> Monoid for MinMonoid<T> {
    type T = T;
    fn mempty(&self) -> T {
        self.min.clone()
    }
    fn mappend(&self, x: &T, y: &T) -> T {
        std::cmp::min(x, y).clone()
    }
}
pub trait Bisect: Copy {
    fn halve(self, other: Self) -> Self;
    fn section_end(self, other: Self) -> bool;
}
impl Bisect for usize {
    fn halve(self, other: Self) -> Self {
        if self > other {
            other + (self - other) / 2
        } else {
            self + (other - self) / 2
        }
    }
    fn section_end(self, other: Self) -> bool {
        (if self > other {
            self - other
        } else {
            other - self
        }) <= 1
    }
}
impl Bisect for i64 {
    fn halve(self, other: Self) -> Self {
        (self + other) / 2
    }
    fn section_end(self, other: Self) -> bool {
        (self - other).abs() <= 1
    }
}
impl Bisect for f64 {
    fn halve(self, other: Self) -> Self {
        (self + other) / 2.
    }
    fn section_end(self, other: Self) -> bool {
        (self - other).abs() <= 1e-8
    }
}
pub fn binary_search<T: Bisect, F: Fn(T) -> bool>(f: F, ok: T, err: T) -> T {
    let mut ok = ok;
    let mut err = err;
    while !ok.section_end(err) {
        let m = ok.halve(err);
        if f(m) {
            ok = m;
        } else {
            err = m;
        }
    }
    ok
}
#[derive(Debug)]
pub struct TreeRec<V, E> {
    n: usize,
    m: usize,
    graph: Vec<Vec<(usize, usize)>>,
    vs: Vec<V>,
    es: Vec<E>,
}
// impl<V: Clone + Default, E: Clone + Default> TreeRec<V, E> {

// }
// use euler_tour::*;
// pub mod euler_tour {
// use super::*;
#[derive(Clone, Debug, Default)]
pub struct Vertex {
    l: usize,
    r: usize,
    d: usize,
    d2: usize,
}
#[derive(Clone, Debug, Default)]
pub struct Edge {
    l: usize,
    r: usize,
    c: usize,
    d: usize,
}
impl TreeRec<Vertex, Edge> {
    pub fn new(n: usize) -> TreeRec<Vertex, Edge> {
        TreeRec {
            n: n,
            m: 0,
            graph: vec![vec![]; n],
            vs: vec![Default::default(); n],
            es: vec![],
        }
    }
    pub fn add_edge(&mut self, u: usize, v: usize, c: usize, d: usize) {
        self.graph[u].push((v, self.m));
        self.graph[v].push((u, self.m));
        self.es.push(Edge {
            c: c,
            d: d,
            ..Default::default()
        });
        self.m += 1;
    }
    pub fn dfs(&mut self, u: usize, p: usize) {
        for i in 0..self.graph[u].len() {
            let (v, _i) = self.graph[u][i];
            if v != p {
                self.dfs(v, u);
            }
        }
    }
    pub fn euler_tour(
        &mut self,
        u: usize,
        p: usize,
        d: usize,
        d2: usize,
        vi: &mut usize,
        ei: &mut usize,
    ) {
        self.vs[u].l = *vi;
        self.vs[u].d = d;
        self.vs[u].d2 = d2;
        *vi += 1;
        for i in 0..self.graph[u].len() {
            let (v, i) = self.graph[u][i];
            if v != p {
                self.es[i].l = *ei;
                *ei += 1;
                let dd = self.es[i].d;
                self.euler_tour(v, u, d + 1, d2 + dd, vi, ei);
                *vi += 1;
                self.es[i].r = *ei;
                *ei += 1;
            }
        }
        self.vs[u].r = *vi - 1;
    }
}
pub struct LowestCommonAncestor {
    seg: SegmentTree<MinMonoid<(usize, usize)>>,
    left: Vec<usize>,
    right: Vec<usize>,
}
impl LowestCommonAncestor {
    pub fn get_lca(&self, u: usize, v: usize) -> usize {
        let x = self.seg.query(self.left[u], self.right[v] + 1);
        let y = self.seg.query(self.left[v], self.right[u] + 1);
        std::cmp::min(x, y).1
    }
}
// }
fn main() {
    input! { n, q, abcd: [(usize1,usize1,usize1,usize); n-1], xyuv: [(usize1,usize,usize1,usize1); q] };
    let mut rec = TreeRec::new(n);
    for &(a, b, c, d) in &abcd {
        rec.add_edge(a, b, c, d);
    }
    let (mut vi, mut ei) = (0, 0);
    rec.euler_tour(0, n, 0, 0, &mut vi, &mut ei);
    let mut euler = vec![(0, 0); vi];
    for i in 0..n {
        euler[rec.vs[i].l] = (rec.vs[i].d, i);
        euler[rec.vs[i].r] = (rec.vs[i].d, i);
    }
    let lca = LowestCommonAncestor {
        seg: SegmentTree::from_vec(euler, MinMonoid::new((std::usize::MAX, 0))),
        left: (0..n).map(|i| rec.vs[i].l).collect::<Vec<_>>(),
        right: (0..n).map(|i| rec.vs[i].r).collect::<Vec<_>>(),
    };
    let mut edge = vec![(0, 0, 0); ei];
    let mut par = vec![0; n];
    for i in 0..n - 1 {
        edge[rec.es[i].l] = (rec.es[i].c, rec.es[i].d as i64, 1i64);
        edge[rec.es[i].r] = (rec.es[i].c, -(rec.es[i].d as i64), -1i64);
        let (a, b, _, _) = abcd[i];
        let c = if rec.vs[a].d > rec.vs[b].d { a } else { b };
        par[c] = rec.es[i].l + 1;
    }
    let mut ced = vec![vec![(0, 0, 0)]; n - 1];
    for (i, &(c, d, m)) in edge.iter().enumerate() {
        ced[c].push((i + 1, d, m));
    }
    for i in 0..n - 1 {
        for j in 0..ced[i].len() - 1 {
            ced[i][j + 1].1 += ced[i][j].1;
            ced[i][j + 1].2 += ced[i][j].2;
        }
    }
    for &(x, y, u, v) in &xyuv {
        let mut ans = 0;
        let p = lca.get_lca(u, v);
        let (_, l, m) = ced[x][binary_search(|i| ced[x][i].0 <= par[u], 0, ced[x].len())];
        ans += rec.vs[u].d2 + y * m as usize - l as usize;
        let (_, l, m) = ced[x][binary_search(|i| ced[x][i].0 <= par[v], 0, ced[x].len())];
        ans += rec.vs[v].d2 + y * m as usize - l as usize;
        let (_, l, m) = ced[x][binary_search(|i| ced[x][i].0 <= par[p], 0, ced[x].len())];
        ans -= rec.vs[p].d2 + y * m as usize - l as usize;
        ans -= rec.vs[p].d2 + y * m as usize - l as usize;
        println!("{}", ans);
    }
}