#include using namespace std; #define REP(i,a,b) for(i=a;i edges[1000001]; vector edge2[1000001]; int fac[10000], facc, facp[10000]; int change_fg[100000]; int sest[1000], sests; void get_factors(int k){ int i, j, m, sz = 0; rep(i,ps){ if(p[i]*p[i] > k) break; if(k%p[i]==0){ facp[sz++] = p[i]; while(k%p[i]==0) k /= p[i]; } } if(k > 1) facp[sz++] = k; facc = 0; REP(i,1,1<= 1000100) break; for(j=p[i]*p[i];j<1000100;j+=p[i]*p[i]) mobius[j] = 0; } scanf("%d",&N); rep(i,N-1) scanf("%d%d%d",X+i,Y+i,Z+i), X[i]--, Y[i]--; scanf("%d",&Q); rep(i,Q) scanf("%d%d",A+i,C+i), change_fg[--A[i]] = 1; rep(i,N-1){ get_factors(Z[i]); rep(j,facc){ m = fac[j]; edges[m].push_back(i); } } rep(i,Q){ get_factors(C[i]); rep(j,facc){ m = fac[j]; edge2[m].push_back(i); } } rep(i,N) ind[i] = i, sz[i] = 1; rep(q,Q+1) res[q] = (ll)N * (N-1) / 2; REP(k,2,1000001) if(edges[k].size() + edge2[k].size()){ add = 0; while(sts>0) sts--, used[stk[sts]]=0, sz[stk[sts]] = 1, ind[stk[sts]] = stk[sts]; sests = 0; rep(m,edges[k].size()){ i = X[edges[k][m]]; j = Y[edges[k][m]]; if(used[i]==0) used[i] = 1, stk[sts++] = i; if(used[j]==0) used[j] = 1, stk[sts++] = j; if(change_fg[edges[k][m]]){ sest[sests++] = edges[k][m]; } else { i = unionGet(ind, i); j = unionGet(ind, j); if(i==j) continue; add += (ll)sz[i] * sz[j]; sz[j] += sz[i]; unionConnect(ind, i, j); } } rep(m,edge2[k].size()){ i = X[A[edge2[k][m]]]; j = Y[A[edge2[k][m]]]; if(used[i]==0) used[i] = 1, stk[sts++] = i; if(used[j]==0) used[j] = 1, stk[sts++] = j; } cur = add; start = 0; rep(i,sts){ m = stk[i]; j = unionGet(ind, m); } while(sts2>0) sts2--, used2[stk2[sts2]]=0; sts2 = 0; rep(m,sests){ i = ind[X[sest[m]]]; if(used2[i]==0) used2[i] = 1, stk2[sts2++] = i; i = ind[Y[sest[m]]]; if(used2[i]==0) used2[i] = 1, stk2[sts2++] = i; } rep(m,edge2[k].size()){ i = ind[X[A[edge2[k][m]]]]; if(used2[i]==0) used2[i] = 1, stk2[sts2++] = i; i = ind[Y[A[edge2[k][m]]]]; if(used2[i]==0) used2[i] = 1, stk2[sts2++] = i; } rep(q,Q+1){ rep(i,sts2) ind2[stk2[i]] = ind[stk2[i]], sz2[stk2[i]] = sz[stk2[i]]; add = cur; rep(m,sests) if(sest[m]>=0) { i = unionGet(ind2, ind[X[sest[m]]]); j = unionGet(ind2, ind[Y[sest[m]]]); if(i==j) continue; add += (ll)sz2[i] * sz2[j]; sz2[j] += sz2[i]; unionConnect(ind2, i, j); } res[q] += add * mobius[k]; for(;;){ cg = 1; if(q= 0) sest[mind] = A[q]; else sest[sests++] = A[q]; } } if(cg==0){ q++; res[q] += add * mobius[k]; continue; } break; } } } rep(i,Q+1) printf("%lld\n", res[i]); return 0; }