You play a computer game. Your character stands on some level of a multilevel ice cave. In order to move on forward, you need to descend one level lower and the only way to do this is to fall through the ice.

The level of the cave where you are is a rectangular square grid of n rows and m columns. Each cell consists either from intact or from cracked ice. From each cell you can move to cells that are side-adjacent with yours (due to some limitations of the game engine you cannot make jumps on the same place, i.e. jump from a cell to itself). If you move to the cell with cracked ice, then your character falls down through it and if you move to the cell with intact ice, then the ice on this cell becomes cracked.

Let's number the rows with integers from 1 to n from top to bottom and the columns with integers from 1 to m from left to right. Let's denote a cell on the intersection of the r-th row and the c-th column as (r, c). 

You are staying in the cell (r_1, c_1) and this cell is cracked because you've just fallen here from a higher level. You need to fall down through the cell (r_2, c_2) since the exit to the next level is there. Can you do this?


-----Input-----

The first line contains two integers, n and m (1 ≤ n, m ≤ 500) — the number of rows and columns in the cave description.

Each of the next n lines describes the initial state of the level of the cave, each line consists of m characters "." (that is, intact ice) and "X" (cracked ice).

The next line contains two integers, r_1 and c_1 (1 ≤ r_1 ≤ n, 1 ≤ c_1 ≤ m) — your initial coordinates. It is guaranteed that the description of the cave contains character 'X' in cell (r_1, c_1), that is, the ice on the starting cell is initially cracked.

The next line contains two integers r_2 and c_2 (1 ≤ r_2 ≤ n, 1 ≤ c_2 ≤ m) — the coordinates of the cell through which you need to fall. The final cell may coincide with the starting one.


-----Output-----

If you can reach the destination, print 'YES', otherwise print 'NO'.


-----Examples-----
Input
4 6
X...XX
...XX.
.X..X.
......
1 6
2 2

Output
YES

Input
5 4
.X..
...X
X.X.
....
.XX.
5 3
1 1

Output
NO

Input
4 7
..X.XX.
.XX..X.
X...X..
X......
2 2
1 6

Output
YES



-----Note-----

In the first sample test one possible path is:

[Image]

After the first visit of cell (2, 2) the ice on it cracks and when you step there for the second time, your character falls through the ice as intended.

Source: codeforces | Difficulty: HARD
Tags: Graph traversal


Solutions:
from sys import stdin, stdout, setrecursionlimit
input = stdin.readline
dir = [-1, 0, 1, 0, -1]
inf = float('inf')
from functools import cmp_to_key
from collections import defaultdict as dd
from collections import Counter, deque
from heapq import *
import math
from math import floor, ceil, sqrt

def geti():
	return map(int, input().strip().split())

def getl():
	return list(map(int, input().strip().split()))

def getis():
	return map(str, input().strip().split())

def getls():
	return list(map(str, input().strip().split()))

def gets():
	return input().strip()

def geta():
	return int(input())

def print_s(s):
	stdout.write(s + '\n')

def solve():
	(n, m) = geti()
	mat = []
	vis = [[False] * m for _ in range(n)]
	for i in range(n):
		mat.append(gets())
	q = deque()
	start = getl()
	end = getl()
	start[0] -= 1
	start[1] -= 1
	end[0] -= 1
	end[1] -= 1
	have = 0
	ok = False
	for d in range(4):
		x = end[0] + dir[d]
		y = end[1] + dir[d + 1]
		if [x, y] == start:
			ok = True
		if 0 <= x < n and 0 <= y < m and (mat[x][y] != 'X'):
			have += 1
	if start == end:
		if have > 0:
			print('YES')
		else:
			print('NO')
		return
	q.append(start)
	while q:
		(i, j) = q.pop()
		if vis[i][j]:
			continue
		vis[i][j] = True
		if [i, j] == end:
			if have >= 2:
				print('YES')
			elif have == 1 and ok:
				print('YES')
			else:
				print('NO')
			return
		for d in range(4):
			x = i + dir[d]
			y = j + dir[d + 1]
			if 0 <= x < n and 0 <= y < m and (not vis[x][y]):
				if mat[x][y] != 'X':
					q.append((x, y))
				elif [x, y] == end:
					print('YES')
					return
	print('NO')
solve()


(n, m) = map(int, input().split())
L = [input() for i in range(n)]
Visited = [[0] * m for i in range(n)]
start = list(map(int, input().split()))
end = list(map(int, input().split()))
if abs(end[0] - start[0]) + abs(end[1] - start[1]) == 1:
	if L[end[0] - 1][end[1] - 1] == 'X':
		print('YES')
	else:
		k = 0
		if end[0] != 1:
			if L[end[0] - 2][end[1] - 1] == '.':
				k += 1
		if end[1] != 1:
			if L[end[0] - 1][end[1] - 2] == '.':
				k += 1
		if end[0] != n:
			if L[end[0]][end[1] - 1] == '.':
				k += 1
		if end[1] != m:
			if L[end[0] - 1][end[1]] == '.':
				k += 1
		if k >= 1:
			print('YES')
		else:
			print('NO')
	exit()

def Do(i, j):
	q = [[i, j]]
	f = False
	while q:
		d = q[0]
		if d[0] != 0:
			if Visited[d[0] - 1][d[1]] == 0 and L[d[0] - 1][d[1]] == '.':
				Visited[d[0] - 1][d[1]] = 1
				q.append([d[0] - 1, d[1]])
		if d[0] != n - 1:
			if Visited[d[0] + 1][d[1]] == 0 and L[d[0] + 1][d[1]] == '.':
				Visited[d[0] + 1][d[1]] = 1
				q.append([d[0] + 1, d[1]])
		if d[1] != 0:
			if Visited[d[0]][d[1] - 1] == 0 and L[d[0]][d[1] - 1] == '.':
				Visited[d[0]][d[1] - 1] = 1
				q.append([d[0], d[1] - 1])
		if d[1] != m - 1:
			if Visited[d[0]][d[1] + 1] == 0 and L[d[0]][d[1] + 1] == '.':
				Visited[d[0]][d[1] + 1] = 1
				q.append([d[0], d[1] + 1])
		del q[0]
Do(start[0] - 1, start[1] - 1)
if end[0] == start[0] and start[1] == end[1]:
	Visited[end[0] - 1][end[1] - 1] = 0
if Visited[end[0] - 1][end[1] - 1] == 1:
	k = 0
	if end[0] != 1:
		if L[end[0] - 2][end[1] - 1] == '.':
			k += 1
	if end[1] != 1:
		if L[end[0] - 1][end[1] - 2] == '.':
			k += 1
	if end[0] != n:
		if L[end[0]][end[1] - 1] == '.':
			k += 1
	if end[1] != m:
		if L[end[0] - 1][end[1]] == '.':
			k += 1
	if k >= 2:
		print('YES')
	else:
		print('NO')
elif L[end[0] - 1][end[1] - 1] == 'X':
	k = 0
	f = False
	if end[0] != 1:
		if L[end[0] - 2][end[1] - 1] == '.':
			k += 1
		if Visited[end[0] - 2][end[1] - 1] == 1:
			f = True
	if end[1] != 1:
		if L[end[0] - 1][end[1] - 2] == '.':
			k += 1
		if Visited[end[0] - 1][end[1] - 2] == 1:
			f = True
	if end[0] != n:
		if L[end[0]][end[1] - 1] == '.':
			k += 1
		if Visited[end[0]][end[1] - 1] == 1:
			f = True
	if end[1] != m:
		if L[end[0] - 1][end[1]] == '.':
			k += 1
		if Visited[end[0] - 1][end[1]] == 1:
			f = True
	if k >= 1 and f:
		print('YES')
	else:
		print('NO')
else:
	print('NO')


(n, m) = map(int, input().split())
a = []
for i in range(n):
	a.append([])
for i in range(n):
	c = input()
	for j in c:
		if j == '.':
			a[i].append(0)
		else:
			a[i].append(1)
(x1, y1) = map(int, input().split())
(x2, y2) = map(int, input().split())
x1 -= 1
y1 -= 1
x2 -= 1
y2 -= 1
a[x1][y1] = 0
f = []
qs = 0
qt = 1
f.append([x1, y1])
while qs < qt:
	x = f[qs][0]
	y = f[qs][1]
	if [x, y] == [x2, y2]:
		break
	a[x][y] = 1
	qs += 1
	if x < n - 1 and (a[x + 1][y] == 0 or [x + 1, y] == [x2, y2]):
		qt += 1
		f.append([x + 1, y])
		if [x + 1, y] == [x2, y2]:
			break
		a[x + 1][y] += 2
	if x > 0 and (a[x - 1][y] == 0 or [x - 1, y] == [x2, y2]):
		qt += 1
		f.append([x - 1, y])
		if [x - 1, y] == [x2, y2]:
			break
		a[x - 1][y] += 2
	if y < m - 1 and (a[x][y + 1] == 0 or [x, y + 1] == [x2, y2]):
		qt += 1
		f.append([x, y + 1])
		if [x, y + 1] == [x2, y2]:
			break
		a[x][y + 1] += 2
	if y > 0 and (a[x][y - 1] == 0 or [x, y - 1] == [x2, y2]):
		qt += 1
		f.append([x, y - 1])
		if [x, y - 1] == [x2, y2]:
			break
		a[x][y - 1] += 2
