import std.container;
import std.range;
import std.algorithm;
import std.array;
import std.string;
import std.conv;
import std.stdio;
import std.container;

void main() {
	enum Inf = int.max / 2 - 1;

	int h, w;
	readf(" %s %s\n", &h, &w);

	int cy, cx;
	readf(" %s %s\n", &cy, &cx);
	--cy;
	--cx;

	int goalY, goalX;
	readf(" %s %s\n", &goalY, &goalX);
	--goalY;
	--goalX;

	auto maze = new string[h];
	foreach (i;0..h) {
		maze[i] = readln.chomp;
		assert(maze[i].length == w);
	}


	auto warpTable = new int[][](h, w);
	foreach (line;warpTable) {
		line[] = Inf;
	}

	bool isValid(int y, int x) {
		return y >= 0 && y < h && x >= 0 && x < w;
	}

	struct Position {
		int warpCount, y, x;
	}

	auto queue = heapify!"a.warpCount > b.warpCount"(new Position[0]);
	void insert(int warpCount, int y, int x) {
		if (!isValid(y, x)) {
			return;
		}
		if (maze[y][x] != '.') {
			return;
		}
		if (warpTable[y][x] <= warpCount) {
			return;
		}

		queue.insert(Position(warpCount, y, x));
	}

	insert(0, cy, cx);

	while (!queue.empty) {
		auto pos = queue.front;
		queue.removeFront;

		if (warpTable[pos.y][pos.x] <= pos.warpCount) {
			continue;
		}
		warpTable[pos.y][pos.x] = pos.warpCount;

		insert(pos.warpCount, pos.y - 1, pos.x);
		insert(pos.warpCount, pos.y + 1, pos.x);
		insert(pos.warpCount, pos.y, pos.x - 1);
		insert(pos.warpCount, pos.y, pos.x + 1);

		for (int i = pos.y - 2;i <= pos.y + 2;++i) {
			for (int j = pos.x - 2;j <= pos.x + 2;++j) {
				insert(pos.warpCount + 1, i, j);
			}
		}
	}

	if (warpTable[goalY][goalX] == Inf) {
		writeln(-1);
	} else {
		writeln(warpTable[goalY][goalX]);
	}
}
