Language: C++

#include <iostream>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#include <cassert>
#include <random>
#include <functional>
#include <stack>
#include <iomanip>
#include <cassert>
//#include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>
#include <bitset>

//< in.txt > out.txt
using namespace std;
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
const long long MOD = 998244353;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
typedef pair<LL, LL> PLL;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned long long ULL;
//typedef boost::multiprecision::cpp_int bigint;

template<class T>
struct Gedge {
	LL src,to;
	T cost;
	Gedge(LL s,LL t, T c) :src(s),to(t), cost(c) {}
	Gedge(LL t, T c) :src(-1), to(t), cost(c) {}
};

template<class T>
using WeightedGraph = vector<vector<Gedge<T>>>;
using UnweightedGraph = vector<vector<LL>>;
template<class T>
using Gedges = vector<Gedge<T>>;

//require Monoid
template<class T>
class Segtree {
private:
	vector<T> seg;
	LL RN;
public:
	Segtree(LL N) {
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, T());
	}
	Segtree(vector<T>& V) {
		LL N = V.size();
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, T());
		for (LL n = 0; n < N; n++) seg[RN + n] = V[n];
		for (LL k = RN - 1; k >= 1; k--) {
			seg[k] = seg[2 * k] * seg[2 * k + 1];
		}
	}
	//set n-th as x(0 index!!!!!)
	void set(LL n, T x) {
		seg[RN + n] = x;
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = seg[2 * n] * seg[2 * n + 1];
			n /= 2;
		}
	}
	//change n-th number p to x*p(0 index!!!!!)
	void addl(LL n, T x) {
		seg[RN + n] = x*seg[RN+n];
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = seg[2 * n] * seg[2 * n + 1];
			n /= 2;
		}
	}
	//change n-th number p to p*x(0 index!!!!!)
	void addr(LL n, T x) {
		seg[RN + n] = seg[RN + n]*x;
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = seg[2 * n] * seg[2 * n + 1];
			n /= 2;
		}
	}
	//get [l,r] (0 index!!!!!)
	T get(LL l, LL r) {
		T ansl, ansr;
		r++;
		l += RN;
		r += RN;
		while (l < r) {
			if (l & 1) {
				ansl = ansl * seg[l];
				l++;
			}
			if (r & 1) {
				r--;
				ansr = seg[r] * ansr;
			}
			l >>= 1;
			r >>= 1;
		}
		return ansl * ansr;
	}
	//get n-th number(0 index!!!!!)
	T get(LL n) {
		return seg[RN + n];
	}
	T operator[](LL n) {
		return seg[RN + n];
	}
};

struct TNode {
	LL parent;
	VLL childs;
	TNode() :parent(-1) {};
};
using Tree = vector<TNode>;

void ETSdfs(Tree& G, LL& id, vector<PLL>& range, LL n) {
	range[n].first = id++;
	for (LL ch : G[n].childs) {
		ETSdfs(G, id, range,ch);
	}
	range[n].second = id-1;
}

//dfs:dfsした順に頂点が格納される(重複無し、size = V)
//range:range[n] = (u,v) <==> dfs上でnの部分木は[u,v]
void EulerTour_subtree(Tree& G, vector<PLL>& range, LL root = 0) {
	range.resize(G.size());
	LL id = 0;
	ETSdfs(G, id, range, root);
}

struct ETPsegnode {
	LL n;
	LL d;
	ETPsegnode() :n(0), d(1e9) {};
	ETPsegnode(LL _n, LL _d) :n(_n), d(_d) {};
};

ETPsegnode operator*(ETPsegnode a, ETPsegnode b) {
	if (a.d < b.d)return a;
	else return b;
}

void ETPdfs(Tree& G, LL& ord, vector<ETPsegnode>& dfs, vector<PLL>& id, LL n) {
	if (ord == 0)dfs[ord] = { n, 0 };
	else {
		dfs[ord] = { n, dfs[ord - 1].d+1 };
	}
	id[n].first = ord++;
	for (LL ch : G[n].childs) {
		ETPdfs(G, ord, dfs, id, ch);
		dfs[ord] = { n, dfs[ord - 1].d-1 };
		ord++;
	}
	id[n].second = ord-1;
}

//dfs:dfsした順に頂点およびその深さが格納される(重複あり、size=2*V-1)
//id:dfsである頂点vが最初に出てくる添え字(つまりvの親->vをした時の添え字)
//辺(p(u),u)をxに更新
//->seg[id[u].first-1]をx、seg[id[u].second]を-xに
//パス(u,v) (lca(u,v) == u)での和を取得
//->seg[id[u].first]+...+seg[id[v].first-1]
void EulerTour_path(Tree& G, vector<ETPsegnode>& dfs, vector<PLL>& id, LL root = 0) {
	dfs.resize(2*G.size()-1);
	id.resize(G.size());
	LL ord = 0;
	ETPdfs(G, ord, dfs, id, root);
}

