// ver coigos de : 
//|https://codeforces.com/contest/2006/problem/E

#include <cstdio>
#include <vector>
#include <algorithm>
#include <ostream>
typedef long long ll; 
typedef unsigned  u32;
const int INF = 1e9;  
//const int MOD = 1e9 + 7;
const int N = 1e5 + 7;


template<u32 MOD>
struct Modular_Integer{
    ll value;
    using mod = Modular_Integer;
    Modular_Integer(ll v = 0) {
        value = v % MOD;
        if (value < 0) value += MOD;
    }
 
    mod& operator+=(const mod& other) {
        value += other.value;
        if (value >= MOD) value -= MOD;
        return *this;
    }
 
    mod& operator-=(const Modular_Integer& other) {
        value -= other.value;
        if (value < 0) value += MOD;
        return *this;
    }
 
    mod& operator*=(const Modular_Integer& other) {
        value = value * other.value % MOD;
        return *this;
    }
 
    mod& operator/=(const Modular_Integer& other) {
        return *this *= other.inv(); 
    }
 
    mod operator-() const {
        return mod(-value);
    }
 
    mod inv() const {
        return binpow(MOD - 2);
    }
    mod binpow(ll exp) const {
        mod result = 1;
        mod base = value;
        while (exp) {
            if (exp % 2) result *= base;
            base *= base;
            exp>>=1;
        }
        return result;
    }
 
    friend mod operator+(mod a, const mod& b) { return a += b; }
    friend mod operator-(mod a, const mod& b) { return a -= b; }
    friend mod operator*(mod a, const mod& b) { return a *= b; }
    friend mod operator/(mod a, const mod& b) { return a /= b; }
 
    friend std::ostream& operator<<(std::ostream& os, const mod& m) {
        return os << m.value;
    }
};

const u32 MOD = 1e9+7;
using Mint=Modular_Integer<MOD>;



std::vector<std::pair<int, int>> G[N];  
std::vector<std::pair<int, int>> edges; 
int cnt = 0,n,fa[N], deep[N], sz[N], head[N], son[N], pos[N], lucas[N];



void Precomp(){
    lucas[1] = 3; 
    lucas[2] = 4; 
    for (int i = 3; i < N; i++) {
        lucas[i] = (lucas[i - 1] + lucas[i - 2]) % MOD;
    }
}

int seg[N];
struct Node{   
    Mint sum; 
    ll lazyVal; 
    bool haslazy;
};
 
 
Node tree[N];

#define left  node << 1 
#define right  node<< 1 | 1
 

void merge(int node){
    tree[node].sum = tree[left].sum + tree[right].sum;
}


void init(int node, int nl ,int nr){
    if(nl == nr){
        tree[node].sum = seg[nl];
        return; 
    }
    int mid = (nl + nr) >> 1;
    init(left,nl, mid);
    init(right, mid + 1, nr);
    merge(node);
}
 
 
void apply(int node, int l, int r, ll val){
    tree[node].sum += val * (r - l + 1);
    tree[node].lazyVal += val;
    tree[node].haslazy = true;
}
 
void propagate(int node, int l ,int r){
    if(tree[node].haslazy){
        int mid = (l + r) >> 1; 
        apply(left, l, mid, tree[node].lazyVal);
        apply(right,  mid + 1, r, tree[node].lazyVal);
        tree[node].haslazy = false; 
        tree[node].lazyVal = 0;
    }
}
 
void updateST(int node, int nl, int nr, int ql ,int qr, ll val){
    if(nr < ql || nl > qr) return;
    if(ql <= nl && nr <= qr){
        apply(node,nl,nr,val);
        return;
    }
    propagate(node,nl,nr);
    int mid = (nl + nr) >> 1; 
    updateST(left, nl, mid, ql, qr, val);
    updateST(right, mid + 1,nr, ql ,qr, val);
    merge(node);
        
}
void updateST(int l ,int r , ll val){
    updateST(1,0,n-1,l,r,val);
}
Mint queryST(int node, int nl ,int nr, int ql, int qr){
    if(nr < ql || nl > qr) return 0LL;
    if(ql <= nl && nr <= qr){
        return tree[node].sum;
    }
    propagate(node, nl ,nr);
 
    int mid = (nl + nr)>>1;
    Mint iz = queryST(left, nl , mid,ql,qr);
    Mint de = queryST(right , mid + 1, nr, ql,qr);
    return iz + de;
}   
 
