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: Wrong Answer)

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];

            Queue<int[]> que = new Queue<int[]>();
            Queue<int> next = new Queue<int>();

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

                p[0] = int.Parse(s[0])-1;
                p[1] = int.Parse(s[1])-1;
                p[2] = int.Parse(s[2]);
                p[3] = int.Parse(s[3]);

                que.Enqueue(p);
            }

            next.Enqueue(0);
            int[][] x = new int[N][];

            x[0] = new int[4];
            x[0][0] = 0;
            x[0][1] = 0;
            x[0][2] = 0;

            while (que.Count > 0)
            {
                int point = next.Dequeue();

                int counter = que.Count;

                for(int i=0;i<counter;i++)
                {
                    int[] pop = que.Dequeue();

                    if (pop[0] == point)
                    {
                        x[pop[1]] = new int[3];
                        x[pop[1]][0] = pop[0];
                        x[pop[1]][1] = pop[2];
                        x[pop[1]][2] = pop[3];

                        next.Enqueue(pop[1]);
                    }
                    else if (pop[1] == point)
                    {
                        x[pop[0]] = new int[3];
                        x[pop[0]][0] = pop[1];
                        x[pop[0]][1] = pop[2];
                        x[pop[0]][2] = pop[3];

                        next.Enqueue(pop[0]);
                    }
                    else
                        que.Enqueue(pop);

                    if (que.Count == 0)
                        break;
                }
            }

            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[] path = getPath(a, b, x);

                for(int i=0;i<path.Length;i++)
                {
                    int point = path[i];

                    if (x[point][1] == color)
                        ans[q] += l;
                    else
                        ans[q] += x[point][2];

                }
            }

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

        }

        static int[] getPath(int a,int b,int[][] x)
        {
            Queue<int> aque = getQue(a,x);
            Queue<int> bque = getQue(b,x);

            while(aque.Peek() == bque.Peek())
            {
                aque.Dequeue();
                bque.Dequeue();
            }

            int[] ret = new int[aque.Count + bque.Count];

            int acount = aque.Count;

            for(int i=0;i<acount;i++)
            {
                ret[i] = aque.Dequeue();
            }

            int bcount = acount + bque.Count;

            for (int i = acount; i < bcount; i++)
            {
                ret[i] = bque.Dequeue();
            }

            return ret;
        }

        static Queue<int> getQue(int a,int[][] x)
        {
            Queue<int> que = new Queue<int>();

            int point = a;

            while(point != 0)
            {
                que.Enqueue(point);
                point = x[point][0];
            }

            que.Enqueue(0);

            return que;
        }
    }
}