The round carousel consists of $$$n$$$ figures of animals. Figures are numbered from $$$1$$$ to $$$n$$$ in order of the carousel moving. Thus, after the $$$n$$$-th figure the figure with the number $$$1$$$ follows. Each figure has its own type — the type of the animal corresponding to this figure (the horse, the tiger and so on). The type of animal of the $$$i$$$-th figure equals $$$t_i$$$.    The example of the carousel for $$$n=9$$$ and $$$t=[5, 5, 1, 15, 1, 5, 5, 1, 1]$$$. You want to color each figure in one of the colors. You think that it's boring if the carousel contains two different figures (with the distinct types of animals) going one right after another and colored in the same color.Your task is to color the figures in such a way that the number of distinct colors used is the minimum possible and there are no figures of the different types going one right after another and colored in the same color. If you use exactly $$$k$$$ distinct colors, then the colors of figures should be denoted with integers from $$$1$$$ to $$$k$$$.

The input contains one or more test cases. The first line contains one integer $$$q$$$ ($$$1 \le q \le 10^4$$$) — the number of test cases in the test. Then $$$q$$$ test cases follow. One test case is given on two lines. The first line of the test case contains one integer $$$n$$$ ($$$3 \le n \le 2 \cdot 10^5$$$) — the number of figures in the carousel. Figures are numbered from $$$1$$$ to $$$n$$$ in order of carousel moving. Assume that after the $$$n$$$-th figure the figure $$$1$$$ goes. The second line of the test case contains $$$n$$$ integers $$$t_1, t_2, \dots, t_n$$$ ($$$1 \le t_i \le 2 \cdot 10^5$$$), where $$$t_i$$$ is the type of the animal of the $$$i$$$-th figure. The sum of $$$n$$$ over all test cases does not exceed $$$2\cdot10^5$$$.

Print $$$q$$$ answers, for each test case print two lines. In the first line print one integer $$$k$$$ — the minimum possible number of distinct colors of figures. In the second line print $$$n$$$ integers $$$c_1, c_2, \dots, c_n$$$ ($$$1 \le c_i \le k$$$), where $$$c_i$$$ is the color of the $$$i$$$-th figure. If there are several answers, you can print any.

package main

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

var reader *bufio.Reader = bufio.NewReader(os.Stdin)
var writer *bufio.Writer = bufio.NewWriter(os.Stdout)
func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{}) { fmt.Fscanf(reader, f, a...) }

