using System;
using System.Collections.Generic;

namespace E_nocna_voznja
{
    class Edge<T>
    {
        public Vertex<T> Destination;
        public Edge<T> Next;

        public Edge(Vertex<T> destination, Edge<T> next)
        {
            Destination = destination;
            Next = next;
        }
    }

    enum Status
    {
        Unprocessed,
        Queued,
        Processed,
    }

    class Vertex<T>
    {
        public T Data;
        public Edge<T> Edge;
        public Vertex<T> Next;
        public Status Status;
        public int Distance;
        public int Index;

        public Vertex(T data, Edge<T> edge, Vertex<T> next, int index)
        {
            Data = data;
            Edge = edge;
            Next = next;
            Index = index;
        }
    }

    class Graph<T>
    {
        public Vertex<T> Start;
        public int Count;

        public Vertex<T> FindVertex(T x)
        {
            var vertex = Start;
            for (; vertex != null && !vertex.Data.Equals(x); vertex = vertex.Next) ;
            return vertex;
        }

        public Edge<T> FindEdge(T a, T b)
        {
            var vertex = FindVertex(a);
            if (vertex == null)
                return null;

            var edge = vertex.Edge;
            for (; edge != null && !edge.Destination.Data.Equals(b); edge = edge.Next) ;
            return edge;
        }
        
        public void AddVertex(T data)
        {
            var vertex = new Vertex<T>(data, null, Start, Count);
            Count++;
            Start = vertex;
        }
        
        public void AddEdge(T a, T b)
        {
            Vertex<T> vertexA = FindVertex(a);
            Vertex<T> vertexB = FindVertex(b);

            if (vertexA == null || vertexB == null)
            {
                return;
            }

            var edge = new Edge<T>(vertexB, vertexA.Edge);
            vertexA.Edge = edge;
        }
        
        public void PrintNodes()
        {
            for (var vertex = Start; vertex != null; vertex = vertex.Next)
                Console.WriteLine(vertex);
        }
        
        public void BreadthFirstSearch(int l, int r, T x)
        {
            var s = FindVertex(x);
            
            if (s == null)
                return;

            for (var vertex = Start; vertex != null; vertex = vertex.Next)
            {
                vertex.Status = Status.Unprocessed;
                vertex.Distance = -1;
            }
            
            s.Status = Status.Queued;
            s.Distance = 0;
            
            var queue = new Queue<Vertex<T>>();

            queue.Enqueue(s);

            while (queue.Count > 0)
            {
                var vertex = queue.Dequeue();
                vertex.Status = Status.Processed;

                for (var edge = vertex.Edge; edge != null; edge = edge.Next)
                {
                    if (edge.Destination.Status == Status.Unprocessed && edge.Destination.Index + 1 <= r)
                    {
                        edge.Destination.Status = Status.Queued;
                        edge.Destination.Distance = vertex.Distance + 1;
                        queue.Enqueue(edge.Destination);
                    }
                }
            }
        }
    }
    
    internal class Program
    {
        public static void Main(string[] args)
        {
            var n = int.Parse(Console.ReadLine());

            var g = new Graph<int>();
            var s = Console.ReadLine().Split();

            for (int i = 0; i < n; i++)
            {
                g.AddVertex(int.Parse(s[i]));
            }
            
            for (int i = 0; i < n - 1; i++)
            {
                s = Console.ReadLine().Split();
                var a = int.Parse(s[0]);
                var b = int.Parse(s[1]);
                g.AddEdge(a, b);
                g.AddEdge(b, a);
            }

            var q = int.Parse(Console.ReadLine());

            for (int i = 0; i < q; i++)
            {
                s = Console.ReadLine().Split();
                if (int.Parse(s[0]) == 1)
                {
                    var a = int.Parse(s[1]);
                    var b = int.Parse(s[2]);

                    Vertex<int> vA = g.Start, vB = g.Start;

                    for (; vA != null && !vA.Data.Equals(a); vA = vA.Next) ;
                    for (; vB != null && !vB.Data.Equals(b); vB = vB.Next) ;

                    var t = vA.Index;
                    vA.Index = vB.Index;
                    vB.Index = t;
                }
                else
                {
                    var l = int.Parse(s[1]);
                    var r = int.Parse(s[2]);
                    var x = int.Parse(s[3]);
                    g.BreadthFirstSearch(l, r, x);

                    int maxLen = 0;

                    for (var vertex = g.Start; vertex != null; vertex = vertex.Next)
                    {
                        if (vertex.Index + 1 >= l && vertex.Index + 1 <= r && vertex.Distance > maxLen)
                        {
                            maxLen = vertex.Distance;
                        }
                    }
                    
                    Console.WriteLine(maxLen);
                }
            }
        }
    }
}