```go
package main
import (
"io"
"os"
"sort"
"strconv"
)
type Edge struct {
to int
id int
}
type Item struct {
kind int
x int
}
func main() {
data, _ := io.ReadAll(os.Stdin)
idx := 0
nextInt := func() int {
for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
idx++
}
val := 0
for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
val = val*10 + int(data[idx]-'0')
idx++
}
return val
}
n := nextInt()
m := nextInt()
p := make([]int, n+1)
for i := 1; i <= n; i++ {
p[i] = nextInt()
}
vis := make([]bool, n+1)
pos := make([]int, n+1)
cycles := make([][]int, 0)
for i := 1; i <= n; i++ {
if vis[i] {
continue
}
cur := i
cyc := make([]int, 0)
for !vis[cur] {
vis[cur] = true
pos[cur] = len(cyc)
cyc = append(cyc, cur)
cur = p[cur]
}
cycles = append(cycles, cyc)
}
adj := make([][]Edge, n+1)
for i := 1; i <= m; i++ {
x := nextInt()
y := nextInt()
adj[x] = append(adj[x], Edge{y, i})
adj[y] = append(adj[y], Edge{x, i})
}
parent := make([]int, n+1)
parentEdge := make([]int, n+1)
minPos := make([]int, n+1)
maxPos := make([]int, n+1)
children := make([][]int, n+1)
ans := make([]int, 0, m)
for _, cyc := range cycles {
if len(cyc) <= 1 {
continue
}
root := cyc[0]
for _, v := range cyc {
parent[v] = 0
minPos[v] = pos[v]
maxPos[v] = pos[v]
children[v] = children[v][:0]
}
order := make([]int, 0, len(cyc))
st := make([]int, 0, len(cyc))
st = append(st, root)
parent[root] = -1
for len(st) > 0 {
u := st[len(st)-1]
st = st[:len(st)-1]
order = append(order, u)
for _, e := range adj[u] {
v := e.to
if v == parent[u] {
continue
}
parent[v] = u
parentEdge[v] = e.id
children[u] = append(children[u], v)
st = append(st, v)
}
}
for i := len(order) - 1; i >= 0; i-- {
u := order[i]
for _, v := range children[u] {
if minPos[v] < minPos[u] {
minPos[u] = minPos[v]
}
if maxPos[v] > maxPos[u] {
maxPos[u] = maxPos[v]
}
}
}
for _, u := range cyc {
if len(children[u]) > 1 {
sort.Slice(children[u], func(i, j int) bool {
return minPos[children[u][i]] < minPos[children[u][j]]
})
}
}
items := make([]Item, 0, 2*len(cyc))
items = append(items, Item{0, root})
for len(items) > 0 {
it := items[len(items)-1]
items = items[:len(items)-1]
if it.kind == 1 {
ans = append(ans, it.x)
continue
}
u := it.x
ch := children[u]
for i := len(ch) - 1; i >= 0; i-- {
v := ch[i]
eid := parentEdge[v]
if pos[v] == maxPos[v] {
items = append(items, Item{0, v})
items = append(items, Item{1, eid})
} else {
items = append(items, Item{1, eid})
items = append(items, Item{0, v})
}
}
}
}
out := make([]byte, 0, m*7)
for i, x := range ans {
if i > 0 {
out = append(out, ' ')
}
out = strconv.AppendInt(out, int64(x), 10)
}
out = append(out, '\n')
os.Stdout.Write(out)
}
```