Buggy python submission (verdict: Time Limit Exceeded):
class Digraph:
    #入力定義
    def __init__(self,vertex=[]):
        self.vertex=set(vertex)

        self.edge_number=0
        self.vertex_number=len(vertex)

        self.adjacent_out={v:{} for v in vertex} #出近傍(vが始点)
        self.adjacent_in={v:{} for v in vertex} #入近傍(vが終点)

    #頂点の追加
    def add_vertex(self,*adder):
        for v in adder:
            if v not in self.vertex:
                self.adjacent_in[v]={}
                self.adjacent_out[v]={}

                self.vertex_number+=1
                self.vertex.add(v)

    #辺の追加(更新)
    def add_edge(self,From,To,weight=1):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To not in self.adjacent_in[From]:
            self.edge_number+=1

        self.adjacent_out[From][To]=weight
        self.adjacent_in[To][From]=weight

    #辺を除く
    def remove_edge(self,From,To):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To in self.adjacent_out[From]:
            del self.adjacent_out[From][To]
            del self.adjacent_in[To][From]
            self.edge_number-=1

    #頂点を除く
    def remove_vertex(self,*vertexes):
        for  v in vertexes:
            if v in self.vertex:
                self.vertex_number-=1

                for u in self.adjacent_out[v]:
                    del self.adjacent_in[u][v]
                    self.edge_number-=1
                del self.adjacent_out[v]

                for u in self.adjacent_in[v]:
                    del self.adjacent_out[u][v]
                    self.edge_number-=1
                del self.adjacent_in[v]

    #Walkの追加
    def add_walk(self,*walk):
        pass

    #Cycleの追加
    def add_cycle(self,*cycle):
        pass

    #頂点の交換
    def __vertex_swap(self,p,q):
        self.vertex.sort()

    #グラフに頂点が存在するか否か
    def vertex_exist(self,v):
        return v in self.vertex

    #グラフに辺が存在するか否か
    def edge_exist(self,From,To):
        if not(self.vertex_exist(From) and self.vertex_exist(To)):
            return False
        return To in self.adjacent_out[From]

    #近傍
    def neighbohood(self,v):
        if not self.vertex_exist(v):
            return []
        return list(self.adjacent[v])

    #出次数
    def out_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_out[v])

    #入次数
    def in_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_in[v])

    #次数
    def degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return self.out_degree(v)-self.in_degree(v)

    #頂点数
    def vertex_count(self):
        return len(self.vertex)

    #辺数
    def edge_count(self):
        return self.edge_number

    #頂点vを含む連結成分
    def connected_component(self,v):
        pass

#Dijkstra
def Dijkstra(D,From,To,with_path=False):
    """Dijksta法を用いて,FromからToまでの距離を求める.

    D:辺の重みが全て非負の有向グラフ
    From:始点
    To:終点
    with_path:最短路も含めて出力するか?

    (出力の結果)
    with_path=True->(距離,最短経路の辿る際の前の頂点)
    with_path=False->距離
    """
    from copy import copy
    from heapq import heappush,heappop

    T={v:float("inf") for v in D.vertex}
    T[From]=0

    if with_path:
        Prev={v:None for v in D.vertex}

    Q=[(0,From)]

    Flag=False
    while Q:
        c,u=heappop(Q)

        if u==To:
            Flag=True
            break

        if T[u]<c:
            continue

        for v in D.adjacent_out[u]:
            if T[v]>T[u]+D.adjacent_out[u][v]:
                T[v]=T[u]+D.adjacent_out[u][v]
                heappush(Q,(T[v],v))

                if with_path:
                    Prev[v]=u

    if not Flag:
        if with_path:
            return (float("inf"),None)
        else:
            return float("inf")

    if with_path:
        path=[To]
        u=To
        while (Prev[u]!=None):
            u=Prev[u]
            path.append(u)
        return (T[To],path[::-1])
    else:
        return T[To]