ETPsegnode LCA(Segtree<ETPsegnode>& seg, vector<PLL>& id, LL u, LL v) {
	if (id[u] > id[v])swap(u, v);
	return seg.get(id[u].first, id[v].first);
}

//辺(p(ch),ch)をxに更新
//->seg[id[ch].first-1]をx、seg[id[ch].second]を-xに
template<class T>
void ETP_set(vector<PLL>& id, Segtree<T>& seg, LL ch, T x,T nx) {
	seg.set([id[ch].first - 1],x);
	seg.set([id[ch].second],nx);
}

template<class T>
void ETP_add(vector<PLL>& id, Segtree<T>& seg, LL ch, T x, T nx) {
	seg.addl([id[ch].first - 1], x);
	seg.addl([id[ch].second], nx);
}

//パス(u,v) (lca(u,v) == u)での和を取得
//->seg[id[u].first]+...+seg[id[v].first-1]
template<class T>
T ETP_get(Segtree<ETPsegnode>& lcaseg, vector<PLL>& id, Segtree<T>& seg, LL u,LL v) {
	LL lca = LCA(lcaseg, id, u, v);
	T ans;
	if (lca == u) {
		return seg.get(id[u].first, id[v].first - 1);
	}
	else if (lca == v) {
		return seg.get(id[v].first, id[u].first - 1);
	}
	else {
		return seg.get(id[lca].first, id[u].first - 1) * seg.get(id[lca].first, id[v].first - 1);
	}
}

void SetTree(UnweightedGraph& G, Tree& T, LL root = 0) {
	T.resize(G.size());
	stack<PLL> st;
	st.push(PLL(root, -1));
	while (!st.empty()) {
		LL cur = st.top().first;
		LL p = st.top().second;
		st.pop();
		T[cur].parent = p;
		for (LL ch : G[cur]) {
			if (ch == p)continue;
			T[cur].childs.push_back(ch);
			st.push(PLL(ch, cur));
		}
	}
}

class Monoid {
public:
	LL v;
	Monoid(LL _v) :v(_v) {};
	Monoid() :v(0) {};
};
Monoid operator*(Monoid a, Monoid b) {
	return Monoid(a.v + b.v);
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	LL N, Q;
	cin >> N >> Q;
	Tree T;
	Segtree<Monoid> segn(1), segd(1);
	vector<PLL> id;
	Segtree<ETPsegnode> lcaseg(1);
	vector<vector<Gedge<LL>>> edges(N);   //src:親,to:子,cost:cost
	struct query {
		LL num;
		LL y;
		LL u,v;
		query(LL n, LL _y, LL _u,LL _v) :num(n), y(_y), u(_u),v(_v) {};
	};
	vector<vector<query>> querys(N);
	{
		UnweightedGraph G(N);
		VLL A(N), B(N), C(N);
		vector<Monoid> D(N);
		for (LL n = 0; n < N-1; n++) {
			cin >> A[n] >> B[n] >> C[n] >> D[n].v;
			A[n]--;
			B[n]--;
			G[A[n]].push_back(B[n]);
			G[B[n]].push_back(A[n]);
		}
		SetTree(G, T);
		vector<ETPsegnode> dfsres;
		EulerTour_path(T, dfsres, id);
		lcaseg = Segtree<ETPsegnode>(dfsres);
		segn = Segtree<Monoid>(2*N-1);
		segd = Segtree<Monoid>(2*N-1);
		for (LL n = 0; n < N-1; n++) {
			//A[n]がB[n]の親
			if (B[n] == T[A[n]].parent)swap(A[n], B[n]);
			edges[C[n]].push_back(Gedge<LL>(A[n], B[n], D[n].v));
			segd.addl(id[B[n]].first - 1, D[n]);
			segd.addl(id[B[n]].second, Monoid(-D[n].v));
		}
		for (LL q = 0; q < Q; q++) {
			LL x, y, u, v;
			cin >> x >> y >> u >> v;
			u--; v--;
			querys[x].push_back({ q,y,u,v });
		}
	}
	VLL ans(Q);
	for (LL color = 0; color < N; color++) {
		if (querys[color].size() == 0)continue;
		for (Gedge<LL>& e : edges[color]) {
			LL n = e.to;
			ETP_add(id, segn, n, Monoid(1), Monoid(-1));
			ETP_set(id, segd, n, Monoid(0), Monoid(0));
		}
		for (query& que : querys[color]) {
			LL u = que.u;
			LL v = que.v;
			LL p = ETP_get(lcaseg, id, segd, u, v).v;
			LL q = ETP_get(lcaseg, id, segn, u, v).v;
			ans[que.num] = p + q * que.y;
		}
		for (Gedge<LL>& e : edges[color]) {
			LL n = e.to;
			ETP_add(id, segn, n, Monoid(-1), Monoid(1));
			ETP_set(id, segd, n, Monoid(e.cost), Monoid(-e.cost));
		}
	}
	for (LL q = 0; q < Q; q++) {
		cout << ans[q] << "\n";
	}
	return 0;
}


