#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> bfs(vector<vector<int>>& tree, int source)
{
	int n = tree.size();
	vector<bool> visited(n);
	vector<int> dist(n);
	queue<int> q;
	q.push(source);
	dist[source] = 0;
	while (!q.empty())
	{
		int curr_node = q.front(); q.pop();
		visited[curr_node] = true;
		//dist[curr_node] = curr_dist;
		for (int neighbor : tree[curr_node])
		{
			if (!visited[neighbor])
			{
				q.push(neighbor);
				dist[neighbor] = dist[curr_node] + 1;
			}
		}
	}

	return dist;
}

vector<vector<int>> all_pairs_shortest_path(vector<vector<int>>& tree)
{
	int n = tree.size();
	vector<vector<int>> shortest_path(n);
	for (int i = 0; i < n; i++)
	{
		shortest_path[i] = bfs(tree, i);
	}

	return shortest_path;
}

void solve1(vector<vector<int>>& tree, vector<int>& labeling, vector<vector<int>>& queries)
{
	vector<vector<int>> shortest_path = all_pairs_shortest_path(tree);
	for (int i = 0; i < queries.size(); i++)
	{
		vector<int> query = queries[i];
		int type = query[0];
		if (type == 1)
		{
			int a = query[1], b = query[2];
			a--; b--;
			swap(labeling[a], labeling[b]);
		}
		else
		{
			int l = query[1], r = query[2], x = query[3];
			l--; r--; x--;
			int max_length = -1;
			for (int j = l; j <= r; j++)
			{
				max_length = max(max_length, shortest_path[x][labeling[j]]);
			}
			cout << max_length << endl;
		}
	}
}

int t[4 * 80000];
void build(vector<int> a, int v, int tl, int tr) {
	if (tl == tr) {
		t[v] = a[tl];
	}
	else {
		int tm = (tl + tr) / 2;
		build(a, v * 2, tl, tm);
		build(a, v * 2 + 1, tm + 1, tr);
		t[v] = t[v * 2] + t[v * 2 + 1];
	}
}

int min_query(int v, int tl, int tr, int l, int r) {
	if (l > r)
		return 0;
	if (l == tl && r == tr) {
		return t[v];
	}
	int tm = (tl + tr) / 2;
	return min(min_query(v * 2, tl, tm, l, min(r, tm)), min_query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}

int max_query(int v, int tl, int tr, int l, int r) {
	if (l > r)
		return 0;
	if (l == tl && r == tr) {
		return t[v];
	}
	int tm = (tl + tr) / 2;
	return max(min_query(v * 2, tl, tm, l, min(r, tm)), min_query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}

void update(int v, int tl, int tr, int pos, int new_val) {
	if (tl == tr) {
		t[v] = new_val;
	}
	else {
		int tm = (tl + tr) / 2;
		if (pos <= tm)
			update(v * 2, tl, tm, pos, new_val);
		else
			update(v * 2 + 1, tm + 1, tr, pos, new_val);
		t[v] = t[v * 2] + t[v * 2 + 1];
	}
}

void solve2(vector<vector<int>>& tree, vector<int>& labeling, vector<vector<int>>& queries)
{
	int n = tree.size();
	int chain_end;
	vector<int> relabeling(n);
	for (int i = 0; i < tree.size(); i++)
	{
		if (tree[i].size() == 1)
		{
			chain_end = i;
			relabeling[chain_end] = 0;
		}
	}

	vector<bool> visited(n);
	visited[chain_end] = true;
	int index = 1;
	int curr_node = tree[chain_end][0];
	while (tree[curr_node].size() != 1)
	{
		visited[curr_node] = true;
		relabeling[curr_node] = index++;
		curr_node = visited[tree[curr_node][0]] ? tree[curr_node][1] : tree[curr_node][0];
	}
	relabeling[curr_node] = n;

	for (int i = 0; i < n; i++)
	{
		labeling[i] = relabeling[labeling[i]];
	}

	build(labeling, 1, 0, n - 1);

	for (int i = 0; i < queries.size(); i++)
	{
		vector<int> query = queries[i];
		int type = query[0];
		if (type == 1)
		{
			int a = query[1], b = query[2];
			a--; b--;
			swap(labeling[a], labeling[b]);
			update(1, 0, n - 1, a, labeling[a]);
			update(1, 0, n - 1, b, labeling[b]);
		}
		else
		{
			int l = query[1], r = query[2], x = query[3];
			l--; r--; x--;
			int max_length = -1;
			int max_index = max_query(1, 0, n - 1, l, r);
			int min_index = min_query(1, 0, n - 1, l, r);
			max_length = max(abs(x - max_index), abs(x - min_index));
			cout << max_length << endl;
		}
	}
	
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n; cin >> n;
	vector<int> labeling(n);
	for (int i = 0; i < n; i++)
	{
		cin >> labeling[i];
		labeling[i]--;
	}
	vector<vector<int>> tree(n);
	for (int i = 0; i < n - 1; i++)
	{
		int u, v; cin >> u >> v;
		u--; v--;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}

	int q; cin >> q;

	vector<vector<int>> queries(q);
	for (int i = 0; i < q; i++)
	{
		int type; cin >> type;
		if (type == 1)
		{
			int a, b; cin >> a >> b;
			queries[i] = vector<int>{ 1, a, b };
		}
		else
		{
			int l, r, x; cin >> l >> r >> x;
			queries[i] = vector<int>{ 2, l, r, x };
		}
	}
	if (n <= 4000 && q <= 4000)
	{
		solve1(tree, labeling, queries);
	}
}