#=====================================
def No_to_Pos(N):
    return (N//W+1,N%W+1)

def Pos_to_No(x,y):
    return (x-1)*W+(y-1)

def dist(P,Q):
    return max(abs(P[0]-Q[0]),abs(P[1]-Q[1]))
#=====================================
H,W=map(int,input().split())
C=tuple(map(int,input().split()))
D=tuple(map(int,input().split()))

S=["*"*(W+4)]*(H+4)

for x in range(H):
    S[x+2]="**"+input()+"**"

V=[]
for x in range(1,H+1):
    V+=[(x,y) for y in range(1,W+1)]

J=Digraph(V)
B=[(0,1),(0,2),(1,-2),(1,-1),(1,0),(1,1),(1,2),(2,-2),(2,-1),(2,0),(2,1),(2,2)]

for x in range(1,H+1):
    for y in range(1,W+1):
        if S[x+1][y+1]!=".":
            continue
        for (p,q) in B:
            if S[x+p+1][y+q+1]==".":
                if p==q-1==0 or p-1==q==0:
                    J.add_edge((x,y),(x+p,y+q),0)
                    J.add_edge((x+p,y+q),(x,y),0)
                else:
                    J.add_edge((x,y),(x+p,y+q),1)
                    J.add_edge((x+p,y+q),(x,y),1)

T=Dijkstra(J,C,D)
if T==float("inf"):
    print(-1)
else:
    print(T)


Fixed submission:
from collections import deque

H,W=map(int,input().split())
C=tuple(map(int,input().split()))
D=tuple(map(int,input().split()))

S=["*"*(W+4)]*(H+4)

for x in range(H):
    S[x+2]="**"+input()+"**"

V=[]
for a in range(-2,3):
    for b in range(-2,3):
        if not(a==b==0):
            if abs(a)+abs(b)<=1:
                V.append(((a,b),0))
            else:
                V.append(((a,b),1))

inf=float("inf")
Dist=[[inf]*(W+1) for _ in range(H+1)]

Q=deque([C])
Dist[C[0]][C[1]]=0

while Q:
    (x,y)=Q.popleft()
    for ((a,b),c) in V:
        try:
            if S[x+a+1][y+b+1]=="." and Dist[x][y]+c<Dist[x+a][y+b]:
                Dist[x+a][y+b]=Dist[x][y]+c
                if c==0:
                    Q.appendleft((x+a,y+b))
                else:
                    Q.append((x+a,y+b))
        except:
            pass

if Dist[D[0]][D[1]]<inf:
    print(Dist[D[0]][D[1]])
else:
    print(-1)

Buggy python submission (verdict: Time Limit Exceeded):
class Union_Find():
    def __init__(self,N):
        """0,1,...,n-1を要素として初期化する.

        n:要素数
        """
        self.n=N
        self.parents=[-1]*N
        self.rank=[0]*N

    def find(self, x):
        """要素xの属している族を調べる.

        x:要素
        """
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        """要素x,yを同一視する.

        x,y:要素
        """
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.rank[x]>self.rank[y]:
            self.parents[x] += self.parents[y]
            self.parents[y] = x
        else:
            self.parents[y] += self.parents[x]
            self.parents[x] = y

            if self.rank[x]==self.rank[y]:
                self.rank[y]+=1

    def size(self, x):
        """要素xの属している要素の数.

        x:要素
        """
        return -self.parents[self.find(x)]

    def same(self, x, y):
        """要素x,yは同一視されているか?

        x,y:要素
        """
        return self.find(x) == self.find(y)

    def members(self, x):
        """要素xが属している族の要素.
        ※族の要素の個数が欲しいときはsizeを使うこと!!

        x:要素
        """
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        """族の名前のリスト
        """
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        """族の個数
        """
        return len(self.roots())

    def all_group_members(self):
        """全ての族の出力
        """
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

class Digraph:
    #入力定義
    def __init__(self,vertex=[]):
        self.vertex=set(vertex)

        self.edge_number=0
        self.vertex_number=len(vertex)

        self.adjacent_out={v:{} for v in vertex} #出近傍(vが始点)
        self.adjacent_in={v:{} for v in vertex} #入近傍(vが終点)

    #頂点の追加
    def add_vertex(self,*adder):
        for v in adder:
            if v not in self.vertex:
                self.adjacent_in[v]={}
                self.adjacent_out[v]={}

                self.vertex_number+=1
                self.vertex.add(v)

    #辺の追加(更新)
    def add_edge(self,From,To,weight=1):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To not in self.adjacent_in[From]:
            self.edge_number+=1

        self.adjacent_out[From][To]=weight
        self.adjacent_in[To][From]=weight

    #辺を除く
    def remove_edge(self,From,To):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To in self.adjacent_out[From]:
            del self.adjacent_out[From][To]
            del self.adjacent_in[To][From]
            self.edge_number-=1

    #頂点を除く
    def remove_vertex(self,*vertexes):
        for  v in vertexes:
            if v in self.vertex:
                self.vertex_number-=1

                for u in self.adjacent_out[v]:
                    del self.adjacent_in[u][v]
                    self.edge_number-=1
                del self.adjacent_out[v]

                for u in self.adjacent_in[v]:
                    del self.adjacent_out[u][v]
                    self.edge_number-=1
                del self.adjacent_in[v]

    #Walkの追加
    def add_walk(self,*walk):
        pass

    #Cycleの追加
    def add_cycle(self,*cycle):
        pass

    #頂点の交換
    def __vertex_swap(self,p,q):
        self.vertex.sort()

    #グラフに頂点が存在するか否か
    def vertex_exist(self,v):
        return v in self.vertex

    #グラフに辺が存在するか否か
    def edge_exist(self,From,To):
        if not(self.vertex_exist(From) and self.vertex_exist(To)):
            return False
        return To in self.adjacent_out[From]

    #近傍
    def neighbohood(self,v):
        if not self.vertex_exist(v):
            return []
        return list(self.adjacent[v])

    #出次数
    def out_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_out[v])

    #入次数
    def in_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_in[v])

    #次数
    def degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return self.out_degree(v)-self.in_degree(v)

    #頂点数
    def vertex_count(self):
        return len(self.vertex)

    #辺数
    def edge_count(self):
        return self.edge_number

    #頂点vを含む連結成分
    def connected_component(self,v):
        pass

