using CompLib.Util;
using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    int N, Q;
    List<Edge>[] E;

    int[] X, U, V;
    long[] Y;

    // LCA[i] ノードiが最近共通祖先になるクエリ
    List<int>[] LCAList;

    // ノードiがU,Vになるクエリ
    List<int>[] UVList;

    // 子に向く辺
    List<Edge>[] Tree;
    // 2^i個上の祖先
    List<int>[] _ancestor;

    int[] Depth;

    long[] Ans;

    void Scan()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        Q = sc.NextInt();
        E = new List<Edge>[N];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<Edge>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int a = sc.NextInt() - 1;
            int b = sc.NextInt() - 1;
            int c = sc.NextInt() - 1;
            long d = sc.NextLong();

            E[a].Add(new Edge(b, c, d));
            E[b].Add(new Edge(a, c, d));
        }

        X = new int[Q];
        Y = new long[Q];
        U = new int[Q];
        V = new int[Q];
        UVList = new List<int>[N];

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

        for (int i = 0; i < Q; i++)
        {
            X[i] = sc.NextInt() - 1;
            Y[i] = sc.NextLong();
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            U[i] = u;
            V[i] = v;
            UVList[u].Add(i);
            UVList[v].Add(i);
        }
    }

    void Build()
    {

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

        Depth = new int[N];
        for (int i = 0; i < N; i++)
        {
            Depth[i] = -1;
        }

        var q = new Queue<int>();
        q.Enqueue(0);
        Depth[0] = 0;

        while (q.Count > 0)
        {
            var d = q.Dequeue();
            foreach (var e in E[d])
            {
                if (Depth[e.To] != -1) continue;
                Tree[d].Add(e);
                Depth[e.To] = Depth[d] + 1;
                q.Enqueue(e.To);

                _ancestor[e.To].Add(d);
            }

            int t = Depth[d] / 2;
            while (t > 0)
            {
                int count = _ancestor[d].Count;
                int last = _ancestor[d][count - 1];
                _ancestor[d].Add(_ancestor[last][count - 1]);
                t /= 2;
            }
        }

    }


    // ノードlのn個上の祖先
    int Ancestor(int l, int n, int index = 0)
    {
        if (n == 0) return l;

        for (int i = index; ; i++)
        {
            if ((n & (1 << i)) > 0)
            {
                return Ancestor(_ancestor[l][i], n - (1 << i), i + 1);
            }
        }
    }

    int LCA(int l, int r)
    {
        // 高さを合わせる

        int dl = Depth[l];
        int dr = Depth[r];

        if (dl < dr)
        {
            r = Ancestor(r, dr - dl);
        }
        else
        {
            l = Ancestor(l, dl - dr);
        }

        if (l == r) return l;

        for (int i = _ancestor[l].Count - 1; i >= 0; i--)
        {
            if (i >= _ancestor[l].Count) continue;
            if (_ancestor[l][i] != _ancestor[r][i])
            {
                l = _ancestor[l][i];
                r = _ancestor[r][i];
            }
        }

        return _ancestor[l][0];
    }

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

        for (int i = 0; i < Q; i++)
        {
            LCAList[LCA(U[i], V[i])].Add(i);
        }
    }

    void Query()
    {
        Ans = new long[Q];
        var stack = new int[N];
        var index = new int[N];
        for (int i = 0; i < N; i++)
        {
            index[i] = -1;
        }
        int ptr = 0;

        long dist = 0;
        int[] cnt = new int[N - 1];
        long[] sum = new long[N - 1];

        while (ptr >= 0)
        {
            index[ptr]++;
            if (index[ptr] < Tree[stack[ptr]].Count)
            {
                var e = Tree[stack[ptr]][index[ptr]];
                dist += e.D;
                cnt[e.C]++;
                sum[e.C] += e.D;
                stack[ptr + 1] = e.To;
                ptr++;
            }
            else
            {
                index[ptr] = -1;

                foreach (int q in UVList[stack[ptr]])
                {
                    Ans[q] += dist - sum[X[q]] + Y[q] * cnt[X[q]];
                }

                foreach (int q in LCAList[stack[ptr]])
                {
                    Ans[q] -= (dist - sum[X[q]] + Y[q] * cnt[X[q]]) * 2;
                }

                ptr--;
                if (ptr >= 0)
                {
                    var e = Tree[stack[ptr]][index[ptr]];
                    dist -= e.D;
                    cnt[e.C]--;
                    sum[e.C] -= e.D;
                }
            }
        }
    }

    public void Solve()
    {
        Scan();
        Build();
        CalcLCA();
        Query();

        Console.WriteLine(string.Join("\n", Ans));
    }



    public static void Main(string[] args) => new Program().Solve();
}

struct Edge
{
    public int To, C;
    public long D;
    public Edge(int to, int c, long d)
    {
        To = to;
        C = c;
        D = d;
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;
    class Scanner
    {
        private int _index;
        private string[] _line;
        const char separator = ' ';

        public Scanner()
        {
            _index = 0;
            _line = new string[0];
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(separator);
                _index = 0;
            }
            return _line[_index++];
        }
        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(separator);
            _index = _line.Length;
            return _line;
        }
        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
    }
}

Measured memory_bytes: 86788