
#include <bits/stdc++.h>
#include <stdio.h>
#define lli long long int
#define pii pair<int,int>
#define plli pair<lli,lli>
#define X first
#define Y second
using namespace std;

const int N = 100005;

struct Edge
{
	int x,y;
	lli c;
	Edge() {}
	Edge(int X , int Y , lli C) { x = X , y=  Y , c = C; }
	
	int other(int p) { return p==x ? y : x; }
} e[N];			// edges
int d[N];		// bottom side of edges

int n , q;					// nodes , queries
vector<int> g[N];			// adjacants

lli path[N];				// path length from root (=1)
int depth[N];				// depth of nodes

int dfsOrder[N] , dfs_i = 0;			// dfsOrder
int start[N] , finish[N];	// start and finish in dfsOrder

int euler[N*2] , ei = 1;	// euler tour
int eulerStart[N];			// euler -> first seen of node

void dfs(int x , int p , lli w = 0 , int dep = 1)
{
	// dfs order
	dfs_i++;
	dfsOrder[dfs_i] = x;
	start[x] = dfs_i;
	
	// node details from root
	path[x] = w;
	depth[x] = dep;
	
	// euler tour
	euler[ei] = x;
	eulerStart[x] = ei;
	ei++;
	
	for (int i=0 ; i<g[x].size() ; i++)
	{
		int y = e[ g[x][i] ].other(x);
		if (y != p)
		{
			d[ g[x][i] ] = y;	// bottom side of this edge
			dfs(y , x , w + e[ g[x][i] ].c , dep+1);
			
			euler[ei] = x;	// euler tour
			ei++;
		}
	}
	
	// dfs order
	finish[x] = dfs_i;
}

lli st[4*N];		// segment tree
int stPos[N];		// position of nodes in segment tree
struct SegmentTree
{
	int mp;

	SegmentTree() {}
	
	void init()
	{
		mp = 0;
		init( 1 , 1 , n );
	}
	
	void init(int p , int i , int j)
	{
		mp = max(mp , p);
		if (i==j)
		{
			st[p] = path[dfsOrder[i]];
			stPos[dfsOrder[i]] = p;
			return;
		}
		int m = (i+j)/2 , l = p*2 , r = l+1;
		init(l , i , m);
		init(r , m+1 , j);
	}
	
	void update(int i, lli c)
	{
		update(1 , 1 , n , start[i] , finish[i] , c);
	}
	
	void update(int p, int i ,int j , int L , int R , lli c)
	{
		if (j<L || i>R) return;
		if (i>=L && j<=R)
		{
			st[p] += c;
			return ;
		}
		int m = (i+j)/2 , l = p*2 , r = l+1;
		update(l , i , m , L , R , c);
		update(r , m+1 , j , L , R , c);
	}
	
	lli get(int i)
	{
		int p = stPos[i];
		lli sum = 0;
		while (p)
		{
			sum += st[p];
			p/=2;
		}
		return sum;
	}
};

int sp[2*N][20];		// sparse table for finding LCA from euler tour
struct SparseTable
{
	int sn;
	SparseTable() {}
	
	void init(int _n)
	{
		sn = _n;
		for (int i=1 ; i<=sn ; i++) sp[i][0] = i;
		
		for (int j=1,k=2 ; k<=sn ; j++,k*=2)
		{
			for (int i=1 ; i<=sn-k+1 ; i++)
			{
				int l = sp[i][j-1];
				int r = sp[i+k/2][j-1];
				sp[i][j] = depth[ euler[l] ] < depth[ euler[r] ] ? l : r;
			}
		}
	}
	
	int get(int i , int j)
	{
		int dis = j-i+1;
		int lg = log2(dis);
		int p = 1<<lg;
		int l = sp[i][lg] , r = sp[j-p+1][lg];
		return depth[ euler[l] ] < depth[ euler[r] ] ? euler[l] : euler[r];
	}
};

void pout(int x)
{
	cout<<x<<(x<10 ? " " : "")<<" ";
}

int main()
{
	ios_base::sync_with_stdio(false);
	
	cin>>n;
	for (int i = 1 ; i<=n-1 ; i++)
	{
		int x,y,c;
		cin>>x>>y>>c;
		e[i] = Edge(x,y,c);
		g[x].push_back(i);
		g[y].push_back(i);
	}
	dfs(1 , 1);
	
	SegmentTree seg;
	seg.init();
	
	SparseTable sps;
	sps.init(ei-1);
	
	cin>>q;
	while (q--)
	{
		int w;
		lli x ,y;
		cin>>w>>x>>y;
		
		if (w==1)
		{
			lli dif = y - e[x].c;
			e[x].c = y;
			seg.update(d[x] , dif);
		}
		else if (w==2)
		{
			int esx = eulerStart[x] , esy = eulerStart[y];
			if ( esy < esx )
			{
				swap(x , y);
				swap(esx , esy);
			}
			int lca = sps.get(esx , esy);
			lli ans = seg.get(x) + seg.get(y) - 2LL*seg.get(lca);
			cout<<ans<<"\n";
		}
	}
	
    return 0;
}
