#include <fstream>
#include <deque>
using namespace std;
class InputReader {
public:
InputReader() {}
InputReader(const char *file_name) {
input_file = fopen(file_name, "r");
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
template <typename T>
inline InputReader &operator >>(T &n) {
while(buffer[cursor] < '0' || buffer[cursor] > '9') {
advance();
}
n = 0;
while('0' <= buffer[cursor] && buffer[cursor] <= '9') {
n = n * 10 + buffer[cursor] - '0';
advance();
}
return *this;
}
private:
FILE *input_file;
static const int SIZE = 1 << 17;
int cursor;
char buffer[SIZE];
inline void advance() {
++ cursor;
if(cursor == SIZE) {
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
}
};
const int NMAX = 500 + 5;
int N, M;
bool blocked[NMAX][NMAX];
int startLin, startCol;
int endLin, endCol;
const int dlin[8] = {1, 1, 1, 0, -1, -1, -1, 0};
const int dcol[8] = {1, 0, -1, -1, -1, 0, 1, 1};
struct State {
int lin, col;
int dir;
State(int _lin = 0, int _col = 0, int _dir = 0):
lin(_lin), col(_col), dir(_dir) {}
};
deque <State> dq;
bool vis[NMAX][NMAX][8];
int dist[NMAX][NMAX][8];
const int INF = NMAX * NMAX * 8;
int Dijkstra() {
if (blocked[startLin][startCol] || blocked[endLin][endCol])
return -1;
for (int i = 1; i <= N; ++ i)
for (int j = 1; j <= M; ++ j)
for (int k = 0; k < 8; ++ k)
dist[i][j][k] = INF;
for (int i = 0; i < 8; ++ i) {
dist[startLin][startCol][i] = 0;
dq.push_back(State(startLin, startCol, i));
}
State node;
while (!dq.empty()) {
node = dq.front();
dq.pop_front();
if (node.lin == endLin && node.col == endCol)
return dist[node.lin][node.col][node.dir];
if (blocked[node.lin][node.col])
continue;
if (vis[node.lin][node.col][node.dir])
continue;
vis[node.lin][node.col][node.dir] = true;
if (dist[node.lin][node.col][node.dir] < dist[node.lin + dlin[node.dir]][node.col + dcol[node.dir]][node.dir]) {
dist[node.lin + dlin[node.dir]][node.col + dcol[node.dir]][node.dir] = dist[node.lin][node.col][node.dir];
dq.push_front(State(node.lin + dlin[node.dir], node.col + dcol[node.dir], node.dir));
}
for (auto k: {-1, 1}) {
if (dist[node.lin][node.col][node.dir] + 1 < dist[node.lin][node.col][(node.dir + k + 8) & 7]) {
dist[node.lin][node.col][(node.dir + k + 8) & 7] = dist[node.lin][node.col][node.dir] + 1;
dq.push_back(State(node.lin, node.col, (node.dir + k + 8) & 7));
}
}
}
return -1;
}
int main()
{
InputReader cin("car.in");
ofstream cout("car.out");
cin >> N >> M;
cin >> startLin >> startCol;
cin >> endLin >> endCol;
for (int i = 1; i <= N; ++ i)
for (int j = 1; j <= M; ++ j)
cin >> blocked[i][j];
cout << Dijkstra() << '\n';
//cin.close();
cout.close();
return 0;
}