#include <bits/stdc++.h>
using namespace std;
const int MAX = 1010;
const int INF = 1e9;
int n, m;
string grid[MAX];
pair<pair<int, int>, int> mst(int a, int b, int y) {
  return make_pair(make_pair(a, b), y);
}
pair<pair<int, int>, int> mst(pair<int, int> a, int b) {
  return make_pair(a, b);
}
int dist[MAX][MAX][4];
void setDist(pair<pair<int, int>, int> st, int d) {
  dist[st.first.first][st.first.second][st.second] = d;
}
int getDist(pair<pair<int, int>, int> st) {
  return dist[st.first.first][st.first.second][st.second];
}
pair<int, int> validDir[4];
void pD(int i) { validDir[i] = make_pair(1, 0); }
void pU(int i) { validDir[i] = make_pair(-1, 0); }
void pL(int i) { validDir[i] = make_pair(0, -1); }
void pR(int i) { validDir[i] = make_pair(0, 1); }
int getValidDir(pair<pair<int, int>, int> st) {
  int x = st.first.first;
  int y = st.first.second;
  int d = st.second;
  if (grid[x][y] == '+') {
    pD(0);
    pU(1);
    pL(2);
    pR(3);
    return 4;
  }
  if ((grid[x][y] == '-' && (d == 0 || d == 2)) ||
      (grid[x][y] == '|' && (d == 3 || d == 1))) {
    pL(0);
    pR(1);
    return 2;
  }
  if ((grid[x][y] == '-' && (d == 3 || d == 1)) ||
      (grid[x][y] == '|' && (d == 0 || d == 2))) {
    pU(0);
    pD(1);
    return 2;
  }
  if ((grid[x][y] == '^' && d == 0) || (grid[x][y] == '>' && d == 3) ||
      (grid[x][y] == 'v' && d == 2) || (grid[x][y] == '<' && d == 1)) {
    pU(0);
    return 1;
  }
  if ((grid[x][y] == '^' && d == 1) || (grid[x][y] == '>' && d == 0) ||
      (grid[x][y] == 'v' && d == 3) || (grid[x][y] == '<' && d == 2)) {
    pR(0);
    return 1;
  }
  if ((grid[x][y] == '^' && d == 2) || (grid[x][y] == '>' && d == 1) ||
      (grid[x][y] == 'v' && d == 0) || (grid[x][y] == '<' && d == 3)) {
    pD(0);
    return 1;
  }
  if ((grid[x][y] == '^' && d == 3) || (grid[x][y] == '>' && d == 2) ||
      (grid[x][y] == 'v' && d == 1) || (grid[x][y] == '<' && d == 0)) {
    pL(0);
    return 1;
  }
  if ((grid[x][y] == 'L' && d == 0) || (grid[x][y] == 'U' && d == 3) ||
      (grid[x][y] == 'R' && d == 2) || (grid[x][y] == 'D' && d == 1)) {
    pU(0);
    pR(1);
    pD(2);
    return 3;
  }
  if ((grid[x][y] == 'L' && d == 3) || (grid[x][y] == 'U' && d == 2) ||
      (grid[x][y] == 'R' && d == 1) || (grid[x][y] == 'D' && d == 0)) {
    pU(0);
    pR(1);
    pL(2);
    return 3;
  }
  if ((grid[x][y] == 'L' && d == 2) || (grid[x][y] == 'U' && d == 1) ||
      (grid[x][y] == 'R' && d == 0) || (grid[x][y] == 'D' && d == 3)) {
    pU(0);
    pD(1);
    pL(2);
    return 3;
  }
  if ((grid[x][y] == 'L' && d == 1) || (grid[x][y] == 'U' && d == 0) ||
      (grid[x][y] == 'R' && d == 3) || (grid[x][y] == 'D' && d == 2)) {
    pR(0);
    pD(1);
    pL(2);
    return 3;
  }
  return 0;
}
char nxt(char e) {
  if (e == 'R') return 'U';
  if (e == 'U') return 'L';
  if (e == 'D') return 'R';
  if (e == 'L') return 'D';
}
bool check(char e, pair<pair<int, int>, int> st) {
  char d = grid[st.first.first][st.first.second];
  if (e == 'U') {
    return (d == '+') || (d == '|') || (d == '^') || (d == 'L') || (d == 'R') ||
           (d == 'D');
  }
  if (e == 'D') {
    return (d == '+') || (d == '|') || (d == 'v') || (d == 'L') || (d == 'R') ||
           (d == 'U');
  }
  if (e == 'R') {
    return (d == '+') || (d == '-') || (d == '>') || (d == 'L') || (d == 'D') ||
           (d == 'U');
  }
  if (e == 'L') {
    return (d == '+') || (d == '-') || (d == '<') || (d == 'R') || (d == 'D') ||
           (d == 'U');
  }
}
bool validEnter(int i, pair<pair<int, int>, int> st) {
  int d = st.second;
  char e;
  if (validDir[i].first == 0) {
    if (validDir[i].second == 1) {
      e = 'L';
    } else {
      e = 'R';
    }
  }
  if (validDir[i].second == 0) {
    if (validDir[i].first == 1) {
      e = 'U';
    } else {
      e = 'D';
    }
  }
  if (d == 0) return check(e, st);
  if (d == 1) return check(nxt(e), st);
  if (d == 2) return check(nxt(nxt(e)), st);
  if (d == 3) return check(nxt(nxt(nxt(e))), st);
}
void pprint(pair<pair<int, int>, int> st, pair<pair<int, int>, int> nst) {
  static int iter = 0;
  if (iter >= 0 && iter < 20) {
    cerr << grid[st.first.first][st.first.second] << ": (" << st.first.first
         << "," << st.first.second << "): " << st.second << endl;
    cerr << grid[nst.first.first][nst.first.second] << ": (" << nst.first.first
         << "," << nst.first.second << "): " << nst.second << endl;
    cerr << "-----------------------" << endl;
  }
  iter++;
}
int bfs(int x0, int y0, int xf, int yf) {
  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      for (int k = 0; k < 4; k++) dist[i][j][k] = INF;
  pair<pair<int, int>, int> ini = mst(x0, y0, 0);
  queue<pair<pair<int, int>, int> > q;
  q.push(ini);
  setDist(ini, 0);
  while (!q.empty()) {
    pair<pair<int, int>, int> st = q.front();
    q.pop();
    int t = getValidDir(st);
    for (int i = 0; i < t; i++) {
      int nx = st.first.first + validDir[i].first;
      int ny = st.first.second + validDir[i].second;
      if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
      pair<pair<int, int>, int> nst = mst(nx, ny, st.second);
      if (validEnter(i, nst)) {
        if (getDist(nst) > getDist(st) + 1) {
          setDist(nst, getDist(st) + 1);
          q.push(nst);
        }
      }
    }
    pair<pair<int, int>, int> nst =
        mst(st.first.first, st.first.second, (st.second + 1) % 4);
    if (getDist(nst) > getDist(st) + 1) {
      setDist(nst, getDist(st) + 1);
      q.push(nst);
    }
  }
  int res = INF;
  for (int i = 0; i < 4; i++) {
    res = min(res, getDist(mst(xf, yf, i)));
  }
  return res;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ;
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> grid[i];
  int x0, y0, xf, yf;
  cin >> x0 >> y0 >> xf >> yf;
  x0--;
  y0--;
  xf--;
  yf--;
  int res = bfs(x0, y0, xf, yf);
  if (res != INF)
    cout << res << endl;
  else
    cout << -1 << endl;
  return 0;
}
