using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using static System.Math;

namespace CSharpSpiral {
	class Program {
		public static void Main(string[] args) {
			var sw = new StreamWriter(Console.OpenStandardOutput()) {
				AutoFlush =
#if DEBUG
			true
#else
			false
#endif
			};
			Console.SetOut(sw);
			new Program().Solve(new ConsoleInput(
#if DEBUG
			new StreamReader("../../../inputData.txt")
#else
			Console.In
#endif
			, ' '));
			Console.Out.Flush();
		}

		public void Solve(ConsoleInput cin) {
			int H = cin.ReadInt; int W = cin.ReadInt;
			var C = cin.ReadIntArray(2);
			var D = cin.ReadIntArray(2);
			var S = new bool[H, W];
			for(int i = 0; i < H; i++) {
				var line = cin.ReadLine;
				for(int j = 0; j < W; j++) {
					S[i, j] = line[j] == '#';
				}
			}

			int x(int h, int w) => h * W + w;
			
			var from = x(C[0] - 1, C[1] - 1);
			var L = new LinkedList<int>();
			L.AddFirst(from);
			var Res = Enumerable.Repeat(long.MaxValue / 2, H * W).ToArray();
			Res[from] = 0;
			while(L.Any()) {
				var v = L.First();
				L.RemoveFirst();
				var i = v / W;
				var j = v % W;
				for(int ii = -2; ii <= 2; ii++) {
					if(i + ii < 0 || i + ii >= H) continue;
					for(int jj = -2; jj <= 2; jj++) {
						if(j + jj < 0 || j + jj >= W) continue;
						if(ii == 0 && jj == 0) continue;
						var cost = Abs(ii) + Abs(jj) < 2 ? 0 : 1;
						if(S[i + ii, j + jj]) continue;
						var w = x(i + ii, j + jj);
						if(Res[v]+ cost < Res[w]) {
							Res[w] = Res[v] + cost;
							if(cost == 0)
								L.AddFirst(w);
							else
								L.AddLast(w);
						}
					}
				}
			}
			var res = Res[x(D[0] - 1, D[1] - 1)];
			Console.WriteLine(res > 11111111 ? -1 : res);
		}


	}
	class Graph: Graph<long> {
		public Graph(int _N) : base(_N) { }
		public long?[,] WarshallFloyd() {
			var matrix = new long?[N, N];
			for(int i = 0; i < N; i++) {
				for(int j = 0; j < N; j++) {
					if(i == j) matrix[i, j] = 0;
					else if(Edges[i].ContainsKey(j))
						matrix[i, j] = Edges[i][j];
					else matrix[i, j] = null;
				}
			}
			for(int k = 0; k < N; k++) {
				var tmp = new long?[N, N];
				for(int i = 0; i < N; i++) {
					for(int j = 0; j < N; j++) {
						var far = matrix[i, k] + matrix[k, j];
						tmp[i, j] = far == null ? matrix[i, j] : matrix[i, j] == null ? far :
						Nullable.Compare(far, matrix[i, j]) > 0 ? matrix[i, j] : far;
					}
				}
				matrix = tmp;
			}
			return matrix;
		}
		public long[] BFS01(int from) {
			var L = new LinkedList<int>();
			L.AddFirst(from);
			var Res = Enumerable.Repeat(long.MaxValue / 2, N).ToArray();
			Res[from] = 0;
			while(L.Any()) {
				var v = L.First();
				L.RemoveFirst();
				foreach(var e in Edges[v]) {
					var w = e.Key;
					if(Res[v] + e.Value < Res[w]) {
						Res[w] = Res[v] + e.Value;
						if(e.Value == 0) {
							L.AddFirst(w);
						} else {
							L.AddLast(w);
						}
					}
				}
			}
			return Res;
		}
	}
	class TinyGraph: Graph<long> {
		protected long[,] Adjacents;
		public TinyGraph(int _N):base(_N) {
			Adjacents = new long[_N, _N];
		}
		public override void AddEdge(int from, int to, long value) {
			Adjacents[from, to] = value;
		}
		public override void AddEdgeMirror(int x, int y, long value) {
			AddEdge(x, y, value);
			AddEdge(y, x, value);
		}

	}
	class Graph<T> {
		public readonly int N;
		public T[] Nodes { get; }
		protected List<int>[] Nexts { get; }
		protected Dictionary<int, T>[] Edges { get; set; }
		public Graph(int _N) {
			N = _N;
			Nodes = new T[_N];
			Nexts = new List<int>[_N];
			Edges = new Dictionary<int, T>[_N];
			for(int i = 0; i < _N; i++) {
				Nexts[i] = new List<int>();
				Edges[i] = new Dictionary<int, T>();
			}
		}
		public void Update(int i, T value) {
			Nodes[i] = value;
		}
		public virtual void AddEdge(int from, int to, T value) {
			Edges[from].Add(to, value);
			Nexts[from].Add(to);
		}
		public virtual void AddEdgeMirror(int x, int y, T value) {
			AddEdge(x, y, value);
			AddEdge(y, x, value);
		}
		
