#include <iostream>
#include <vector>
#include <string>
#include <bits/stdc++.h>

using namespace std;

void zameni_naselja(vector<int>& naselje, int a, int b) {
    --a;--b;

    int tmp = naselje[a];
    naselje[a] = naselje[b];
    naselje[b] = tmp;
}

/* ------------------------ */
void add_edge(vector<int> adj[], int src, int dest)
{
    adj[src].push_back(dest);
    adj[dest].push_back(src);
}

bool BFS(vector<int> adj[], int src, int dest, int v, int pred[], int dist[])
{
    // red za pracenje
    list<int> queue;
 
    // bool vrednosti da li su cvorovi poseceni ili ne
    bool visited[v];
 
    // inicijalizuju se sve distance na INT_MAX, sve visited[i] false zato sto nijedna jos nije posecena
    for (int i = 0; i < v; i++) {
        visited[i] = false;
        dist[i] = INT_MAX;
        pred[i] = -1;
    }
 
    visited[src] = true;
    dist[src] = 0;
    queue.push_back(src);
 
    // bfs
    while (!queue.empty()) {
        int u = queue.front();
        queue.pop_front();
        for (int i = 0; i < adj[u].size(); i++) {
            if (visited[adj[u][i]] == false) {
                visited[adj[u][i]] = true;
                dist[adj[u][i]] = dist[u] + 1;
                pred[adj[u][i]] = u;
                queue.push_back(adj[u][i]);
 
                // stigli smo do destinacije
                if (adj[u][i] == dest)
                    return true;
            }
        }
    }
 
    return false;
}

// pomocna funkcija koja vraca najkracu distancu izmedju 'source' i 'dest' cvora
int getShortestDistance(vector<int> adj[], int source, int dest, int n)
{
    int pred[n], dist[n];
 
    if (BFS(adj, source, dest, n, pred, dist) == false) {
        return -1;
    }
 
    return dist[dest];
}
/* ------------------------ */


int main() {
    int N; // broj naselja
    cin>>N;

    vector<int> naselja; // niz naselja
    for(int i=0;i<N;i++) {
        int a;
        cin >> a;
        naselja.push_back(a);
    }

    vector<int> adj[N]; // graf
    for(int i=0;i<N-1;i++) {
        int a, b;
        cin >> a >> b;
        add_edge(adj, a-1, b-1);
    }

    int Q; // broj dogadjaja
    cin >> Q;

    vector<vector <int>> dogadjaji; // niz dogadjaja
    for(int i=0;i<Q;i++) {
        int broj_dogadjaja;
        cin>>broj_dogadjaja;

        if(broj_dogadjaja == 1) {
            int a, b;
            cin >> a >> b;
            dogadjaji.push_back({broj_dogadjaja, a, b});

        } else {
            int l, r, x;
            cin >> l >> r >> x;
            dogadjaji.push_back({broj_dogadjaja, l, r, x});
        }
    }

    // main
    for(int i=0;i<dogadjaji.size();i++) {
        if(dogadjaji[i][0] == 1) {
            // SLUCAJ KADA JE PRVI DOGADJAJ
            // cout << "ZAMENA" << endl;
            zameni_naselja(naselja, dogadjaji[i][1], dogadjaji[i][2]);
        
        } else if(dogadjaji[i][0] == 2) {
            // SLUCAJ KADA JE DRUGI DOGADJAJ
            // cout << "HAKERI" << endl;
            int left = dogadjaji[i][1]-1;
            int right = dogadjaji[i][2]-1;
            int source = dogadjaji[i][3]-1;

            int max_distance = 0;

            for(int i=left;i<=right;i++) {
                int curr_distance = getShortestDistance(adj, source, naselja[i]-1, N);
                if(max_distance < curr_distance)
                    max_distance = curr_distance;
            }

            cout << max_distance << endl;
        }
    }
}