← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	scanner.Scan()
	m, _ := strconv.Atoi(scanner.Text())

	row_has_col := make([][]int, n)
	col_has_row := make([][]int, m)

	for i := 0; i < n; i++ {
		scanner.Scan()
		s := scanner.Text()
		for j := 0; j < m; j++ {
			if s[j] == '#' {
				row_has_col[i] = append(row_has_col[i], j)
				col_has_row[j] = append(col_has_row[j], i)
			}
		}
	}

	vis_row := make([]bool, n)
	vis_col := make([]bool, m)
	dist_row := make([]int, n)
	dist_col := make([]int, m)

	type State struct {
		isRow bool
		idx   int
	}

	queue := make([]State, 0)
	queue = append(queue, State{isRow: true, idx: 0})
	vis_row[0] = true

	for len(queue) > 0 {
		curr := queue[0]
		queue = queue[1:]

		if curr.isRow {
			if curr.idx == n-1 {
				fmt.Println(dist_row[n-1])
				return
			}
			for _, c := range row_has_col[curr.idx] {
				if !vis_col[c] {
					vis_col[c] = true
					dist_col[c] = dist_row[curr.idx] + 1
					queue = append(queue, State{isRow: false, idx: c})
				}
			}
		} else {
			for _, r := range col_has_row[curr.idx] {
				if !vis_row[r] {
					vis_row[r] = true
					dist_row[r] = dist_col[curr.idx] + 1
					queue = append(queue, State{isRow: true, idx: r})
				}
			}
		}
	}

	fmt.Println("-1")
}