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# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;

namespace AtCoderABC133F
{
    class Program
    {
        static void Main(string[] args)
        {

            string[] s = Console.ReadLine().Split(' ');

            int N = int.Parse(s[0]);
            int Q = int.Parse(s[1]);

            int[] ans = new int[Q];

            List<int[]>[] lists = new List<int[]>[N];

            for (int i = 0; i < N; i++)
            {
                lists[i] = new List<int[]>();
            }

            for (int i = 0; i < N-1; i++)
            {
                s = Console.ReadLine().Split(' ');

                int p1 = int.Parse(s[0])-1;
                int p2 = int.Parse(s[1])-1;
                int col = int.Parse(s[2]);
                int len = int.Parse(s[3]);

                lists[p1].Add(new int[] { p2, col, len });
                lists[p2].Add(new int[] { p1, col, len });
            }

            int[][] tree = new int[N][];

            tree[0] = new int[3];
            tree[0][0] = 0;
            tree[0][1] = 0;
            tree[0][2] = 0;

            tree = maketree(0, 0, tree, lists);

            for(int q=0;q<Q;q++)
            {
                s = Console.ReadLine().Split(' ');

                int a = int.Parse(s[2])-1;
                int b = int.Parse(s[3])-1;
                int color = int.Parse(s[0]);
                int l = int.Parse(s[1]);

                int root=0;
                if (a != 0 && b != 0)
                    root = getRoot(a, b, tree);

                if(a != b)
                    ans[q] = getLength(a, root, color, l, tree) + getLength(b, root, color, l, tree);
            }

            for(int i=0;i<Q;i++)
            {
                Console.WriteLine(ans[i].ToString());
            }

        }

        static int getLength(int a,int root,int col,int length,int[][] tree)
        {
            int p = a;
            int ans = 0;

            while(p != root)
            {
                if (tree[p][1] == col)
                    ans += length;
                else
                    ans += tree[p][2];

                p = tree[p][0];
            }

            return ans;
        }

        static int[][] maketree(int p,int c,int[][] tree,List<int[]>[] lists)
        {
            List<int[]> branch = lists[c];

            for(int i=0;i<branch.Count;i++)
            {
                if(branch[i][0] != p)
                {
                    tree[branch[i][0]] = new int[3];
                    tree[branch[i][0]][0] = c;
                    tree[branch[i][0]][1] = branch[i][1];
                    tree[branch[i][0]][2] = branch[i][2];
                    tree = maketree(c, branch[i][0], tree, lists);
                }
            }

            return tree;

        }

        static int getRoot(int a, int b,int[][] tree)
        {
            Stack<int> A = new Stack<int>();
            Stack<int> B = new Stack<int>();

            int ap = a;
            int bp = b;

            while(ap!=0)
            {
                A.Push(ap);
                ap = tree[ap][0];
            }

            while (bp != 0)
            {
                B.Push(bp);
                bp = tree[bp][0];
            }

            int ret = 0;

            ap = 0;
            bp = 0;

            while(ap == bp)
            {
                ret = ap;

                ap = A.Pop();
                bp = B.Pop();
            }

            return ret;
        }
    }
}