func  main()  {
	defer writer.Flush()
	var t int
	scanf("%d\n",&t)
	const N int = 2e5+5
	var arr [N]int
	var ans [N]int
	for t>0 {
		t--
		var n int
		scanf("%d\n",&n)
		sing := false
		for i:=0; i<n ;i++ {
			if i<n-1{
				scanf("%d",&arr[i])
			}else{
				scanf("%d\n",&arr[i])
			}
			if i>0 && arr[i]!=arr[i-1]{
				sing=true
			}
		}
		if sing==false{
			printf("1\n")
			for i:=0; i<n; i++{
				printf("1 ")
			}
			printf("\n")
		}else if n%2==0{
			printf("2\n")
			for i:=0 ; i<n ;i++{
				printf("%d ",(i%2)+1)
			}
			printf("\n")
		}else{
			var check bool = false
			var tmp bool =false
			for i:=0; i<n; i++{
				if arr[i]==arr[(i+1)%n]{
					check = true
					tmp=true
				}
			}
			if check{
				printf("2\n")
			}else{
				printf("3\n")
			}
			ans[0]=1
			for i:=1; i<n ;i++{
				if(check && arr[i]==arr[i-1]){
					ans[i]=ans[i-1]
					check=false
				}else{
					if ans[i-1]==1{
						ans[i]=2
					}else{
						ans[i]=1
					}
				}
			}
			if tmp==false{
				ans[n-1]=3
			}
			for i:=0; i<n; i++{
				printf("%d ",ans[i])
			}
			printf("\n")
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 2
	colors[0] = "1"

	isEqual := true
	if figuresNumb%2 == 0 {
		for i := 1; i < figuresNumb; i++ {
			if isEqual && animals[i] != animals[i-1] {
				isEqual = false
			}

			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual {
			printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
			return
		}
		printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
		return
	}

	isNormalized := false
	for i := 1; i < figuresNumb; i++ {
		if !isNormalized {
			if animals[i-1] == animals[i] {
				isNormalized = true
				colors[i] = colors[i-1]
				continue
			}
			if isEqual {
				isEqual = false
			}
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual && animals[i] != animals[i-1] {
				isEqual = false
		}
		if colors[i-1] == "1" {
			colors[i] = "2"
			continue
		}
		colors[i] = "1"
	}
	if isEqual {
		printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
		return
	}

	if !isNormalized {
		if animals[0] != animals[figuresNumb-1] {
			colorsNumb = 3
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

var reader io.Reader
var scanner *bufio.Scanner

func Init(io io.Reader, max_token_size int) {
	reader = bufio.NewReader(io)
	scanner = bufio.NewScanner(reader)
	// max token size
	scanner.Split(bufio.ScanWords)
	scanner.Buffer([]byte{}, max_token_size)
}

func stderr(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
}

func die(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
	os.Exit(1)
}

func NextInt() int {
	bytes := NextBytes()
	i, err := Atoi(bytes)
	if err != nil {
		die(err)
	}
	return i
}
func NextInt64() int64 {
	bytes := NextBytes()
	i, err := Atoi64(bytes)
	if err != nil {
		die(err)
	}
	return i
}

func NextBytes() []byte {
	if !scanner.Scan() {
		die(scanner.Err())
	}
	bytes := scanner.Bytes()
	copied := make([]byte, len(bytes))
	copy(copied, bytes)
	return copied
}

func Atoi(b []byte) (int, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	n := 0
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func Atoi64(b []byte) (int64, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	var n int64
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int64(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func ExtendByteArray(a []byte, size int) []byte {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]byte, size-len(a))...)
	}
}

func ExtendIntArray(a []int, size int) []int {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]int, size-len(a))...)
	}
}

func reverseInts(a []int) {
	for l, r := 0, len(a)-1; l < r; l, r = l+1, r-1 {
		a[l], a[r] = a[r], a[l]
	}
}

func unique(a []int) int {
	newLen := 0
	n := len(a)
	for i := 0; i < n; i++ {
		if newLen == 0 || a[i] != a[newLen-1] {
			a[newLen] = a[i]
			newLen++
		}
	}
	return newLen
}

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

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	inf := os.Stdin
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	// inf, err := os.Open("a.in")
	// if err != nil {
	// 	die(err)
	// }
	// out, err := os.Create("a.out")
	// if err != nil {
	// 	die(err)
	// }
	// defer out.Close()
	Init(inf, 1000010)
	T := NextInt()
	a := make([]int, 200000)
	c := make([]int, 200000)

	for t := 0; t < T; t++ {
		n := NextInt()
		since := 0
		for i := 0; i < n; i++ {
			a[i] = NextInt()
			c[i] = -1
			if i > 0 && since == 0 && a[i] == a[i-1] {
				since = i
			}
		}
		mc := 0
		if since == 0 {
			for i := 0; i < n; i++ {
				c[i] = i & 1
				mc = max(mc, c[i])
			}
			if n >= 2 && c[n-1] == c[0] && a[n-1] != a[0] {
				c[n-1] += 2
				mc = max(mc, c[n-1])
			}
		} else {
			c[since] = 0
			pr := since
			for i := 1; i < n; i++ {
				cur := pr + 1
				if cur == n {
					cur = 0
				}
				if a[pr] != a[cur] {
					c[cur] = c[pr] ^ 1
				} else {
					c[cur] = 0
				}
				mc = max(mc, c[cur])
				pr = cur
			}
		}
		fmt.Fprintln(out, mc+1)
		for i := 0; i < n; i++ {
			fmt.Fprint(out, c[i]+1, " ")
		}
		fmt.Fprintln(out)
	}

}

/*
URL:
https://codeforces.com/problemset/problem/1328/D
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	q int

	n int
	A []int
)

func main() {
	q = ReadInt()

	for i := 0; i < q; i++ {
		n = ReadInt()
		A = ReadIntSlice(n)

		solve()
	}
}

func solve() {
	comp, _ := RunLengthEncoding(A)
	if len(comp) == 1 {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			B[i] = 1
		}
		fmt.Println(1)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	if n%2 == 0 || A[0] == A[n-1] {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			if i%2 == 0 {
				B[i] = 1
			} else {
				B[i] = 2
			}
		}

		fmt.Println(2)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	sid := -1
	for i := 0; i < n-1; i++ {
		if A[i] == A[i+1] {
			sid = i
			break
		}
	}

	if sid == -1 {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			if i%2 == 0 {
				B[i] = 1
			} else {
				B[i] = 2
			}
		}
		B[n-1] = 3

		fmt.Println(3)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	B := make([]int, n)
	B[sid], B[sid+1] = 2, 2
	for i := sid - 1; i >= 0; i-- {
		if B[i+1] == 2 {
			B[i] = 1
		} else {
			B[i] = 2
		}
	}
	for i := sid + 2; i < n; i++ {
		if B[i-1] == 2 {
			B[i] = 1
		} else {
			B[i] = 2
		}
	}
	fmt.Println(2)
	fmt.Println(PrintIntsLine(B...))
}

// RunLengthEncoding returns encoded slice of an input.
func RunLengthEncoding(S []int) ([]int, []int) {
	runes := []int{}
	lengths := []int{}

	l := 0
	for i := 0; i < len(S); i++ {
		// 1文字目の場合保持
		if i == 0 {
			l = 1
			continue
		}

		if S[i-1] == S[i] {
			// 直前の文字と一致していればインクリメント
			l++
		} else {
			// 不一致のタイミングで追加し、長さをリセットする
			runes = append(runes, S[i-1])
			lengths = append(lengths, l)
			l = 1
		}
	}
	runes = append(runes, S[len(S)-1])
	lengths = append(lengths, l)

	return runes, lengths
}

// RunLengthDecoding decodes RLE results.
func RunLengthDecoding(S []int, L []int) []int {
	if len(S) != len(L) {
		panic("S, L are not RunLengthEncoding results")
	}

	res := []int{}

	for i := 0; i < len(S); i++ {
		for j := 0; j < L[i]; j++ {
			res = append(res, S[i])
		}
	}

	return res
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"strings"
)

// github.com/EndlessCheng/codeforces-go
func CF1328D(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n int
o:
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n)
		same := true
		a := make([]int, n)
		for i := range a {
			Fscan(in, &a[i])
			if i > 0 && a[i] != a[i-1] {
				same = false
			}
		}
		if same {
			Fprintln(out, 1)
			Fprintln(out, strings.Repeat("1 ", n))
			continue o
		}
		if n&1 == 0 {
			Fprintln(out, 2)
			Fprintln(out, strings.Repeat("1 2 ", n/2))
			continue o
		}
		for i, v := range a {
			if v == a[(i+1)%n] {
				ans := make([]interface{}, n)
				for j, c := i, 1; j >= 0; j-- {
					ans[j] = c
					c = 3 - c
				}
				for j, c := i+1, 1; j < n; j++ {
					ans[j] = c
					c = 3 - c
				}
				Fprintln(out, 2)
				Fprintln(out, ans...)
				continue o
			}
		}
		Fprintln(out, 3)
		Fprintln(out, strings.Repeat("1 2 ", n/2)+"3")
	}
}

func main() { CF1328D(os.Stdin, os.Stdout) }

package main

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

const N = 200010
var nt int
var n int
var a [N] int

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	fmt.Fscanf(reader, "%d\n", &nt)
	for kk := 0; kk < nt; kk++ {
		fmt.Fscanf(reader, "%d\n", &n)
		for i := 1; i <= n; i++ {
			fmt.Fscanf(reader, "%d", &a[i])
		}
		fmt.Fscanf(reader, "\n")

		var same = true
		for i := 1; i < n; i++ {
			if a[i] != a[i + 1] {
				same = false
				break
			}
		}

		if same {
			fmt.Fprintf(writer, "1\n")
			for i := 1; i <= n; i++ {
				fmt.Fprintf(writer, "1 ")
			}
			fmt.Fprintf(writer, "\n")
			continue
		}

		if n % 2 == 0 {
			fmt.Fprintf(writer, "2\n")
			for i := 1; i <= n; i++ {
				if i % 2 == 0 {
					fmt.Fprintf(writer, "1 ")
				} else {
					fmt.Fprintf(writer, "2 ")
				}
			}
			fmt.Fprintf(writer, "\n")
			continue
		}

		a[n + 1] = a[1]
		var pos = -1
		for i := 1; i <= n; i++ {
			if a[i] == a[i + 1] {
				pos = i
				break
			}
		}

		if pos == -1 {
			fmt.Fprintf(writer, "3\n")
			for i := 1; i < n; i++ {
				if i % 2 == 0 {
					fmt.Fprintf(writer, "1 ")
				} else {
					fmt.Fprintf(writer, "2 ")
				}
			}
			fmt.Fprintf(writer, "3\n")
			continue
		}

		val := 1

		fmt.Fprintf(writer, "2\n1 ")
		for i := 2; i <= n; i++ {
			if i != pos + 1 {
				val = 3 - val
			}
			fmt.Fprintf(writer, "%d ", val)
		}
		fmt.Fprintf(writer, "\n")
	}

}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func newScanner() *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	return scanner
}

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

func scanInts(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = scanInt()
	}
	return a
}

func scanString() string {
	if sc.Scan() {
		return sc.Text()
	}
	panic(sc.Err())
}

var sc = newScanner()

func main() {
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()

	for t := scanInt(); t > 0; t-- {
		n := scanInt()
		f := make([]int, n)
		m := make(map[int]bool)
		r := -1
		for i := 0; i < n; i++ {
			f[i] = scanInt()
			m[f[i]] = true
			if r == -1 && i > 0 && f[i] == f[i-1] {
				r = i
			}
		}

		cnt := 0
		res := make([]int, n)
		if len(m) == 1 {
			cnt = 1
			for i := 0; i < n; i++ {
				res[i] = 1
			}

		} else if n&1 == 0 || f[0] == f[n-1] {
			cnt = 2
			res[0] = 1
			for i := 1; i < n; i++ {
				res[i] = res[i-1] ^ 3
			}
		} else if r > 0 {
			cnt = 2
			res[0] = 1
			for i := 1; i < n; i++ {
				res[i] = res[i-1] ^ 3
				if i == r {
					res[i] = res[i-1]
				}
			}
		} else {
			cnt = 3
			res[0], res[n-1] = 1, 3
			for i := 1; i < n-1; i++ {
				res[i] = res[i-1] ^ 3
			}
		}

		fmt.Println(cnt)
		fmt.Println(strings.Trim(fmt.Sprint(res), "[]"))
	}
}

// Author: sighduck
// URL: https://codeforces.com/contest/1328/problem/D

package main

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

type Answer struct {
	min   int
	array []int
}

func Solve(n int, t []int) Answer {
	allSame := true
	for i := 1; i < n; i++ {
		if t[i] != t[0] {
			allSame = false
		}
	}
	ans := Answer{}
	ans.array = make([]int, n)
	if allSame {
		ans.min = 1
		for i := 0; i < n; i++ {
			ans.array[i] = 1
		}
		return ans
	}
	if n%2 == 0 {
		ans.min = 2
		for i := 0; i < n; i++ {
			ans.array[i] = i%2 + 1
		}
		return ans
	}
	l := -1
	r := -1
	if n%2 == 1 {
		for i := 0; i < n; i++ {
			if t[i] == t[(i+1)%n] {
				l = i
				r = (i + 1)%n
			}
		}
	}
	if l == -1 && r == -1 {
		for i := 0; i < n; i++ {
			ans.array[i] = i%2 + 1
		}
		ans.array[n-1] = 3
		ans.min = 3
		return ans
	}
	ans.min = 2
	ans.array[l] = 1
	ans.array[r] = 1
	for i := 0; i < l; i++ {
		ans.array[i] = (l-i)%2 + 1
	}
	for i := r + 1; i < n; i++ {
		ans.array[i] = (i-r)%2 + 1
	}
	return ans
}

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

	var q int
	fmt.Fscanf(reader, "%d\n", &q)
	for i := 0; i < q; i++ {
		var n int
		fmt.Fscanf(reader, "%d\n", &n)
		t := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Fscanf(reader, "%d", &t[i])
		}
		fmt.Fscanf(reader, "\n")
		ans := Solve(n, t)
		fmt.Fprintf(writer, "%d\n", ans.min)
		for _, elem := range ans.array {
			fmt.Fprintf(writer, "%d ", elem)
		}
		fmt.Fprintf(writer, "\n")
	}
}

package main

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

type WordScanner interface {
	NextInt() int
	NextInt64() int64
	NextString() string
}

type wordScannerImpl struct {
	*bufio.Scanner
}

func NewWordScanner(reader io.Reader) WordScanner {
	s := bufio.NewScanner(reader)
	s.Split(bufio.ScanWords)
	return &wordScannerImpl{Scanner: s}
}

func (impl *wordScannerImpl) NextInt() int {
	impl.Scan()
	bb := impl.Bytes()
	i := 0
	for _, b := range bb {
		i *= 10
		i += int(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextInt64() int64 {
	impl.Scan()
	bb := impl.Bytes()
	i := int64(0)
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextString() string {
	impl.Scan()
	return impl.Text()
}

type Writer interface {
	Printf(format string, a ...interface{})
	Flush()
}

type writerImpl struct {
	*bufio.Writer
}

func NewWriter(writer io.Writer) Writer {
	return &writerImpl{Writer: bufio.NewWriter(writer)}
}

func (impl *writerImpl) Printf(f string, a ...interface{}) {
	fmt.Fprintf(impl.Writer, f, a...)
}

func (impl *writerImpl) Flush() {
	impl.Writer.Flush()
}

var reader = NewWordScanner(os.Stdin)
var writer = NewWriter(os.Stdout)

func main() {
	defer writer.Flush()
	q := reader.NextInt64()
	for ; q > 0; q-- {
		n := reader.NextInt64()
		vals := []int64{}
		for ; n > 0; n-- {
			vals = append(vals, reader.NextInt64())
		}
        res, resVals := sol(vals)
        writer.Printf("%d\n", res)
        for _, v := range resVals {
            writer.Printf("%d ", v)
        }
        writer.Printf("\n")
	}
}

func sol(vals []int64) (int64, []int64) {
    maxSoFar := int64(1)
    res := []int64{1}
    for i := 1; i < len(vals); i++ {
        prev := vals[i-1]
        curr := vals[i]
        if curr == prev {
            res = append(res, res[i-1])
        } else {
            res = append(res, alt(res[i-1]))
            maxSoFar = 2
        }
    }
    if vals[0] != vals[len(vals)-1] && res[0] == res[len(res)-1] {
        res[0] = 2
        for i := 1; i < len(vals); i++ {
            if vals[i] != vals[i-1] {
                res[i] = alt(res[i-1])
            } else {
                break
            }
        }
    }
    if vals[0] != vals[len(vals)-1] && res[0] == res[len(res)-1] {
        res[0] = 3
        return 3, res
    }
    return maxSoFar, res
}

func alt(i int64) int64 {
    if i == 1 {
        return 2
    }
    return 1
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 2
	colors[0] = "1"

	isEqual := true
	if figuresNumb%2 == 0 {
		for i := 1; i < figuresNumb; i++ {
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"

			if isEqual && colors[i] != colors[i-1] {
				isEqual = false
			}
		}
		if isEqual {
			printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
			return
		}
		printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
		return
	}

	isNormalized := false
	for i := 1; i < figuresNumb; i++ {
		if !isNormalized {
			if animals[i-1] == animals[i] {
				isNormalized = true
				colors[i] = colors[i-1]
				continue
			}
			if isEqual {
				isEqual = false
			}
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual && animals[i] != animals[i-1] {
				isEqual = false
		}
		if colors[i-1] == "1" {
			colors[i] = "2"
			continue
		}
		colors[i] = "1"
	}
	if isEqual {
		printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
		return
	}

	if !isNormalized {
		if animals[0] != animals[figuresNumb-1] {
			colorsNumb = 3
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 1
	colors[0] = "1"
	for i := 1; i < figuresNumb; i++{
		if animals[i] != animals[i-1] {
			colors[i] = "1"
			if colorsNumb == 1 || colors[i-1] == "1"{
				colors[i] = "2"
				colorsNumb = 2
			}
			continue
		}
		colors[i] = colors[i-1]
	}
	if animals[figuresNumb-1] != animals[0] && colors[figuresNumb-1] == "1" {
		if colorsNumb == 2 {
			colorsNumb = 3
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 1
	colors[0] = "1"

	isEqual := true
	if figuresNumb%2 == 0 {
		for i := 1; i < figuresNumb; i++ {
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"

			if isEqual && colors[i] != colors[i-1] {
				isEqual = false
			}
		}
		if isEqual {
			printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
			return
		}
		printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
		return
	}

	isNormalized := false
	for i := 1; i < figuresNumb; i++ {
		if !isNormalized {
			if animals[i-1] == animals[i] {
				isNormalized = true
				colors[i] = colors[i-1]
				continue
			}
			if isEqual {
				isEqual = false
			}
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual && animals[i] != animals[i-1] {
				isEqual = false
		}
		if colors[i-1] == "1" {
			colors[i] = "2"
			continue
		}
		colors[i] = "1"
	}
	if isEqual {
		printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
		return
	}

	if !isNormalized {
		if animals[figuresNumb-2] != animals[figuresNumb-1] {
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 2
	colors[0] = "1"

	isEqual := true
	if figuresNumb%2 == 0 {
		for i := 1; i < figuresNumb; i++ {
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"

			if isEqual && animals[i] != animals[i-1] {
				isEqual = false
			}
		}
		if isEqual {
			printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
			return
		}
		printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
		return
	}

	isNormalized := false
	for i := 1; i < figuresNumb; i++ {
		if !isNormalized {
			if animals[i-1] == animals[i] {
				isNormalized = true
				colors[i] = colors[i-1]
				continue
			}
			if isEqual {
				isEqual = false
			}
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual && animals[i] != animals[i-1] {
				isEqual = false
		}
		if colors[i-1] == "1" {
			colors[i] = "2"
			continue
		}
		colors[i] = "1"
	}
	if isEqual {
		printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
		return
	}

	if !isNormalized {
		if animals[0] != animals[figuresNumb-1] {
			colorsNumb = 3
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]byte, figuresNumb)
	colorsNumb := 1
	colors[0] = '1'
	for i := 1; i < figuresNumb; i++{
		if animals[i] != animals[i-1] {
			colors[i] = '1'
			if colorsNumb == 1 || colors[i-1] == '1'{
				colors[i] = '2'
				colorsNumb = 2
			}
			continue
		}
		colors[i] = colors[i-1]
	}
	if animals[figuresNumb-1] != animals[0] && colors[figuresNumb-1] == '1' {
		if colorsNumb == 2 {
			colorsNumb = 3
			colors[figuresNumb-1] = '3'
		}
	}

	printf("%d\n%s\n", colorsNumb, colors)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func scanAllStr() (string, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimRight(str, "\n\r"), nil
}
func scanIntArr() ([]int, error) {
	str, err := reader.ReadString('\n')
	if err != nil {
		return nil, err
	}
	str = strings.TrimRight(str, "\n\r")
	strArr := strings.Split(str, " ")

	arr := make([]int, len(strArr))
	for i, strA := range strArr {
		arr[i], err = strconv.Atoi(strA)
		if err != nil {
			return nil, err
		}
	}

	return arr, nil
}

func main() {
	defer writer.Flush()

	var casesNumb int
	scanf("%d\n", &casesNumb)

	for i := 0; i < casesNumb; i++ {
		exec()
	}
}

func exec() {
	var figuresNumb int
	scanf("%d\n", &figuresNumb)

	animals, err := scanIntArr()
	if err != nil {
		fmt.Println(err.Error())
		panic(err)
	}

	colors := make([]string, figuresNumb)
	colorsNumb := 2
	colors[0] = "1"

	isEqual := true
	if figuresNumb%2 == 0 {
		for i := 1; i < figuresNumb; i++ {
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"

			if isEqual && colors[i] != colors[i-1] {
				isEqual = false
			}
		}
		if isEqual {
			printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
			return
		}
		printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
		return
	}

	isNormalized := false
	for i := 1; i < figuresNumb; i++ {
		if !isNormalized {
			if animals[i-1] == animals[i] {
				isNormalized = true
				colors[i] = colors[i-1]
				continue
			}
			if isEqual {
				isEqual = false
			}
			if i%2 == 0 {
				colors[i] = "1"
				continue
			}
			colors[i] = "2"
		}
		if isEqual && animals[i] != animals[i-1] {
				isEqual = false
		}
		if colors[i-1] == "1" {
			colors[i] = "2"
			continue
		}
		colors[i] = "1"
	}
	if isEqual {
		printf("%d\n%s\n", 1, strings.TrimSpace(strings.Repeat("1 ", figuresNumb)))
		return
	}

	if !isNormalized {
		if animals[figuresNumb-2] != animals[figuresNumb-1] {
			colorsNumb = 3
			colors[figuresNumb-1] = "3"
		}
	}

	printf("%d\n%s\n", colorsNumb, strings.Join(colors, " "))
}

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

var reader io.Reader
var scanner *bufio.Scanner

func Init(io io.Reader, max_token_size int) {
	reader = bufio.NewReader(io)
	scanner = bufio.NewScanner(reader)
	// max token size
	scanner.Split(bufio.ScanWords)
	scanner.Buffer([]byte{}, max_token_size)
}

func stderr(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
}

func die(v ...interface{}) {
	fmt.Fprintln(os.Stderr, v...)
	os.Exit(1)
}

func NextInt() int {
	bytes := NextBytes()
	i, err := Atoi(bytes)
	if err != nil {
		die(err)
	}
	return i
}
func NextInt64() int64 {
	bytes := NextBytes()
	i, err := Atoi64(bytes)
	if err != nil {
		die(err)
	}
	return i
}

func NextBytes() []byte {
	if !scanner.Scan() {
		die(scanner.Err())
	}
	bytes := scanner.Bytes()
	copied := make([]byte, len(bytes))
	copy(copied, bytes)
	return copied
}

func Atoi(b []byte) (int, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	n := 0
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func Atoi64(b []byte) (int64, error) {
	neg := false
	if b[0] == '+' {
		b = b[1:]
	} else if b[0] == '-' {
		neg = true
		b = b[1:]
	}
	var n int64
	for _, v := range b {
		if v < '0' || v > '9' {
			return 0, strconv.ErrSyntax
		}
		n = n*10 + int64(v-'0')
	}
	if neg {
		return -n, nil
	}
	return n, nil
}

func ExtendByteArray(a []byte, size int) []byte {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]byte, size-len(a))...)
	}
}

func ExtendIntArray(a []int, size int) []int {
	if size <= len(a) {
		return a
	} else {
		return append(a, make([]int, size-len(a))...)
	}
}

func reverseInts(a []int) {
	for l, r := 0, len(a)-1; l < r; l, r = l+1, r-1 {
		a[l], a[r] = a[r], a[l]
	}
}

func unique(a []int) int {
	newLen := 0
	n := len(a)
	for i := 0; i < n; i++ {
		if newLen == 0 || a[i] != a[newLen-1] {
			a[newLen] = a[i]
			newLen++
		}
	}
	return newLen
}

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

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	inf := os.Stdin
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	// inf, err := os.Open("a.in")
	// if err != nil {
	// 	die(err)
	// }
	// out, err := os.Create("a.out")
	// if err != nil {
	// 	die(err)
	// }
	// defer out.Close()
	Init(inf, 1000010)
	T := NextInt()
	a := make([]int, 200000)
	c := make([]int, 200000)

	for t := 0; t < T; t++ {
		n := NextInt()
		since := 0
		for i := 0; i < n; i++ {
			a[i] = NextInt()
			c[i] = -1
			if i > 0 && since == 0 && a[i] == a[i-1] {
				since = i
			}
		}
		mc := 0
		if since == 0 {
			for i := 0; i < n; i++ {
				c[i] = i & 1
				mc = max(mc, c[i])
			}
			if n >= 2 && c[n-1] == c[0] {
				c[n-1] += 2
				mc = max(mc, c[n-1])
			}
		} else {
			c[since] = 0
			pr := since
			for i := 1; i < n; i++ {
				cur := pr + 1
				if cur == n {
					cur = 0
				}
				if a[pr] != a[cur] {
					c[cur] = c[pr] ^ 1
				} else {
					c[cur] = 0
				}
				mc = max(mc, c[cur])
				pr = cur
			}
		}
		fmt.Fprintln(out, mc+1)
		for i := 0; i < n; i++ {
			fmt.Fprint(out, c[i]+1, " ")
		}
		fmt.Fprintln(out)
	}

}

/*
URL:
https://codeforces.com/problemset/problem/1328/D
*/

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strconv"
)

