```go
package main
import (
"fmt"
)
var dr = []int{-1, 0, 1, 0}
var dc = []int{0, 1, 0, -1}
func getDir(r1, c1, r2, c2 int) int {
if r2-r1 == -1 && c2 == c1 {
return 0
}
if r2 == r1 && c2-c1 == 1 {
return 1
}
if r2-r1 == 1 && c2 == c1 {
return 2
}
if r2 == r1 && c2-c1 == -1 {
return 3
}
return -1
}
func collides(nr, nc, r, c, dirs, k int) bool {
if nr == r && nc == c {
return true
}
for i := 0; i < k-2; i++ {
dir := (dirs >> (2 * i)) & 3
r += dr[dir]
c += dc[dir]
if nr == r && nc == c {
return true
}
}
return false
}
func main() {
var n, m int
if _, err := fmt.Scan(&n, &m); err != nil {
return
}
grid := make([]string, n)
for i := 0; i < n; i++ {
fmt.Scan(&grid[i])
}
pos := make([]struct{ r, c int }, 10)
k := 0
target_r, target_c := -1, -1
for r := 0; r < n; r++ {
for c := 0; c < m; c++ {
ch := grid[r][c]
if ch >= '1' && ch <= '9' {
idx := int(ch - '0')
pos[idx] = struct{ r, c int }{r, c}
if idx > k {
k = idx
}
} else if ch == '@' {
target_r = r
target_c = c
}
}
}
start_r, start_c := pos[1].r, pos[1].c
dirs := 0
for i := 1; i < k; i++ {
d := getDir(pos[i].r, pos[i].c, pos[i+1].r, pos[i+1].c)
dirs |= d << (2 * (i - 1))
}
start_state := uint32(start_r<<20 | start_c<<16 | dirs)
dist := make([]uint16, 1<<24)
queue := make([]uint32, 0, 1000000)
queue = append(queue, start_state)
dist[start_state] = 1
mask := (1 << (2 * (k - 1))) - 1
head_idx := 0
for head_idx < len(queue) {
state := queue[head_idx]
head_idx++
r := int((state >> 20) & 15)
c := int((state >> 16) & 15)
dirs := int(state & 0xFFFF)
if r == target_r && c == target_c {
fmt.Println(dist[state] - 1)
return
}
d_val := dist[state]
for d := 0; d < 4; d++ {
nr := r + dr[d]
nc := c + dc[d]
if nr < 0 || nr >= n || nc < 0 || nc >= m {
continue
}
if grid[nr][nc] == '#' {
continue
}
if collides(nr, nc, r, c, dirs, k) {
continue
}
ndirs := ((dirs << 2) & mask) | (d ^ 2)
nstate := uint32(nr<<20 | nc<<16 | ndirs)
if dist[nstate] == 0 {
dist[nstate] = d_val + 1
queue = append(queue, nstate)
}
}
}
fmt.Println(-1)
}
```