import java.util.*

fun main() {
    var (H, W) = readLine()!!.split(" ").map(String::toInt)
    var (CH, CW) = readLine()!!.split(" ").map{it.toInt()-1}
    var (DH, DW) = readLine()!!.split(" ").map{it.toInt()-1}
    var S = Array<String>(H){""}
    (0 .. H-1).forEach{ i ->
        S[i] = readLine()!!
    }

    // スタートノードから各ノードへの距離。ただし未訪問(初期状態)なら-1
    var dist = Array(H) {Array(W) {-1}}
    dist[CH][CW] = 0
    
    // スタートノードをキューに入れる
    var q = LinkedList<Pair<Int, Int>>()
    q.offer(Pair(CH, CW))
    // 幅優先探索で、未訪問のマスをスタートマスから近い順に巡る
    var DIR1 = arrayOf(Pair(0, 1), Pair(1, 0), Pair(0, -1), Pair(-1, 0))
    var DIR2 = arrayOf(
        Pair(-2, -2), Pair(-2, -1), Pair(-2, 0), Pair(-2, 1), Pair(-2, 2),
        Pair(-1, -2), Pair(-1, -1), Pair(-1, 1), Pair(-1, 2),
        Pair(0, -2), Pair(0, 2),
        Pair(1, -2), Pair(1, -1), Pair(1, 1), Pair(1, 2),
        Pair(2, -2), Pair(2, -1), Pair(2, 0), Pair(2, 1), Pair(2, 2)
        )
    while (!q.isEmpty()) {
        var (y, x) = q.poll()
        var d = dist[y][x]
        DIR1.forEach { (dy, dx) -> 
            var ny = y + dy
            var nx = x + dx
            if (0 <= ny && ny < H && 0 <= nx && nx < W && S[ny][nx] == '.' && (dist[ny][nx] == -1 || dist[ny][nx] > d)) {
                dist[ny][nx] = d
                q.offerFirst(Pair(ny, nx))
            }
        }
        DIR2.forEach { (dy, dx) -> 
            var ny = y + dy
            var nx = x + dx
            if (0 <= ny && ny < H && 0 <= nx && nx < W && S[ny][nx] == '.' && (dist[ny][nx] == -1 || dist[ny][nx] > d+1)) {
                dist[ny][nx] = d + 1
                q.offerLast(Pair(ny, nx))
            }
        }
    }
    println(dist[DH][DW])
}
