import java.io.IOException
import java.lang.NumberFormatException
import java.lang.StringBuilder
import java.util.ArrayDeque
import kotlin.math.max
import kotlin.math.min

object DMain{
    fun solve(){
        val mmax = 5000000

        val h = nextInt()
        val w = nextInt()
        val map = Array<IntArray>(h + 4){ IntArray(w + 4){-1} }

        val ch = nextInt()
        val cw = nextInt()
        val dh = nextInt()
        val dw = nextInt()

        for (i in 0 until h){
            val s = next()
            for(j in 0 until w){
                if(s[j] == '.') map[i+2][j+2] = mmax
            }
        }

        map[ch+1][cw+1] = 0

        val que = ArrayDeque<Pair<Int, Int>>()
        val jumpque = ArrayDeque<Pair<Int, Int>>()

        val move = Array<Pair<Int, Int>>(4){0 to 0}
        move[0] = 0 to 1
        move[1] = 0 to -1
        move[2] = 1 to 0
        move[3] = -1 to 0

        val move2 = Array<Pair<Int, Int>>(20){0 to 0}
        move2[0] = 2 to -2
        move2[1] = 2 to -1
        move2[2] = 2 to 0
        move2[3] = 2 to 1
        move2[4] = 2 to 2

        move2[5] = 1 to -2
        move2[6] = 1 to -1
        move2[7] = 1 to 1
        move2[8] = 1 to 2

        move2[9] = 0 to -2
        move2[10] = 0 to 2

        move2[11] = -1 to -2
        move2[12] = -1 to -1
        move2[13] = -1 to 1
        move2[14] = -1 to 2

        move2[15] = -2 to -2
        move2[16] = -2 to -1
        move2[17] = -2 to 0
        move2[18] = -2 to 1
        move2[19] = -2 to 2

        que.add(ch+1 to cw + 1)
        while(map[dh+1][dw+1] == mmax) {
            while (!que.isEmpty()) {
                val next = que.poll()
                val num = map[next.first][next.second]
                jumpque.add(next.first to next.second)

                for (i in 0 until 4) {
                    val mx = next.first + move[i].first
                    val my = next.second + move[i].second
                    if (map[mx][my] > num) {
                        map[mx][my] = num
                        que.add(mx to my)
                    }
                }


            }

            while(!jumpque.isEmpty()){
                val next = jumpque.poll()
                val num = map[next.first][next.second]
                for (i in 0 until 20) {
                    val mmmx = next.first + move2[i].first
                    val mmmy = next.second + move2[i].second
                    if (map[mmmx][mmmy] > num + 1) {
                        map[mmmx][mmmy] = num + 1
                        que.add(mmmx to mmmy)
                    }
                }
            }
            if(que.isEmpty() && jumpque.isEmpty()) break
        }

        if(map[dh+1][dw+1] == -1 || map[dh+1][dw+1] == mmax){
            println(-1)
        }else{
            println(map[dh+1][dw+1])
        }
    }





    // Scanner based on uwi-san's Java code
    val stream = System.`in`
    val buffer = ByteArray(1024)
    var ptr = 0
    var buflen = 0

    fun hasNextByte(): Boolean{
        if(ptr < buflen){
            return true
        }else{
            ptr = 0
            try{
                buflen = stream.read(buffer)
            }catch (e: IOException){
                e.printStackTrace()
            }
            if(buflen <= 0){
                return false
            }
        }
        return true
    }

    fun readByte() =
            if(hasNextByte()) buffer[ptr++]
            else -1

    fun isPrintableChar(c: Byte) = c in 33..126

    fun hasNext(): Boolean{
        while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++
        return hasNextByte()
    }

    fun next(): String{
        if(!hasNext()) throw NoSuchElementException()
        val sb = StringBuilder()
        var b = readByte()
        while(isPrintableChar(b)){
            sb.appendCodePoint(b.toInt())
            b = readByte()
        }
        return sb.toString()
    }

    fun nextLong(): Long{
        if(!hasNext()) throw NoSuchElementException()
        var n = 0L
        var minus = false
        var b = readByte()
        if(b == '-'.toByte()){
            minus = true
            b = readByte()
        }
        if(b !in '0'.toByte()..'9'.toByte())
            throw NumberFormatException()
        while(true){
            if(b in '0'.toByte()..'9'.toByte()){
                n *= 10
                n += b - '0'.toByte()
            }else if(!isPrintableChar(b)){
                return if(minus) -n else n
            }else{
                throw NumberFormatException()
            }
            b = readByte()
        }
    }

    fun nextInt(): Int{
        val n1 = nextLong()
        if(n1 !in Int.MIN_VALUE..Int.MAX_VALUE)
            throw NumberFormatException()
        return n1.toInt()
    }

    fun NextDouble() = next().toDouble()
}

fun main(){
    DMain.solve()
}
