← Home
```go
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
)

type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x any)        { *h = append(*h, x.(int)) }
func (h *IntHeap) Pop() any {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

type MinHeap struct {
	q   IntHeap
	del IntHeap
}

func (h *MinHeap) Push(v int) {
	heap.Push(&h.q, v)
}

func (h *MinHeap) Del(v int) {
	heap.Push(&h.del, v)
}

func (h *MinHeap) Min() int {
	for h.del.Len() > 0 && h.q[0] == h.del[0] {
		heap.Pop(&h.q)
		heap.Pop(&h.del)
	}
	if h.q.Len() == 0 {
		return 2000000000
	}
	return h.q[0]
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1024*1024), 1024*1024*10)

	nextToken := func() string {
		scanner.Scan()
		return scanner.Text()
	}

	nextInt := func() int {
		scanner.Scan()
		res := 0
		for _, c := range scanner.Bytes() {
			res = res*10 + int(c-'0')
		}
		return res
	}

	n := nextInt()
	m := nextInt()
	q := nextInt()

	w := make([]int, n+m+1)
	for i := 1; i <= n; i++ {
		w[i] = nextInt()
	}

	adj := make([][]int, n+1)
	for i := 0; i < m; i++ {
		u := nextInt()
		v := nextInt()
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	dfn := make([]int, n+1)
	low := make([]int, n+1)
	timer := 0
	stack := make([]int, 0)
	bccCnt := n

	bctAdj := make([][]int, 2*n+1)

	var tarjan func(u, p int)
	tarjan = func(u, p int) {
		timer++
		dfn[u] = timer
		low[u] = timer
		stack = append(stack, u)
		for _, v := range adj[u] {
			if dfn[v] == 0 {
				tarjan(v, u)
				low[u] = min(low[u], low[v])
				if low[v] >= dfn[u] {
					bccCnt++
					if bccCnt >= len(bctAdj) {
						bctAdj = append(bctAdj, make([]int, 0))
					}
					bctAdj[u] = append(bctAdj[u], bccCnt)
					bctAdj[bccCnt] = append(bctAdj[bccCnt], u)
					for {
						wNode := stack[len(stack)-1]
						stack = stack[:len(stack)-1]
						bctAdj[wNode] = append(bctAdj[wNode], bccCnt)
						bctAdj[bccCnt] = append(bctAdj[bccCnt], wNode)
						if wNode == v {
							break
						}
					}
				}
			} else if v != p {
				low[u] = min(low[u], dfn[v])
			}
		}
	}

	tarjan(1, 0)

	totalNodes := bccCnt
	parent := make([]int, totalNodes+1)
	depth := make([]int, totalNodes+1)
	size := make([]int, totalNodes+1)
	heavy := make([]int, totalNodes+1)
	head := make([]int, totalNodes+1)
	pos := make([]int, totalNodes+1)

	var dfs1 func(u, p int)
	dfs1 = func(u, p int) {
		parent[u] = p
		depth[u] = depth[p] + 1
		size[u] = 1
		for _, v := range bctAdj[u] {
			if v != p {
				dfs1(v, u)
				size[u] += size[v]
				if heavy[u] == 0 || size[v] > size[heavy[u]] {
					heavy[u] = v
				}
			}
		}
	}

	dfs1(1, 0)

	posTimer := -1
	var dfs2 func(u, h int)
	dfs2 = func(u, h int) {
		head[u] = h
		posTimer++
		pos[u] = posTimer
		if heavy[u] != 0 {
			dfs2(heavy[u], h)
		}
		for _, v := range bctAdj[u] {
			if v != parent[u] && v != heavy[u] {
				dfs2(v, v)
			}
		}
	}

	dfs2(1, 1)

	tree := make([]int, 2*totalNodes)
	for i := 0; i < 2*totalNodes; i++ {
		tree[i] = 2000000000
	}

	updateST := func(idx, val int) {
		idx += totalNodes
		tree[idx] = val
		for idx > 1 {
			idx >>= 1
			tree[idx] = min(tree[idx<<1], tree[idx<<1|1])
		}
	}

	queryST := func(l, r int) int {
		res := 2000000000
		l += totalNodes
		r += totalNodes
		for l <= r {
			if l%2 == 1 {
				res = min(res, tree[l])
				l++
			}
			if r%2 == 0 {
				res = min(res, tree[r])
				r--
			}
			l >>= 1
			r >>= 1
		}
		return res
	}

	heaps := make([]MinHeap, totalNodes+1)
	for i := 1; i <= n; i++ {
		updateST(pos[i], w[i])
		if parent[i] != 0 {
			heaps[parent[i]].Push(w[i])
		}
	}
	for i := n + 1; i <= totalNodes; i++ {
		updateST(pos[i], heaps[i].Min())
	}

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	for i := 0; i < q; i++ {
		typeStr := nextToken()
		if typeStr == "C" {
			a := nextInt()
			val := nextInt()
			if parent[a] != 0 {
				p := parent[a]
				heaps[p].Del(w[a])
				heaps[p].Push(val)
				updateST(pos[p], heaps[p].Min())
			}
			w[a] = val
			updateST(pos[a], w[a])
		} else if typeStr == "A" {
			u := nextInt()
			v := nextInt()
			res := 2000000000
			for head[u] != head[v] {
				if depth[head[u]] < depth[head[v]] {
					u, v = v, u
				}
				res = min(res, queryST(pos[head[u]], pos[u]))
				u = parent[head[u]]
			}
			if depth[u] > depth[v] {
				u, v = v, u
			}
			res = min(res, queryST(pos[u], pos[v]))
			if u > n {
				res = min(res, w[parent[u]])
			}
			fmt.Fprintln(out, res)
		}
	}
}
```