else:
	print('NO')
	exit(0)
if a[x2][y2] == 1:
	print('YES')
elif x2 > 0 and a[x2 - 1][y2] != 1:
	print('YES')
elif x2 < n - 1 and a[x2 + 1][y2] != 1:
	print('YES')
elif y2 < m - 1 and a[x2][y2 + 1] != 1:
	print('YES')
elif y2 > 0 and a[x2][y2 - 1] != 1:
	print('YES')
else:
	print('NO')


(n, m) = map(int, input().split())
arr = [None] * n
for i in range(n):
	arr[i] = list(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())

def bfs(maze, x, y, r2, c2):
	global n, m
	q = [(x, y)]
	DIR = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	while len(q) != 0:
		nextLevel = []
		for (x, y) in q:
			for (dx, dy) in DIR:
				(new_x, new_y) = (x + dx, y + dy)
				if 0 <= new_x < n and 0 <= new_y < m and (maze[new_x][new_y] == '.'):
					maze[new_x][new_y] = 'X'
					nextLevel.append((new_x, new_y))
				elif new_x == r2 and new_y == c2 and (maze[new_x][new_y] == 'X'):
					return True
		q = nextLevel
	return False
answer = bfs(arr, r1, c1, r2, c2)
print('YES' if answer == True else 'NO')


def recurse():
	nonlocal ans
	qu = []
	qu.append((r1, c1))
	count = 1
	i = 0
	while i < count:
		(r, c) = qu[i]
		if r == r2 and c == c2:
			ans = True
			return
		mas[r][c] = 1
		if mas[r + 1][c] == 0:
			qu.append((r + 1, c))
			mas[r + 1][c] = 1
			count += 1
		if mas[r - 1][c] == 0:
			qu.append((r - 1, c))
			mas[r - 1][c] = 1
			count += 1
		if mas[r][c + 1] == 0:
			qu.append((r, c + 1))
			mas[r][c + 1] = 1
			count += 1
		if mas[r][c - 1] == 0:
			qu.append((r, c - 1))
			mas[r][c - 1] = 1
			count += 1
		i += 1
(n, m) = [int(x) for x in input().split()]
mas = []
mas.append([-1] * (m + 2))
for i in range(1, n + 1):
	mas.append([0] * (m + 2))
mas.append([-1] * (m + 2))
for i in range(1, n + 1):
	mas[i][0] = mas[i][m + 1] = -1
for i in range(1, n + 1):
	s = input()
	for j in range(1, m + 1):
		if s[j - 1] == 'X':
			mas[i][j] = -1
(r1, c1) = [int(x) for x in input().split()]
(r2, c2) = [int(x) for x in input().split()]
her = 0
if mas[r2 - 1][c2] != -1:
	her += 1
if mas[r2 + 1][c2] != -1:
	her += 1
if mas[r2][c2 - 1] != -1:
	her += 1
if mas[r2][c2 + 1] != -1:
	her += 1
if r1 == r2 and c1 == c2:
	if her > 0:
		print('YES')
	else:
		print('NO')
elif abs(r1 - r2) + abs(c1 - c2) == 1:
	if mas[r2][c2] != 0 or her > 0:
		print('YES')
	else:
		print('NO')
else:
	ans = False
	z = mas[r2][c2]
	mas[r1][c1] = mas[r2][c2] = 0
	recurse()
	if not ans:
		print('NO')
	elif z != 0:
		print('YES')
	elif her > 1:
		print('YES')
	else:
		print('NO')


from queue import Queue
DIR = [(0, -1), (-1, 0), (0, 1), (1, 0)]

def bfs(r1, c1, r2, c2, cave):
	q = [None] * (n * m)
	l = r = 0
	q[0] = (r1, c1)
	while l <= r:
		(x, y) = q[l]
		l += 1
		for (dx, dy) in DIR:
			new_x = x + dx
			new_y = y + dy
			if new_x < len(cave) and new_y < len(cave[0]) and (new_x >= 0) and (new_y >= 0):
				if cave[new_x][new_y] == 'X':
					if new_x == r2 and new_y == c2:
						return 'YES'
					else:
						continue
				else:
					r += 1
					q[r] = (new_x, new_y)
					cave[new_x][new_y] = 'X'
	return 'NO'
(n, m) = map(int, input().split())
cave = [None] * n
for i in range(n):
	cave[i] = list(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
print(bfs(r1 - 1, c1 - 1, r2 - 1, c2 - 1, cave))


(n, m) = map(int, input().split())
arr = [None] * n
for i in range(n):
	arr[i] = list(input())
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())

def bfs(maze, x, y, r2, c2):
	q = [(x, y)]
	path = [[None] * len(maze[0]) for i in range(len(maze))]
	path[x][y] = (x, y)
	DIR = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	while len(q) != 0:
		nextLevel = []
		for (x, y) in q:
			for (dx, dy) in DIR:
				(new_x, new_y) = (x + dx, y + dy)
				if 0 <= new_x < len(maze) and 0 <= new_y < len(maze[0]) and (path[new_x][new_y] == None) and (maze[new_x][new_y] == '.'):
					path[new_x][new_y] = (x, y)
					nextLevel.append((new_x, new_y))
				if new_x == r2 and new_y == c2 and (path[new_x][new_y] == None):
					path[new_x][new_y] = (x, y)
					nextLevel.append((new_x, new_y))
		q = nextLevel
	return path

def printPath(arr, path, sx, sy, fx, fy):
	b = []
	while True:
		b.append((fx, fy))
		(fx, fy) = path[fx][fy]
		if fx == sx and fy == sy:
			break
	for i in range(len(b) - 1, -1, -1):
		(u, v) = b[i]
		arr[u][v] = 'X'
path = bfs(arr, r1, c1, r2, c2)
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
answer = 'NO'
if n == 1 and m == 1:
	answer = 'NO'
elif r1 == r2 and c1 == c2:
	for (dx, dy) in directions:
		(new_x, new_y) = (r2 + dx, c2 + dy)
		if 0 <= new_x < n and 0 <= new_y < m and (arr[new_x][new_y] == '.'):
			answer = 'YES'
			break
elif path[r2][c2] != None:
	if arr[r2][c2] == 'X':
		answer = 'YES'
	else:
		printPath(arr, path, r1, c1, r2, c2)
		for (dx, dy) in directions:
			(new_x, new_y) = (r2 + dx, c2 + dy)
			if 0 <= new_x < n and 0 <= new_y < m and (arr[new_x][new_y] == '.'):
				answer = 'YES'
				break
print(answer)


import queue
MAX = 500
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]

def isValid(r, c):
	return r in range(m) and c in range(n)

def BFS(sr, sc, fr, fc):
	q = [0] * (MAX * MAX)
	left = right = 0
	q[0] = (sr, sc)
	while left <= right:
		(ur, uc) = q[left]
		left += 1
		for i in range(4):
			vr = ur + dr[i]
			vc = uc + dc[i]
			if isValid(vr, vc):
				if maze[vr][vc] == '.':
					maze[vr][vc] = 'X'
					right += 1
					q[right] = (vr, vc)
				elif vr == fr and vc == fc:
					return True
	return False
maze = [] * MAX
(m, n) = map(int, input().split())
for i in range(m):
	temp = list(input())
	maze.append(temp)
(start, start2) = map(int, input().split())
(end1, end2) = map(int, input().split())
if BFS(start - 1, start2 - 1, end1 - 1, end2 - 1):
	print('YES')
else:
	print('NO')


def neighbours(current, ok):
	global field
	global x_size
	global y_size
	neighs = set()
	x = current[0]
	y = current[1]
	if x - 1 >= 0 and field[y][x - 1] == ok:
		neighs.add((x - 1, y))
	if x + 1 < x_size and field[y][x + 1] == ok:
		neighs.add((x + 1, y))
	if y - 1 >= 0 and field[y - 1][x] == ok:
		neighs.add((x, y - 1))
	if y + 1 < y_size and field[y + 1][x] == ok:
		neighs.add((x, y + 1))
	return neighs

def all_neighbours(current):
	global field
	global x_size
	global y_size
	neighs = set()
	x = current[0]
	y = current[1]
	if x - 1 >= 0:
		neighs.add((x - 1, y))
	if x + 1 < x_size:
		neighs.add((x + 1, y))
	if y - 1 >= 0:
		neighs.add((x, y - 1))
	if y + 1 < y_size:
		neighs.add((x, y + 1))
	return neighs

def print_field(field, hor, vert):
	print(vert)
	for i in range(vert + 1):
		print(''.join(field[i]))
	print()
import time
start_time = time.clock()
(y_size, x_size) = [int(i) for i in input().split()]
crack = 'X'
ok = '.'
field = [None] * y_size
for i in range(y_size):
	field[i] = []
	field[i].extend(list(input()))
(start_y, start_x) = [int(i) for i in input().split()]
(goal_y, goal_x) = [int(i) for i in input().split()]
current = (start_x - 1, start_y - 1)
start = (start_x - 1, start_y - 1)
goal = (goal_x - 1, goal_y - 1)
stack = []
stack.append(current)
if field[goal[1]][goal[0]] == ok and len(neighbours(goal, ok)) <= 1 and (not current in all_neighbours(goal)):
	print('NO')
	exit(0)