/********** FAU standard libraries **********/

//fmt.Sprintf("%b\n", 255) 	// binary expression

/********** I/O usage **********/

//str := ReadString()
//i := ReadInt()
//X := ReadIntSlice(n)
//S := ReadRuneSlice()
//a := ReadFloat64()
//A := ReadFloat64Slice(n)

//str := ZeroPaddingRuneSlice(num, 32)
//str := PrintIntsLine(X...)

/*******************************************************************/

const (
	// General purpose
	MOD          = 1000000000 + 7
	ALPHABET_NUM = 26
	INF_INT64    = math.MaxInt64
	INF_BIT60    = 1 << 60
	INF_INT32    = math.MaxInt32
	INF_BIT30    = 1 << 30
	NIL          = -1

	// for dijkstra, prim, and so on
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

func init() {
	// bufio.ScanWords <---> bufio.ScanLines
	ReadString = newReadString(os.Stdin, bufio.ScanWords)
	stdout = bufio.NewWriter(os.Stdout)
}

var (
	q int

	n int
	A []int
)

func main() {
	q = ReadInt()

	for i := 0; i < q; i++ {
		n = ReadInt()
		A = ReadIntSlice(n)

		solve()
	}
}

func solve() {
	comp, _ := RunLengthEncoding(A)
	if len(comp) == 1 {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			B[i] = 1
		}
		fmt.Println(1)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	if n%2 == 0 {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			if i%2 == 0 {
				B[i] = 1
			} else {
				B[i] = 2
			}
		}

		fmt.Println(2)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	sid := -1
	for i := 0; i < n-1; i++ {
		if A[i] == A[i+1] {
			sid = i
			break
		}
	}

	if sid == -1 {
		B := make([]int, n)
		for i := 0; i < n; i++ {
			if i%2 == 0 {
				B[i] = 1
			} else {
				B[i] = 2
			}
		}
		B[n-1] = 3

		fmt.Println(3)
		fmt.Println(PrintIntsLine(B...))
		return
	}

	B := make([]int, n)
	B[sid], B[sid+1] = 2, 2
	for i := sid - 1; i >= 0; i-- {
		if B[i+1] == 2 {
			B[i] = 1
		} else {
			B[i] = 2
		}
	}
	for i := sid + 2; i < n; i++ {
		if B[i-1] == 2 {
			B[i] = 1
		} else {
			B[i] = 2
		}
	}
	fmt.Println(2)
	fmt.Println(PrintIntsLine(B...))
}

// RunLengthEncoding returns encoded slice of an input.
func RunLengthEncoding(S []int) ([]int, []int) {
	runes := []int{}
	lengths := []int{}

	l := 0
	for i := 0; i < len(S); i++ {
		// 1文字目の場合保持
		if i == 0 {
			l = 1
			continue
		}

		if S[i-1] == S[i] {
			// 直前の文字と一致していればインクリメント
			l++
		} else {
			// 不一致のタイミングで追加し、長さをリセットする
			runes = append(runes, S[i-1])
			lengths = append(lengths, l)
			l = 1
		}
	}
	runes = append(runes, S[len(S)-1])
	lengths = append(lengths, l)

	return runes, lengths
}

// RunLengthDecoding decodes RLE results.
func RunLengthDecoding(S []int, L []int) []int {
	if len(S) != len(L) {
		panic("S, L are not RunLengthEncoding results")
	}

	res := []int{}

	for i := 0; i < len(S); i++ {
		for j := 0; j < L[i]; j++ {
			res = append(res, S[i])
		}
	}

	return res
}

/*******************************************************************/

/*********** I/O ***********/

var (
	// ReadString returns a WORD string.
	ReadString func() string
	stdout     *bufio.Writer
)

func newReadString(ior io.Reader, sf bufio.SplitFunc) func() string {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+9)) // for Codeforces
	r.Split(sf)

	return func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
}

