#include <bits/stdc++.h>

using namespace std;

const int mxn = 200006;
using ai = int[mxn];

int n;
vector<int> e[mxn];

struct Val {
        int s;
        int ts;
        Val operator+(Val b) {
                return {s + b.s, min(ts, b.ts)};
        }
        Val operator*(int b) {
                return {s * b, ts}; // 叶节点set的时候会*1的，所以ts没了⋯⋯
        }
        operator bool() {
                return ts;
        }
};

Val last(Val a, Val b) {
        return a.ts >= b.ts ? a : b;
}

using Ope = Val;

int ts = 0;

struct Segtree {
        Val val_[mxn * 2];
        Ope laz_[mxn * 2];
        #define oddr(l,r) (l+r|l!=r)
        #define val val_[oddr(l,r)]
        #define laz laz_[oddr(l,r)]
        #define m (l+r>>1)
        Val &operator[](int x) {
                return val_[x + x];
        }
        void down(int l, int r) {
                if (laz) {
                        set(l, m, l, r, laz);
                        set(m + 1, r, l, r, laz);
                        laz = Ope();
                }
        }
        void renew(int l, int r) {
                val = get(l, m, l, r) + get(m + 1, r, l, r);
        }
        void build(int l, int r) {
                laz = Ope();
                if (l == r) return;
                build(l, m);
                build(m + 1, r);
                renew(l, r);
        }
        Val get(int l, int r, int sl, int sr) {
                if (sl <= l && r <= sr) return val;
                down(l, r);
                if (sr <= m) return get(l, m, sl, sr);
                if (sl > m) return get(m + 1, r, sl, sr);
                return get(l, m, sl, sr) + get(m + 1, r, sl, sr);
        }
        void set(int l, int r, int sl, int sr, Ope ope) {
                if (sl <= l && r <= sr) {
                        val = ope * (r + 1 - l);
                        laz = ope;
                        return;
                }
                down(l, r);
                if (sl <= m) set(l, m, sl, sr, ope);
                if (sr > m) set(m + 1, r, sl, sr, ope);
                renew(l, r);
        }
        #undef oddr
        #undef val
        #undef laz
        #undef m
} QE, QV; // QE: 边权赋值记录，记在下方节点; QV: 子树轻边赋值记录，记在上方节点;

struct HPD {
        #define fors(i) for (auto i : e[x]) if (i != p)
        ai s, h, top, pa, dfn, hea;
        int cnt;
        int size(int x, int p) {
                s[x] = 1;
                fors(i) s[x] += size(i, x);
                return s[x];
        }
        void dfs(int x, int p, int t) {
                pa[x] = p;
                top[x] = t;
                h[x] = h[p] + 1;
                dfn[x] = ++cnt;
                int &y = hea[x] = 0; // int y = 0;
                fors(i) if (s[y] < s[i]) y = i;
                if (y) dfs(y, x, t);
                fors(i) if (i != y) dfs(i, x, i);
        }
        void build() { size(1, 0); cnt = 0; dfs(1, 0, 1); }
        void set(int x, int y) {
                ++ts;
                while (top[x] != top[y])
                        if (h[top[x]] >= h[top[y]]) {
                                if (hea[x]) QE.set(1, n, dfn[hea[x]], dfn[hea[x]], {1, ts});
                                QE.set(1, n, dfn[top[x]], dfn[x], {0, ts});
                                QV.set(1, n, dfn[top[x]], dfn[x], {1, ts});
                                x = pa[top[x]];
                        } else {
                                swap(x, y);
                        }
                if (dfn[x] < dfn[y]) swap(x, y);
                if (hea[x]) QE.set(1, n, dfn[hea[x]], dfn[hea[x]], {1, ts});
                if (x != y) QE.set(1, n, dfn[y] + 1, dfn[x], {0, ts});
                QE.set(1, n, dfn[y], dfn[y], {1, ts});
                QV.set(1, n, dfn[y], dfn[x], {1, ts});
        }
        int get(int x, int y) {
                int re = 0;
                while (top[x] != top[y])
                        if (h[top[x]] >= h[top[y]]) {
                                if (top[x] != x) re += QE.get(1, n, dfn[top[x]] + 1, dfn[x]).s;
                                re += last(QE.get(1, n, dfn[top[x]], dfn[top[x]]), QV.get(1, n, dfn[pa[top[x]]], dfn[pa[top[x]]])).s;
                                x = pa[top[x]];
                        } else {
                                swap(x, y);
                        }
                if (dfn[x] < dfn[y]) swap(x, y);
                if (y != x) re += QE.get(1, n, dfn[y] + 1, dfn[x]).s;
                return re;
        }
} G;

int main() {
        cin >> n;
        for (int i = 1; i < n; ++i) {
                int x, y;
                scanf("%d%d", &x, &y);
                e[x].push_back(y);
                e[y].push_back(x);
        }

        ++ts;
        for (int i = 1; i <= n; ++i)
                QE[i] = {1, ts};

        QE.build(1, n);
        QV.build(1, n);
        G.build();

        int q;
        cin >> q;
        while (q--) {
                int op, x, y;
                scanf("%d%d%d", &op, &x, &y);
                if (op == 1) {
                        G.set(x, y);
                } else {
                        printf("%d\n", G.get(x, y));
                }
        }

        return 0;
}