#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<random>
#include<ctime>

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,avx2,bmi,sse4,popcnt")

using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned int;

const int N = 150000 + 2, inf = 1e9 + 100;
const ll llinf = 1e18 + 1000;

struct st {
	int l, r;
	ll t;
};
struct st2 {
	ll t;
	int ty, i;
};
bool operator<(st2 a, st2 b) {
	return a.t > b.t || (a.t == b.t && a.ty > b.ty);
}
ll curt = 0;
priority_queue<st2> q;
struct str {
	set<pair<ll, int>> l0, l1, r0, r1;
	void findp_l0(ll x, int ind) {
		auto g = l1.lower_bound({ x, -1 });
		if (g != l1.end() && g->first == x) {
			q.push({ curt, 1, ind });
		}
		g = r1.upper_bound({ x - curt * 2, inf });
		if (g != r1.begin()) {
			--g;
			q.push({ (x - g->first) / 2, 1, ind });
		}
	}
	void findp_l1(ll x, int ind) {
		auto g = l0.lower_bound({ x, -1 });
		if (g != l0.end() && g->first == x) {
			q.push({ curt, 1, g->second });
		}
		g = r0.lower_bound({ x - curt * 2, inf });
		if (g != r0.begin()) {
			--g;
			q.push({ (x - g->first) / 2, 1, g->second });
		}
	}
	void findp_r0(ll x, int ind) {
		auto g = r1.lower_bound({ x, -1 });
		if (g != r1.end() && g->first == x) {
			q.push({ curt, 1, ind });
		}
		g = l1.lower_bound({ x + curt * 2, -1 });
		if (g != l1.end()) {
			q.push({ (g->first - x) / 2, 1, ind });
		}
	}
	void findp_r1(ll x, int ind) {
		auto g = r0.lower_bound({ x, -1 });
		if (g != r0.end() && g->first == x) {
			q.push({ curt, 1, g->second });
		}
		g = l0.lower_bound({ x + curt * 2, -1 });
		if (g != l0.end()) {
			q.push({ (g->first - x) / 2, 1, g->second });
		}
	}
	void ins_l0(ll x, int ind) {
		l0.insert({ x, ind });
		findp_l0(x, ind);
	}
	void ins_l1(ll x, int ind) {
		l1.insert({ x, ind });
		findp_l1(x, ind);
	}
	void ins_r0(ll x, int ind) {
		r0.insert({ x, ind });
		findp_r0(x, ind);
	}
	void ins_r1(ll x, int ind) {
		r1.insert({ x, ind });
		findp_r1(x, ind);
	}
	void del_l0(ll x, int ind) {
		l0.erase({ x, ind });
		auto g = l0.lower_bound({ x, ind });
		if (g != l0.end()) {
			findp_l0(g->first, g->second);
		}
		if (g != l0.begin()) {
			--g;
			findp_l0(g->first, g->second);
		}
	}
	void del_l1(ll x, int ind) {
		l1.erase({ x, ind });
		auto g = l1.lower_bound({ x, ind });
		if (g != l1.end()) {
			findp_l1(g->first, g->second);
		}
		if (g != l1.begin()) {
			--g;
			findp_l1(g->first, g->second);
		}
	}
	void del_r0(ll x, int ind) {
		r0.erase({ x, ind });
		auto g = r0.upper_bound({ x, ind });
		if (g != r0.end()) {
			findp_r0(g->first, g->second);
		}
		if (g != r0.begin()) {
			--g;
			findp_r0(g->first, g->second);
		}
	}
	void del_r1(ll x, int ind) {
		r1.erase({ x, ind });
		auto g = r1.upper_bound({ x, ind });
		if (g != r1.end()) {
			findp_r1(g->first, g->second);
		}
		if (g != r1.begin()) {
			--g;
			findp_r1(g->first, g->second);
		}
	}
	bool check(ll x) {
		auto g = l1.lower_bound({ x + curt, -1 });
		if (g != l1.end() && x + curt == g->first) return true;
		g = r1.lower_bound({ x - curt, -1 });
		if (g != r1.end() && x - curt == g->first) return true;
		return false;
	}
};

int n, m, sz[N], h[N], pr[N], tin[N], tout[N], ind[N], path[N], ans[N], timer = 0;
vector<int> g[N];
vector<st> a[N];
int c[N], curp[N];
str b[N][2];