// ReadInt returns an integer.
func ReadInt() int {
	return int(readInt64())
}
func ReadInt2() (int, int) {
	return int(readInt64()), int(readInt64())
}
func ReadInt3() (int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64())
}
func ReadInt4() (int, int, int, int) {
	return int(readInt64()), int(readInt64()), int(readInt64()), int(readInt64())
}

// ReadInt64 returns as integer as int64.
func ReadInt64() int64 {
	return readInt64()
}
func ReadInt64_2() (int64, int64) {
	return readInt64(), readInt64()
}
func ReadInt64_3() (int64, int64, int64) {
	return readInt64(), readInt64(), readInt64()
}
func ReadInt64_4() (int64, int64, int64, int64) {
	return readInt64(), readInt64(), readInt64(), readInt64()
}

func readInt64() int64 {
	i, err := strconv.ParseInt(ReadString(), 0, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// ReadIntSlice returns an integer slice that has n integers.
func ReadIntSlice(n int) []int {
	b := make([]int, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt()
	}
	return b
}

// ReadInt64Slice returns as int64 slice that has n integers.
func ReadInt64Slice(n int) []int64 {
	b := make([]int64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadInt64()
	}
	return b
}

// ReadFloat64 returns an float64.
func ReadFloat64() float64 {
	return float64(readFloat64())
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(ReadString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// ReadFloatSlice returns an float64 slice that has n float64.
func ReadFloat64Slice(n int) []float64 {
	b := make([]float64, n)
	for i := 0; i < n; i++ {
		b[i] = ReadFloat64()
	}
	return b
}

// ReadRuneSlice returns a rune slice.
func ReadRuneSlice() []rune {
	return []rune(ReadString())
}

/*********** Debugging ***********/

// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.
// For debugging use.
func ZeroPaddingRuneSlice(n, digitsNum int) []rune {
	sn := fmt.Sprintf("%b", n)

	residualLength := digitsNum - len(sn)
	if residualLength <= 0 {
		return []rune(sn)
	}

	zeros := make([]rune, residualLength)
	for i := 0; i < len(zeros); i++ {
		zeros[i] = '0'
	}

	res := []rune{}
	res = append(res, zeros...)
	res = append(res, []rune(sn)...)

	return res
}

// Strtoi is a wrapper of strconv.Atoi().
// If strconv.Atoi() returns an error, Strtoi calls panic.
func Strtoi(s string) int {
	if i, err := strconv.Atoi(s); err != nil {
		panic(errors.New("[argument error]: Strtoi only accepts integer string"))
	} else {
		return i
	}
}

// PrintIntsLine returns integers string delimited by a space.
func PrintIntsLine(A ...int) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.Itoa(A[i])
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintIntsLine returns integers string delimited by a space.
func PrintInts64Line(A ...int64) string {
	res := []rune{}

	for i := 0; i < len(A); i++ {
		str := strconv.FormatInt(A[i], 10) // 64bit int version
		res = append(res, []rune(str)...)

		if i != len(A)-1 {
			res = append(res, ' ')
		}
	}

	return string(res)
}

// PrintfDebug is wrapper of fmt.Fprintf(os.Stderr, format, a...)
func PrintfDebug(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
}

// PrintfBufStdout is function for output strings to buffered os.Stdout.
// You may have to call stdout.Flush() finally.
func PrintfBufStdout(format string, a ...interface{}) {
	fmt.Fprintf(stdout, format, a...)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"strings"
)

// github.com/EndlessCheng/codeforces-go
func CF1328D(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n)
		segCnt := 1
		samePos := -1
		a := make([]int, n)
		for i := range a {
			Fscan(in, &a[i])
			if i > 0 {
				if a[i] != a[i-1] {
					segCnt++
				} else {
					samePos = i
				}
			}
		}
		if segCnt == 1 {
			Fprintln(out, 1)
			Fprintln(out, strings.Repeat("1 ", n))
		} else if samePos == -1 && segCnt&1 == 1 {
			Fprintln(out, 3)
			Fprintln(out, strings.Repeat("1 2 ", n/2)+"3")
		} else {
			Fprintln(out, 2)
			c := 1
			Fprint(out, 1, " ")
			if samePos == -1 || segCnt&1 == 0 {
				for i := 1; i < n; i++ {
					if a[i] != a[i-1] {
						c = 3 - c
					}
					Fprint(out, c, " ")
				}
			} else {
				for i := 1; i < n; i++ {
					if i == samePos || a[i] != a[i-1] {
						c = 3 - c
					}
					Fprint(out, c, " ")
				}
			}
			Fprintln(out)
		}
	}
}

func main() { CF1328D(os.Stdin, os.Stdout) }

package main

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

const N = 200010
var nt int
var n int
var a [N] int

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	fmt.Fscanf(reader, "%d\n", &nt)
	for kk := 0; kk < nt; kk++ {
		fmt.Fscanf(reader, "%d\n", &n)
		for i := 1; i <= n; i++ {
			fmt.Fscanf(reader, "%d", &a[i])
		}
		fmt.Fscanf(reader, "\n")

		var same = true
		for i := 1; i < n; i++ {
			if a[i] != a[i + 1] {
				same = false
				break
			}
		}

		if same {
			fmt.Fprintf(writer, "1\n")
			for i := 1; i <= n; i++ {
				fmt.Fprintf(writer, "1 ")
			}
			fmt.Fprintf(writer, "\n")
			continue
		}

		if n % 2 == 0 {
			fmt.Fprintf(writer, "2\n")
			for i := 1; i <= n; i++ {
				if i % 2 == 0 {
					fmt.Fprintf(writer, "1 ")
				} else {
					fmt.Fprintf(writer, "2 ")
				}
			}
			fmt.Fprintf(writer, "\n")
			continue
		}

		a[n + 1] = a[1]
		var pos = -1
		for i := 1; i <= n; i++ {
			if a[i] == a[i + 1] {
				pos = i
				break
			}
		}

		if pos == -1 {
			fmt.Fprintf(writer, "3\n")
			for i := 1; i < n; i++ {
				if i % 2 == 0 {
					fmt.Fprintf(writer, "1 ")
				} else {
					fmt.Fprintf(writer, "2 ")
				}
			}
			fmt.Fprintf(writer, "3\n")
			continue
		}

		val := 1

		fmt.Fprintf(writer, "2\n")
		for i := 2; i <= n; i++ {
			if i != pos + 1 {
				val = 3 - val
			}
			fmt.Fprintf(writer, "%d ", val)
		}
		fmt.Fprintf(writer, "\n")
	}

}

package main

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

const N = 200010
var nt int
var n int
var a [N] int
var b [N] int

func main()  {
	var reader = bufio.NewReader(os.Stdin)
	var writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	fmt.Fscanf(reader, "%d\n", &nt)
	for kk := 0; kk < nt; kk++ {
		fmt.Fscanf(reader, "%d\n", &n)
		for i := 1; i <= n; i++ {
			fmt.Fscanf(reader, "%d", &a[i])
		}

		a[n + 1] = a[1]
		b[1] = 1
		cnt := 1

		for i := 2; i <= n; i++ {
			if a[i] == a[i - 1] {
				b[i] = b[i - 1]
			} else {
				b[i] = 3 - b[i - 1]
			}

			if b[i] == 2 && cnt == 1 {
				cnt++
			}
		}

		if a[1] != a[n] && b[n] == b[1] {
			cnt++
			b[n] = cnt
		}

		fmt.Fscanf(reader, "\n")

		fmt.Fprintf(writer, "%d\n", cnt)

		for i:= 1; i <= n; i++ {
			fmt.Fprintf(writer, "%d ", b[i])
		}

		fmt.Fprintf(writer, "\n")
	}

}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func newScanner() *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	return scanner
}

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