Mint queryST(int l ,int r){
    return queryST(1, 0 ,n-1,l,r);
}





void Dfs(int node, int d, int father) {
    sz[node] = 1;
    deep[node] = d;
    fa[node] = father;
    int mx = 0; 
    for (auto &u : G[node]) {
        if (u.first == father) continue;
        Dfs(u.first, d + 1, node);
        sz[node] += sz[u.first];
        if (sz[u.first] > mx) {
            mx = sz[u.first];
            son[node] = u.first;
        }
    }
}
void HLD(int node, int w, int prev) {
    head[node] = prev;
    pos[node] = cnt++;
    seg[pos[node]] = w;
    if (son[node]) {
        for (auto &u : G[node]) {
            if (u.first == son[node]) {
                HLD(u.first, u.second, prev);
                break;
            }
        }
    }
    for (auto &u : G[node]) {
        if (u.first != fa[node] && u.first != son[node]) {
            HLD(u.first, u.second, u.first);
        }
    }
}
// LCA using HLD
int LCA(int u, int v) {
    while (head[u] != head[v]) {
        if (deep[head[u]] > deep[head[v]]) {
            u = fa[head[u]];
        } else {
            v = fa[head[v]];
        }
    }
    return (deep[u] < deep[v]) ? u : v;
}


//Mint queryHLD(int u, int v) {
//    Mint res = 0;
//    int lca = LCA(u, v);
//    
//    // Query u to LCA
//    while (head[u] != head[lca]) {
//        res += queryST(pos[head[u]], pos[u]);
//        u = fa[head[u]];
//    }
//    res += queryST(pos[lca], pos[u]);
//
//    // Query v to LCA
//    while (head[v] != head[lca]) {
//        res += queryST(pos[head[v]], pos[v]);
//        v = fa[head[v]];
//    }
//    if (lca != v) {
//        res += queryST(pos[lca] + 1, pos[v]);
//    }
//
//    return res;
//}

Mint queryHLD(int u, int v) {
    Mint res = 0;
    while (head[u] != head[v]) {
        if (deep[head[u]] > deep[head[v]]) std::swap(u, v);
        res = (res + queryST(pos[head[v]], pos[v])) ;
        v = fa[head[v]];
    }
    if (u != v) {
        if (deep[u] > deep[v]) std::swap(u, v);
        res = (res + queryST(pos[u] + 1, pos[v])) ;
    }
    return res;
}






void updateHLD(int u, int v) {
    int idx = 0;  
    while (head[u] != head[v]) {
        if (deep[head[u]] > deep[head[v]]) std::swap(u, v);
        int num_nodos = pos[v] - pos[head[v]] + 1; 
        for (int i = 0; i < num_nodos; ++i) {
            updateST(pos[head[v]] + i, pos[head[v]] + i, lucas[++idx]);
        }
        v = fa[head[v]];  // volvemos
    }
    if (u != v) {
        if (deep[u] > deep[v]) std::swap(u, v);
        int num_nodos = pos[v] - pos[u]; 
        for (int i = 1; i <= num_nodos; ++i) {
            updateST(pos[u] + i, pos[u] + i, lucas[++idx]);
        }
    }
}

void solve() {
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back({v, w});
        G[v].push_back({u, w});
        edges.push_back({u, v});
    }

    Dfs(1, 0, 0);
    HLD(1, 0, 1);
    init(1, 0, n - 1);  
    //printf("segtree init\n");
   // for(int i = 0;i<20;i++){
   //     printf("%lld ",tree[i].sum.value);
   // }
    printf("\n");
    int Q;
    scanf("%d", &Q);
    while (Q--) {
        int t, a, b;
        scanf("%d%d%d", &t, &a, &b);
        if (t == 1) {
            printf("%lld\n", queryHLD(a, b).value);
        } else if (t == 2) {
            updateHLD(a, b);
            //for(int i = 0;i<20;i++){
            //    printf("%lld ",tree[i].sum.value);
            //}
            //printf("\n");
        }
    }
}

int main() {
    Precomp();
    int t = 1;
    //scanf("%d", &t);
    while (t--) {
        solve();
    }
    return 0;
}