import sys

read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



import numpy as np



N,Q = list(map(int,readline().split()))

data = np.array(read().split(),np.int64)



ABCD = data[:4*N-4].reshape(-1,4).tolist()



graph = [[] for _ in range(N+1)]

for a,b,c,d in ABCD:

    graph[a].append((b,c,d))

    graph[b].append((a,c,d))



color = [0] * (N+1) # 自身と親を結ぶ辺の色

length = [0] * (N+1) # 自身と親を結ぶ辺の長さ



def EulerTour(graph,start=1):

    """

    1-indexed graph

    graphを破壊しているので場合によっては注意

    """

    V = len(graph)

    par = [0] * V

    depth = [0] * V; depth[start] = 0

    tour = [start]; st = [start]

    while st:

        x = st[-1]

        if not graph[x]:

            st.pop()

            tour.append(par[x])

            continue

        y,c,d = graph[x].pop()

        if y == par[x]:

            continue

        par[y] = x

        color[y] = c

        length[y] = d

        depth[y] = depth[x] + 1

        st.append(y)

        tour.append(y)

    return tour,depth



tour,depth = EulerTour(graph)



Ltour = len(tour)

tour_arr = np.array(tour)

depth_arr = np.array(depth)

tour_d = depth_arr[tour_arr]

idx = np.arange(len(depth))

idx[tour_arr] = np.arange(Ltour)



# depth最小を実現するインデックスのsparse tableを作る

sp = np.empty((Ltour.bit_length(),Ltour),np.int32)

sp[0] = np.arange(Ltour)

for n in range(1,Ltour.bit_length()):

    prev,width = sp[n-1],1<<(n-1)

    x = prev[:-width]; y = prev[width:]

    condition = tour_d[x] > tour_d[y]

    sp[n] = prev

    sp[n,:-width][condition] = y[condition]



def LCA(A,B):

    AB = np.vstack([A,B]).T

    LR = idx[AB]

    LR.sort(axis=1)

    # [L,R] におけるRmQ

    L = LR[:,0]; R = LR[:,1]

    x = R-L

    n = np.zeros_like(x) # 2^n <= R-L

    for _ in range(20):

        x >>= 1

        n[x>0] += 1

    x = sp[n,L]; y = sp[n,R-(1<<n)+1]

    return np.where(tour_d[x] < tour_d[y], tour_arr[x], tour_arr[y])



XYUV = data[4*N-4:]

U = XYUV[2::4]; V = XYUV[3::4]

lca = LCA(U,V)



answer = [0] * Q

task = [[] for _ in range(N+1)]

for i,((x,y,u,v),w) in enumerate(zip(XYUV.reshape(-1,4),lca)):

    # x,yの条件下での距離の何倍かをanswer[i]に加算する

    task[u].append((x,y,1,i))

    task[v].append((x,y,1,i))

    task[w].append((x,y,-2,i))



color_cnt = [0] * N

color_sum = [0] * N

d = 0 # いじらないときの距離



for fr,to in zip(tour,tour[1:]):

    d1 = depth[fr]; d2 = depth[to]

    if d1 > d2:

        # 上る前にクエリ処理

        for x,y,coef,i in task[fr]:

            answer[i] += coef * (d - color_sum[x] + color_cnt[x] * y)

    if d1 < d2:

        c = color[to]; l = length[to]

        color_cnt[c] += 1

        color_sum[c] += l; d += l

    else:

        c = color[fr]; l = length[fr]

        color_cnt[c] -= 1

        color_sum[c] -= l; d -= l



print(('\n'.join(map(str,answer))))
import sys

read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



import numpy as np



N,Q = list(map(int,readline().split()))

data = np.array(read().split(),np.int64)



ABCD = data[:4*N-4].reshape(-1,4).tolist()



graph = [[] for _ in range(N+1)]

for a,b,c,d in ABCD:

    graph[a].append((b,c,d))

    graph[b].append((a,c,d))



color = [0] * (N+1) # 自身と親を結ぶ辺の色

length = [0] * (N+1) # 自身と親を結ぶ辺の長さ



def EulerTour(graph,start=1):

    """

    1-indexed graph

    graphを破壊しているので場合によっては注意

    """

    V = len(graph)

    par = [0] * V

    depth = [0] * V; depth[start] = 0

    tour = [start]; st = [start]

    while st:

        x = st[-1]

        if not graph[x]:

            st.pop()

            tour.append(par[x])

            continue

        y,c,d = graph[x].pop()

        if y == par[x]:

            continue

        par[y] = x

        color[y] = c

        length[y] = d

        depth[y] = depth[x] + 1

        st.append(y)

        tour.append(y)

    return tour,depth



tour,depth = EulerTour(graph)



Ltour = len(tour)

tour_arr = np.array(tour)

depth_arr = np.array(depth)

tour_d = depth_arr[tour_arr]

idx = np.arange(len(depth))