func scanInts(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = scanInt()
	}
	return a
}

func scanString() string {
	if sc.Scan() {
		return sc.Text()
	}
	panic(sc.Err())
}

var sc = newScanner()

func main() {
	t := scanInt()
	for i := 0; i < t; i++ {
		solve()
	}
}

func solve() {
	n := scanInt()
	m := make(map[int]int)
	res := make([]int, n)
	max := 1
	for i := 0; i < n; i++ {
		f := scanInt()
		if _, ok := m[f]; ok {
			res[i] = m[f]
		} else {
			res[i] = max
			m[f] = max
			max++
		}
	}
	fmt.Println(len(m))
	fmt.Println(strings.Trim(fmt.Sprint(res), "[]"))
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func newScanner() *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	return scanner
}

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

func scanInts(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = scanInt()
	}
	return a
}

func scanString() string {
	if sc.Scan() {
		return sc.Text()
	}
	panic(sc.Err())
}

var sc = newScanner()

func main() {
	for t := scanInt(); t > 0; t-- {
		n := scanInt()
		f := scanInts(n)
		res := make([]int, n)
		m := 1
		res[0] = 1
		for i := 1; i < n; i++ {
			if f[i] == f[i-1] {
				res[i] = res[i-1]
			} else {
				res[i] = res[i-1] ^ 3
				m = 2
			}
			if i == n-1 && f[i] != f[0] && res[i] == res[0] {
				res[i] = 3
				m = 3
			}
		}
		fmt.Println(m)
		fmt.Println(strings.Trim(fmt.Sprint(res), "[]"))
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func newScanner() *bufio.Scanner {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	return scanner
}

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

func scanInts(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = scanInt()
	}
	return a
}

func scanString() string {
	if sc.Scan() {
		return sc.Text()
	}
	panic(sc.Err())
}

var sc = newScanner()

func main() {
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()

	for t := scanInt(); t > 0; t-- {
		n := scanInt()
		f := make([]int, n)
		m := make(map[int]bool)
		r := -1
		for i := 0; i < n; i++ {
			x := scanInt()
			f[i] = x
			m[x] = true
			if i > 0 && r == -1 && f[i] == f[i-1] {
				r = i
			}
		}

		cnt := 0
		res := make([]int, n)
		if len(m) == 1 {
			cnt = 1
			for i := 0; i < n; i++ {
				res[i] = 1
			}

		} else if n&1 == 0 {
			cnt = 2
			res[0] = 1
			for i := 1; i < n; i++ {
				res[i] = res[i-1] ^ 3
			}
		} else if r > 0 {
			cnt = 2
			res[0] = 1
			for i := 1; i < n; i++ {
				res[i] = res[i-1] ^ 3
				if i == r {
					res[i] = res[i-1]
				}
			}
		} else {
			cnt = 3
			res[0], res[n-1] = 1, 3
			for i := 1; i < n-1; i++ {
				res[i] = res[i-1] ^ 3
			}
		}

		fmt.Println(cnt)
		fmt.Println(strings.Trim(fmt.Sprint(res), "[]"))
	}
}

// Author: sighduck
// URL: https://codeforces.com/contest/1328/problem/D

package main

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

type Answer struct {
	min   int
	array []int
}

func Solve(n int, t []int) Answer {
	allSame := true
	for i := 1; i < n; i++ {
		if t[i] != t[0] {
			allSame = false
		}
	}
	ans := Answer{}
	ans.array = make([]int, n)
	if allSame {
		ans.min = 1
		for i := 0; i < n; i++ {
			ans.array[i] = 1
		}
		return ans
	}
	if n%2 == 0 {
		ans.min = 2
		for i := 0; i < n; i++ {
			ans.array[i] = i%2 + 1
		}
		return ans
	}
	l := -1
	r := -1
	if n%2 == 1 {
		for i := 0; i < n-1; i++ {
			if t[i] == t[i+1] {
				l = i
				r = i + 1
			}
		}
	}
	if l == -1 && r == -1 {
		for i := 0; i < n; i++ {
			ans.array[i] = i%2 + 1
		}
		ans.array[n-1] = 3
		ans.min = 3
		return ans
	}
	ans.min = 2
	ans.array[l] = 1
	ans.array[r] = 1
	for i := 0; i < l; i++ {
		ans.array[i] = (l-i)%2 + 1
	}
	for i := r + 1; i < n; i++ {
		ans.array[i] = (i-r)%2 + 1
	}
	return ans
}

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

	var q int
	fmt.Fscanf(reader, "%d\n", &q)
	for i := 0; i < q; i++ {
		var n int
		fmt.Fscanf(reader, "%d\n", &n)
		t := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Fscanf(reader, "%d", &t[i])
		}
		fmt.Fscanf(reader, "\n")
		ans := Solve(n, t)
		fmt.Fprintf(writer, "%d\n", ans.min)
		for _, elem := range ans.array {
			fmt.Fprintf(writer, "%d ", elem)
		}
		fmt.Fprintf(writer, "\n")
	}
}

