← Home
 ```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)
	a := make([]int, n)
	vals := make([]int, 0, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &a[i])
		vals = append(vals, a[i])
	}

	// coordinate compression
	mp := make(map[int]int)
	for _, v := range vals {
		mp[v] = 0
	}
	keys := make([]int, 0, len(mp))
	for k := range mp {
		keys = append(keys, k)
	}
	for i, k := range keys {
		mp[k] = i
	}
	m := len(keys)
	b := make([]int, n)
	for i := range a {
		b[i] = mp[a[i]]
	}

	freq := make([]int, m)
	for _, v := range b {
		freq[v]++
	}

	B := 800 // threshold
	isHeavy := make([]bool, m)
	heavies := make([]int, 0)
	for i, f := range freq {
		if f > B {
			isHeavy[i] = true
			heavies = append(heavies, i)
		}
	}

	INF := -1
	dp1 := make([]int, m)
	for i := range dp1 {
		dp1[i] = INF
	}
	best3 := make([]int, m)
	for i := range best3 {
		best3[i] = INF
	}
	fromX := make([]int, m) // tracks which x achieved best3[y]
	for i := range fromX {
		fromX[i] = -1
	}

	// dp2 for heavy: dp2[x] is map[y]val
	dp2 := make([]map[int]int, m)

	// for light elements: track last occurrence info
	lastIdx := make([]int, m)
	lastVal := make([]int, m)
	for i := range lastIdx {
		lastIdx[i] = -1
	}

	ans := 0
	pairs := make([][2]int, 0, n/4+1) // stores (x,y) at index ans-1

	for i := 0; i < n; i++ {
		v := b[i]

		// 1. Try to complete a block with current v (as y)
		if best3[v] >= 0 {
			if best3[v]+1 > ans {
				ans = best3[v] + 1
				// Expand pairs slice if necessary
				for len(pairs) < ans {
					pairs = append(pairs, [2]int{-1, -1})
				}
				pairs[ans-1] = [2]int{fromX[v], v}
			}
		}

		// 2. Promote dp2 to best3 if v is heavy
		if isHeavy[v] {
			if dp2[v] != nil {
				for y, val := range dp2[v] {
					if val > best3[y] {
						best3[y] = val
						fromX[y] = v
					}
				}
				// Clear the map for future use
				for y := range dp2[v] {
					delete(dp2[v], y)
				}
			}
		} else {
			// Light v: process interval from lastIdx[v] to i
			if lastIdx[v] >= 0 {
				// Scan elements between lastIdx[v] and i
				val := lastVal[v]
				for j := lastIdx[v] + 1; j < i; j++ {
					y := b[j]
					if val > best3[y] {
						best3[y] = val
						fromX[y] = v
					}
				}
			}
		}

		// 3. Update dp2 for heavy x using current v (as y)
		for _, x := range heavies {
			if dp1[x] >= 0 {
				if dp2[x] == nil {
					dp2[x] = make(map[int]int)
				}
				if dp1[x] > dp2[x][v] {
					dp2[x][v] = dp1[x]
				}
			}
		}

		// 4. Update dp1[v]
		if ans > dp1[v] {
			dp1[v] = ans
		}

		// 5. Update light tracking
		if !isHeavy[v] {
			lastIdx[v] = i
			lastVal[v] = dp1[v]
		}
	}

	// Reconstruct answer
	fmt.Fprintln(out, ans*4)
	res := make([]int, 0, ans*4)
	for i := 0; i < ans; i++ {
		x, y := pairs[i][0], pairs[i][1]
		res = append(res, keys[x], keys[y], keys[x], keys[y])
	}
	for i, v := range res {
		if i > 0 {
			fmt.Fprint(out, " ")
		}
		fmt.Fprint(out, v)
	}
	fmt.Fprintln(out)
}
```