Problem:
Score : 600 points

Problem Statement

Snuke, a water strider, lives in a rectangular pond that can be seen as a grid with H east-west rows and W north-south columns. Let (i,j) be the square at the i-th row from the north and j-th column from the west.

Some of the squares have a lotus leaf on it and cannot be entered.
The square (i,j) has a lotus leaf on it if c_{ij} is @, and it does not if c_{ij} is ..

In one stroke, Snuke can move between 1 and K squares (inclusive) toward one of the four directions: north, east, south, and west.
The move may not pass through a square with a lotus leaf. Moving to such a square or out of the pond is also forbidden.

Find the minimum number of strokes Snuke takes to travel from the square (x_1,y_1) to (x_2,y_2).
If the travel from (x_1,y_1) to (x_2,y_2) is impossible, point out that fact.

Constraints

1 \leq H,W,K \leq 10^6

H \times W \leq 10^6

1 \leq x_1,x_2 \leq H

1 \leq y_1,y_2 \leq W

x_1 \neq x_2 or y_1 \neq y_2.

c_{i,j} is . or @.

c_{x_1,y_1} = .

c_{x_2,y_2} = .

All numbers in input are integers.

Input

Input is given from Standard Input in the following format:

H W K
x_1 y_1 x_2 y_2
c_{1,1}c_{1,2} .. c_{1,W}
c_{2,1}c_{2,2} .. c_{2,W}
:
c_{H,1}c_{H,2} .. c_{H,W}

Output

Print the minimum number of strokes Snuke takes to travel from the square (x_1,y_1) to (x_2,y_2), or print -1 if the travel is impossible.

Sample Input 1

3 5 2
3 2 3 4
.....
.@..@
..@..

Sample Output 1

5

Initially, Snuke is at the square (3,2).
He can reach the square (3, 4) by making five strokes as follows:

From (3, 2), go west one square to (3, 1).

From (3, 1), go north two squares to (1, 1).

From (1, 1), go east two squares to (1, 3).

From (1, 3), go east one square to (1, 4).

From (1, 4), go south two squares to (3, 4).

Sample Input 2

1 6 4
1 1 1 6
......

Sample Output 2

2

Sample Input 3

3 3 1
2 1 2 3
.@.
.@.
.@.

Sample Output 3

-1

Solution in Fortran (GNU Fortran 9.2.1) (judge verdict: Accepted)

module mod_leftist_heap
  implicit none
  type t_key
    integer :: distance, count, x, y, direction
  end type
  type t_node
    type(t_node), private, pointer :: left => null(), right => null()
    integer :: rank = 1
    type(t_key), pointer :: key
  end type
  type leftist_heap
    integer :: size = 0
    type(t_node), private, pointer :: root => null()
  contains
    procedure :: offer => offer
    procedure :: poll => poll
    procedure :: meld => meld
  end type
contains
  logical function less(a, b) result(res)
    type(t_node), pointer, intent(in) :: a, b
    res = a%key%distance < b%key%distance
  end
  subroutine swap(a, b)
    type(t_node), pointer, intent(inout) :: a, b
    type(t_node), pointer :: c
    c => a
    a => b
    b => c
  end
  function newk0(distance, count, x, y, direction) result(res)
    integer, intent(in) :: distance, count, x, y, direction
    type(t_key), pointer :: res
    res => null()
    allocate(res)
    res%distance = distance
    res%count = count
    res%x = x
    res%y = y
    res%direction = direction
  end
  function newn0(key) result(res)
    type(t_key), pointer, intent(in) :: key
    type(t_node), pointer :: res
    res => null()
    allocate(res)
    res%key => key
  end
  recursive function meld_node(a, b) result(res)
    type(t_node), pointer, intent(in) :: a, b
    type(t_node), pointer :: res
    logical :: f
    if (.not.associated(a)) then
      res => b; return
    end if
    if (.not.associated(b)) then
      res => a; return
    end if
    if (less(a, b)) then
      res => a
      res%right => meld_node(res%right, b)
    else
      res => b
      res%right => meld_node(res%right, a)
    end if
    f = .not.associated(res%left)
    if (.not.f) f = res%left%rank < res%right%rank
    if (f) call swap(res%left, res%right)
    res%rank = merge(res%right%rank, 0, associated(res%right)) + 1
  end
  function poll(this) result(res)
    class(leftist_heap), intent(inout) :: this
    type(t_node), pointer :: left, right
    type(t_key), pointer :: res
    res => this%root%key
    left => this%root%left
    right => this%root%right
    deallocate(this%root)
    this%root => meld_node(left, right)
    this%size = this%size - 1
  end
  subroutine offer(this, distance, count, x, y, direction)
    class(leftist_heap), intent(inout) :: this
    integer, intent(in) :: distance, count, x, y, direction
    this%root => meld_node(this%root, newn0(newk0(distance, count, x, y, direction)))
    this%size = this%size + 1
  end
  type(leftist_heap) function meld(this, other) result(res)
    class(leftist_heap), intent(in) :: this
    type(leftist_heap), intent(in) :: other
    res%root => meld_node(this%root, other%root)
    res%size = this%size + other%size
  end
end module mod_leftist_heap
program pond_skater
  use mod_leftist_heap
  implicit none
  integer, parameter :: infty = lshift(1, 30)
  integer :: h, w, k, x(2), y(2), i, j
  integer :: dx(4) = (/0, 1, 0, -1/), dy(4) = (/1, 0, -1, 0/)
  integer :: dist, cnt, p, q, idx, u, v, cost, next
  integer, allocatable :: a(:, :, :)
  character(1000000) :: s
  type(leftist_heap) :: pq
  type(t_key), pointer :: key
  read(*,*) h, w, k
  read(*,*) x(1), y(1), x(2), y(2)
  allocate(a(0:h + 1, 0:w + 1, 4))
  a = -1
  do i = 1, h
    read(*,*) s
    do j = 1, w
      if (s(j:j) == '.') a(i, j, :) = infty
    end do
  end do
  a(x(1), y(1), :) = 0
  do i = 1, 4
    call pq%offer(0, k - 1, x(1), y(1), i)
  end do
  do while (pq%size > 0)
    key => pq%poll()
    dist = key%distance
    cnt = key%count
    p = key%x
    q = key%y
    idx = key%direction
    if (a(p, q, idx) < dist) cycle
    do i = 1, 4
      u = p + dx(i)
      v = q + dy(i)
      if (i == idx) then
        cost = 0
        next = cnt + 1
        if (next >= k) then
          cost = 1
          next = 0
        end if
        if (a(u, v, i) > dist + cost) then
          a(u, v, i) = dist + cost
          call pq%offer(a(u, v, i), next, u, v, i)
        end if
      else
        if (a(u, v, i) > dist + 1) then
          a(u, v, i) = dist + 1
          call pq%offer(a(u, v, i), 0, u, v, i)
        end if
      end if
    end do
  end do
  dist = minval(a(x(2), y(2), :))
  write(*,'(i0)') merge(-1, dist, dist == infty)
end program pond_skater