← Home
```go
package main

import (
	"bufio"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	scanInt := func() int {
		scanner.Scan()
		val, _ := strconv.Atoi(scanner.Text())
		return val
	}

	if !scanner.Scan() {
		return
	}
	q, _ := strconv.Atoi(scanner.Text())

	type query struct {
		op, x, y int
	}
	queries := make([]query, q)
	k := 0

	for i := 0; i < q; i++ {
		op := scanInt()
		x := scanInt()
		y := 0
		if op == 2 {
			y = scanInt()
		}
		queries[i] = query{op, x, y}
		if op == 1 {
			k++
		}
	}

	// Constraints: x, y <= 5*10^5. 
	// mapping[v] stores the final value that v will become after all subsequent operations.
	mapping := make([]int, 500005)
	for i := range mapping {
		mapping[i] = i
	}

	result := make([]int, k)
	idx := k - 1

	// Process queries in reverse order
	for i := q - 1; i >= 0; i-- {
		curr := queries[i]
		if curr.op == 1 {
			// For type 1, the value added is curr.x.
			// Its final form is whatever curr.x currently maps to.
			result[idx] = mapping[curr.x]
			idx--
		} else {
			// For type 2 (x -> y), any occurrence of x at this point
			// will transform into y and follow y's future transformations.
			// So, mapping[x] becomes whatever mapping[y] is.
			mapping[curr.x] = mapping[curr.y]
		}
	}

	for i, val := range result {
		if i > 0 {
			writer.WriteByte(' ')
		}
		writer.WriteString(strconv.Itoa(val))
	}
	writer.WriteByte('\n')
}
```