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 C++ (GCC 9.2.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
using namespace std;
int LOG = 20;
struct lowest_common_ancestor{
  vector<int> d;
  vector<vector<int>> p;
  lowest_common_ancestor(){
  }
  lowest_common_ancestor(vector<vector<int>> &ch){
    int N = ch.size();
    d = vector<int>(N, 0);
    p = vector<vector<int>>(LOG, vector<int>(N, -1));
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      for (int w : ch[v]){
        d[w] = d[v] + 1;
        p[0][w] = v;
        Q.push(w);
      }
    }
    for (int i = 1; i < LOG; i++){
      for (int j = 0; j < N; j++){
        if (p[i - 1][j] != -1){
          p[i][j] = p[i - 1][p[i - 1][j]];
        }
      }
    }
  }
  int lca(int v, int w){
    if (d[v] < d[w]){
      swap(v, w);
    }
    int diff = d[v] - d[w];
    for (int i = 0; i < LOG; i++){
      if (diff >> i & 1){
        v = p[i][v];
      }
    }
    if (v == w){
      return v;
    } else {
      for (int i = LOG - 1; i >= 0; i--){
        if (p[i][v] != p[i][w]){
          v = p[i][v];
          w = p[i][w];
        }
      }
      return p[0][v];
    }
  }
};
template <typename T>
struct segment_tree{
  int N;
  vector<T> ST;
  T E;
  segment_tree(){
  }
  segment_tree(vector<T> A, T E): E(E){
    int n = A.size();
    N = 1;
    while (N < n){
      N *= 2;
    }
    ST = vector<T>(N * 2 - 1, E);
    for (int i = 0; i < n; i++){
      ST[N - 1 + i] = A[i];
    }
    for (int i = N - 2; i >= 0; i--){
      ST[i] = ST[i * 2 + 1] + ST[i * 2 + 2];
    }
  }
  void update(int i, T x){
    i += N - 1;
    ST[i] = x;
    while (i > 0){
      i = (i - 1) / 2;
      ST[i] = ST[i * 2 + 1] + ST[i * 2 + 2];
    }
  }
  T query(int L, int R, int i, int l, int r){
    if (r <= L || R <= l){
      return E;
    } else if (L <= l && r <= R){
      return ST[i];
    } else {
      int m = (l + r) / 2;
      return query(L, R, i * 2 + 1, l, m) + query(L, R, i * 2 + 2, m, r);
    }
  }
  T query(int L, int R){
    return query(L, R, 0, 0, N);
  }
};
template <typename T>
struct euler_tour{
  vector<int> left, right;
  vector<T> A;
  segment_tree<T> ST;
  lowest_common_ancestor LCA;
  void dfs(vector<vector<int>> &ch, vector<T> a, int v = 0){
    left[v] = A.size();
    if (A.size() > 300000){
      cout << "Error" << endl;
      return;
    }
    A.push_back(a[v]);
    for (int w : ch[v]){
      dfs(ch, a, w);
    }
    right[v] = A.size();
    if (A.size() > 300000){
      cout << "Error" << endl;
      return;
    }
    A.push_back(-a[v]);
  }
  euler_tour(vector<vector<int>> &ch, vector<T> &a, T E){
    int N = a.size();
    left = vector<int>(N, 0);
    right = vector<int>(N, 0);
    dfs(ch, a);
    LCA = lowest_common_ancestor(ch);
    ST = segment_tree(A, E);
  }
  void update(int v, T x){
    ST.update(left[v], x);
    ST.update(right[v], -x);
  }
  T query(int v, int w){
    int u = LCA.lca(v, w);
    return ST.query(left[u], left[v] + 1) + ST.query(left[u] + 1, left[w] + 1);
  }
};
pair<int, int> operator +(pair<int, int> A, pair<int, int> B){
  return make_pair(A.first + B.first, A.second + B.second);
}
pair<int, int> operator -(pair<int, int> A){
  return make_pair(-A.first, -A.second);
}
int main(){
  int N, Q;
  cin >> N >> Q;
  vector<vector<tuple<int, int, int>>> E(N);
  for (int i = 0; i < N - 1; i++){
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    E[a].push_back(make_tuple(b, c, d));
    E[b].push_back(make_tuple(a, c, d));
  }
  vector<int> c(N), d(N, 0);
  vector<int> p(N, -1);
  vector<bool> used(N, false);
  used[0] = true;
  queue<int> q;
  q.push(0);
  while (!q.empty()){
    int v = q.front();
    q.pop();
    for (auto edge : E[v]){
      int w = get<0>(edge);
      if (!used[w]){
        used[w] = true;
        p[w] = v;
        c[w] = get<1>(edge);
        d[w] = get<2>(edge);
        q.push(w);
      }
    }
  }
  map<int, vector<int>> mp;
  for (int i = 1; i < N; i++){
    mp[c[i]].push_back(i);
  }
  vector<vector<int>> ch(N);
  for (int i = 1; i < N; i++){
    ch[p[i]].push_back(i);
  }
  vector<pair<int, int>> d2(N);
  for (int i = 0; i < N; i++){
    d2[i] = make_pair(d[i], 0);
  }
  euler_tour<pair<int, int>> T(ch, d2, make_pair(0, 0));
  return 0;
  vector<tuple<int, int, int, int, int>> query(Q);
  for (int i = 0; i < Q; i++){
    int x, y, u, v;
    cin >> x >> y >> u >> v;
    u--;
    v--;
    query[i] = make_tuple(x, y, u, v, i);
  }
  sort(query.begin(), query.end());
  int color = -1;
  vector<int> ans(Q);
  int cnt = 0;
  for (int i = 0; i < Q; i++){
    int x = get<0>(query[i]);
    int y = get<1>(query[i]);
    int u = get<2>(query[i]);
    int v = get<3>(query[i]);
    int id = get<4>(query[i]);
    if (color != x){
      if (color != -1){
        for (int w : mp[color]){
          T.update(w, d2[w]);
          cnt++;
        }
      }
      color = x;
      for (int w : mp[color]){
        T.update(w, make_pair(0, 1));
        cnt++;
      }
    }
    pair<int, int> tmp = T.query(u, v);
    ans[id] = tmp.first + tmp.second * y;
    if (cnt > N * 2){
      cout << "error" << endl;
      return 0;
    }
  }
  for (int i = 0; i < Q; i++){
    cout << ans[i] << endl;
  }
}