idx[tour_arr] = np.arange(Ltour)



# depth最小を実現するインデックスのsparse tableを作る

sp = np.empty((Ltour.bit_length(),Ltour),np.int32)

sp[0] = np.arange(Ltour)

for n in range(1,Ltour.bit_length()):

    prev,width = sp[n-1],1<<(n-1)

    x = prev[:-width]; y = prev[width:]

    condition = tour_d[x] > tour_d[y]

    sp[n] = prev

    sp[n,:-width][condition] = y[condition]



def LCA(A,B):

    AB = np.vstack([A,B]).T

    LR = idx[AB]

    LR.sort(axis=1)

    # [L,R] におけるRmQ

    L = LR[:,0]; R = LR[:,1]

    x = R-L

    n = np.zeros_like(x) # 2^n <= R-L

    for _ in range(20):

        x >>= 1

        n[x>0] += 1

    x = sp[n,L]; y = sp[n,R-(1<<n)+1]

    return np.where(tour_d[x] < tour_d[y], tour_arr[x], tour_arr[y])



XYUV = data[4*N-4:]

U = XYUV[2::4]; V = XYUV[3::4]

lca = LCA(U,V)



answer = [0] * Q

task = [[] for _ in range(N+1)]

for i,((x,y,u,v),w) in enumerate(zip(XYUV.reshape(-1,4).tolist(),lca.tolist())):

    # x,yの条件下での距離の何倍かをanswer[i]に加算する

    task[u].append((x,y,1,i))

    task[v].append((x,y,1,i))

    task[w].append((x,y,-2,i))



color_cnt = [0] * N

color_sum = [0] * N

d = 0 # いじらないときの距離



for fr,to in zip(tour,tour[1:]):

    d1 = depth[fr]; d2 = depth[to]

    if d1 > d2:

        # 上る前にクエリ処理

        for x,y,coef,i in task[fr]:

            answer[i] += coef * (d - color_sum[x] + color_cnt[x] * y)

    if d1 < d2:

        c = color[to]; l = length[to]

        color_cnt[c] += 1

        color_sum[c] += l; d += l

    else:

        c = color[fr]; l = length[fr]

        color_cnt[c] -= 1

        color_sum[c] -= l; d -= l



print(('\n'.join(map(str,answer))))
import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np

N, Q = list(map(int, readline().split()))
data = np.array(read().split(), np.int64)
ABCD = data[: 4 * N - 4].reshape(-1, 4).tolist()
graph = [[] for _ in range(N + 1)]
for a, b, c, d in ABCD:
    graph[a].append((b, c, d))
    graph[b].append((a, c, d))
color = [0] * (N + 1)  # 自身と親を結ぶ辺の色
length = [0] * (N + 1)  # 自身と親を結ぶ辺の長さ


def EulerTour(graph, start=1):
    """
    1-indexed graph
    graphを破壊しているので場合によっては注意
    """
    V = len(graph)
    par = [0] * V
    depth = [0] * V
    depth[start] = 0
    tour = [start]
    st = [start]
    while st:
        x = st[-1]
        if not graph[x]:
            st.pop()
            tour.append(par[x])
            continue
        y, c, d = graph[x].pop()
        if y == par[x]:
            continue
        par[y] = x
        color[y] = c
        length[y] = d
        depth[y] = depth[x] + 1
        st.append(y)
        tour.append(y)
    return tour, depth


tour, depth = EulerTour(graph)
Ltour = len(tour)
tour_arr = np.array(tour)
depth_arr = np.array(depth)
tour_d = depth_arr[tour_arr]
idx = np.arange(len(depth))
idx[tour_arr] = np.arange(Ltour)
# depth最小を実現するインデックスのsparse tableを作る
sp = np.empty((Ltour.bit_length(), Ltour), np.int32)
sp[0] = np.arange(Ltour)
for n in range(1, Ltour.bit_length()):
    prev, width = sp[n - 1], 1 << (n - 1)
    x = prev[:-width]
    y = prev[width:]
    condition = tour_d[x] > tour_d[y]
    sp[n] = prev
    sp[n, :-width][condition] = y[condition]


def LCA(A, B):
    AB = np.vstack([A, B]).T
    LR = idx[AB]
    LR.sort(axis=1)
    # [L,R] におけるRmQ
    L = LR[:, 0]
    R = LR[:, 1]
    x = R - L
    n = np.zeros_like(x)  # 2^n <= R-L
    for _ in range(20):
        x >>= 1
        n[x > 0] += 1
    x = sp[n, L]
    y = sp[n, R - (1 << n) + 1]
    return np.where(tour_d[x] < tour_d[y], tour_arr[x], tour_arr[y])


