← Home
package main

import (
	"io"
	"os"
)

type Scanner struct {
	buf []byte
	pos int
}

func NewScanner() *Scanner {
	b, _ := io.ReadAll(os.Stdin)
	return &Scanner{buf: b, pos: 0}
}

func (s *Scanner) nextInt() int {
	for s.pos < len(s.buf) && s.buf[s.pos] <= ' ' {
		s.pos++
	}
	if s.pos >= len(s.buf) {
		return 0
	}
	res := 0
	for s.pos < len(s.buf) && s.buf[s.pos] > ' ' {
		res = res*10 + int(s.buf[s.pos]-'0')
		s.pos++
	}
	return res
}

type Writer struct {
	buf []byte
}

func NewWriter() *Writer {
	return &Writer{buf: make([]byte, 0, 1024*1024*10)}
}

func (w *Writer) printInt(n int) {
	if n == -1 {
		w.buf = append(w.buf, '-', '1', '\n')
		return
	}
	if n == 0 {
		w.buf = append(w.buf, '0', '\n')
		return
	}
	var rev [20]byte
	pos := 0
	for n > 0 {
		rev[pos] = byte(n%10) + '0'
		n /= 10
		pos++
	}
	for i := pos - 1; i >= 0; i-- {
		w.buf = append(w.buf, rev[i])
	}
	w.buf = append(w.buf, '\n')
}

func (w *Writer) flush() {
	os.Stdout.Write(w.buf)
}

const MAX_NODES = 10000000
const MAX_N = 300005

type Node struct {
	ls   int
	rs   int
	hash uint64
}

var nodes [MAX_NODES]Node
var nodeCnt int

var up [MAX_N][20]int
var depth [MAX_N]int
var roots [MAX_N]int
var a [MAX_N]int
var H [MAX_N]uint64
var head [MAX_N]int
var next []int
var to []int

var seed uint64 = 0x1234567890abcdef

func randUint64() uint64 {
	seed ^= seed << 13
	seed ^= seed >> 7
	seed ^= seed << 17
	return seed
}

func newNode() int {
	nodeCnt++
	return nodeCnt
}

func insert(prev, L, R, idx int) int {
	curr := newNode()
	nodes[curr] = nodes[prev]
	nodes[curr].hash ^= H[idx]
	if L == R {
		return curr
	}
	mid := L + (R-L)/2
	if idx <= mid {
		nodes[curr].ls = insert(nodes[prev].ls, L, mid, idx)
	} else {
		nodes[curr].rs = insert(nodes[prev].rs, mid+1, R, idx)
	}
	return curr
}

func addEdge(u, v int) {
	to = append(to, v)
	next = append(next, head[u])
	head[u] = len(to) - 1
}

var n, q int

func dfs(u, p, d int) {
	up[u][0] = p
	depth[u] = d
	roots[u] = insert(roots[p], 1, n, a[u])
	for i := 1; i < 20; i++ {
		up[u][i] = up[up[u][i-1]][i-1]
	}
	for e := head[u]; e != -1; e = next[e] {
		v := to[e]
		if v != p {
			dfs(v, u, d+1)
		}
	}
}

func getLCA(u, v int) int {
	if depth[u] < depth[v] {
		u, v = v, u
	}
	diff := depth[u] - depth[v]
	for i := 0; i < 20; i++ {
		if (diff & (1 << i)) != 0 {
			u = up[u][i]
		}
	}
	if u == v {
		return u
	}
	for i := 19; i >= 0; i-- {
		if up[u][i] != up[v][i] {
			u = up[u][i]
			v = up[v][i]
		}
	}
	return up[u][0]
}

func query(nu, nv, nlca, np, L, R, l, r int) int {
	hash := nodes[nu].hash ^ nodes[nv].hash ^ nodes[nlca].hash ^ nodes[np].hash
	if hash == 0 {
		return -1
	}
	if L == R {
		return L
	}
	mid := L + (R-L)/2
	if l <= mid {
		res := query(nodes[nu].ls, nodes[nv].ls, nodes[nlca].ls, nodes[np].ls, L, mid, l, r)
		if res != -1 {
			return res
		}
	}
	if r > mid {
		res := query(nodes[nu].rs, nodes[nv].rs, nodes[nlca].rs, nodes[np].rs, mid+1, R, l, r)
		if res != -1 {
			return res
		}
	}
	return -1
}

func main() {
	scanner := NewScanner()
	n = scanner.nextInt()
	q = scanner.nextInt()

	for i := 1; i <= n; i++ {
		a[i] = scanner.nextInt()
		H[i] = randUint64()
		head[i] = -1
	}

	next = make([]int, 0, 2*n)
	to = make([]int, 0, 2*n)

	for i := 1; i < n; i++ {
		u := scanner.nextInt()
		v := scanner.nextInt()
		addEdge(u, v)
		addEdge(v, u)
	}

	dfs(1, 0, 0)

	writer := NewWriter()
	for i := 0; i < q; i++ {
		u := scanner.nextInt()
		v := scanner.nextInt()
		l := scanner.nextInt()
		r := scanner.nextInt()

		lca := getLCA(u, v)
		p := up[lca][0]

		res := query(roots[u], roots[v], roots[lca], roots[p], 1, n, l, r)
		writer.printInt(res)
	}
	writer.flush()
}