while 1:
	cur_neigh_ok = neighbours(current, ok)
	if abs(goal[0] - current[0]) <= 1 or abs(goal[1] - current[1]) <= 1:
		cur_neigh_crack = neighbours(current, crack)
		if goal in cur_neigh_crack:
			print('YES')
			break
		elif goal in cur_neigh_ok:
			if neighbours(goal, ok):
				print('YES')
				break
			else:
				print('NO')
				break
	if cur_neigh_ok:
		current = cur_neigh_ok.pop()
		field[current[1]][current[0]] = crack
		stack.append(current)
	elif stack:
		current = stack.pop()
	else:
		neighs = neighbours(start, ok)
		if not neighs:
			print('NO')
			break
		else:
			current = neighs.pop()


import heapq
from copy import deepcopy
dir = [(-1, 0), (0, 1), (1, 0), (0, -1)]

def decr(x):
	return x - 1
(H, W) = map(int, input().split())
l = [list(input()) for i in range(H)]
(si, sj) = map(decr, map(int, input().split()))
(gi, gj) = map(decr, map(int, input().split()))
que = []
heapq.heappush(que, (si, sj))
res = False
while len(que):
	(i, j) = heapq.heappop(que)
	for k in range(4):
		ni = i + dir[k][0]
		nj = j + dir[k][1]
		if ni == gi and nj == gj and (l[ni][nj] == 'X'):
			res = True
		if 0 <= ni < H and 0 <= nj < W and (l[ni][nj] == '.'):
			l[ni][nj] = 'X'
			heapq.heappush(que, (ni, nj))
if res:
	print('YES')
else:
	print('NO')


def is_path_exist(cage, visited, i1, j1, i2, j2):
	dx = [0, 0, -1, 1]
	dy = [-1, 1, 0, 0]
	temp_point = []
	reached = False
	stk_adj = []
	stk_adj.append([i1, j1])
	cage[i1][j1] = 'X'
	while len(stk_adj) and (not reached):
		temp_point = stk_adj.pop()
		for i in range(0, 4):
			if (temp_point[0] + dx[i] > -1 and temp_point[0] + dx[i] < len(cage)) and (temp_point[1] + dy[i] > -1 and temp_point[1] + dy[i] < len(cage[0])) and (visited[temp_point[0] + dx[i]][temp_point[1] + dy[i]] == False):
				if temp_point[0] + dx[i] == i2 and temp_point[1] + dy[i] == j2:
					reached = True
					break
				if cage[temp_point[0] + dx[i]][temp_point[1] + dy[i]] != 'X':
					visited[temp_point[0] + dx[i]][temp_point[1] + dy[i]] = True
					stk_adj.append([temp_point[0] + dx[i], temp_point[1] + dy[i]])
	return reached
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
numbers = list(map(int, input().split()))
n = int(numbers[0])
m = int(numbers[1])
temp_line = ''
cage = []
visited = [[False] * m for _ in range(n)]
for i in range(0, n):
	cage.append([])
	temp_line = input()
	for j in range(0, m):
		cage[i].append(temp_line[j])
numbers = list(map(int, input().split()))
i1 = int(numbers[0] - 1)
j1 = int(numbers[1] - 1)
numbers = list(map(int, input().split()))
i2 = int(numbers[0] - 1)
j2 = int(numbers[1] - 1)
pos = 0
if is_path_exist(cage, visited, i1, j1, i2, j2):
	if cage[i2][j2] == 'X':
		print('YES')
		pos = 1
	if pos == 0:
		count = 0
		for i in range(0, 4):
			if i2 + dx[i] > -1 and i2 + dx[i] < len(cage) and (j2 + dy[i] > -1) and (j2 + dy[i] < len(cage[0])) and (cage[i2 + dx[i]][j2 + dy[i]] == '.' or (i2 + dx[i] == i1 and j2 + dy[i] == j1)):
				count += 1
		if count > 1:
			print('YES')
		else:
			print('NO')
else:
	print('NO')


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
M = [None] * n
for i in range(n):
	M[i] = list(input())
(a, b) = map(int, input().split())
a -= 1
b -= 1
(x, y) = map(int, input().split())
x -= 1
y -= 1
if a == x and b == y:
	for (h, k) in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
		if 0 <= h < n and 0 <= k < m and (M[h][k] == '.'):
			print('YES')
			exit()
	print('NO')
	exit()
vis = [[False] * m for _ in range(n)]

def ok():
	for i in range(n):
		for j in range(m):
			vis[i][j] = False
	vis[a][b] = True
	q = [(a, b)]
	while q:
		(i, j) = q.pop()
		for (h, k) in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
			if 0 <= h < n and 0 <= k < m and (not vis[h][k]) and (M[h][k] == '.'):
				vis[h][k] = True
				q.append((h, k))
			if h == x and k == y:
				return True
	return False
if M[x][y] == 'X':
	if ok():
		print('YES')
	else:
		print('NO')
	exit()
for (h, k) in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
	if 0 <= h < n and 0 <= k < m and (M[h][k] == '.'):
		M[h][k] = 'X'
		if ok():
			print('YES')
			exit()
		M[h][k] = '.'
print('NO')
exit()


def main():
	(n, m) = map(int, input().split())
	nm = n * m
	neigh = [[] for _ in range(nm)]
	for i in range(0, nm - m, m):
		for j in range(i, i + m):
			neigh[j].append(j + m)
			neigh[j + m].append(j)
	for i in range(0, nm, m):
		for j in range(i, i + m - 1):
			neigh[j].append(j + 1)
			neigh[j + 1].append(j)
	field = [c == '.' for _ in range(n) for c in input()]
	l = []
	for _ in (0, 1):
		(i, j) = map(int, input().split())
		l.append(i * m + j - m - 1)
	(start, stop) = l
	if start == stop:
		print(('NO', 'YES')[any((field[_] for _ in neigh[stop]))])
		return
	field[start] = True
	if field[stop] and sum((field[_] for _ in neigh[stop])) < 2:
		print('NO')
		return
	(nxt, field[stop]) = ((start,), True)
	while nxt:
		(cur, nxt) = (nxt, set())
		for u in cur:
			if u == stop:
				print('YES')
				return
			for v in neigh[u]:
				if field[v]:
					field[v] = False
					nxt.add(v)
	print('NO')
main()


from typing import List, Tuple

def intact_neighbor_count(n: int, m: int, cave: List[str], pos: Tuple[int, int]) -> int:
	(x, y) = pos
	intact_neighbor_count = 0
	for (xo, yo) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
		if 0 <= x + xo < n and 0 <= y + yo < m and (cave[x + xo][y + yo] == '.'):
			intact_neighbor_count += 1
	return intact_neighbor_count

def is_cracked(cave: List[str], end: Tuple[int, int]) -> bool:
	return cave[end[0]][end[1]] == 'X'

def is_path(n: int, m: int, cave: List[str], start: Tuple[int, int], end: Tuple[int, int]) -> bool:
	visited = [[0] * m for _ in range(n)]
	stack = [start]
	while stack:
		(x, y) = stack.pop()
		visited[x][y] = 1
		for (xo, yo) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
			if 0 <= x + xo < n and 0 <= y + yo < m:
				if x + xo == end[0] and y + yo == end[1]:
					return True
				if cave[x + xo][y + yo] == '.' and (not visited[x + xo][y + yo]):
					stack.append((x + xo, y + yo))
	return False

def normalize_index(pos: Tuple[int, int]) -> Tuple[int, int]:
	return (pos[0] - 1, pos[1] - 1)

def are_neighbors(pos1: Tuple[int, int], pos2: Tuple[int, int]) -> bool:
	return abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1]) == 1

def solve(n: int, m: int, cave: List[str], start: Tuple[int, int], end: Tuple[int, int]) -> str:
	n_start = normalize_index(start)
	n_end = normalize_index(end)
	path_exists = is_path(n, m, cave, n_start, n_end)
	count = intact_neighbor_count(n, m, cave, n_end)
	if start == end and count >= 1:
		return 'YES'
	elif path_exists and is_cracked(cave, n_end):
		return 'YES'
	elif path_exists and (not is_cracked(cave, n_end)) and (count >= 2):
		return 'YES'
	elif are_neighbors(n_start, n_end) and count >= 1:
		return 'YES'
	else:
		return 'NO'
(n, m) = list(map(int, input().split()))
cave = [input() for _ in range(n)]
start = list(map(int, input().split()))
end = list(map(int, input().split()))
print(solve(n, m, cave, start, end))


from sys import stdin
from collections import defaultdict
(n, m) = map(int, input().split())

def get_neighbors(r, c):
	neighbors = []
	if r - 1 >= 0:
		neighbors.append((r - 1, c))
	if c - 1 >= 0:
		neighbors.append((r, c - 1))
	if r + 1 < n:
		neighbors.append((r + 1, c))
	if c + 1 < m:
		neighbors.append((r, c + 1))
	return neighbors
graph = []
for i in range(n):
	graph.append(list(input()))
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1