// Author: sighduck
// URL: https://codeforces.com/contest/1328/problem/D

package main

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

type Answer struct {
	min   int
	array []int
}

func Solve(n int, t []int) Answer {
	ans := Answer{}
	ans.array = make([]int, n)
	ans.array[0] = 1
	ans.min = 1
	for i := 1; i < n; i++ {
		if t[i] == t[i-1] {
			ans.array[i] = ans.array[i-1]
		} else {
			ans.array[i] = -ans.array[i-1] + 3
		}
	}
	if ans.array[n-1] == ans.array[0] && t[n-1] != t[0] {
		ans.array[n-1] = 3
	}
	for _, elem := range ans.array {
		if elem > ans.min {
			ans.min = elem
		}
	}
	return ans
}

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

	var q int
	fmt.Fscanf(reader, "%d\n", &q)
	for i := 0; i < q; i++ {
		var n int
		fmt.Fscanf(reader, "%d\n", &n)
		t := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Fscanf(reader, "%d", &t[i])
		}
		fmt.Fscanf(reader, "\n")
		ans := Solve(n, t)
		fmt.Fprintf(writer, "%d\n", ans.min)
		for _, elem := range ans.array {
			fmt.Fprintf(writer, "%d ", elem)
		}
		fmt.Fprintf(writer, "\n")
	}
}

