#include <bits/stdc++.h>
using namespace std;
struct Block {
  int i, j, rotation;
  bitset<4> hasDoor;
};
const int MAX_N = 1000, MAX_M = 1000, UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
int n, m, xT, yT, xM, yM, minTime[MAX_N + 1][MAX_M + 1][4];
Block labyrinth[MAX_N + 1][MAX_M + 1];
queue<Block> q;
bool _reached[MAX_N + 1][MAX_M + 1][4];
inline void optimizeIO() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
}
inline bool& reached(Block block) {
  return _reached[block.i][block.j][block.rotation];
}
inline bool& reached(Block block, int rotation) {
  return _reached[block.i][block.j][rotation];
}
inline Block up(const Block& block) {
  return {block.i - 1, block.j, block.rotation,
          labyrinth[block.i - 1][block.j].hasDoor};
}
inline Block right(const Block& block) {
  return {block.i, block.j + 1, block.rotation,
          labyrinth[block.i][block.j + 1].hasDoor};
}
inline Block down(const Block& block) {
  return {block.i + 1, block.j, block.rotation,
          labyrinth[block.i + 1][block.j].hasDoor};
}
inline Block left(const Block& block) {
  return {block.i, block.j - 1, block.rotation,
          labyrinth[block.i][block.j - 1].hasDoor};
}
inline Block rotateOf(const Block& block) {
  return {block.i, block.j, (block.rotation + 1) % 4,
          labyrinth[block.i][block.j].hasDoor};
}
inline bool canGoUp(const Block& block) {
  return block.hasDoor[(UP - block.rotation + 4) % 4] and block.i > 1 and
         up(block).hasDoor[(DOWN - block.rotation + 4) % 4];
}
inline bool canGoRight(const Block& block) {
  return block.hasDoor[(RIGHT - block.rotation + 4) % 4] and block.j < m and
         right(block).hasDoor[(LEFT - block.rotation + 4) % 4];
}
inline bool canGoDown(const Block& block) {
  return block.hasDoor[(DOWN - block.rotation + 4) % 4] and block.i < n and
         down(block).hasDoor[(UP - block.rotation + 4) % 4];
}
inline bool canGoLeft(const Block& block) {
  return block.hasDoor[(LEFT - block.rotation + 4) % 4] and block.j > 1 and
         left(block).hasDoor[(RIGHT - block.rotation + 4) % 4];
}
inline void go(const Block& currentBlock, Block nextBlock) {
  minTime[nextBlock.i][nextBlock.j][nextBlock.rotation] =
      minTime[currentBlock.i][currentBlock.j][currentBlock.rotation] + 1;
  q.push(nextBlock);
  reached(nextBlock) = true;
}
int main() {
  optimizeIO();
  cin >> n >> m;
  cin.ignore();
  for (int i = 1, state; i <= n; ++i, cin.ignore())
    for (int j = 1; j <= m; ++j) {
      labyrinth[i][j].i = i;
      labyrinth[i][j].j = j;
      labyrinth[i][j].rotation = 0;
      state = cin.get();
      if (state == '+') {
        labyrinth[i][j].hasDoor[UP] = true;
        labyrinth[i][j].hasDoor[RIGHT] = true;
        labyrinth[i][j].hasDoor[DOWN] = true;
        labyrinth[i][j].hasDoor[LEFT] = true;
      } else if (state == '-') {
        labyrinth[i][j].hasDoor[RIGHT] = true;
        labyrinth[i][j].hasDoor[LEFT] = true;
      } else if (state == '|') {
        labyrinth[i][j].hasDoor[UP] = true;
        labyrinth[i][j].hasDoor[DOWN] = true;
      } else if (state == '^')
        labyrinth[i][j].hasDoor[UP] = true;
      else if (state == '>')
        labyrinth[i][j].hasDoor[RIGHT] = true;
      else if (state == '<')
        labyrinth[i][j].hasDoor[LEFT] = true;
      else if (state == 'v')
        labyrinth[i][j].hasDoor[DOWN] = true;
      else if (state == 'L') {
        labyrinth[i][j].hasDoor[UP] = true;
        labyrinth[i][j].hasDoor[RIGHT] = true;
        labyrinth[i][j].hasDoor[DOWN] = true;
      } else if (state == 'R') {
        labyrinth[i][j].hasDoor[UP] = true;
        labyrinth[i][j].hasDoor[DOWN] = true;
        labyrinth[i][j].hasDoor[LEFT] = true;
      } else if (state == 'U') {
        labyrinth[i][j].hasDoor[RIGHT] = true;
        labyrinth[i][j].hasDoor[DOWN] = true;
        labyrinth[i][j].hasDoor[LEFT] = true;
      } else if (state == 'D') {
        labyrinth[i][j].hasDoor[UP] = true;
        labyrinth[i][j].hasDoor[RIGHT] = true;
        labyrinth[i][j].hasDoor[LEFT] = true;
      }
    }
  cin >> xT >> yT >> xM >> yM;
  Block& TheseusInitialBlock = labyrinth[xT][yT];
  Block& MinotaurHidingBlock = labyrinth[xM][yM];
  minTime[xT][yT][0] = 0;
  q.push(TheseusInitialBlock);
  reached(TheseusInitialBlock) = true;
  while (not q.empty()) {
    Block block = q.front();
    q.pop();
    reached(block, block.rotation) = true;
    if (not reached(up(block), block.rotation) and canGoUp(block))
      go(block, up(block));
    if (not reached(right(block), block.rotation) and canGoRight(block))
      go(block, right(block));
    if (not reached(down(block), block.rotation) and canGoDown(block))
      go(block, down(block));
    if (not reached(left(block), block.rotation) and canGoLeft(block))
      go(block, left(block));
    if (not reached(rotateOf(block))) go(block, rotateOf(block));
  }
  if (reached(MinotaurHidingBlock))
    cout << *min_element(minTime[xM][yM], minTime[xM][yM] + 4) << endl;
  else
    cout << "-1" << endl;
  return 0;
}
