```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
func readInt(reader *bufio.Reader) int {
var res int
var sign int = 1
for {
c, err := reader.ReadByte()
if err != nil {
break
}
if c == '-' {
sign = -1
continue
}
if c >= '0' && c <= '9' {
res = int(c - '0')
break
}
}
for {
c, err := reader.ReadByte()
if err != nil || c < '0' || c > '9' {
break
}
res = res*10 + int(c-'0')
}
return res * sign
}
func main() {
reader := bufio.NewReader(os.Stdin)
n := readInt(reader)
if n == 0 {
return
}
m := readInt(reader)
nm := n * m
grid := make([]int, nm)
for i := 0; i < nm; i++ {
grid[i] = readInt(reader)
}
adj := make([][]int, nm)
for i := 0; i < nm; i++ {
r := i / m
c := i % m
if r > 0 {
adj[i] = append(adj[i], i-m)
}
if r < n-1 {
adj[i] = append(adj[i], i+m)
}
if c > 0 {
adj[i] = append(adj[i], i-1)
}
if c < m-1 {
adj[i] = append(adj[i], i+1)
}
}
isBad := func(i int) bool {
if grid[i] == 1 {
return false
}
for _, nbr := range adj[i] {
if grid[nbr] < grid[i] {
return false
}
}
return true
}
badCount := 0
var badCells []int
for i := 0; i < nm; i++ {
if isBad(i) {
badCells = append(badCells, i)
badCount++
}
}
if badCount == 0 {
fmt.Println(0)
return
}
firstBad := badCells[0]
cand := []int{firstBad}
cand = append(cand, adj[firstBad]...)
inCand := make(map[int]bool)
var uniqueCand []int
for _, c := range cand {
if !inCand[c] {
inCand[c] = true
uniqueCand = append(uniqueCand, c)
}
}
var validSwaps []int64
visited := make([]int, nm)
visitToken := 0
S := make([]int, 0, 10)
for _, a := range uniqueCand {
for b := 0; b < nm; b++ {
if a == b {
continue
}
S = S[:0]
visitToken++
add := func(x int) {
if visited[x] != visitToken {
visited[x] = visitToken
S = append(S, x)
}
}
add(a)
add(b)
for _, nbr := range adj[a] {
add(nbr)
}
for _, nbr := range adj[b] {
add(nbr)
}
badBefore := 0
for _, x := range S {
if isBad(x) {
badBefore++
}
}
grid[a], grid[b] = grid[b], grid[a]
badAfter := 0
for _, x := range S {
if isBad(x) {
badAfter++
}
}
grid[a], grid[b] = grid[b], grid[a]
if badCount-badBefore+badAfter == 0 {
u, v := a, b
if u > v {
u, v = v, u
}
validSwaps = append(validSwaps, int64(u)*int64(nm)+int64(v))
}
}
}
if len(validSwaps) > 0 {
sort.Slice(validSwaps, func(i, j int) bool {
return validSwaps[i] < validSwaps[j]
})
uniqueCount := 1
for i := 1; i < len(validSwaps); i++ {
if validSwaps[i] != validSwaps[i-1] {
uniqueCount++
}
}
fmt.Printf("1 %d\n", uniqueCount)
} else {
fmt.Println(2)
}
}
```