← Home
package main

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

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

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

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

	for tc := 0; tc < t; tc++ {
		n := readInt()
		m := readInt()

		A := make([]int, n*m)
		for i := 0; i < n*m; i++ {
			A[i] = readInt()
		}

		B := make([]int, n*m)
		posB := make([]int, 2*n*m+1)
		for i := range posB {
			posB[i] = -1
		}
		for i := 0; i < n*m; i++ {
			B[i] = readInt()
			posB[B[i]] = i
		}

		L := 0
		for L < n*m {
			p := posB[A[L]]
			if p != -1 {
				if L == 0 || p > posB[A[L-1]] {
					L++
				} else {
					break
				}
			} else {
				break
			}
		}

		check := func(K int) bool {
			isRet := make([]bool, n*m)
			for i := 0; i < K; i++ {
				isRet[posB[A[i]]] = true
			}
			c := 0
			for j := 0; j < n*m; j++ {
				if !isRet[j] {
					if c > (j/m)*m {
						return false
					}
				} else {
					c++
				}
			}
			return true
		}

		ansK := 0
		low := 0
		high := L
		for low <= high {
			mid := (low + high) / 2
			if check(mid) {
				ansK = mid
				low = mid + 1
			} else {
				high = mid - 1
			}
		}

		isRet := make([]bool, n*m)
		for i := 0; i < ansK; i++ {
			isRet[posB[A[i]]] = true
		}

		Ij := make([]int, 0, n*m-ansK)
		for j := 0; j < n*m; j++ {
			if !isRet[j] {
				Ij = append(Ij, j)
			}
		}

		numI := len(Ij)
		fmt.Fprintln(out, numI)

		if numI > 0 {
			type Operation struct {
				i int
				x int
			}
			ansOps := make([]Operation, numI)

			tree := make([]int, numI+1)
			for i := 1; i <= numI; i++ {
				tree[i] += 1
				nxt := i + (i & -i)
				if nxt <= numI {
					tree[nxt] += tree[i]
				}
			}

			for i := numI - 1; i >= 0; i-- {
				j := Ij[i]
				pi := i - (j % m)

				idx := 0
				rem := pi
				for step := 19; step >= 0; step-- {
					next := idx + (1 << step)
					if next <= numI && tree[next] <= rem {
						idx = next
						rem -= tree[next]
					}
				}
				pos := idx + 1

				for k := pos; k <= numI; k += k & -k {
					tree[k] -= 1
				}

				ansOps[pos-1] = Operation{
					i: j/m + 1,
					x: B[j],
				}
			}

			for i := 0; i < numI; i++ {
				fmt.Fprintln(out, ansOps[i].i, ansOps[i].x)
			}
		}
	}
}