def is_next?(x, y)
    return false if x != 0 && y != 0
    return false if x == 0 && y == 0

    return true
end

def is_out_of_range?(x, y, h, w)
    return true if x < 0 || y < 0
    return true if h <= x || w <= y

    return false
end

def print_zip(zip)
    zip.size.times do |r|
        zip.first.size.times do |d|
            print "#{zip[r][d]}\t"
        end
        puts 
    end
    puts 
end

h, w = gets.split(' ').map(&:to_i)
sh, sw = gets.split(' ').map { |a| a.to_i - 1}
gh, gw = gets.split(' ').map { |a| a.to_i - 1}

box = []
zip = []
DEFAULT_VALUE = 1001
h.times do
  box << gets
  zip << [DEFAULT_VALUE] * w
end

goto = [[sh, sw]]
zip[sh][sw] = 0
while true
    break if goto.empty?
    x, y = goto.pop
    # 行動A
    (-1..1).each do |i|
        (-1..1).each do |j|
            if is_next?(i, j)
                nx, ny = x + i, y + j
                # 枠からはみ出していたら次に行く
                next if is_out_of_range?(nx, ny, h, w)
                next if box[nx][ny] == '#'

                # データの更新
                if zip[nx][ny] == DEFAULT_VALUE
                    goto.push([nx, ny])
                end
                # puts "#{nx}, #{ny}"
                # print_zip(zip)
                # puts ">> #{goto}"

                # 魔法を使う
                if zip[nx][ny] > zip[x][y]
                    zip[nx][ny] = zip[x][y]
                end
            end
        end
    end

    # 行動B
    (-2..2).each do |i|
        (-2..2).each do |j|
            nx, ny = x + i, y + j
            # 枠からはみ出していたら次に行く
            next if is_out_of_range?(nx, ny, h, w)
            next if box[nx][ny] == '#'

            # データの更新
            if zip[nx][ny] == DEFAULT_VALUE
                goto.push([nx, ny])
            end

            # 魔法を使う
            if zip[nx][ny] > zip[x][y] + 1
                zip[nx][ny] = zip[x][y] + 1
            end
        end
    end
end

# print_zip(zip)
# puts zip[gh][gw]

if zip[gh][gw] == DEFAULT_VALUE
    puts -1
else
    puts zip[gh][gw]
end