output_description: Print Q lines. The j-th line (1 \leq j \leq Q) should contain the answer to
  Query j.
  
  * * *
input_description: 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
attempt: class Tree:  # weighted
      def __init__(self, n, edge):
          self.n = n
          self.tree = [[] for _ in range(n)]
          for e in edge:
              self.tree[e[0] - 1].append((e[1] - 1, e[2] - 1, e[3]))
              self.tree[e[1] - 1].append((e[0] - 1, e[2] - 1, e[3]))
  
      def setroot(self, root):
          self.root = root
          self.parent = [None for _ in range(self.n)]
          self.parent[root] = -1
          self.depth = [None for _ in range(self.n)]
          self.depth[root] = 0
          self.distance = [None for _ in range(self.n)]
          self.distance[root] = 0
          self.order = []
          self.order.append(root)
          self.color = [None for _ in range(self.n)]
          self.cost = [0 for _ in range(self.n)]
          self.size = [1 for _ in range(self.n)]
          stack = [root]
          while stack:
              node = stack.pop()
              for adj, color, cost in self.tree[node]:
                  if self.parent[adj] is None:
                      self.parent[adj] = node
                      self.depth[adj] = self.depth[node] + 1
                      self.distance[adj] = self.distance[node] + cost
                      self.color[adj] = color
                      self.cost[adj] = cost
                      self.order.append(adj)
                      stack.append(adj)
          for node in self.order[::-1]:
              for adj, color, cost in self.tree[node]:
                  if self.parent[node] == adj:
                      continue
                  self.size[node] += self.size[adj]
  
      def heavylight_decomposition(self):
          self.order = [None for _ in range(self.n)]
          self.head = [None for _ in range(self.n)]
          self.head[self.root] = self.root
          self.next = [None for _ in range(self.n)]
          stack = [self.root]
          order = 0
          while stack:
              node = stack.pop()
              self.order[node] = order
              order += 1
              maxsize = 0
              for adj, color, cost in self.tree[node]:
                  if self.parent[node] == adj:
                      continue
                  if maxsize < self.size[adj]:
                      maxsize = self.size[adj]
                      self.next[node] = adj
              for adj, color, cost in self.tree[node]:
                  if self.parent[node] == adj or self.next[node] == adj:
                      continue
                  self.head[adj] = adj
                  stack.append(adj)
              if self.next[node] is not None:
                  self.head[self.next[node]] = self.head[node]
                  stack.append(self.next[node])
  
      def range_hld(self, u, v, edge=False):
          res = []
          while True:
              if self.order[u] > self.order[v]:
                  u, v = v, u
              if self.head[u] != self.head[v]:
                  res.append((self.order[self.head[v]], self.order[v] + 1))
                  v = self.parent[self.head[v]]
              else:
                  res.append((self.order[u] + edge, self.order[v] + 1))
                  return res
  
      def subtree_hld(self, u):
          return self.order[u], self.order[u] + self.size[u]
  
      def lca_hld(self, u, v):
          while True:
              if self.order[u] > self.order[v]:
                  u, v = v, u
              if self.head[u] != self.head[v]:
                  v = self.parent[self.head[v]]
              else:
                  return u
  
  
  class SegmentTree:
      def __init__(self, arr, func=min, ie=2**63):
          self.h = (len(arr) - 1).bit_length()
          self.n = 2**self.h
          self.ie = ie
          self.func = func
          self.tree = [ie for _ in range(2 * self.n)]
          for i in range(len(arr)):
              self.tree[self.n + i] = arr[i]
          for i in range(1, self.n)[::-1]:
              self.tree[i] = func(self.tree[2 * i], self.tree[2 * i + 1])
  
      def set(self, idx, x):
          idx += self.n
          self.tree[idx] = x
          while idx:
              idx >>= 1
              self.tree[idx] = self.func(self.tree[2 * idx], self.tree[2 * idx + 1])
  
      def query(self, lt, rt):
          lt += self.n
          rt += self.n
          vl = vr = self.ie
          while rt - lt > 0:
              if lt & 1:
                  vl = self.func(vl, self.tree[lt])
                  lt += 1
              if rt & 1:
                  rt -= 1
                  vr = self.func(self.tree[rt], vr)
              lt >>= 1
              rt >>= 1
          return self.func(vl, vr)
  
  
  import sys
  
  input = sys.stdin.readline
  
  N, Q = map(int, input().split())
  
  edge = [tuple(map(int, input().split())) for _ in range(N - 1)]
  query = [tuple(map(int, input().split())) for _ in range(Q)]
  
  tree = Tree(N, edge)
  tree.setroot(0)
  tree.heavylight_decomposition()
  
  arr = [None for _ in range(N)]
  
  for i in range(N):
      arr[tree.order[i]] = (tree.cost[i], 0)
  
  
  def func(x, y):
      x0, x1 = x
      y0, y1 = y
      return x0 + y0, x1 + y1
  
  
  ie = (0, 0)
  
  st = SegmentTree(arr, func, ie)
  
  query_color = [[] for _ in range(N)]
  
  for j in range(Q):
      x, y, u, v = query[j]
      query_color[x - 1].append((y, u, v, j))
  
  node_color = [[] for _ in range(N)]
  
  for i in range(1, N):
      node_color[tree.color[i]].append(i)
  
  res = [0 for _ in range(Q)]
  
  for i in range(N):
      for node in node_color[i]:
          st.set(tree.order[node], (0, 1))
  
      for y, u, v, j in query_color[i]:
          for lt, rt in tree.range_hld(u - 1, v - 1, True):
              d, k = st.query(lt, rt)
              res[j] += d + k * y
  
      for node in node_color[i]:
          st.set(tree.order[node], (tree.cost[node], 0))
  
  print("\n".join(map(str, res)))
  
problem_description: 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.)
samples: [{"input": "5 3\n    1 2 1 10\n    1 3 2 20\n    2 4 4 30\n    5 2 1 40\n    1 100 1 4\n    1 100 1 5\n    3 1000 3 4", "output": "130\n    200\n    60\n    \n\nThe graph in this input is as follows:\n\n![Figure](https://img.atcoder.jp/ghi/ca75688b08f73eb63a30ce6daa54a781.png)\n\nHere the edges of Color 1 are shown as solid red lines, the edge of Color 2 is\nshown as a bold green line, and the edge of Color 4 is shown as a blue dashed\nline.\n\n  * 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.\n  * 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.\n  * 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."}]