```go
package main
import (
"fmt"
"os"
)
const bufferSize = 1 << 16
type Scanner struct {
buf []byte
pos int
max int
file *os.File
}
func NewScanner() *Scanner {
return &Scanner{
buf: make([]byte, bufferSize),
file: os.Stdin,
}
}
func (s *Scanner) nextByte() byte {
if s.pos >= s.max {
n, err := s.file.Read(s.buf)
if err != nil || n == 0 {
return 0
}
s.pos = 0
s.max = n
}
b := s.buf[s.pos]
s.pos++
return b
}
func (s *Scanner) NextInt() int {
var b byte
for b = s.nextByte(); b <= ' '; b = s.nextByte() {
if b == 0 {
return 0
}
}
var res int = 0
for b > ' ' {
res = res*10 + int(b-'0')
b = s.nextByte()
}
return res
}
func (s *Scanner) NextStringBytes() []byte {
var b byte
for b = s.nextByte(); b <= ' '; b = s.nextByte() {
if b == 0 {
return nil
}
}
res := make([]byte, 0, 1024)
for b > ' ' {
res = append(res, b)
b = s.nextByte()
}
return res
}
func (s *Scanner) NextChar() byte {
var b byte
for b = s.nextByte(); b <= ' '; b = s.nextByte() {
if b == 0 {
return 0
}
}
return b
}
func main() {
scanner := NewScanner()
n := scanner.NextInt()
m := scanner.NextInt()
k := scanner.NextInt()
T := make([][]byte, n)
for i := 0; i < n; i++ {
T[i] = scanner.NextStringBytes()
}
type DUpdate struct {
y int
char int
val int
}
type QEvent struct {
y int
char int
sign int
q_idx int
}
d_events := make([][]DUpdate, n+2)
events := make([][]QEvent, n+2)
for i := 0; i < k; i++ {
a := scanner.NextInt()
b := scanner.NextInt()
c := scanner.NextInt()
d := scanner.NextInt()
e := scanner.NextChar()
e_idx := int(e - 'a')
d_events[a] = append(d_events[a], DUpdate{b, e_idx, 1})
d_events[c+1] = append(d_events[c+1], DUpdate{b, e_idx, -1})
d_events[a] = append(d_events[a], DUpdate{d + 1, e_idx, -1})
d_events[c+1] = append(d_events[c+1], DUpdate{d + 1, e_idx, 1})
events[c] = append(events[c], QEvent{d, e_idx, 1, i})
if a-1 > 0 {
events[a-1] = append(events[a-1], QEvent{d, e_idx, -1, i})
if b-1 > 0 {
events[a-1] = append(events[a-1], QEvent{b - 1, e_idx, 1, i})
}
}
if b-1 > 0 {
events[c] = append(events[c], QEvent{b - 1, e_idx, -1, i})
}
}
var V [26][1005]int
var W_pref [26][1005]int64
var BaseCost int64 = 0
query_ans := make([]int64, k)
for x := 1; x <= n; x++ {
for _, upd := range d_events[x] {
V[upd.char][upd.y] += upd.val
}
var current_A [26]int
var W_row_sum [26]int64
for y := 1; y <= m; y++ {
var R int = 0
for char := 0; char < 26; char++ {
current_A[char] += V[char][y]
R += current_A[char]
}
t := int(T[x-1][y-1] - 'a')
var cost0 int64 = 0
for char := 0; char < 26; char++ {
cnt := current_A[char]
if char == t {
cnt += k - R
}
cost0 += int64(cnt) * int64(char)
}
var cost [26]int64
cost[0] = cost0
var prefCnt int = 0
for c := 0; c < 25; c++ {
cnt := current_A[c]
if c == t {
cnt += k - R
}
prefCnt += cnt
cost[c+1] = cost[c] + int64(prefCnt) - int64(k-prefCnt)
}
BaseCost += cost[t]
for c := 0; c < 26; c++ {
W_row_sum[c] += cost[c] - cost[t]
W_pref[c][y] += W_row_sum[c]
}
}
for _, ev := range events[x] {
query_ans[ev.q_idx] += int64(ev.sign) * W_pref[ev.char][ev.y]
}
}
minAns := int64(9e18)
for i := 0; i < k; i++ {
ans := BaseCost + query_ans[i]
if ans < minAns {
minAns = ans
}
}
fmt.Println(minAns)
}
```