← Home
```go
package main

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

func rotate(mat [][]byte) [][]byte {
	n, m := len(mat), len(mat[0])
	res := make([][]byte, m)
	for i := 0; i < m; i++ {
		res[i] = make([]byte, n)
		for j := 0; j < n; j++ {
			res[i][j] = mat[n-1-j][i]
		}
	}
	return res
}

func serialize(mat [][]byte) string {
	var b strings.Builder
	n, m := len(mat), len(mat[0])
	b.Grow(n*m + n - 1)
	for i := 0; i < n; i++ {
		if i > 0 {
			b.WriteByte('|')
		}
		b.Write(mat[i])
	}
	return b.String()
}

func canonical(mat [][]byte) string {
	best := serialize(mat)
	cur := mat
	for i := 0; i < 3; i++ {
		cur = rotate(cur)
		s := serialize(cur)
		if s < best {
			best = s
		}
	}
	return best
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var A, B int
	if _, err := fmt.Fscan(in, &A, &B); err != nil {
		return
	}

	pic := make([][]byte, A)
	for i := 0; i < A; i++ {
		var s string
		fmt.Fscan(in, &s)
		pic[i] = []byte(s)
	}

	count := 0
	bestArea := 1 << 30
	bestX, bestY := 0, 0

	for x := 1; x <= A; x++ {
		if A%x != 0 {
			continue
		}
		for y := 1; y <= B; y++ {
			if B%y != 0 {
				continue
			}

			seen := make(map[string]struct{})
			good := true

			for r := 0; r < A && good; r += x {
				for c := 0; c < B; c += y {
					piece := make([][]byte, x)
					for i := 0; i < x; i++ {
						row := make([]byte, y)
						copy(row, pic[r+i][c:c+y])
						piece[i] = row
					}
					sig := canonical(piece)
					if _, ok := seen[sig]; ok {
						good = false
						break
					}
					seen[sig] = struct{}{}
				}
			}

			if good {
				count++
				area := x * y
				if area < bestArea || (area == bestArea && x < bestX) {
					bestArea = area
					bestX, bestY = x, y
				}
			}
		}
	}

	out := bufio.NewWriter(os.Stdout)
	fmt.Fprintln(out, count)
	fmt.Fprintln(out, bestX, bestY)
	out.Flush()
}
```