#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int need[4] = {2, 0, 3, 1};
int reallyNeed[4] = {0, 2, 1, 3};
int sx, sy, ex, ey;
struct state {
  int x, y, dir;
  long long cost;
  state(int _x, int _y, int _dir, long long _cost) {
    x = _x;
    y = _y;
    dir = _dir % 4;
    cost = _cost;
  }
  bool operator<(const state &st) const { return cost > st.cost; }
};
long long res[N][N][4];
bool vis[N][N][4];
struct door {
  int hasDoor[4];
  door() {
    for (int i = 0; i < 4; ++i) {
      hasDoor[i] = 0;
    }
  }
  void assign(int a, int b, int c, int d) {
    hasDoor[0] = a;
    hasDoor[1] = b;
    hasDoor[2] = c;
    hasDoor[3] = d;
  }
};
door grid[N][N];
char st[N];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%s", &st);
    for (int j = 1; j <= m; ++j) {
      if (st[j - 1] == '+') {
        grid[i][j].assign(1, 1, 1, 1);
      } else if (st[j - 1] == '-') {
        grid[i][j].assign(0, 1, 0, 1);
      } else if (st[j - 1] == '|') {
        grid[i][j].assign(1, 0, 1, 0);
      } else if (st[j - 1] == '^') {
        grid[i][j].assign(1, 0, 0, 0);
      } else if (st[j - 1] == '>') {
        grid[i][j].assign(0, 1, 0, 0);
      } else if (st[j - 1] == '<') {
        grid[i][j].assign(0, 0, 0, 1);
      } else if (st[j - 1] == 'v') {
        grid[i][j].assign(0, 0, 1, 0);
      } else if (st[j - 1] == 'L') {
        grid[i][j].assign(1, 1, 1, 0);
      } else if (st[j - 1] == 'R') {
        grid[i][j].assign(1, 0, 1, 1);
      } else if (st[j - 1] == 'U') {
        grid[i][j].assign(0, 1, 1, 1);
      } else if (st[j - 1] == 'D') {
        grid[i][j].assign(1, 1, 0, 1);
      } else if (st[j - 1] == '*') {
        grid[i][j].assign(0, 0, 0, 0);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; j++) {
      for (int u = 0; u < 4; u++) {
        res[i][j][u] = 1e18;
      }
    }
  }
  scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
  priority_queue<state> queue;
  queue.push(state(sx, sy, 0, 0));
  res[sx][sy][0] = 0;
  while (!queue.empty()) {
    state src = queue.top();
    queue.pop();
    if (vis[src.x][src.y][src.dir]) continue;
    vis[src.x][src.y][src.dir] = true;
    int can[4] = {};
    for (int i = 0; i < 4; i++) can[i] = grid[src.x][src.y].hasDoor[i];
    rotate(can, can + (4 - src.dir), can + 4);
    for (int i = 0; i < 4; ++i) {
      int newX = dx[i] + src.x;
      int newY = dy[i] + src.y;
      if (newY > 0 && newX > 0 && newX <= n && newY <= m && can[need[i]]) {
        int secondCan[4] = {};
        for (int j = 0; j < 4; j++) {
          secondCan[j] = grid[newX][newY].hasDoor[j];
        }
        rotate(secondCan, secondCan + (4 - src.dir), secondCan + 4);
        if (!secondCan[reallyNeed[i]]) continue;
        long long cost = src.cost + 1;
        if (cost < res[newX][newY][src.dir]) {
          res[newX][newY][src.dir] = cost;
          queue.push(state(newX, newY, src.dir, cost));
        }
      }
    }
    for (int u = 1; u < 4; u++) {
      queue.push(state(src.x, src.y, src.dir + u, src.cost + u));
    }
  }
  long long ans = 1e18;
  for (int i = 0; i < 4; ++i) {
    ans = min(res[ex][ey][i], ans);
  }
  if (ans >= 1e17) {
    ans = -1;
  }
  printf("%d\n", ans);
  return 0;
}
