#include <bits/stdc++.h>
using namespace std;

struct Query{
    int t;
    int a, b;
    int l, r, x;
};

const int N = 80005;
const int Q = N;
int p[N];
int n, q;


vector<int> graph[N];
Query quer[Q];

int mxDist = 0;
bool takeNotice[N];

void dfs(int v, int p, int d){
    if(takeNotice[v])
        mxDist = max(mxDist, d);

    for(auto u : graph[v]){
        if(u != p){
            dfs(u, v, d + 1);
        }
    }
}

void slowSolve(){
    for(int t = 0; t < q; ++t){
        if(quer[t].t == 1){
            swap(p[quer[t].a], p[quer[t].b]);
        }else{
            for(int i = quer[t].l; i <= quer[t].r; ++i){
                takeNotice[p[i]] = true;
            }
            mxDist = 0;
            dfs(quer[t].x, -1, 0);
            for(int i = quer[t].l; i <= quer[t].r; ++i){
                takeNotice[p[i]] = false;
            }

            cout << mxDist << "\n";
        }
    }
}

int stmn[N * 4];
int stmx[N * 4];
int dist[N];

void build(int id, int l, int r){
    if(l == r){
        stmn[id] = dist[p[l]];
        stmx[id] = dist[p[l]];
        return;
    }

    int mid = (l + r) / 2;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);
    stmn[id] = min(stmn[id * 2], stmn[id * 2 + 1]);
    stmx[id] = max(stmx[id * 2], stmx[id * 2 + 1]);
}

int getMax(int x, int y, int id, int l, int r){
    if(x > r || y < l)
        return 0;
    if(x <= l && r <= y){
        return stmx[id];
    }

    int mid = (l + r) / 2;
    int v1 = getMax(x, y, id * 2, l, mid);
    int v2 = getMax(x, y, id * 2 + 1, mid + 1, r);
    return max(v1, v2);
}

int getMin(int x, int y, int id, int l, int r){
    if(x > r || y < l)
        return INT_MAX;
    if(x <= l && r <= y){
        return stmn[id];
    }

    int mid = (l + r) / 2;
    int v1 = getMin(x, y, id * 2, l, mid);
    int v2 = getMin(x, y, id * 2 + 1, mid + 1, r);
    return min(v1, v2);
}

void update(int x, int val, int id, int l, int r){
    if(x > r || x < l)
        return;
    if(l == r){
        stmn[id] = stmx[id] = val;
        return;
    }
    int mid = (l + r) / 2;
    update(x, val, id * 2, l, mid);
    update(x, val, id * 2 + 1, mid + 1, r);
    stmn[id] = min(stmn[id * 2], stmn[id * 2 + 1]);
    stmx[id] = max(stmx[id * 2], stmx[id * 2 + 1]);
}

void dfsLine(int v, int p, int d){
    dist[v] = d;
    for(auto u : graph[v]){
        if(u != p)
            dfsLine(u, v, d + 1);
    }
}

void solveLine(){
    //setup dist
    int root = -1;
    for(int i = 1; i <= n; ++i){
        if((int)graph[i].size() == 1){
            root = i;
            break;
        }
    }
    dfsLine(root, -1, 0);
    build(1, 1, n);

    for(int t = 0; t < q; ++t){
        if(quer[t].t == 1){
            int a = dist[p[quer[t].a]];
            int b = dist[p[quer[t].b]];
            update(quer[t].a, b, 1, 1, n);
            update(quer[t].b, a, 1, 1, n);
        }else{
            int mn = getMin(quer[t].l, quer[t].r, 1, 1, n);
            int mx = getMax(quer[t].l, quer[t].r, 1, 1, n);
            int res = max(abs(mx - dist[quer[t].x]), abs(mn - dist[quer[t].x]));
            cout << res << "\n";
        }
    }
}

void dfsRoot(int v, int p, int d){
    dist[v] = d;
    for(auto u : graph[v]){
        if(u != p)
            dfsRoot(u, v, d + 1);
    }
}

void solveRoot(){
    dfsRoot(1, -1, 0);
    build(1, 1, n);

    for(int t = 0; t < q; ++t){
        if(quer[t].t == 1){
            int a = dist[p[quer[t].a]];
            int b = dist[p[quer[t].b]];
            update(quer[t].a, b, 1, 1, n);
            update(quer[t].b, a, 1, 1, n);
        }else{
            int res = getMax(quer[t].l, quer[t].r, 1, 1, n);
            cout << res << "\n";
        }
    }
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> p[i];
    }

    for(int i = 0; i < n - 1; ++i){
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    bool canRoot = true;
    cin >> q;
    for(int i = 0; i < q; ++i){
        cin >> quer[i].t;
        if(quer[i].t == 1){
            cin >> quer[i].a >> quer[i].b;
        }else{
            cin >> quer[i].l >> quer[i].r >> quer[i].x;
            if(quer[i].x != 1)
                canRoot = false;
        }
    }

    //check which sub
    bool isLine = true;
    for(int i = 0; i <= n; ++i){
        if((int)graph[i].size() > 2)
            isLine = false;
    }

    if(n <= 4000 && q <= 4000){
        slowSolve();
    }else if(isLine){
        solveLine();
    }else if(canRoot){
        solveRoot();
    }else{
        slowSolve();
    }
    return 0;
}

/*


line
7
5 7 4 2 1 3 6
1 2
2 3
3 4
4 5
5 6
6 7
5
2 2 5 4
1 3 4
1 1 2
1 5 6
2 2 5 4
-----
3
2



*/