XYUV = data[4 * N - 4 :]
U = XYUV[2::4]
V = XYUV[3::4]
lca = LCA(U, V)
answer = [0] * Q
task = [[] for _ in range(N + 1)]
for i, ((x, y, u, v), w) in enumerate(zip(XYUV.reshape(-1, 4), lca)):
    # x,yの条件下での距離の何倍かをanswer[i]に加算する
    task[u].append((x, y, 1, i))
    task[v].append((x, y, 1, i))
    task[w].append((x, y, -2, i))
color_cnt = [0] * N
color_sum = [0] * N
d = 0  # いじらないときの距離
for fr, to in zip(tour, tour[1:]):
    d1 = depth[fr]
    d2 = depth[to]
    if d1 > d2:
        # 上る前にクエリ処理
        for x, y, coef, i in task[fr]:
            answer[i] += coef * (d - color_sum[x] + color_cnt[x] * y)
    if d1 < d2:
        c = color[to]
        l = length[to]
        color_cnt[c] += 1
        color_sum[c] += l
        d += l
    else:
        c = color[fr]
        l = length[fr]
        color_cnt[c] -= 1
        color_sum[c] -= l
        d -= l
print(("\n".join(map(str, answer))))

import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np

N, Q = list(map(int, readline().split()))
data = np.array(read().split(), np.int64)
ABCD = data[: 4 * N - 4].reshape(-1, 4).tolist()
graph = [[] for _ in range(N + 1)]
for a, b, c, d in ABCD:
    graph[a].append((b, c, d))
    graph[b].append((a, c, d))
color = [0] * (N + 1)  # 自身と親を結ぶ辺の色
length = [0] * (N + 1)  # 自身と親を結ぶ辺の長さ


def EulerTour(graph, start=1):
    """
    1-indexed graph
    graphを破壊しているので場合によっては注意
    """
    V = len(graph)
    par = [0] * V
    depth = [0] * V
    depth[start] = 0
    tour = [start]
    st = [start]
    while st:
        x = st[-1]
        if not graph[x]:
            st.pop()
            tour.append(par[x])
            continue
        y, c, d = graph[x].pop()
        if y == par[x]:
            continue
        par[y] = x
        color[y] = c
        length[y] = d
        depth[y] = depth[x] + 1
        st.append(y)
        tour.append(y)
    return tour, depth


tour, depth = EulerTour(graph)
Ltour = len(tour)
tour_arr = np.array(tour)
depth_arr = np.array(depth)
tour_d = depth_arr[tour_arr]
idx = np.arange(len(depth))
idx[tour_arr] = np.arange(Ltour)
# depth最小を実現するインデックスのsparse tableを作る
sp = np.empty((Ltour.bit_length(), Ltour), np.int32)
sp[0] = np.arange(Ltour)
for n in range(1, Ltour.bit_length()):
    prev, width = sp[n - 1], 1 << (n - 1)
    x = prev[:-width]
    y = prev[width:]
    condition = tour_d[x] > tour_d[y]
    sp[n] = prev
    sp[n, :-width][condition] = y[condition]


def LCA(A, B):
    AB = np.vstack([A, B]).T
    LR = idx[AB]
    LR.sort(axis=1)
    # [L,R] におけるRmQ
    L = LR[:, 0]
    R = LR[:, 1]
    x = R - L
    n = np.zeros_like(x)  # 2^n <= R-L
    for _ in range(20):
        x >>= 1
        n[x > 0] += 1
    x = sp[n, L]
    y = sp[n, R - (1 << n) + 1]
    return np.where(tour_d[x] < tour_d[y], tour_arr[x], tour_arr[y])


XYUV = data[4 * N - 4 :]
U = XYUV[2::4]
V = XYUV[3::4]
lca = LCA(U, V)
answer = [0] * Q
task = [[] for _ in range(N + 1)]
for i, ((x, y, u, v), w) in enumerate(zip(XYUV.reshape(-1, 4).tolist(), lca.tolist())):
    # x,yの条件下での距離の何倍かをanswer[i]に加算する
    task[u].append((x, y, 1, i))
    task[v].append((x, y, 1, i))
    task[w].append((x, y, -2, i))
color_cnt = [0] * N
color_sum = [0] * N
d = 0  # いじらないときの距離
for fr, to in zip(tour, tour[1:]):
    d1 = depth[fr]
    d2 = depth[to]
    if d1 > d2:
        # 上る前にクエリ処理
        for x, y, coef, i in task[fr]:
            answer[i] += coef * (d - color_sum[x] + color_cnt[x] * y)
    if d1 < d2:
        c = color[to]
        l = length[to]
        color_cnt[c] += 1
        color_sum[c] += l
        d += l
    else:
        c = color[fr]
        l = length[fr]
        color_cnt[c] -= 1
        color_sum[c] -= l
        d -= l
print(("\n".join(map(str, answer))))

-for i, ((x, y, u, v), w) in enumerate(zip(XYUV.reshape(-1, 4), lca)): +for i, ((x, y, u, v), w) in enumerate(zip(XYUV.reshape(-1, 4).tolist(), lca.tolist())):