		public void PointDFS(int from, Action<int> onEnter, Action<int> onLeave) {
			var S = new Stack<int>();
			S.Push(from);
			var entered = new bool[N];
			var departed = new bool[N];//dep<=ent
			var childCount = new int[N];
			while(S.Any()) {
				var v = S.Peek();
				if(!entered[v]) {
					onEnter?.Invoke(v);
					entered[v] = true;
				}
				for(int i = childCount[v]; i < Nexts[v].Count; i++) {
					if(!entered[Nexts[v][i]]) {
						S.Push(Nexts[v][i]);
						childCount[v] = i + 1;
						goto NextLoop;
					}
				}
				S.Pop();
				childCount[v] = Nexts[v].Count;
				if(!departed[v]) {
					onLeave?.Invoke(v);
					departed[v] = true;
				}
			NextLoop:;
			}
		}
	}

	static class ExtendClass {
		public static string Join<T>(this IEnumerable<T> X, string separator = " ")
			=> string.Join(separator, X);
	}
	class ConsoleInput {
		private readonly TextReader _stream;
		private readonly char _separator = ' ';
		private readonly Queue<string> inputStream;
		public ConsoleInput(TextReader stream, char separator = ' ') {
			this._separator = separator;
			this._stream = stream;
			inputStream = new Queue<string>();
		}
		public string Read {
			get {
				if(inputStream.Count != 0) return inputStream.Dequeue();
				string[] tmp = _stream.ReadLine().Split(_separator);
				for(int i = 0; i < tmp.Length; ++i)
					inputStream.Enqueue(tmp[i]);
				return inputStream.Dequeue();
			}
		}
		public string ReadLine { get { return _stream.ReadLine(); } }
		public int ReadInt { get { return int.Parse(Read); } }
		public long ReadLong { get { return long.Parse(Read); } }
		public double ReadDouble { get { return double.Parse(Read); } }
		public string[] ReadStrArray(long N) {
			var ret = new string[N];
			for(long i = 0; i < N; ++i)
				ret[i] = Read;
			return ret;
		}
		public int[] ReadIntArray(long N) { var ret = new int[N]; for(long i = 0; i < N; ++i) ret[i] = ReadInt; return ret; }
		public long[] ReadLongArray(long N) { var ret = new long[N]; for(long i = 0; i < N; ++i) ret[i] = ReadLong; return ret; }
		public double[] ReadDoubleArray(long N) { var ret = new double[N]; for(long i = 0; i < N; ++i) ret[i] = ReadDouble; return ret; }
		public bool isEOF {
			get { return _stream.Peek() == -1; }
		}
	}

	static class Extend {
		public static string Join<T>(this IEnumerable<T> X, string separator = " ")
		=> string.Join(separator, X);
	}
}


Measured memory_bytes: 55884