// Author: sighduck
// URL: https://codeforces.com/contest/1328/problem/D

package main

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

type Answer struct {
	min   int
	array []int
}

func Solve(n int, t []int) Answer {
	allSame := true
	for i := 1; i < n; i++ {
		if t[i] != t[0] {
			allSame = false
		}
	}
	ans := Answer{}
	ans.array = make([]int, n)
	if allSame {
		ans.min = 1
		for i := 0; i < n; i++ {
			ans.array[i] = 1
		}
		return ans
	}
	if n%2 == 0 {
		ans.min = 2
		for i := 0; i < n; i++ {
			ans.array[i] = i%2 + 1
		}
		return ans
	}
	ans.array[0] = 1
	ans.min = 1
	for i := 1; i < n; i++ {
		if t[i] == t[i-1] {
			ans.array[i] = ans.array[i-1]
		} else {
			ans.array[i] = -ans.array[i-1] + 3
		}
	}
	if ans.array[n-1] == ans.array[0] && t[n-1] != t[0] {
		ans.array[n-1] = 3
	}
	for _, elem := range ans.array {
		if elem > ans.min {
			ans.min = elem
		}
	}
	return ans
}

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

	var q int
	fmt.Fscanf(reader, "%d\n", &q)
	for i := 0; i < q; i++ {
		var n int
		fmt.Fscanf(reader, "%d\n", &n)
		t := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Fscanf(reader, "%d", &t[i])
		}
		fmt.Fscanf(reader, "\n")
		ans := Solve(n, t)
		fmt.Fprintf(writer, "%d\n", ans.min)
		for _, elem := range ans.array {
			fmt.Fprintf(writer, "%d ", elem)
		}
		fmt.Fprintf(writer, "\n")
	}
}