def has_path(visited, start_x, start_y, goal_x, goal_y):
	stack = []
	stack.append((start_x, start_y))
	while stack:
		(node_r, node_c) = stack.pop()
		if not visited[node_r][node_c]:
			visited[node_r][node_c] = True
			if node_r == goal_x and node_c == goal_y:
				return True
			if node_r + 1 < n and (not visited[node_r + 1][node_c]) and (graph[node_r + 1][node_c] != 'X'):
				stack.append((node_r + 1, node_c))
			if node_c + 1 < m and (not visited[node_r][node_c + 1]) and (graph[node_r][node_c + 1] != 'X'):
				stack.append((node_r, node_c + 1))
			if node_r - 1 >= 0 and (not visited[node_r - 1][node_c]) and (graph[node_r - 1][node_c] != 'X'):
				stack.append((node_r - 1, node_c))
			if node_c - 1 >= 0 and (not visited[node_r][node_c - 1]) and (graph[node_r][node_c - 1] != 'X'):
				stack.append((node_r, node_c - 1))
	return False
visited = [[False for j in range(m)] for i in range(n)]
goal = graph[r2][c2]
graph[r2][c2] = '.'
if not has_path(visited, r1, c1, r2, c2):
	print('NO')
else:
	graph[r2][c2] = goal
	if r1 == r2 and c1 == c2:
		neighbors = get_neighbors(r1, c1)
		ans = False
		for (x, y) in neighbors:
			if graph[x][y] == '.':
				ans = True
		print('YES' if ans else 'NO')
	elif (r2, c2) in get_neighbors(r1, c1):
		if graph[r2][c2] == 'X':
			print('YES')
		else:
			neighbors = get_neighbors(r2, c2)
			ans = False
			for (x, y) in neighbors:
				if graph[x][y] == '.':
					ans = True
			print('YES' if ans else 'NO')
	else:
		neighbors = get_neighbors(r2, c2)
		intact = 0
		for (x, y) in neighbors:
			if graph[x][y] == '.':
				intact += 1
		if graph[r2][c2] == 'X':
			print('YES' if intact >= 1 else 'NO')
		else:
			print('YES' if intact >= 2 else 'NO')


def test(x):
	if x == 'X' or type(x) == int:
		return False
	return True
(n, m) = (int(i) for i in input().split())
map = []
for i in range(n):
	map.append([i for i in input()])
for i in map:
	while ' ' in i:
		i.remove(' ')
(r1, c1) = (int(i) for i in input().split())
(r2, c2) = (int(i) for i in input().split())
step = 0
map[r1 - 1][c1 - 1] = 0
if map[r2 - 1][c2 - 1] == 'X':
	flag = 0
	map[r2 - 1][c2 - 1] = '.'
else:
	flag = 1
now = [(r1 - 1, c1 - 1)]
while type(map[r2 - 1][c2 - 1]) != int and now != []:
	now_new = []
	for (i, j) in now:
		if i > 0:
			if test(map[i - 1][j]):
				map[i - 1][j] = step + 1
				now_new.append((i - 1, j))
		if i < n - 1:
			if test(map[i + 1][j]):
				map[i + 1][j] = step + 1
				now_new.append((i + 1, j))
		if j > 0:
			if test(map[i][j - 1]):
				map[i][j - 1] = step + 1
				now_new.append((i, j - 1))
		if j < m - 1:
			if test(map[i][j + 1]):
				map[i][j + 1] = step + 1
				now_new.append((i, j + 1))
	now = now_new
	step = step + 1
if type(map[r2 - 1][c2 - 1]) != int:
	print('NO')
elif flag == 0:
	print('YES')
else:
	acc = 0
	acc1 = 0
	i = r2 - 1
	j = c2 - 1
	if i > 0:
		if type(map[i - 1][j]) == int:
			acc1 += 1
		elif map[i - 1][j] != 'X':
			acc += 1
	if i < n - 1:
		if type(map[i + 1][j]) == int:
			acc1 += 1
		elif map[i + 1][j] != 'X':
			acc += 1
	if j > 0:
		if type(map[i][j - 1]) == int:
			acc1 += 1
		elif map[i][j - 1] != 'X':
			acc += 1
	if j < m - 1:
		if type(map[i][j + 1]) == int:
			acc1 += 1
		elif map[i][j + 1] != 'X':
			acc += 1
	if acc == 0 and acc1 < 2:
		print('NO')
	else:
		print('YES')


import queue
dx = [0, -1, 0, 1]
dy = [-1, 0, 1, 0]

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y

def BFS(s, f):
	q = queue.Queue()
	q.put(s)
	a[s.x][s.y] = 0
	while q.qsize() > 0:
		u = q.get()
		for i in range(4):
			x = u.x + dx[i]
			y = u.y + dy[i]
			if 0 <= x < n and 0 <= y < m:
				if a[x][y] == 0:
					if x == f.x and y == f.y:
						return True
				else:
					a[x][y] = 0
					q.put(Point(x, y))
	return False
(n, m) = map(int, input().split())
x = []
for i in range(n):
	line = input()
	x.append(line)
a = []
for i in range(n):
	b = []
	for j in range(m):
		if x[i][j] == 'X':
			b.append(0)
		else:
			b.append(1)
	a.append(b)
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
if BFS(Point(r1 - 1, c1 - 1), Point(r2 - 1, c2 - 1)):
	print('YES')
else:
	print('NO')


(n, m) = [int(x) for x in input().split()]
visited = [[True for i in range(m + 2)]]
visited += [[True] + [False if c == '.' else True for c in input()] + [True] for i in range(n)]
visited += [[True for i in range(m + 2)]]
start = tuple((int(x) for x in input().split()))
finish = tuple((int(x) for x in input().split()))
visited[start[0]][start[1]] = False

def neighbours(p):
	return ((p[0] + 1, p[1]), (p[0], p[1] + 1), (p[0] - 1, p[1]), (p[0], p[1] - 1))
gates = [p for p in neighbours(finish) if not visited[p[0]][p[1]]]

def DFS(p, gates):
	stack = [p]
	while stack:
		node = stack.pop()
		if node in gates:
			return True
		(x, y) = node
		if visited[x][y]:
			continue
		visited[x][y] = True
		stack.extend(neighbours(node))
	return False
if finish == start and len(gates) > 0:
	print('YES')
elif not visited[finish[0]][finish[1]] and len(gates) < 2 or len(gates) == 0:
	print('NO')
else:
	print('YES' if DFS(start, gates) else 'NO')


(n, m) = map(int, input().split())
arr = []
for row in range(n):
	arr.append(list(input()))
(r1, c1) = map(lambda x: int(x) - 1, input().split())
(r2, c2) = map(lambda x: int(x) - 1, input().split())
curr_cell = (r1, c1)
q = [curr_cell]

def neighbors(r, c):
	l = []
	if r != 0 and arr[r - 1][c] == '.':
		l.append((r - 1, c))
	if r != n - 1 and arr[r + 1][c] == '.':
		l.append((r + 1, c))
	if c != 0 and arr[r][c - 1] == '.':
		l.append((r, c - 1))
	if c != m - 1 and arr[r][c + 1] == '.':
		l.append((r, c + 1))
	return l
finished = False
while q:
	(r, c) = q.pop()
	arr[r][c] = 'X'
	if r2 == r and c2 == c:
		if neighbors(r, c):
			print('YES')
			finished = True
			break
		else:
			print('NO')
			finished = True
			break
	elif abs(r2 - r) + abs(c2 - c) == 1:
		if arr[r2][c2] == 'X':
			print('YES')
			finished = True
			break
		else:
			q.append((r2, c2))
			continue
	else:
		q += neighbors(r, c)
if not finished:
	print('NO')


(n, m) = (int(x) for x in input().split())
mp = [['']] * n
for i in range(n):
	mp[i] = list(input().strip())
(x0, y0) = (int(x) for x in input().split())
x0 -= 1
y0 -= 1
(x1, y1) = (int(x) for x in input().split())
x1 -= 1
y1 -= 1

def gen_neighbours(x, y):
	res = []
	if x > 0:
		res.append((x - 1, y))
	if x < n - 1:
		res.append((x + 1, y))
	if y > 0:
		res.append((x, y - 1))
	if y < m - 1:
		res.append((x, y + 1))
	return res
cnt = 0
for el in gen_neighbours(x1, y1):
	if mp[el[0]][el[1]] == '.' or el == (x0, y0):
		cnt += 1
if x0 == x1 and y0 == y1:
	if cnt > 0:
		print('YES')
	else:
		print('NO')
	exit(0)
if mp[x1][y1] == '.' and cnt <= 1:
	print('NO')
	exit(0)
ind = 0
end = 1
q = [0] * (n * m * 2)
q[0] = (x0, y0)
while True:
	if ind == len(q) or q[ind] == 0:
		break
	(x, y) = q[ind]
	if (x, y) == (x1, y1):
		print('YES')
		exit(0)
	for el in gen_neighbours(x, y):
		if el == (x1, y1):
			print('YES')
			exit(0)
		if mp[el[0]][el[1]] == '.':
			q[end] = el
			end += 1
			mp[el[0]][el[1]] = 'X'
	ind += 1
print('NO')


