#include"police.h"
#include<bits/stdc++.h>
#define reg register
#define int long long
const int N=2e5+10;
int n,q,Fa[20][N],dep[N],dis[N];
std::vector<std::pair<int,int>> G[N];
#define ll __int128
struct Node{
int x,y;
inline bool operator<(const Node &A)const{return x!=A.x?x<A.x:y<A.y;}
inline bool operator>(const Node &A)const{return x!=A.x?x>A.x:y>A.y;}
inline Node operator+(const int &A)const{return {x+A,y};}
}f1[N],f2[N],g[N];
struct Fac{
int x,y;
inline bool operator<(const Fac &A)const{return (ll)x*A.y<y*A.x;}
inline bool operator>(const Fac &A)const{return (ll)x*A.y>y*A.x;}
inline void prt(){std::cerr<<"Fac "<<x<<" "<<y<<"\n";}
};
#define mp std::make_pair
inline void add(reg int u,reg int v,reg int w){G[u].push_back({v,w}),G[v].push_back({u,w});}
void dfs1(reg int u,reg int fa=0){
f1[u]=f2[u]={0,-1},dep[u]=dep[Fa[0][u]=fa]+1;
for (reg int j=1;j<19;j++) Fa[j][u]=Fa[j-1][Fa[j-1][u]];
for (auto [v,w]:G[u]) if (v^fa){
dis[v]=dis[u]+w,dfs1(v,u); reg Node F=f1[v]+w; F.y=v;
if (F>f1[u]) f2[u]=f1[u],f1[u]=F; else f2[u]=std::max(f2[u],F);
}
}
void dfs2(reg int u,reg int fa=0){
for (auto [v,w]:G[u]) if (v^fa){
g[v]=std::max(g[u],f1[u].y==v?f2[u]:f1[u])+w;
g[v].y=u,dfs2(v,u);
}
}
inline int LCA(reg int x,reg int y){
if (dep[x]<dep[y]) std::swap(x,y);
for (reg int i=18;i>=0;i--) if (dep[Fa[i][x]]>=dep[y]) x=Fa[i][x];
if (x==y) return x;
for (reg int i=18;i>=0;i--) if (Fa[i][x]^Fa[i][y]) x=Fa[i][x],y=Fa[i][y];
return Fa[0][x];
}
inline int jump(reg int x,reg int d){
// std::cerr<<"jump "<<x<<" "<<d<<"\n";
for (reg int i=18;i>=0;i--) if (d>>i&1) x=Fa[i][x]; return x;}
inline int get(reg int u,reg int ban){
// std::cerr<<"get "<<u<<" "<<ban<<"\n";
Node res=f1[u].y==ban?f2[u]:f1[u];
if (g[u].y!=ban) res=std::max(res,g[u]); return res.x;
}
inline Fac query(reg int x,reg int y,reg int v1,reg int v2){
reg int p=LCA(x,y),D=dep[x]+dep[y]-dep[p]-dep[p];
reg Fac val,ans={0,1};
// std::cerr<<x<<" "<<y<<" "<<v1<<" "<<v2<<"\n";
auto check=[&](reg int d)->bool {
reg int u,d1,d2;
if (d<=dep[x]-dep[p]){
u=jump(x,d),d2=dis[x]-dis[u],d1=dis[y]+dis[u]-dis[p]-dis[p];
if (d2*v1>=d1*v2) return val={0,1},0;
reg int mxd=get(jump(x,d),d==dep[x]-dep[p]?jump(y,dep[y]-dep[p]-1):jump(x,d+1));
if (v1<=v2) return val={d1+mxd,v1},1;
// std::cerr<<"<< "<<d<<" "<<mxd<<"\n";
return val=std::min(Fac{d1+mxd,v1},Fac{d1-d2,v1-v2}),Fac{d1+mxd,v1}<Fac{d1-d2,v1-v2};
}else{
u=jump(y,D-d),d2=dis[x]+dis[u]-dis[p]-dis[p],d1=dis[y]-dis[u];
if (d2*v1>=d1*v2) return val={0,1},0;
reg int mxd=get(jump(y,D-d),jump(y,D-d-1));
if (v1<=v2) return val={d1+mxd,v1},1;
return val=std::min(Fac{d1+mxd,v1},Fac{d1-d2,v1-v2}),Fac{d1+mxd,v1}<Fac{d1-d2,v1-v2};
}
};
reg int L=0,R=D-1,nw=-1;
while (L<=R){
reg int mid=L+R>>1;
if (check(mid)) L=mid+1,nw=mid;
else R=mid-1;
}
// std::cerr<<nw<<"\n";
if (nw>-1) check(nw),val.prt(),ans=std::max(ans,val);
if (nw+1<D) check(nw+1),val.prt(),ans=std::max(ans,val);
return ans;
}
#undef int
std::vector<std::array<long long, 2>> police_thief(std::vector<int> A, std::vector<int> B, std::vector<int> D, std::vector<int> P, std::vector<int> V1, std::vector<int> T, std::vector<int> V2){
n=A.size()+1,q=P.size(); std::vector<std::array<long long, 2>> C(q);
for (reg int i=1;i<n;i++) add(A[i-1]+1,B[i-1]+1,D[i-1]);
dfs1(1),dfs2(1);
for (reg int i=0;i<q;i++){
auto [x,y]=query(T[i]+1,P[i]+1,V1[i],V2[i]);
reg long long g=std::__gcd(x,y); C[i][0]=x/g,C[i][1]=y/g;
}
return C;
}