package main

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

type WordScanner interface {
	NextInt() int
	NextInt64() int64
	NextString() string
}

type wordScannerImpl struct {
	*bufio.Scanner
}

func NewWordScanner(reader io.Reader) WordScanner {
	s := bufio.NewScanner(reader)
	s.Split(bufio.ScanWords)
	return &wordScannerImpl{Scanner: s}
}

func (impl *wordScannerImpl) NextInt() int {
	impl.Scan()
	bb := impl.Bytes()
	i := 0
	for _, b := range bb {
		i *= 10
		i += int(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextInt64() int64 {
	impl.Scan()
	bb := impl.Bytes()
	i := int64(0)
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextString() string {
	impl.Scan()
	return impl.Text()
}

type Writer interface {
	Printf(format string, a ...interface{})
	Flush()
}

type writerImpl struct {
	*bufio.Writer
}

func NewWriter(writer io.Writer) Writer {
	return &writerImpl{Writer: bufio.NewWriter(writer)}
}

func (impl *writerImpl) Printf(f string, a ...interface{}) {
	fmt.Fprintf(impl.Writer, f, a...)
}

func (impl *writerImpl) Flush() {
	impl.Writer.Flush()
}

var reader = NewWordScanner(os.Stdin)
var writer = NewWriter(os.Stdout)

func main() {
	defer writer.Flush()
	q := reader.NextInt64()
	for ; q > 0; q-- {
		n := reader.NextInt64()
		vals := []int64{}
		for ; n > 0; n-- {
			vals = append(vals, reader.NextInt64())
		}
        res, resVals := sol(vals)
        writer.Printf("%d\n", res)
        for _, v := range resVals {
            writer.Printf("%d ", v)
        }
        writer.Printf("\n")
	}
}

func sol(vals []int64) (int64, []int64) {
    maxSoFar := int64(1)
    res := []int64{1}
    for i := 1; i < len(vals); i++ {
        prev := vals[i-1]
        curr := vals[i]
        if curr == prev {
            res = append(res, res[i-1])
        } else {
            res = append(res, alt(res[i-1]))
            maxSoFar = 2
        }
    }
    if vals[0] != vals[len(vals)-1] && res[0] == res[len(res)-1] {
        for i := 1; i < len(vals); i++ {
            if vals[i] == vals[i-1] {
                res[i-1] = alt(res[i-1])
                return maxSoFar, res
            }
        }
    }
    if vals[0] != vals[len(vals)-1] && res[0] == res[len(res)-1] {
        res[0] = 3
        return 3, res
    }
    return maxSoFar, res
}

func alt(i int64) int64 {
    if i == 1 {
        return 2
    }
    return 1
}

package main

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

type WordScanner interface {
	NextInt() int
	NextInt64() int64
	NextString() string
}

type wordScannerImpl struct {
	*bufio.Scanner
}

func NewWordScanner(reader io.Reader) WordScanner {
	s := bufio.NewScanner(reader)
	s.Split(bufio.ScanWords)
	return &wordScannerImpl{Scanner: s}
}

func (impl *wordScannerImpl) NextInt() int {
	impl.Scan()
	bb := impl.Bytes()
	i := 0
	for _, b := range bb {
		i *= 10
		i += int(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextInt64() int64 {
	impl.Scan()
	bb := impl.Bytes()
	i := int64(0)
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func (impl *wordScannerImpl) NextString() string {
	impl.Scan()
	return impl.Text()
}

type Writer interface {
	Printf(format string, a ...interface{})
	Flush()
}

type writerImpl struct {
	*bufio.Writer
}

func NewWriter(writer io.Writer) Writer {
	return &writerImpl{Writer: bufio.NewWriter(writer)}
}

func (impl *writerImpl) Printf(f string, a ...interface{}) {
	fmt.Fprintf(impl.Writer, f, a...)
}

func (impl *writerImpl) Flush() {
	impl.Writer.Flush()
}

var reader = NewWordScanner(os.Stdin)
var writer = NewWriter(os.Stdout)

func main() {
	defer writer.Flush()
	q := reader.NextInt64()
	for ; q > 0; q-- {
		n := reader.NextInt64()
		dll := &DLL{Nodes: []*Node{}}
		for ; n > 0; n-- {
			dll.Add(reader.NextInt64())
		}
		dll.Build()
		dll.Solve()
		res := dll.GetRes()
		for _, num := range res {
			writer.Printf("%d ", num)
		}
		writer.Printf("\n")
	}
}

// DLL is a doubly linked list
type DLL struct {
	Nodes []*Node
}

type Node struct {
	Val   int64 // fill on init
	Left  *Node // fill on build
	Right *Node // fill on build
	Res   int64 // fill on solve
}

func (dll *DLL) Add(v int64) {
	dll.Nodes = append(dll.Nodes, &Node{Val: v})
}

func (dll *DLL) Build() {
	for i := range dll.Nodes {
		left := i - 1
		if i-1 < 0 {
			left = len(dll.Nodes) - 1
		}
		right := i + 1
		if i+1 > len(dll.Nodes)-1 {
			right = 0
		}
		dll.Nodes[i].Left = dll.Nodes[left]
		dll.Nodes[i].Right = dll.Nodes[right]
	}
}

func (dll *DLL) Solve() {
	u := 1
	dll.Nodes[0].Res = int64(1)
	for i := 1; i < len(dll.Nodes); i++ {
		node := dll.Nodes[i]
		if node.Val == node.Left.Val {
			node.Res = node.Left.Res
		} else {
			node.Res = alt(node.Left.Res)
			u = 2
		}
	}
	if dll.Nodes[0].Val != dll.Nodes[0].Left.Val {
		if dll.Nodes[0].Left.Res == dll.Nodes[0].Res {
			if dll.Nodes[0].Right.Val == dll.Nodes[0].Val {
				dll.Nodes[0].Res = 2
			} else {
				dll.Nodes[0].Res = 3
				u = 3
			}
		}
	}
	writer.Printf("%d\n", u)
}

func alt(color int64) int64 {
	if color == 1 {
		return 2
	}
	return 1
}

func (dll *DLL) GetRes() []int64 {
	ret := []int64{}
	for _, node := range dll.Nodes {
		ret = append(ret, node.Res)
	}
	return ret
}