#Dijkstra
def Dijkstra(D,From,To,with_path=False):
    """Dijksta法を用いて,FromからToまでの距離を求める.

    D:辺の重みが全て非負の有向グラフ
    From:始点
    To:終点
    with_path:最短路も含めて出力するか?

    (出力の結果)
    with_path=True->(距離,最短経路の辿る際の前の頂点)
    with_path=False->距離
    """
    from copy import copy
    from heapq import heappush,heappop

    T={v:float("inf") for v in D.vertex}
    T[From]=0

    if with_path:
        Prev={v:None for v in D.vertex}

    Q=[(0,From)]

    Flag=False
    while Q:
        c,u=heappop(Q)

        if u==To:
            Flag=True
            break

        if T[u]<c:
            continue

        for v in D.adjacent_out[u]:
            if T[v]>T[u]+D.adjacent_out[u][v]:
                T[v]=T[u]+D.adjacent_out[u][v]
                heappush(Q,(T[v],v))

                if with_path:
                    Prev[v]=u

    if not Flag:
        if with_path:
            return (float("inf"),None)
        else:
            return float("inf")

    if with_path:
        path=[To]
        u=To
        while (Prev[u]!=None):
            u=Prev[u]
            path.append(u)
        return (T[To],path[::-1])
    else:
        return T[To]
#=====================================
def No_to_Pos(N):
    return (N//W+1,N%W+1)

def Pos_to_No(x,y):
    return (x-1)*W+(y-1)

def dist(P,Q):
    return max(abs(P[0]-Q[0]),abs(P[1]-Q[1]))
#=====================================
H,W=map(int,input().split())
FROM=tuple(map(int,input().split()))
TO=tuple(map(int,input().split()))

S=["*"*(W+2)]
for x in range(H):
    S+=["*"+input()+"*"]
S+=["*"*(W+2)]

U=Union_Find(H*W)

for a in range(1,H+1):
    for b in range(1,W+1):
        if S[a][b]==S[a+1][b]==".":
            U.union(Pos_to_No(a,b),Pos_to_No(a+1,b))
        if S[a][b]==S[a][b+1]==".":
            U.union(Pos_to_No(a,b),Pos_to_No(a,b+1))


P=set()
for u in U.roots():
    x,y=No_to_Pos(u)
    if S[x][y]==".":
        P.add(u)
P=list(P)
D=Digraph(P)
K=list(D.vertex)

for i in range(D.vertex_number):
    for j in range(i+1,D.vertex_number):
        for P in U.members(K[i]):
            for Q in U.members(K[j]):
                if dist(No_to_Pos(P),No_to_Pos(Q))<=2:
                    D.add_edge(K[i],K[j],1)
                    D.add_edge(K[j],K[i],1)

T=Dijkstra(D,U.find(Pos_to_No(*FROM)),U.find(Pos_to_No(*TO)))

if T==float("Inf"):
    print(-1)
else:
    print(T)

assert 1

Fixed submission:
from collections import deque

H,W=map(int,input().split())
C=tuple(map(int,input().split()))
D=tuple(map(int,input().split()))

S=["*"*(W+4)]*(H+4)

for x in range(H):
    S[x+2]="**"+input()+"**"

V=[]
for a in range(-2,3):
    for b in range(-2,3):
        if not(a==b==0):
            if abs(a)+abs(b)<=1:
                V.append(((a,b),0))
            else:
                V.append(((a,b),1))

inf=float("inf")
Dist=[[inf]*(W+1) for _ in range(H+1)]

Q=deque([C])
Dist[C[0]][C[1]]=0

while Q:
    (x,y)=Q.popleft()
    for ((a,b),c) in V:
        try:
            if S[x+a+1][y+b+1]=="." and Dist[x][y]+c<Dist[x+a][y+b]:
                Dist[x+a][y+b]=Dist[x][y]+c
                if c==0:
                    Q.appendleft((x+a,y+b))
                else:
                    Q.append((x+a,y+b))
        except:
            pass

if Dist[D[0]][D[1]]<inf:
    print(Dist[D[0]][D[1]])
else:
    print(-1)