package main
import (
"bufio"
"fmt"
"os"
)
type Point struct {
x, y, z int
}
func main() {
reader := bufio.NewReader(os.Stdin)
var n, m, k int
fmt.Fscan(reader, &n, &m, &k)
grid := make([][]int, n+1)
for i := 1; i <= n; i++ {
grid[i] = make([]int, m+1)
for j := 1; j <= m; j++ {
fmt.Fscan(reader, &grid[i][j])
}
}
occupied := make(map[Point]int)
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
occupied[Point{i, j, 1}] = grid[i][j]
}
}
ans := make(map[Point]int)
maxX, maxY, maxZ := 65, 65, 60
dx := []int{1, -1, 0, 0, 0, 0}
dy := []int{0, 0, 1, -1, 0, 0}
dz := []int{0, 0, 0, 0, 1, -1}
for c := 1; c <= k; c++ {
var targets []Point
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
if grid[i][j] == c {
targets = append(targets, Point{i, j, 1})
}
}
}
if len(targets) <= 1 {
continue
}
connected := make(map[Point]bool)
isTarget := make(map[Point]bool)
for _, t := range targets {
isTarget[t] = true
}
connected[targets[0]] = true
delete(isTarget, targets[0])
for len(isTarget) > 0 {
queue := []Point{}
parent := make(map[Point]Point)
visited := make(map[Point]bool)
for p := range connected {
queue = append(queue, p)
visited[p] = true
}
var foundTarget *Point
for len(queue) > 0 {
curr := queue[0]
queue = queue[1:]
if isTarget[curr] && !connected[curr] {
foundTarget = &curr
break
}
for i := 0; i < 6; i++ {
nx, ny, nz := curr.x+dx[i], curr.y+dy[i], curr.z+dz[i]
if nx >= 1 && nx <= maxX && ny >= 1 && ny <= maxY && nz >= 1 && nz <= maxZ {
np := Point{nx, ny, nz}
if !visited[np] {
if occ, exists := occupied[np]; !exists || occ == c {
visited[np] = true
parent[np] = curr
queue = append(queue, np)
}
}
}
}
}
if foundTarget == nil {
fmt.Println("-1")
return
}
curr := *foundTarget
for {
connected[curr] = true
if curr.z > 1 {
ans[curr] = c
occupied[curr] = c
}
delete(isTarget, curr)
if p, ok := parent[curr]; ok {
curr = p
} else {
break
}
}
}
}
if len(ans) > 400000 {
fmt.Println("-1")
return
}
fmt.Println(len(ans))
writer := bufio.NewWriter(os.Stdout)
for p, c := range ans {
fmt.Fprintf(writer, "%d %d %d %d\n", p.x, p.y, p.z, c)
}
writer.Flush()
}