def ice_cave(start, dest, n, m, matrix):

	def checkBorder(u, v):
		if u >= 0 and u < m and (v >= 0) and (v < n):
			return True
		return False
	q = [0] * (n * m)
	front = 0
	rear = 0
	q[rear] = start
	rear += 1
	dx = [-1, 1, 0, 0]
	dy = [0, 0, 1, -1]
	while front != rear:
		(y, x) = q[front]
		front += 1
		for k in range(4):
			(v, u) = (y + dy[k], x + dx[k])
			if checkBorder(u, v) and matrix[v][u] == '.':
				matrix[v][u] = 'X'
				q[rear] = (v, u)
				rear += 1
			elif checkBorder(u, v) and matrix[v][u] == 'X' and (u == dest[1]) and (v == dest[0]):
				return 'YES'
	return 'NO'
(n, m) = map(int, input().strip().split(' '))
matrix = []
for _ in range(n):
	matrix.append(list(input().strip()))
start = tuple((int(x) - 1 for x in input().strip().split(' ')))
dest = tuple((int(x) - 1 for x in input().strip().split(' ')))
print(ice_cave(start, dest, n, m, matrix))


3
from collections import deque

def dfs():
	while len(queue) != 0:
		s = queue.popleft()
		(i, j) = s
		for (ni, nj) in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
			if ni in range(0, n) and nj in range(0, m):
				fl = data[ni][nj]
				if e == (ni, nj) and fl == 'X':
					return True
				elif fl == '.':
					data[ni][nj] = 'X'
					queue.append((ni, nj))
	return False
[n, m] = list(map(int, input().split()))
data = list()
for i in range(0, n):
	data.append(list([x for x in input()]))
[si, sj] = list(map(int, input().split()))
[ei, ej] = list(map(int, input().split()))
e = (ei - 1, ej - 1)
queue = deque()
queue.append((si - 1, sj - 1))
print('YES' if dfs() else 'NO')


import sys
from queue import Queue
n = m = xS = yS = xD = yD = -1
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
grid = []
marked = []

def check(x, y):
	global n, m
	return -1 < x and x < n and (-1 < y) and (y < m)

def bfs(grid, xS, yS, xD, yD):
	q = [None for _ in range(250005)]
	l = r = 0
	q[r] = (xS, yS)
	r += 1
	while l < r:
		(xC, yC) = q[l]
		l += 1
		for i in range(4):
			xN = xC + dx[i]
			yN = yC + dy[i]
			if check(xN, yN):
				if grid[xN][yN] == 'X' and xN == xD and (yN == yD):
					return True
				if grid[xN][yN] == '.':
					grid[xN][yN] = 'X'
					q[r] = (xN, yN)
					r += 1
	return False
(n, m) = map(int, input().split())
grid = [[] for _ in range(n)]
marked = [[False for _ in range(m)] for _ in range(n)]
for i in range(n):
	grid[i] = list(input())
(xS, yS) = map(lambda x: int(x) - 1, input().split())
(xD, yD) = map(lambda x: int(x) - 1, input().split())
if bfs(grid, xS, yS, xD, yD):
	print('YES')
else:
	print('NO')


from collections import deque
(n, m) = map(int, input().split(' '))
ice = [[]]
for _ in range(n):
	ice.append([''] + list(input()))
(r1, c1) = map(int, input().split(' '))
(r2, c2) = map(int, input().split(' '))
q = deque()
q.append((r1, c1))
while q:
	cur = q.popleft()
	for (x, y) in ((0, 1), (1, 0), (0, -1), (-1, 0)):
		cx = cur[0] + x
		cy = cur[1] + y
		if 0 < cx <= n and 0 < cy <= m and (ice[cx][cy] == '.' or (cx, cy) == (r2, c2)):
			if (cx, cy) == (r2, c2) and ice[cx][cy] == 'X':
				print('YES')
				exit()
			ice[cx][cy] = 'X'
			q.append((cx, cy))
print('NO')


def pick(D, v):
	return D[v[0]][v[1]]

def getNeighbours(A, x, y, t='.'):
	neighbours = []
	if x > 0 and A[x - 1][y] == t:
		neighbours.append((x - 1, y))
	if y > 0 and A[x][y - 1] == t:
		neighbours.append((x, y - 1))
	if x < len(A) - 1 and A[x + 1][y] == t:
		neighbours.append((x + 1, y))
	if y < len(A[0]) - 1 and A[x][y + 1] == t:
		neighbours.append((x, y + 1))
	return neighbours

def countNeighbours(A, x, y, t='.'):
	return len(getNeighbours(A, x, y, t))

def hasPath(A, xs, ys, xe, ye):
	A[xe][ye] = '.'
	D = [[-1 for _ in range(len(A[0]))] for _ in range(len(A))]
	D[xs][ys] = 0
	Q = [(xs, ys)]
	while len(Q) > 0:
		u = Q.pop()
		for v in getNeighbours(A, *u):
			if pick(D, v) == -1:
				Q.insert(0, v)
				D[v[0]][v[1]] = pick(D, u) + 1
	return D[xe][ye] != -1

def solve(A, r1, c1, r2, c2):
	if r1 == r2 and c1 == c2:
		if countNeighbours(A, r1, c1) > 0:
			return True
		else:
			return False
	elif (r2, c2) in getNeighbours(A, r1, c1) or (r2, c2) in getNeighbours(A, r1, c1, 'X'):
		if A[r2][c2] == 'X':
			return True
		elif countNeighbours(A, r2, c2) > 0:
			return True
		else:
			return False
	elif A[r2][c2] == '.':
		if countNeighbours(A, r2, c2) >= 2 and hasPath(A, r1, c1, r2, c2):
			return True
		else:
			return False
	elif A[r2][c2] == 'X':
		if countNeighbours(A, r2, c2) > 0 and hasPath(A, r1, c1, r2, c2):
			return True
		else:
			return False

def main():
	(n, m) = list(map(int, input().split()))
	A = [list(input()) for _ in range(n)]
	(r1, c1) = [int(w) - 1 for w in input().split()]
	(r2, c2) = [int(w) - 1 for w in input().split()]
	ans = solve(A, r1, c1, r2, c2)
	print('YES' if ans else 'NO')
main()


def read_data():
	(n, m) = map(int, input().split())
	maze = [[False] * (m + 2)]
	for i in range(n):
		maze.append([False] + [c == '.' for c in input().rstrip()] + [False])
	maze.append([False] * (m + 2))
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	return (n, m, maze, r1, c1, r2, c2)

def solve(n, m, maze, r1, c1, r2, c2):
	dots = count_surrounding_intact_ices(maze, r2, c2)
	if maze[r2][c2] == False:
		if r1 == r2 and c1 == c2:
			return dots >= 1
		else:
			return solve_wfs(n, m, maze, r1, c1, r2, c2)
	else:
		if dots >= 2:
			return solve_wfs(n, m, maze, r1, c1, r2, c2)
		if dots == 0:
			return False
		if dots == 1:
			return is_side_by_side(r1, c1, r2, c2)

def is_side_by_side(r1, c1, r2, c2):
	if r1 == r2:
		return abs(c1 - c2) == 1
	if c1 == c2:
		return abs(r1 - r2) == 1
	return False

def count_surrounding_intact_ices(maze, r, c):
	count = 0
	for (rr, cc) in [(r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)]:
		if maze[rr][cc]:
			count += 1
	return count

def solve_wfs(n, m, maze, r1, c1, r2, c2):
	frontier = [(r1, c1)]
	while frontier:
		new_frontier = []
		for (r, c) in frontier:
			for (nr, nc) in [(r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)]:
				if nr == r2 and nc == c2:
					return True
				if not maze[nr][nc]:
					continue
				maze[nr][nc] = False
				new_frontier.append((nr, nc))
		frontier = new_frontier
	return False

def __starting_point():
	(n, m, maze, r1, c1, r2, c2) = read_data()
	if solve(n, m, maze, r1, c1, r2, c2):
		print('YES')
	else:
		print('NO')
__starting_point()


from collections import deque
directions = ((1, 0), (0, 1), (-1, 0), (0, -1))
(n, m) = map(int, input().split())
a = [list(input()) for _ in range(n)]
(si, sj) = map(lambda x: int(x) - 1, input().split())
(ti, tj) = map(lambda x: int(x) - 1, input().split())

def is_valid(i, j):
	return 0 <= i < n and 0 <= j < m

def check(i, j):
	r = 0
	for (di, dj) in directions:
		(ni, nj) = (i + di, j + dj)
		if is_valid(ni, nj) and a[ni][nj] != 'X' or (ni, nj) == (si, sj):
			r += 1
	return r
if (si, sj) == (ti, tj):
	print('YES' if check(si, sj) >= 1 else 'NO')
	exit()
c = a[ti][tj]
a[ti][tj] = '.'
(vis, q) = (set(), deque())
vis.add((si, sj))
q.append((si, sj))
while q:
	(i, j) = q.popleft()
	for (di, dj) in directions:
		(ni, nj) = (i + di, j + dj)
		if is_valid(ni, nj) and a[ni][nj] != 'X' and ((ni, nj) not in vis):
			vis.add((ni, nj))
			q.append((ni, nj))
if (ti, tj) not in vis:
	print('NO')
elif c == 'X':
	print('YES')
else:
	print('YES' if check(ti, tj) >= 2 else 'NO')


