Problem: Peter decided to lay a parquet in the room of size n × m, the parquet consists of tiles of size 1 × 2. When the workers laid the parquet, it became clear that the tiles pattern looks not like Peter likes, and workers will have to re-lay it.

The workers decided that removing entire parquet and then laying it again is very difficult task, so they decided to make such an operation every hour: remove two tiles, which form a 2 × 2 square, rotate them 90 degrees and put them back on the same place.

<image>

They have no idea how to obtain the desired configuration using these operations, and whether it is possible at all.

Help Peter to make a plan for the workers or tell that it is impossible. The plan should contain at most 100 000 commands.

Input

The first line contains integer n and m, size of the room (1 ≤ n, m ≤ 50). At least one of them is even number.

The following n lines contain m characters each, the description of the current configuration of the parquet tiles. Each character represents the position of the half-tile. Characters 'L', 'R', 'U' and 'D' correspond to the left, right, upper and lower halves, respectively.

The following n lines contain m characters each, describing the desired configuration in the same format.

Output

In the first line output integer k, the number of operations. In the next k lines output description of operations. The operation is specified by coordinates (row and column) of the left upper half-tile on which the operation is performed.

If there is no solution, output -1 in the first line.

Examples

Input

2 3
ULR
DLR
LRU
LRD


Output

2
1 2
1 1


Input

4 3
ULR
DLR
LRU
LRD
ULR
DUU
UDD
DLR

Output

3
3 1
3 2
2 2

Note

In the first sample test first operation is to rotate two rightmost tiles, after this all tiles lie vertically. Second operation is to rotate two leftmost tiles, after this we will get desired configuration.

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
struct ofl {
  long double value;
  int precision;
  inline ofl(long double value, int precision)
      : value(value), precision(precision) {}
};
const int seed = hash<string>()("alex256");
const int inf = (int)1e9 + 7;
const int64_t llInf = (int64_t)2e18 + 256;
const int mod = (int)1e9 + 7;
const long double pi = 3.141592653589793238462643383279502884197169399375105821;
const string luck = "🍀";
const char* errText = "error :(";
template <typename T1, typename T2>
inline istream& operator>>(istream& is, pair<T1, T2>& p) {
  return is >> p.first >> p.second;
}
template <typename T1, typename T2>
inline ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
  return os << p.first << " " << p.second;
}
template <typename T>
inline istream& operator>>(istream& is, vector<T>& v) {
  for (int i = 0; i < (int)(v.size()); i++) {
    is >> v[i];
  }
  return is;
}
template <typename T>
inline ostream& operator<<(ostream& os, const vector<T>& v) {
  for (int i = 0; i < (int)(v.size()); i++) {
    if (i) {
      os << "\n";
    }
    os << v[i];
  }
  return os;
}
inline ostream& operator<<(ostream& os, const ofl& o) {
  return os << fixed << setprecision(o.precision) << o.value;
}
inline bool iosOptimize() {
  ios_base::sync_with_stdio(false);
  return true;
}
bool iosOptimized = iosOptimize();
template <typename T>
inline T get() {
  T value;
  cin >> value;
  return value;
}
template <>
inline char get() {
  char c = '\0';
  while (c <= ' ') {
    cin >> c;
  }
  return c;
}
inline string getLn() {
  string s;
  getline(cin, s);
  return s;
}
template <typename T, size_t Count>
struct VectorPacker {};
template <typename T>
struct VectorPacker<T, 0> {};
template <typename T>
inline vector<T> getVector(int size) {
  vector<T> res(size);
  cin >> res;
  return res;
}
template <typename T, typename U, typename... Args>
inline typename VectorPacker<T, sizeof...(Args) + 1>::T getVector(
    U size, Args... sizes) {
  typename VectorPacker<T, sizeof...(Args) + 1>::T res(size);
  for (int i = 0; i < (int)size; i++) {
    res[i] = getVector<T>(sizes...);
  }
  return res;
}
inline void put() {}
template <typename T, typename... Args>
inline void put(const T& value, const Args&... vals) {
  cout << value;
  put(vals...);
}
template <typename... Args>
inline void putLn(const Args&... vals) {
  put(vals...);
  cout << "\n";
}
namespace std {
template <typename T1, typename T2>
struct hash<pair<T1, T2> > {
  inline size_t operator()(const pair<T1, T2>& p) const {
    return hash<T1>()(p.first) ^ hash<T2>()(p.second);
  }
};
};  // namespace std
mt19937_64 rnd(seed);
inline void error(const char* text = errText) {
  ;
  exit(256);
}
template <typename T1, typename T2>
inline void umax(T1& a, const T2& b) {
  if (a < b) {
    a = b;
  }
}
template <typename T1, typename T2>
inline void umin(T1& a, const T2& b) {
  if (a > b) {
    a = b;
  }
}
int64_t gcd(int64_t a, int64_t b) { return b ? gcd(b, a % b) : a; }
int64_t extGcd(int64_t a, int64_t b, int64_t& x, int64_t& y) {
  if (!a) {
    x = 0;
    y = 1;
    return b;
  }
  int64_t x1, y1, d = extGcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
inline int addMod(int a, int b, int m = mod) { return ((int64_t)a + b) % m; }
inline int subMod(int a, int b, int m = mod) {
  return ((int64_t)a + m - b) % m;
}
inline int mulMod(int a, int b, int m = mod) { return ((int64_t)a * b) % m; }
inline int divMod(int a, int b, int m = mod) {
  int64_t x, y;
  int64_t g = extGcd(b, m, x, y);
  if (g != 1) {
    ;
    exit(42);
  }
  x = (x % m + m) % m;
  return mulMod(a, x, m);
}
int n = get<int>(), m = get<int>();
vector<string> a = getVector<string>(n), b = getVector<string>(n);
vector<pair<int, int> > frontOp, backOp;
signed main() {
  auto apply1 = [&](vector<string>& a, vector<pair<int, int> >& ops) -> bool {
    bool good = false;
    for (;;) {
      bool ok = false;
      for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
          if (a[i - 1][j - 1] == 'L' && a[i - 1][j] == 'R' &&
              a[i][j - 1] == 'L' && a[i][j] == 'R') {
            ok = true;
            a[i - 1][j - 1] = a[i - 1][j] = 'U';
            a[i][j - 1] = a[i][j] = 'D';
            ops.emplace_back(i, j);
          }
        }
      }
      if (!ok) {
        break;
      }
      good = true;
    }
    return good;
  };
  auto apply2 = [&](vector<string>& a, vector<pair<int, int> >& ops) -> bool {
    bool good = false;
    for (;;) {
      bool ok = false;
      for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
          if (a[i - 1][j - 1] == 'U' && a[i - 1][j] == 'U' &&
              a[i][j - 1] == 'D' && a[i][j] == 'D') {
            ok = true;
            a[i - 1][j - 1] = a[i][j - 1] = 'L';
            a[i - 1][j] = a[i][j] = 'R';
            ops.emplace_back(i, j);
          }
        }
      }
      if (!ok) {
        break;
      }
      good = true;
    }
    return good;
  };
  while (true) {
    apply1(a, frontOp);
    apply1(b, backOp);
    if (a == b) {
      break;
    }
    apply2(a, frontOp);
    apply2(b, backOp);
    if (a == b) {
      break;
    }
  }
  frontOp.insert(frontOp.end(), backOp.rbegin(), backOp.rend());
  putLn(frontOp.size());
  putLn(frontOp);
  return 0;
}