#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
template <typename T>
void UMAX(T &a, T b) {
  a = (a > b ? a : b);
}
template <typename T>
void UMIN(T &a, T b) {
  a = (a < b ? a : b);
}
long long readint() {
  char c = getchar();
  long long ret = 0ll;
  bool neg = 0;
  while (!(c >= '0' && c <= '9')) {
    if (c == '-') neg = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    ret = ret * 10ll + (long long)(c - '0');
    c = getchar();
  }
  return neg ? -ret : ret;
}
void putint(long long v) {
  if (v < 0) {
    putchar('-');
    v = -v;
  }
  if (!v) {
    putchar('0');
    return;
  }
  if (v >= 10ll) putint(v / 10ll);
  putchar('0' + (v % 10ll));
}
char readch() {
  char c = getchar();
  while (!(c != ' ' && c != '\n' && c != '\r')) c = getchar();
  return c;
}
int n, m;
namespace SA {
char s[1600005];
int cnt[1600005], rk[1600005], ls[1600005], vy[1600005], tmp[1600005];
void bsort(int n) {
  int i, T = max(3, n * 2) + 4;
  memset(cnt, 0, sizeof(int) * T);
  for (i = 0; i < n; ++i) ++cnt[vy[i]];
  for (i = 1; i <= n + 3 || i <= 3; ++i) cnt[i] += cnt[i - 1];
  for (i = n - 1; i >= 0; --i) tmp[--cnt[vy[i]]] = i;
  memset(cnt, 0, sizeof(int) * T);
  for (i = 0; i < n; ++i) ++cnt[rk[tmp[i]]];
  for (i = 1; i <= n + 3 || i <= 3; ++i) cnt[i] += cnt[i - 1];
  for (i = n - 1; i >= 0; --i) ls[--cnt[rk[tmp[i]]]] = tmp[i];
  memset(tmp, 0, sizeof(int) * T);
}
void getsa(int n) {
  int i, j, cv, T = max(3, n * 2) + 4;
  memset(rk, 0, sizeof(int) * T);
  memset(vy, 0, sizeof(int) * T);
  for (i = 0; i < n; ++i) {
    rk[i] = s[i] - '0' + 1;
  }
  for (i = 2; i <= n * 2; i <<= 1) {
    for (j = 0; j < n; ++j) {
      vy[j] = rk[(j + (i >> 1)) % n];
    }
    bsort(n);
    cv = 1;
    for (j = 0; j < n; ++j) {
      if (j && (rk[ls[j - 1]] != rk[ls[j]] || vy[ls[j - 1]] != vy[ls[j]])) ++cv;
      tmp[ls[j]] = cv;
    }
    memcpy(rk, tmp, sizeof(int) * T);
  }
}
}  // namespace SA
int minrep(string S) {
  int len = (int)S.size(), i;
  memcpy(SA::s, S.c_str(), sizeof(char) * len);
  SA::getsa(len);
  return SA::ls[0];
}
int inarea(int d) {
  if (d < n) return 0;
  if (d < n + m) return 1;
  if (d < n + m + n) return 2;
  return 3;
}
int opposite(int d) {
  if (d < n) return n + m + (n - 1 - d);
  if (d < n + m) return n + m + n + (m - 1 - (d - n));
  if (d < n + m + n) return n - 1 - (d - n - m);
  return m - 1 - (d - n - m - n) + n;
}
int repid(int d) { return d < n + m ? d : opposite(d); }
pair<string, vector<int> > getrep(string s, vector<int> ds) {
  int d = minrep(s);
  rotate(s.begin(), s.begin() + d, s.end());
  rotate(ds.begin(), ds.begin() + d, ds.end());
  return make_pair(s, ds);
}
struct config {
  int opp[400005];
  vector<vector<int> > getstat() {
    int i;
    vector<vector<int> > R(4, vector<int>(4));
    for (i = 0; i < n + m + n + m; ++i) {
      if (opp[i] < i) {
        ++R[inarea(opp[i])][inarea(i)];
      }
    }
    return R;
  }
  bool buildfromstat(vector<vector<int> > S) {
    int pl[4] = {0, n, n + m, n + m + n},
        pr[4] = {n - 1, n + m - 1, n + m + n - 1, n + m + n + m - 1};
    int i, j, k;
    for (i = 0; i < 4; ++i) {
      int x = i, y = (i + 1) % 4, c = S[min(x, y)][max(x, y)];
      while (c--) {
        int a = pr[x]--, b = pl[y]++;
        opp[a] = b;
        opp[b] = a;
      }
    }
    if (S[0][2] && S[1][3]) return 0;
    for (i = 0; i < 2; ++i) {
      int c = S[i][i + 2];
      while (c--) {
        int a = pl[i]++, b = pr[i + 2]--;
        opp[a] = b;
        opp[b] = a;
      }
    }
    for (i = 0; i < 4; ++i) assert(pl[i] == pr[i] + 1);
    return 1;
  }
  bool vis[400005];
  vector<pair<string, vector<int> > > getcycrep() {
    int i, j, k;
    vector<pair<string, vector<int> > > R;
    memset(vis, 0, sizeof(vis));
    for (i = 0; i < n + m; ++i) {
      if (vis[i]) continue;
      string s;
      vector<int> ds;
      for (j = i;; j = opp[opposite(j)]) {
        if (vis[j]) break;
        vis[j] = vis[opposite(j)] = 1;
        s.push_back('0' + inarea(j));
        ds.push_back(repid(j));
        s.push_back('0' + inarea(opposite(j)));
        ds.push_back(repid(opposite(j)));
      }
      pair<string, vector<int> > cur = getrep(s, ds);
      reverse(s.begin(), s.end());
      reverse(ds.begin(), ds.end());
      UMIN(cur, getrep(s, ds));
      R.push_back(cur);
    }
    sort(R.begin(), R.end());
    return R;
  }
} F, T;
int p2d(char c, int d) {
  if (c == 'L') return d;
  if (c == 'B') return n + d;
  if (c == 'R') return opposite(d);
  return opposite(n + d);
}
void fafa() {
  printf("No solution\n");
  exit(0);
}
int res[400005];
int main() {
  int i, j, k;
  n = readint();
  m = readint();
  for (i = 0; i < n + m; ++i) {
    char a = readch(), b = readch();
    int p = readint() - 1, q = readint() - 1;
    F.opp[p2d(a, p)] = p2d(b, q);
    F.opp[p2d(b, q)] = p2d(a, p);
  }
  if (!T.buildfromstat(F.getstat())) fafa();
  vector<pair<string, vector<int> > > rF = F.getcycrep(), rT = T.getcycrep();
  if (rF.size() != rT.size()) fafa();
  for (i = 0; i < (int)rF.size(); ++i) {
    if (rF[i].first != rT[i].first) fafa();
    for (j = 0; j < (int)rF[i].second.size(); ++j) {
      res[rT[i].second[j]] = rF[i].second[j];
    }
  }
  for (i = 0; i < n; ++i) printf("%d ", res[i] + 1);
  printf("\n");
  for (i = 0; i < m; ++i) printf("%d ", res[i + n] + 1 - n);
  printf("\n");
  return 0;
}