(n, m) = map(int, input().split())
field = []
for i in range(n):
	next = list(input())
	field.append(next)
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
r2 -= 1
c1 -= 1
c2 -= 1
visited = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
for i in range(n):
	for j in range(m):
		if field[i][j] == 'X':
			visited[i][j] = 1
		else:
			visited[i][j] = 0
ans = 'NO'

def walk(r, c):
	up = [min(n - 1, r + 1), c]
	down = [max(r - 1, 0), c]
	left = [r, max(0, c - 1)]
	right = [r, min(m - 1, c + 1)]
	ret = [up, down, left, right]
	return ret
queue = [[r1, c1]]
while len(queue) > 0:
	(r, c) = queue.pop(0)
	paths = walk(r, c)
	for next in paths:
		(row, col) = (next[0], next[1])
		if not ((r == row) & (c == col) or field[row][col] == 'O'):
			if (row == r2 and col == c2) and field[row][col] == 'X':
				print('YES')
				exit()
			if visited[row][col] != 1:
				visited[row][col] += 1
				field[row][col] = 'X'
				queue.append([row, col])
			else:
				field[row][col] = 'O'
print('NO')


(n, m) = map(int, input().split())
d = {0: {i: 'X' for i in range(m + 2)}}
for i in range(1, n + 1):
	s = input()
	d[i] = {0: 'X'}
	for j in range(1, m + 1):
		d[i][j] = s[j - 1]
	d[i][m + 1] = 'X'
d[n + 1] = {i: 'X' for i in range(m + 2)}
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
(e, p) = (0, 0)
if d[r2][c2] == 'X':
	e = 1
	d[r2][c2] = '.'
(t1, t2) = (d[r2 - 1][c2], d[r2 + 1][c2])
(t3, t4) = (d[r2][c2 - 1], d[r2][c2 + 1])
if t1 == '.':
	p += 1
if t2 == '.':
	p += 1
if t3 == '.':
	p += 1
if t4 == '.':
	p += 1
if r1 == r2 and c1 == c2:
	if p == 0:
		print('NO')
	else:
		print('YES')
	from sys import exit
	exit()
queue = [[r1, c1]]
a = 0
while queue:
	q = queue.pop(0)
	(r, c) = (q[0], q[1])
	if r == r2 and c == c2:
		a = 1
		break
	if d[r - 1][c] == '.':
		queue.append([r - 1, c])
		d[r - 1][c] = 'X'
	if d[r + 1][c] == '.':
		queue.append([r + 1, c])
		d[r + 1][c] = 'X'
	if d[r][c - 1] == '.':
		queue.append([r, c - 1])
		d[r][c - 1] = 'X'
	if d[r][c + 1] == '.':
		queue.append([r, c + 1])
		d[r][c + 1] = 'X'
if a == 0:
	print('NO')
elif e == 1:
	print('YES')
elif p > 1:
	print('YES')
else:
	d = 0
	if r1 == r2:
		if abs(c1 - c2) == 1:
			d = 1
	if c1 == c2:
		if abs(r1 - r2) == 1:
			d = 1
	if d == 1 and p > 0:
		print('YES')
	else:
		print('NO')


(n, m) = [int(x) for x in input().split()]
inp = [input() for i in range(n)]
source = [int(x) - 1 for x in input().split()]
dest = [int(x) - 1 for x in input().split()]

def valid(x):
	return True if 0 <= x[0] < n and 0 <= x[1] < m and (inp[x[0]][x[1]] == '.') else False

def getn(x):
	toret = []
	y = (x[0] - 1, x[1])
	if valid(y):
		toret.append(y)
	y = (x[0] + 1, x[1])
	if valid(y):
		toret.append(y)
	y = (x[0], x[1] - 1)
	if valid(y):
		toret.append(y)
	y = (x[0], x[1] + 1)
	if valid(y):
		toret.append(y)
	return toret
if source == dest:
	print('YES' if len(getn(dest)) else 'NO')
else:
	dat = False
	dis = 0
	if inp[dest[0]][dest[1]] == 'X':
		inp[dest[0]] = inp[dest[0]][:dest[1]] + '.' + inp[dest[0]][dest[1] + 1:]
		dat = True
	if tuple(dest) in getn(source):
		dis = 1
	vis = [[False] * m for i in range(n)]
	mystak = [source]
	while mystak != []:
		x = mystak.pop()
		if vis[x[0]][x[1]]:
			continue
		vis[x[0]][x[1]] = True
		for i in getn(x):
			mystak.append(i)
	print('YES' if vis[dest[0]][dest[1]] and (len(getn(dest)) > 1 - dis or dat) else 'NO')


def dfs(graph, node, destination):
	visited = [False for x in graph]
	stack = []
	stack.append(node)
	while len(stack) > 0:
		node = stack.pop()
		visited[node] = True
		for n in graph[node]:
			if n == destination:
				return (True, visited)
			if not visited[n]:
				stack.append(n)
	return (False, visited)
try:
	(m, n) = map(int, input().split())
	matrix = []
	nodes = {}
	count_nodes = 0
	graph = []
	for i in range(m):
		row = input()
		matrix.append(row)
	origin = tuple(map(lambda x: int(x) - 1, input().split()))
	destination = tuple(map(lambda x: int(x) - 1, input().split()))
	x = [0, -1]
	y = [-1, 0]
	for (i, row) in enumerate(matrix):
		for (j, space) in enumerate(row):
			if space == '.' or (i, j) in [origin, destination]:
				node = (i, j)
				nodes[node] = count_nodes
				graph.append([])
				count_nodes += 1
				for k in range(2):
					neighbor_x = i + x[k]
					neighbor_y = j + y[k]
					neighbor = (neighbor_x, neighbor_y)
					is_in_boundaries = 0 <= neighbor_x < m and 0 <= neighbor_y < n
					if is_in_boundaries and (matrix[neighbor_x][neighbor_y] == '.' or neighbor in [origin, destination]):
						node_abstraction = nodes[node]
						neighbor_abstraction = nodes[neighbor]
						graph[node_abstraction].append(neighbor_abstraction)
						graph[neighbor_abstraction].append(node_abstraction)
	(wau, vis) = dfs(graph, nodes[origin], nodes[destination])
	(i, j) = destination
	x = [0, 1, 0, -1]
	y = [1, 0, -1, 0]
	c = 0
	for k in range(4):
		neighbor_x = i + x[k]
		neighbor_y = j + y[k]
		neighbor = (neighbor_x, neighbor_y)
		is_in_boundaries = 0 <= neighbor_x < m and 0 <= neighbor_y < n
		if is_in_boundaries and matrix[neighbor_x][neighbor_y] == '.' and (not vis[nodes[neighbor]]):
			c += 1
	if wau and (c >= 1 or matrix[i][j] == 'X'):
		print('YES')
	else:
		print('NO')
except RuntimeError as err:
	print(err)


dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]
MAX_N = 500 + 1
level = [None] * MAX_N
q = [None] * (MAX_N * MAX_N)

def BFS(sx, sy, fx, fy):
	left = right = 0
	q[0] = (sx, sy)
	level[sx][sy] = 'X'
	while left <= right:
		(ux, uy) = q[left]
		left += 1
		for i in range(4):
			xx = ux + dx[i]
			yy = uy + dy[i]
			if xx == fx and yy == fy and (level[xx][yy] == 'X'):
				return True
			if xx in range(n) and yy in range(m) and (level[xx][yy] == '.'):
				level[xx][yy] = 'X'
				right += 1
				q[right] = (xx, yy)
	return False
(n, m) = map(int, input().split())
for i in range(n):
	level[i] = list(input())
(sx, sy) = map(int, input().split(' '))
(fx, fy) = map(int, input().split(' '))
if BFS(sx - 1, sy - 1, fx - 1, fy - 1) == True:
	print('YES')
else:
	print('NO')


def is_valid_tile(r, c, n, m):
	return r >= 0 and c >= 0 and (r < n) and (c < m)

def gen_adjacents(r, c, n, m):
	adjs = []
	possibles = [(r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)]
	for possible in possibles:
		if is_valid_tile(*possible, n, m):
			adjs.append(possible)
	return adjs

def solve(table, r1, c1, r2, c2, n, m):
	if r1 == r2 and c1 == c2:
		adjacents = gen_adjacents(r1, c1, n, m)
		for adjacent in adjacents:
			if table[adjacent[0]][adjacent[1]] == '.':
				return True
		return n + m < 2
	if table[r2][c2] == '.':
		adjacents = gen_adjacents(r2, c2, n, m)
		solid = 0
		for adj in adjacents:
			if table[adj[0]][adj[1]] == '.':
				solid += 1
		if solid < 2:
			return solid == 1 and (r1, c1) in adjacents
	forward_visited = set([(r1, c1)])
	backward_visited = set([(r2, c2)])
	forward_nodes = [(r1, c1)]
	backward_nodes = [(r2, c2)]
	while forward_nodes and backward_nodes:
		for i in range(len(forward_nodes)):
			node = forward_nodes.pop(0)
			adjacents = gen_adjacents(*node, n, m)
			for adjacent in adjacents:
				if adjacent in backward_visited:
					return True
				if adjacent not in forward_visited and table[adjacent[0]][adjacent[1]] == '.':
					forward_visited.add(adjacent)
					forward_nodes.append(adjacent)
		for j in range(len(backward_nodes)):
			node = backward_nodes.pop(0)
			adjacents = gen_adjacents(*node, n, m)
			for adjacent in adjacents:
				if adjacent in forward_visited:
					return True
				if adjacent not in backward_visited and table[adjacent[0]][adjacent[1]] == '.':
					backward_visited.add(adjacent)
					backward_nodes.append(adjacent)
	return False

