#include <iostream>
#include <vector>
#include <queue>
#include <sstream>

class Graph
{
public:
	std::vector<std::vector<int>> adj_list;
	std::vector<std::vector<int>> dists;
	
	int num_nodes;

	Graph(int n) : num_nodes{n} 
	{
		adj_list.resize(n);
	}

	void add_edge(int u, int v)
	{
		adj_list[u].push_back(v);
		adj_list[v].push_back(u);
	}

	int node_dist(int u, int v)
	{
		std::vector<bool> visited(num_nodes, false);
		std::vector<int> distance(num_nodes, 0);

		std::queue<int> node_queue;
		distance[u] = 0;

		node_queue.push(u);
		visited[u] = true;

		while(!node_queue.empty())
		{
			int x = node_queue.front();
			node_queue.pop();

			for(int i = 0; i < adj_list[x].size(); i++)
			{
				int index = adj_list[x][i];

				if(visited[index])
					continue;

				distance[index] = distance[x] + 1;
				node_queue.push(index);
				visited[index] = true;
			}
		}

		return distance[v];
	}
};

int main()
{
	int num_nodes;
	int num_event;

	std::cin >> num_nodes;
	std::cin.get();

	std::vector<int> order;

	std::string input_line;
	std::getline(std::cin, input_line);
	std::istringstream iss(input_line);

	int value;	
	while(iss >> value)
		order.push_back(value);

	Graph graph(num_nodes);

	for(int i = 0; i < num_nodes - 1; i++)
	{
		int u, v;
		std::cin >> u >> v;
		graph.add_edge(u - 1, v - 1);
	}

	std::cin >> num_event;

	for(int i = 0; i < num_event; i++)
	{
		int event_type;
		std::cin >> event_type;

		if(event_type == 1)
		{
			int a, b;
			std::cin >> a >> b;
			std::swap(order[a-1], order[b-1]);
		}
		else if(event_type == 2)
		{
			int range_start, range_end, node;
			std::cin >> range_start >> range_end >> node;
			
			int max = graph.node_dist(order[range_start - 1] - 1, node - 1);
			for(int nd = range_start + 1; nd <= range_end; nd++)
			{
				int dist = graph.node_dist(order[nd - 1] - 1, node - 1);
				if(dist > max)
					max = dist;
			}
			std::cout << max << "\n";
		}
	}

	return 0;
}