#include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<numeric>
#include<cassert>
#include<random>
#include<chrono>
#include<unordered_set>
#include<unordered_map>
#include<fstream>
#include<list>
#include<functional>
#include<bitset>
#include<complex>
#include<tuple>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
const ll MOD=1000000007;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

namespace Mo{
    //長さNの数列上、Q個のクエリに答える
    //insert::数列のi番目の値を挿入する
    //delete::数列のi番目の値を削除
    //cul::i番目のクエリに対して答える
    template<typename Data>
    vector<Data> mo(int N,int Q,const vector<pair<int,int>> &sec,function<void(int)> insert,function<void(int)> del,function<Data(int)> cul){
        vector<Data> ret(Q);
        int SIZE=max<int>(sqrt(N),1);
        vector<int> ord(Q);
        for(int i=0;i<Q;i++){ord[i]=i;}
        sort(ord.begin(),ord.end(),[&](int a,int b){return sec[a].F/SIZE==sec[b].F/SIZE?sec[a].S<sec[b].S:sec[a].F<sec[b].F;});
        int left=0,right=0;
        auto move=[&](int l,int r){
            while(left>l){insert(--left);}
            while(right<r){insert(right++);}
            while(left<l){del(left++);}
            while(right>r){del(--right);}
        };
        int idx=0;
        for(int i=0;i<N;i+=SIZE){
            while(idx<Q && sec[ord[idx]].F<i+SIZE){
                int num=ord[idx++];
                move(sec[num].F,sec[num].S);
                ret[num]=cul(num);
            }
        }
        return ret;
    }
}

using namespace Mo;



ll N,Q;
vector<vector<pair<ll,pll>>> edge;//行き先、距離、色
vector<pair<pll,pll>> query;
vector<pair<pll,ll>> euler;
vector<ll> node_number;

void dfs_mo(ll w,ll p,ll &num){
    node_number[w]=euler.size();
    for(auto &I:edge[w]){
        if(I.F!=p){
            ll k=num; num++;
            euler.push_back({I.S,k});
            dfs_mo(I.F,w,num);
            euler.push_back({I.S,k});
        }
    }
}





int main(){
    cin>>N>>Q;
    edge.resize(N);
    query.resize(Q);
    node_number.resize(N,-1);
    for(int i=1;i<N;i++){
        ll a,b,c,w;
        cin>>a>>b>>c>>w;
        a--; b--; c--;
        edge[a].push_back({b,{w,c}});
        edge[b].push_back({a,{w,c}});
    }
    cin>>query;
    for(auto &I:query){
        I.F.F--; I.S.F--; I.S.S--;
    }
    ll cnt=0;
    dfs_mo(0,-1,cnt);
    vector<pair<int,int>> sec(Q);
    for(int i=0;i<Q;i++){
        sec[i].F=min(node_number[query[i].S.F],node_number[query[i].S.S]);
        sec[i].S=max(node_number[query[i].S.F],node_number[query[i].S.S]);
    }
    vector<bool> used_edge(cnt,false);
    vector<ll> cnt_color(N,0);
    vector<ll> cnt_weight(N,0);
    ll ans=0;
    auto edge_do=[&](int k){
        if(used_edge[euler[k].S]){
            ans-=euler[k].F.F;
            cnt_color[euler[k].F.S]--;
            cnt_weight[euler[k].F.S]-=euler[k].F.F;
            used_edge[euler[k].S]=false;
        }
        else{
            ans+=euler[k].F.F;
            cnt_color[euler[k].F.S]++;
            cnt_weight[euler[k].F.S]+=euler[k].F.F;
            used_edge[euler[k].S]=true;
        }
    };
    auto cul=[&](int qnum){
        ll c=query[qnum].F.F;
        return ans-cnt_weight[c]+cnt_color[c]*query[qnum].F.S;
    };
    auto ret=mo<ll>(euler.size(),Q,sec,edge_do,edge_do,cul);
    for(auto &I:ret){cout<<I<<endl;}
    
    
    
    
    return 0;
}


Measured memory_bytes: 29932