def main():
	(n, m) = map(int, input().split())
	table = []
	for _ in range(n):
		row = input()
		table.append(row)
	(r1, c1) = map(int, input().split())
	(r2, c2) = map(int, input().split())
	r1 -= 1
	c1 -= 1
	r2 -= 1
	c2 -= 1
	if solve(table, r1, c1, r2, c2, n, m):
		print('YES')
	else:
		print('NO')
main()


import sys, re, math
from collections import deque, defaultdict, Counter, OrderedDict
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from queue import Queue
from heapq import heappush, heappop, heapify, nlargest, nsmallest

def STR():
	return list(input())

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def sortListWithIndex(listOfTuples, idx):
	return sorted(listOfTuples, key=lambda x: x[idx])

def sortDictWithVal(passedDic):
	temp = sorted(passedDic.items(), key=lambda kv: (kv[1], kv[0]))[::-1]
	toret = {}
	for tup in temp:
		toret[tup[0]] = tup[1]
	return toret

def sortDictWithKey(passedDic):
	return dict(OrderedDict(sorted(passedDic.items())))
INF = float('inf')
mod = 10 ** 9 + 7

def dfs(r1, c1, r2, c2, reqd):
	stack = [(r1, c1)]
	tillNow = 0
	while len(stack) > 0:
		popped = stack.pop()
		row = popped[0]
		col = popped[1]
		X = [1, 0, 0, -1]
		Y = [0, 1, -1, 0]
		for i in range(4):
			if row + X[i] >= 0 and row + X[i] < n and (col + Y[i] >= 0) and (col + Y[i] < m):
				if grid[row + X[i]][col + Y[i]] == '.':
					stack.append((row + X[i], col + Y[i]))
					grid[row + X[i]][col + Y[i]] = 'X'
				elif row + X[i] == r2 and col + Y[i] == c2:
					return True
	return False
(n, m) = MAP()
grid = []
for _ in range(n):
	grid.append(list(input()))
(r1, c1) = MAP()
(r2, c2) = MAP()
vis = list2d(n, m, False)
(r1, c1) = (r1 - 1, c1 - 1)
(r2, c2) = (r2 - 1, c2 - 1)
reqd = 2
if grid[r2][c2] == 'X':
	reqd = 1
if dfs(r1, c1, r2, c2, reqd):
	print('YES')
else:
	print('NO')


from collections import deque
ds = ((1, 0), (0, 1), (-1, 0), (0, -1))
(n, m) = map(int, input().split())
a = [list(input()) for _ in range(n)]
(si, sj) = tuple(map(int, input().split()))
(ti, tj) = tuple(map(int, input().split()))
si -= 1
sj -= 1
ti -= 1
tj -= 1

def count_ok(i, j):
	r = 0
	for (di, dj) in ds:
		(ni, nj) = (i + di, j + dj)
		if 0 <= ni < n and 0 <= nj < m and (a[ni][nj] != 'X') or (ni, nj) == (si, sj):
			r += 1
	return r
if (si, sj) == (ti, tj):
	print('YES' if count_ok(si, sj) >= 1 else 'NO')
	exit(0)
c = a[ti][tj]
a[ti][tj] = '.'
used = set()
q = deque()
used.add((si, sj))
q.append((si, sj))
while q:
	(i, j) = q.popleft()
	for (di, dj) in ds:
		(ni, nj) = (i + di, j + dj)
		if 0 <= ni < n and 0 <= nj < m and (a[ni][nj] != 'X') and ((ni, nj) not in used):
			used.add((ni, nj))
			q.append((ni, nj))
if (ti, tj) not in used:
	print('NO')
elif c == 'X':
	print('YES')
else:
	print('YES' if count_ok(ti, tj) >= 2 else 'NO')


def isConnected(r1, c1, r2, c2, board):
	visited = [[0] * c for i in range(r)]
	Q = [[r1, c1]]
	visited[r1][c1] = 1
	while Q:
		q = Q.pop(0)
		(x, y) = (q[0], q[1])
		for i in range(4):
			new_x = x + dx[i]
			new_y = y + dy[i]
			if 0 <= new_x < r and 0 <= new_y < c and (visited[new_x][new_y] == 0) and (board[new_x][new_y] == '.'):
				visited[new_x][new_y] = 1
				Q.append([new_x, new_y])
				if new_x == r2 and new_y == c2:
					return True
	return False
dx = [-1, 0, 0, 1]
dy = [0, -1, 1, 0]
(r, c) = list(map(int, input().split()))
board = [list(input()) for i in range(r)]
(r1, c1) = list(map(int, input().split()))
(r2, c2) = list(map(int, input().split()))
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
isX = board[r2][c2] == 'X'
G = []
for i in range(4):
	x = r2 + dx[i]
	y = c2 + dy[i]
	if x >= 0 and x < r and (y >= 0) and (y < c) and (board[x][y] == '.'):
		G.append([x, y])
if abs(r1 - r2) + abs(c1 - c2) == 1:
	if board[r2][c2] == 'X':
		print('YES')
	elif len(G) > 0:
		print('YES')
	else:
		print('NO')
elif r1 == r2 and c1 == c2:
	if len(G) == 0:
		print('NO')
	else:
		print('YES')
elif len(G) == 0:
	print('NO')
elif board[r2][c2] == 'X':
	board[r2][c2] = '.'
	if isConnected(r1, c1, r2, c2, board):
		print('YES')
	else:
		print('NO')
elif len(G) < 2:
	print('NO')
elif isConnected(r1, c1, r2, c2, board):
	print('YES')
else:
	print('NO')


import sys, queue

def FILE_IO():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
dirt = [(0, -1), (-1, 0), (0, 1), (1, 0)]
grp = []
m = n = None

def canGo(x, y):
	if x < 0 or x >= m or y < 0 or (y >= n):
		return False
	return True

def bfs(r1, c1, r2, c2):
	q = queue.Queue()
	q.put([r1, c1])
	while not q.empty():
		(ux, uy) = q.get()
		for (x, y) in dirt:
			(vx, vy) = (ux + x, uy + y)
			if canGo(vx, vy):
				if grp[vx][vy] == 'X':
					if vx == r2 and vy == c2:
						return 'YES'
				else:
					q.put([vx, vy])
					grp[vx][vy] = 'X'
	return 'NO'
(m, n) = map(int, input().split())
grp = [None] * m
for i in range(m):
	grp[i] = list(input())
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
print(bfs(r1 - 1, c1 - 1, r2 - 1, c2 - 1))


import sys
sys.setrecursionlimit(1000000000)

def bfs(x, y):
	q = [(y, x)]
	while q:
		x = q[0][1]
		y = q[0][0]
		q.pop(0)
		if x - 1 > -1 and g[y][x - 1] == '.':
			g[y][x - 1] = 'X'
			q.append((y, x - 1))
		if x + 1 < m and g[y][x + 1] == '.':
			g[y][x + 1] = 'X'
			q.append((y, x + 1))
		if y - 1 > -1 and g[y - 1][x] == '.':
			g[y - 1][x] = 'X'
			q.append((y - 1, x))
		if y + 1 < n and g[y + 1][x] == '.':
			g[y + 1][x] = 'X'
			q.append((y + 1, x))
(n, m) = map(int, input().split())
g = [[''] * m for i in range(n)]
for i in range(n):
	t = input()
	for j in range(m):
		g[i][j] = t[j]
(y, x) = map(int, input().split())
(b, a) = map(int, input().split())
x -= 1
y -= 1
a -= 1
b -= 1
if x == a and y == b:
	if x - 1 > -1 and g[y][x - 1] == '.' or (x + 1 < m and g[y][x + 1] == '.') or (y - 1 > -1 and g[y - 1][x] == '.') or (y + 1 < n and g[y + 1][x] == '.'):
		print('YES')
	else:
		print('NO')
else:
	f = False
	if g[b][a] == '.':
		f = True
	one = a - 1 > -1 and g[b][a - 1] == '.'
	two = a + 1 < m and g[b][a + 1] == '.'
	three = b - 1 > -1 and g[b - 1][a] == '.'
	four = b + 1 < n and g[b + 1][a] == '.'
	g[b][a] = '.'
	bfs(x, y)
	if g[b][a] == 'X':
		if f:
			if one + two + three + four > 1:
				print('YES')
			elif (a == x - 1 and b == y or (a == x + 1 and b == y) or (a == x and b == y - 1) or (a == x and b == y + 1)) and one + two + three + four == 1:
				print('YES')
			else:
				print('NO')
		else:
			print('YES')
	else:
		print('NO')


__author__ = 'huash06'
import sys
import os
import itertools
import collections
import functools
import bisect
import datetime
DELTA = [(1, 0), (-1, 0), (0, -1), (0, 1)]