Compiler output:
a.cc: In function 'void ETP_set(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T)':
a.cc:204:20: error: expected ',' before '[' token
  204 |         seg.set([id[ch].first - 1],x);
      |                    ^
      |                    ,
a.cc:204:20: error: expected identifier before '[' token
a.cc: In lambda function:
a.cc:204:35: error: expected '{' before ',' token
  204 |         seg.set([id[ch].first - 1],x);
      |                                   ^
a.cc: In function 'void ETP_set(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T)':
a.cc:205:20: error: expected ',' before '[' token
  205 |         seg.set([id[ch].second],nx);
      |                    ^
      |                    ,
a.cc:205:20: error: expected identifier before '[' token
a.cc: In lambda function:
a.cc:205:32: error: expected '{' before ',' token
  205 |         seg.set([id[ch].second],nx);
      |                                ^
a.cc: In function 'void ETP_add(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T)':
a.cc:210:21: error: expected ',' before '[' token
  210 |         seg.addl([id[ch].first - 1], x);
      |                     ^
      |                     ,
a.cc:210:21: error: expected identifier before '[' token
a.cc: In lambda function:
a.cc:210:36: error: expected '{' before ',' token
  210 |         seg.addl([id[ch].first - 1], x);
      |                                    ^
a.cc: In function 'void ETP_add(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T)':
a.cc:211:21: error: expected ',' before '[' token
  211 |         seg.addl([id[ch].second], nx);
      |                     ^
      |                     ,
a.cc:211:21: error: expected identifier before '[' token
a.cc: In lambda function:
a.cc:211:33: error: expected '{' before ',' token
  211 |         seg.addl([id[ch].second], nx);
      |                                 ^
a.cc: In instantiation of 'void ETP_add(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T) [with T = Monoid; LL = long long int]':
a.cc:311:11:   required from here
  311 |                         ETP_add(id, segn, n, Monoid(1), Monoid(-1));
      |                         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:210:18: error: cannot convert 'ETP_add<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>' to 'LL' {aka 'long long int'}
  210 |         seg.addl([id[ch].first - 1], x);
      |                  ^~~~~~~~~~~~~~~~~~
      |                  |
      |                  ETP_add<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>
a.cc:87:22: note:   initializing argument 1 of 'void Segtree<T>::addl(LL, T) [with T = Monoid; LL = long long int]'
   87 |         void addl(LL n, T x) {
      |                   ~~~^
a.cc:211:18: error: cannot convert 'ETP_add<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>' to 'LL' {aka 'long long int'}
  211 |         seg.addl([id[ch].second], nx);
      |                  ^~~~~~~~~~~~~~~
      |                  |
      |                  ETP_add<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>
a.cc:87:22: note:   initializing argument 1 of 'void Segtree<T>::addl(LL, T) [with T = Monoid; LL = long long int]'
   87 |         void addl(LL n, T x) {
      |                   ~~~^
a.cc: In instantiation of 'void ETP_set(std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, T, T) [with T = Monoid; LL = long long int]':
a.cc:312:11:   required from here
  312 |                         ETP_set(id, segd, n, Monoid(0), Monoid(0));
      |                         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:204:17: error: cannot convert 'ETP_set<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>' to 'LL' {aka 'long long int'}
  204 |         seg.set([id[ch].first - 1],x);
      |                 ^~~~~~~~~~~~~~~~~~
      |                 |
      |                 ETP_set<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>
a.cc:78:21: note:   initializing argument 1 of 'void Segtree<T>::set(LL, T) [with T = Monoid; LL = long long int]'
   78 |         void set(LL n, T x) {
      |                  ~~~^
a.cc:205:17: error: cannot convert 'ETP_set<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>' to 'LL' {aka 'long long int'}
  205 |         seg.set([id[ch].second],nx);
      |                 ^~~~~~~~~~~~~~~
      |                 |
      |                 ETP_set<Monoid>(std::vector<std::pair<long long int, long long int> >&, Segtree<Monoid>&, LL, Monoid, Monoid)::<lambda()>
a.cc:78:21: note:   initializing argument 1 of 'void Segtree<T>::set(LL, T) [with T = Monoid; LL = long long int]'
   78 |         void set(LL n, T x) {
      |                  ~~~^
a.cc: In instantiation of 'T ETP_get(Segtree<ETPsegnode>&, std::vector<std::pair<long long int, long long int> >&, Segtree<T>&, LL, LL) [with T = Monoid; LL = long long int]':
a.cc:317:18:   required from here
  317 |                         LL p = ETP_get(lcaseg, id, segd, u, v).v;
      |                                ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
a.cc:218:21: error: cannot convert 'ETPsegnode' to 'LL' {aka 'long long int'} in initialization
  218 |         LL lca = LCA(lcaseg, id, u, v);
      |                  ~~~^~~~~~~~~~~~~~~~~~
      |                     |
      |                     ETPsegnode