void dfs1(int v, int p) {
	sz[v] = 1;
	for (int i = 0; i < g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p) {
			swap(g[v][i], g[v].back());
			g[v].pop_back();
			--i;
			continue;
		}
		h[to] = h[v] + 1;
		dfs1(to, v);
		pr[to] = v;
		sz[v] += sz[to];
		if (sz[to] > sz[g[v][0]]) swap(g[v][0], g[v][i]);
	}
}
void dfs2(int v, int p) {
	path[v] = p;
	ind[timer] = v;
	tin[v] = timer++;
	for (auto to : g[v]) {
		dfs2(to, to == g[v][0] ? p : to);
	}
	tout[v] = timer;
}
void build_path(int x, int y, int ind, ll t) {
	vector<pair<int, int>> sl, sr;
	while (1) {
		if (path[x] == path[y]) {
			sl.push_back({ tin[x], tin[y] });
			break;
		}
		if (tin[x] > tin[y]) {
			sl.push_back({ tin[x], tin[path[x]] });
			x = pr[path[x]];
		}
		else {
			sr.push_back({ tin[path[y]], tin[y] });
			y = pr[path[y]];
		}
	}
	reverse(all(sr));
	for (auto p : sr) sl.push_back(p);
	for (auto p : sl) {
		a[ind].push_back({ p.first, p.second, t });
		t += abs(p.first - p.second) + 1;
	}
	a[ind].push_back({ -1, -1, t });
}
void add_seg(int i, int j) {
	int pt = path[ind[a[i][j].l]];
	if (c[i] == 0) {
		if (a[i][j].l <= a[i][j].r) {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].ins_r0(a[i][j].l - a[i][j].t, i);
		}
		else {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].ins_l0(a[i][j].l + a[i][j].t, i);
		}
	}
	else {
		if (a[i][j].l <= a[i][j].r) {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].ins_r1(a[i][j].l - a[i][j].t, i);
		}
		else {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].ins_l1(a[i][j].l + a[i][j].t, i);
		}
		ll lg = a[i][j].l;
		if (a[i][j].l <= a[i][j].r) {
			lg += curt - a[i][j].t;
		}
		else {
			lg -= curt - a[i][j].t;
		}
		ll rg = a[i][j].r;
		ans[i] += abs(rg - lg) + 1;
	}
}
void del_seg(int i, int j) {
	int pt = path[ind[a[i][j].l]];
	if (c[i] == 0) {
		if (a[i][j].l <= a[i][j].r) {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].del_r0(a[i][j].l - a[i][j].t, i);
		}
		else {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].del_l0(a[i][j].l + a[i][j].t, i);
		}
	}
	else {
		if (a[i][j].l <= a[i][j].r) {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].del_r1(a[i][j].l - a[i][j].t, i);
		}
		else {
			b[pt][((ll)a[i][j].l ^ a[i][j].t) & 1].del_l1(a[i][j].l + a[i][j].t, i);
		}
	}
}
bool check(int i) {
	if (curp[i] == -1 || curp[i] + 1 == a[i].size()) return false;
	ll x = a[i][curp[i]].l;
	if (a[i][curp[i]].l < a[i][curp[i]].r) {
		x += (curt - a[i][curp[i]].t);
	}
	else {
		x -= (curt - a[i][curp[i]].t);
	}
	int pt = path[ind[a[i][curp[i]].l]];
	return b[pt][(curt ^ x) & 1].check(x);
}

vector<int> solve(vector<pair<int, int>> _r, vector<ll> _d, vector<int> _s, vector<int> _t, vector<bool> _ty) {
	n = _r.size() + 1;
	m = _d.size();
	for (int i = 0; i + 1 < n; ++i) {
		g[_r[i].first].push_back(_r[i].second);
		g[_r[i].second].push_back(_r[i].first);
	}
	dfs1(0, -1);
	dfs2(0, 0);
	for (int i = 0; i < m; ++i) {
		build_path(_s[i], _t[i], i, _d[i]);
		c[i] = _ty[i];
		for (int j = 0; j < a[i].size(); ++j) {
			q.push({ a[i][j].t, 0, i });
		}
		curp[i] = -1;
	}
	while (!q.empty()) {
		auto p = q.top();
		q.pop();
		int i = p.i, ty = p.ty;
		curt = p.t;
		if (ty == 0) {
			if (curp[i] >= 0) {
				del_seg(i, curp[i]);
			}
			++curp[i];
			if (curp[i] + 1 < a[i].size()) {
				add_seg(i, curp[i]);
			}
		}
		else {
			if (c[i] == 0 && check(i)) {
				del_seg(i, curp[i]);
				c[i] = 1;
				add_seg(i, curp[i]);
			}
		}
	}
	vector<int> ans1(m);
	for (int i = 0; i < m; ++i) {
		ans1[i] = ans[i];
	}
	return ans1;
}

void solve() {
	int _n, _m;
	cin >> _n >> _m;
	vector<pair<int, int>> _r(_n - 1);
	for (auto& p : _r) {
		cin >> p.first >> p.second;
	}
	vector<ll> _d(_m);
	vector<int> _s(_m);
	vector<int> _t(_m);
	vector<bool> _ty(_m);
	for (int i = 0; i < _m; ++i) {
		cin >> _d[i] >> _s[i] >> _t[i];
		int x;
		cin >> x;
		_ty[i] = x;
	}
	vector<int> _ans = solve(_r, _d, _s, _t, _ty);
	for (auto i : _ans) {
		cout << i << ' ';
	}
}

//signed main() {
//	ios_base::sync_with_stdio(0);
//	cin.tie(0);
//	int tt = 1;
//	//cin >> tt;
//	while (tt--) {
//		solve();
//		cout << '\n';
//		cout.flush();
//	}
//	return 0;
//}