def existsPath(board, sr, sc, er, ec):
	visited = {(sr, sc)}
	q = [(sr, sc)]
	while q:
		(r, c) = q.pop(0)
		for d in DELTA:
			nr = r + d[0]
			nc = c + d[1]
			if nr == er and nc == ec:
				return True
			if 0 <= nr < N and 0 <= nc < M and ((nr, nc) not in visited) and (board[nr][nc] == '.'):
				visited.add((nr, nc))
				q.append((nr, nc))
	return False

def isNeighbor(sr, sc, er, ec):
	for d in DELTA:
		r = sr + d[0]
		c = sc + d[1]
		if r == er and c == ec:
			return True
	return False
(N, M) = list(map(int, input().split()))
board = []
for i in range(N):
	board.append([x for x in input()])
(sr, sc) = list(map(int, input().split()))
(er, ec) = list(map(int, input().split()))
sr -= 1
sc -= 1
er -= 1
ec -= 1
if board[er][ec] == 'X':
	if existsPath(board, sr, sc, er, ec):
		print('YES')
	else:
		print('NO')
else:
	itactNeighbor = 0
	for d in DELTA:
		r = er + d[0]
		c = ec + d[1]
		if 0 <= r < N and 0 <= c < M and (board[r][c] == '.'):
			itactNeighbor += 1
	if itactNeighbor > 1:
		if existsPath(board, sr, sc, er, ec):
			print('YES')
		else:
			print('NO')
	elif itactNeighbor == 1 and isNeighbor(sr, sc, er, ec):
		print('YES')
	else:
		print('NO')


(n, m) = (0, 0)
(start_x, start_y) = (0, 0)
(end_x, end_y) = (0, 0)
graph = []
direct_x = [-1, 1, 0, 0]
direct_y = [0, 0, 1, -1]

def BFS():
	global start_x, start_y, end_x, end_y, n, m, graph
	queue_x = [start_x - 1]
	queue_y = [start_y - 1]
	while len(queue_x) > 0:
		ux = queue_x.pop(0)
		uy = queue_y.pop(0)
		for i in range(4):
			vx = ux + direct_x[i]
			vy = uy + direct_y[i]
			if 0 <= vx < n and 0 <= vy < m:
				if vx == end_x - 1 and vy == end_y - 1:
					if graph[vx][vy] == 'X':
						return 1
					else:
						graph[vx][vy] = 'X'
						queue_x.append(vx)
						queue_y.append(vy)
				elif graph[vx][vy] != 'X':
					graph[vx][vy] = 'X'
					queue_x.append(vx)
					queue_y.append(vy)
	return 0

def main():
	global n, m, graph, start_x, start_y, end_x, end_y
	(n, m) = map(int, input().split())
	for _ in range(n):
		line = list(input())
		graph.append(line)
	(start_x, start_y) = map(int, input().split())
	(end_x, end_y) = map(int, input().split())
	ans = BFS()
	if ans:
		print('YES')
	else:
		print('NO')
main()


a = [[] for _ in range(505)]
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
(n, m) = map(int, input().split())
for i in range(n):
	s = input()
	for j in range(len(s)):
		a[i].append(s[j])
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
r1 -= 1
c1 -= 1
r2 -= 1
c2 -= 1
count = 0
for k in range(4):
	i = r2 + dr[k]
	j = c2 + dc[k]
	if i in range(n) and j in range(m):
		if a[i][j] == '.' or (i == r1 and j == c1):
			count += 1
if a[r2][c2] == '.' and count <= 1:
	print('NO')
	exit()
if r1 == r2 and c1 == c2:
	if count > 0:
		print('YES')
	else:
		print('NO')
	exit()
front = back = 0
q = []
q.append((r1, c1))
while front <= back:
	(ui, uj) = q[front]
	front += 1
	for k in range(4):
		vi = ui + dr[k]
		vj = uj + dc[k]
		if vi in range(n) and vj in range(m):
			if vi == r2 and vj == c2:
				print('YES')
				exit()
			if a[vi][vj] == '.':
				q.append((vi, vj))
				a[vi][vj] = 'X'
				back += 1
print('NO')


(row, col) = (int(x) for x in input().split())
matrix = [['X' for i in range(col + 2)]]
for _ in range(row):
	matrix.append(['X'] + [str(x) for x in input()] + ['X'])
matrix.append(['X' for i in range(col + 2)])
(startR, startC) = (int(x) for x in input().split())
(endR, endC) = (int(x) for x in input().split())

def search_way(matrix, startR, startC, endR, endC):
	countToEnd = 0
	dx = [0, 0, -1, 1]
	dy = [1, -1, 0, 0]
	for i in range(len(dx)):
		if matrix[endR + dx[i]][endC + dy[i]] == '.':
			countToEnd += 1
	if endR == startR and endC == startC:
		if matrix[endR][endC] == 'X' and countToEnd < 1:
			return 'NO'
		elif matrix[endR][endC] == 'X':
			return 'YES'
	if countToEnd < 2 and matrix[endR][endC] == '.':
		if countToEnd == 1 and abs(endR - startR) + abs(endC - startC) == 1:
			return 'YES'
		return 'NO'
	matrix[endR][endC] = '.'
	queue = [(startR, startC)]
	while len(queue) >= 1:
		curValue = queue.pop(-1)
		if curValue[0] == endR and curValue[1] == endC:
			return 'YES'
		for i in range(len(dx)):
			if matrix[curValue[0] + dx[i]][curValue[1] + dy[i]] == '.':
				matrix[curValue[0] + dx[i]][curValue[1] + dy[i]] = 'X'
				queue.append((curValue[0] + dx[i], curValue[1] + dy[i]))
	return 'NO'
print(search_way(matrix, startR, startC, endR, endC))


import sys
from queue import Queue
sys.setrecursionlimit(100000)
INF = int(10000000.0 + 1)
MAX = 100005
step_i = (1, 0, -1, 0)
step_j = (0, 1, 0, -1)

class Pair:

	def __init__(self, a, b):
		self.first = a
		self.second = b

class Edge:

	def __init__(self, u, v, w):
		self.u = u
		self.v = v
		self.w = w

	def __lt__(self, other):
		return self.w < other.w

def mask(x):
	if x == 'X':
		return 1
	else:
		return 0

def bfs(n, m, graph, si, sj, ei, ej):
	Q = [None for _ in range(250005)]
	l = r = 0
	Q[r] = (si, sj)
	r += 1
	while l < r:
		(ci, cj) = Q[l]
		l += 1
		for i in range(4):
			ni = ci + step_i[i]
			nj = cj + step_j[i]
			if 0 <= ni < n and 0 <= nj < m:
				if graph[ni][nj] == 'X' and ni == ei and (nj == ej):
					return True
				if graph[ni][nj] == '.':
					graph[ni][nj] = 'X'
					Q[r] = (ni, nj)
					r += 1
	return False

def main():
	(n, m) = map(int, input().split())
	graph = []
	for _ in range(n):
		graph.append(list(input()))
	(si, sj) = map(int, input().split())
	(ei, ej) = map(int, input().split())
	if bfs(n, m, graph, si - 1, sj - 1, ei - 1, ej - 1):
		print('YES')
	else:
		print('NO')
main()


dr = [0, 0, -1, 1]
dc = [1, -1, 0, 0]
MAX = 500 + 1
level = [None] * MAX
q = [None] * (MAX * MAX)

def BFS(sr, sc, fr, fc):
	left = right = 0
	q[0] = (sr, sc)
	level[sr][sc] = 'X'
	while left <= right:
		(ur, uc) = q[left]
		left += 1
		for i in range(4):
			r = ur + dr[i]
			c = uc + dc[i]
			if r == fr and c == fc and (level[r][c] == 'X'):
				return True
			if r in range(n) and c in range(m) and (level[r][c] == '.'):
				level[r][c] = 'X'
				right += 1
				q[right] = (r, c)
	return False
(n, m) = map(int, input().split())
for i in range(n):
	level[i] = list(input())
(sr, sc) = map(int, input().split())
(fr, fc) = map(int, input().split())
print('YES' if BFS(sr - 1, sc - 1, fr - 1, fc - 1) else 'NO')


def bfs(x1, y1, x2, y2):
	visited = []
	dx = [0, 0, -1, 1]
	dy = [-1, 1, 0, 0]
	for _ in range(n):
		visited.append([0] * m)
	queue = []
	queue.append([x1, y1])
	while queue:
		(x, y) = queue.pop(0)
		for k in range(4):
			i = x + dx[k]
			j = y + dy[k]
			if 0 <= i and i < n and (0 <= j) and (j < m) and (not visited[i][j]):
				visited[i][j] = 1
				if i == x2 and j == y2:
					if a[x2][y2] == 'X':
						return 1
					else:
						a[x2][y2] = 'X'
						visited[x2][y2] = 0
				elif a[i][j] == 'X':
					continue
				queue.append([i, j])
	return 0
(n, m) = map(int, input().split())
a = []
for _ in range(n):
	a.append([j for j in input().strip()])
(r1, c1) = map(int, input().split())
(r2, c2) = map(int, input().split())
ans = bfs(r1 - 1, c1 - 1, r2 - 1, c2 - 1)
if ans:
	print('YES')
else:
	print('NO')