Problem: Emuskald is an innovative musician and always tries to push the boundaries of music production. Now he has come up with an idea for a revolutionary musical instrument — a rectangular harp.

A rectangular harp is a rectangle n × m consisting of n rows and m columns. The rows are numbered 1 to n from top to bottom. Similarly the columns are numbered 1 to m from left to right. String pins are spaced evenly across every side, one per unit. Thus there are n pins on the left and right sides of the harp and m pins on its top and bottom. The harp has exactly n + m different strings, each string connecting two different pins, each on a different side of the harp.

Emuskald has ordered his apprentice to construct the first ever rectangular harp. However, he didn't mention that no two strings can cross, otherwise it would be impossible to play the harp. Two strings cross if the segments connecting their pins intersect. To fix the harp, Emuskald can perform operations of two types: 

  1. pick two different columns and swap their pins on each side of the harp, not changing the pins that connect each string; 
  2. pick two different rows and swap their pins on each side of the harp, not changing the pins that connect each string; 



In the following example, he can fix the harp by swapping two columns: 

<image>

Help Emuskald complete his creation and find the permutations how the rows and columns of the harp need to be rearranged, or tell that it is impossible to do so. He can detach and reattach each string to its pins, so the physical layout of the strings doesn't matter.

Input

The first line of input contains two space-separated integers numbers n and m (1 ≤ n, m ≤ 105), the height and width of the harp in units. Each of the following n + m lines contains 4 space-separated tokens, describing a single string: two symbols ai, bi and two integer numbers pi, qi. The pair ai, pi describes the first pin, and the pair bi, qi describes the second pin of the string;

A pair s, x describes the position of a single pin in a following way: 

  1. s is equal to one of the symbols "L", "T", "R" or "B" (without quotes), which means that the pin is positioned on the left, top, right or bottom side of the harp accordingly; 
  2. x is equal to the number of the row, if the pin is on the left or right border of the harp, and to the number of the column, if the pin is on the top or bottom border of the harp. 



It is guaranteed that no two different strings are connected to the same pin.

Output

If it is possible to rearrange the rows and columns to fix the harp, on the first line output n space-separated integers — the old numbers of rows now placed from top to bottom in the fixed harp. On the second line, output m space-separated integers — the old numbers of columns now placed from left to right in the fixed harp.

If it is impossible to rearrange the rows and columns to fix the harp, output "No solution" (without quotes).

Examples

Input

3 4
L T 1 3
L B 2 2
L B 3 3
T R 1 2
T B 2 1
T R 4 1
B R 4 3


Output

1 2 3 
3 2 1 4 


Input

3 3
L T 1 1
T R 3 1
R B 3 3
B L 1 3
L R 2 2
T B 2 2


Output

No solution

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:36777216")
template <class T>
inline T &RD(T &);
template <class T>
inline void OT(const T &);
inline long long RD() {
  long long x;
  return RD(x);
}
inline double &RF(double &);
inline double RF() {
  double x;
  return RF(x);
}
inline char *RS(char *s);
inline char &RC(char &c);
inline char RC();
inline char &RC(char &c) {
  scanf(" %c", &c);
  return c;
}
inline char RC() {
  char c;
  return RC(c);
}
template <class T>
inline T &RDD(T &x) {
  char c;
  for (c = getchar(); c < '-'; c = getchar())
    ;
  if (c == '-') {
    x = '0' - getchar();
    for (c = getchar(); '0' <= c && c <= '9'; c = getchar())
      x = x * 10 + '0' - c;
  } else {
    x = c - '0';
    for (c = getchar(); '0' <= c && c <= '9'; c = getchar())
      x = x * 10 + c - '0';
  }
  return x;
}
inline long long RDD() {
  long long x;
  return RDD(x);
}
template <class T0, class T1>
inline T0 &RD(T0 &x0, T1 &x1) {
  RD(x0), RD(x1);
  return x0;
}
template <class T0, class T1, class T2>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2) {
  RD(x0), RD(x1), RD(x2);
  return x0;
}
template <class T0, class T1, class T2, class T3>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3) {
  RD(x0), RD(x1), RD(x2), RD(x3);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);
  return x0;
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline T0 &RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6) {
  RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);
  return x0;
}
template <class T0, class T1>
inline void OT(const T0 &x0, const T1 &x1) {
  OT(x0), OT(x1);
}
template <class T0, class T1, class T2>
inline void OT(const T0 &x0, const T1 &x1, const T2 &x2) {
  OT(x0), OT(x1), OT(x2);
}
template <class T0, class T1, class T2, class T3>
inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3) {
  OT(x0), OT(x1), OT(x2), OT(x3);
}
template <class T0, class T1, class T2, class T3, class T4>
inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3,
               const T4 &x4) {
  OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3,
               const T4 &x4, const T5 &x5) {
  OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3,
               const T4 &x4, const T5 &x5, const T6 &x6) {
  OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);
}
inline char &RC(char &a, char &b) {
  RC(a), RC(b);
  return a;
}
inline char &RC(char &a, char &b, char &c) {
  RC(a), RC(b), RC(c);
  return a;
}
inline char &RC(char &a, char &b, char &c, char &d) {
  RC(a), RC(b), RC(c), RC(d);
  return a;
}
inline char &RC(char &a, char &b, char &c, char &d, char &e) {
  RC(a), RC(b), RC(c), RC(d), RC(e);
  return a;
}
inline char &RC(char &a, char &b, char &c, char &d, char &e, char &f) {
  RC(a), RC(b), RC(c), RC(d), RC(e), RC(f);
  return a;
}
inline char &RC(char &a, char &b, char &c, char &d, char &e, char &f, char &g) {
  RC(a), RC(b), RC(c), RC(d), RC(e), RC(f), RC(g);
  return a;
}
inline double &RF(double &a, double &b) {
  RF(a), RF(b);
  return a;
}
inline double &RF(double &a, double &b, double &c) {
  RF(a), RF(b), RF(c);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d) {
  RF(a), RF(b), RF(c), RF(d);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e) {
  RF(a), RF(b), RF(c), RF(d), RF(e);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e,
                  double &f) {
  RF(a), RF(b), RF(c), RF(d), RF(e), RF(f);
  return a;
}
inline double &RF(double &a, double &b, double &c, double &d, double &e,
                  double &f, double &g) {
  RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g);
  return a;
}
inline void RS(char *s1, char *s2) { RS(s1), RS(s2); }
inline void RS(char *s1, char *s2, char *s3) { RS(s1), RS(s2), RS(s3); }
template <class T0, class T1>
inline void RDD(const T0 &a, const T1 &b) {
  RDD(a), RDD(b);
}
template <class T0, class T1, class T2>
inline void RDD(const T0 &a, const T1 &b, const T2 &c) {
  RDD(a), RDD(b), RDD(c);
}
template <class T>
inline void RST(T &A) {
  memset(A, 0, sizeof(A));
}
template <class T>
inline void FLC(T &A, int x) {
  memset(A, x, sizeof(A));
}
template <class T>
inline void CLR(T &A) {
  A.clear();
}
template <class T0, class T1>
inline void RST(T0 &A0, T1 &A1) {
  RST(A0), RST(A1);
}
template <class T0, class T1, class T2>
inline void RST(T0 &A0, T1 &A1, T2 &A2) {
  RST(A0), RST(A1), RST(A2);
}
template <class T0, class T1, class T2, class T3>
inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3) {
  RST(A0), RST(A1), RST(A2), RST(A3);
}
template <class T0, class T1, class T2, class T3, class T4>
inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4) {
  RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5) {
  RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6) {
  RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);
}
template <class T0, class T1>
inline void FLC(T0 &A0, T1 &A1, int x) {
  FLC(A0, x), FLC(A1, x);
}
template <class T0, class T1, class T2>
inline void FLC(T0 &A0, T1 &A1, T2 &A2, int x) {
  FLC(A0, x), FLC(A1, x), FLC(A2, x);
}
template <class T0, class T1, class T2, class T3>
inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x) {
  FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x);
}
template <class T0, class T1, class T2, class T3, class T4>
inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x) {
  FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x);
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x) {
  FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x);
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x) {
  FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x),
      FLC(A6, x);
}
template <class T>
inline void CLR(priority_queue<T, vector<T>, less<T> > &Q) {
  while (!Q.empty()) Q.pop();
}
template <class T>
inline void CLR(priority_queue<T, vector<T>, greater<T> > &Q) {
  while (!Q.empty()) Q.pop();
}
template <class T0, class T1>
inline void CLR(T0 &A0, T1 &A1) {
  CLR(A0), CLR(A1);
}
template <class T0, class T1, class T2>
inline void CLR(T0 &A0, T1 &A1, T2 &A2) {
  CLR(A0), CLR(A1), CLR(A2);
}
template <class T0, class T1, class T2, class T3>
inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3) {
  CLR(A0), CLR(A1), CLR(A2), CLR(A3);
}
template <class T0, class T1, class T2, class T3, class T4>
inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4) {
  CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);
}
template <class T0, class T1, class T2, class T3, class T4, class T5>
inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5) {
  CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);
}
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6) {
  CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);
}
template <class T>
inline void CLR(T &A, int n) {
  for (int i = 0; i < int(n); ++i) CLR(A[i]);
}
template <class T>
inline T &SRT(T &A) {
  sort(A.begin(), A.end());
  return A;
}
template <class T, class C>
inline T &SRT(T &A, C B) {
  sort(A.begin(), A.end(), B);
  return A;
}
template <class T>
inline T &UNQ(T &A) {
  A.resize(unique(SRT(A).begin(), SRT(A).end()) - A.begin());
  return A;
}
int MOD = 99990001;
const int INF = 0x3f3f3f3f;
const long long INFF = 1LL << 60;
const double EPS = 1e-9;
const double OO = 1e20;
const double PI = acos(-1.0);
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
template <class T>
inline void checkMin(T &a, const T b) {
  if (b < a) a = b;
}
template <class T>
inline void checkMax(T &a, const T b) {
  if (a < b) a = b;
}
template <class T>
inline void checkMin(T &a, T &b, const T x) {
  checkMin(a, x), checkMin(b, x);
}
template <class T>
inline void checkMax(T &a, T &b, const T x) {
  checkMax(a, x), checkMax(b, x);
}
template <class T, class C>
inline void checkMin(T &a, const T b, C c) {
  if (c(b, a)) a = b;
}
template <class T, class C>
inline void checkMax(T &a, const T b, C c) {
  if (c(a, b)) a = b;
}
template <class T>
inline T min(T a, T b, T c) {
  return min(min(a, b), c);
}
template <class T>
inline T max(T a, T b, T c) {
  return max(max(a, b), c);
}
template <class T>
inline T min(T a, T b, T c, T d) {
  return min(min(a, b), min(c, d));
}
template <class T>
inline T max(T a, T b, T c, T d) {
  return max(max(a, b), max(c, d));
}
template <class T>
inline T sqr(T a) {
  return a * a;
}
template <class T>
inline T cub(T a) {
  return a * a * a;
}
inline int ceil(int x, int y) { return (x - 1) / y + 1; }
inline int sgn(double x) { return x < -EPS ? -1 : x > EPS; }
inline int sgn(double x, double y) { return sgn(x - y); }
namespace BO {
inline bool _1(int x, int i) { return bool(x & 1 << i); }
inline bool _1(long long x, int i) { return bool(x & 1LL << i); }
inline long long _1(int i) { return 1LL << i; }
inline long long _U(int i) { return _1(i) - 1; };
inline int reverse_bits(int x) {
  x = ((x >> 1) & 0x55555555) | ((x << 1) & 0xaaaaaaaa);
  x = ((x >> 2) & 0x33333333) | ((x << 2) & 0xcccccccc);
  x = ((x >> 4) & 0x0f0f0f0f) | ((x << 4) & 0xf0f0f0f0);
  x = ((x >> 8) & 0x00ff00ff) | ((x << 8) & 0xff00ff00);
  x = ((x >> 16) & 0x0000ffff) | ((x << 16) & 0xffff0000);
  return x;
}
inline long long reverse_bits(long long x) {
  x = ((x >> 1) & 0x5555555555555555LL) | ((x << 1) & 0xaaaaaaaaaaaaaaaaLL);
  x = ((x >> 2) & 0x3333333333333333LL) | ((x << 2) & 0xccccccccccccccccLL);
  x = ((x >> 4) & 0x0f0f0f0f0f0f0f0fLL) | ((x << 4) & 0xf0f0f0f0f0f0f0f0LL);
  x = ((x >> 8) & 0x00ff00ff00ff00ffLL) | ((x << 8) & 0xff00ff00ff00ff00LL);
  x = ((x >> 16) & 0x0000ffff0000ffffLL) | ((x << 16) & 0xffff0000ffff0000LL);
  x = ((x >> 32) & 0x00000000ffffffffLL) | ((x << 32) & 0xffffffff00000000LL);
  return x;
}
template <class T>
inline bool odd(T x) {
  return x & 1;
}
template <class T>
inline bool even(T x) {
  return !odd(x);
}
template <class T>
inline T low_bit(T x) {
  return x & -x;
}
template <class T>
inline T high_bit(T x) {
  T p = low_bit(x);
  while (p != x) x -= p, p = low_bit(x);
  return p;
}
template <class T>
inline T cover_bit(T x) {
  T p = 1;
  while (p < x) p <<= 1;
  return p;
}
inline int low_idx(int x) { return __builtin_ffs(x); }
inline int low_idx(long long x) { return __builtin_ffsll(x); }
inline int high_idx(int x) { return low_idx(reverse_bits(x)); }
inline int high_idx(long long x) { return low_idx(reverse_bits(x)); }
inline int clz(int x) { return __builtin_clz(x); }
inline int clz(long long x) { return __builtin_clzll(x); }
inline int ctz(int x) { return __builtin_ctz(x); }
inline int ctz(long long x) { return __builtin_ctzll(x); }
inline int parity(int x) { return __builtin_parity(x); }
inline int parity(long long x) { return __builtin_parityll(x); }
inline int lg2(int a) { return 31 - clz(a); }
inline int lg2(long long a) { return 63 - clz(a); }
inline int count_bits(int x) { return __builtin_popcount(x); }
inline int count_bits(long long x) { return __builtin_popcountll(x); }
}  // namespace BO
using namespace BO;
template <class T>
inline T &RD(T &x) {
  char c;
  for (c = getchar(); c < '0'; c = getchar())
    ;
  x = c - '0';
  for (c = getchar(); '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0';
  return x;
}
inline double &RF(double &x) {
  scanf("%lf", &x);
  return x;
}
inline char *RS(char *s) {
  scanf("%s", s);
  return s;
}
int Case;
template <class T>
inline void OT(const T &x) {
  printf("%d ", x);
}
const int MAXN = int(4e5) + 9;
vector<vector<int> > cyc1, cyc2;
bool vis[MAXN], used[MAXN];
char tmp[MAXN * 2];
int link[MAXN], dir1[MAXN], dir2[MAXN];
int r, c, n, ans_r[MAXN], ans_c[MAXN];
inline int id(char s, int x) {
  if (s == 'L') return x;
  if (s == 'T') return x + r;
  if (s == 'R') return x + n;
  return x + n + r;
}
inline pair<char, int> di(int x) {
  return x < n       ? x < r ? make_pair('L', x) : make_pair('T', x - r)
               : x < n + r ? make_pair('R', x - n)
                     : make_pair('B', x - n - r);
}
inline int cp(int x) { return x < n ? x + n : x - n; }
void dump(const vector<int> &cyc, char *str) {
  for (int i = 0; i < int(int(cyc.size())); ++i) str[i] = di(cyc[i]).first;
  str[int(cyc.size())] = 0;
}
int lex_smallest_head(char s[], int n) {
  for (int i = 0; i < n; i++) s[i + n] = s[i];
  int i = 0, j = 1, k = 0;
  while (j < n && k < n) {
    if (s[i + k] == s[j + k])
      k++;
    else {
      if (s[i + k] < s[j + k])
        j += k + 1;
      else
        i += k + 1;
      k = 0;
    }
    if (i == j) j++;
  }
  return i;
}
void shift(vector<int> &a, int o) {
  vector<int> _a = a;
  for (int i = 0; i < int(int(a.size())); ++i)
    a[i] = _a[(i + o) % int(a.size())];
}
void dfs(int u, int *link, vector<int> &cyc) {
  if (vis[u]) return;
  vis[u] = 1, cyc.push_back(u);
  dfs(link[u], link, cyc), dfs(cp(u), link, cyc);
}
int iscyc1(const vector<int> &cyc) {
  if (int(cyc.size()) != 8) return 0;
  dump(cyc, tmp);
  if (!strcmp(tmp, "LTBLRBTR")) return 1;
  if (!strcmp(tmp, "LBTLRTBR")) return 2;
  return 0;
}
void gao1() {
  for (int i = 0; i < int(int(cyc1.size())); ++i) {
    const vector<int> &cyc = cyc1[i];
    if (iscyc1(cyc) == 1) {
      ans_r[i] = di(cyc[0]).second, ans_r[r - 1 - i] = di(cyc[3]).second;
      ans_c[i] = di(cyc[1]).second, ans_c[c - 1 - i] = di(cyc[5]).second;
    } else {
      ans_r[r - 1 - i] = di(cyc[0]).second, ans_r[i] = di(cyc[3]).second;
      ans_c[i] = di(cyc[1]).second, ans_c[c - 1 - i] = di(cyc[5]).second;
    }
    used[id('L', i)] = used[id('L', r - 1 - i)] = 1;
    used[id('R', i)] = used[id('R', r - 1 - i)] = 1;
    used[id('T', i)] = used[id('T', c - 1 - i)] = 1;
    used[id('B', i)] = used[id('B', c - 1 - i)] = 1;
  }
}
void gen_dir() {
  vector<int> a1, a2;
  for (int i = int(r - 1); i >= int(0); --i)
    if (!used[i]) a1.push_back(i);
  for (int i = 0; i < int(c); ++i)
    if (!used[r + i]) a1.push_back(r + i);
  for (int i = 0; i < int(r); ++i)
    if (!used[n + i]) a1.push_back(n + i);
  for (int i = int(c - 1); i >= int(0); --i)
    if (!used[n + r + i]) a1.push_back(n + r + i);
  for (int i = 0; i < int(r); ++i)
    if (!used[i]) a2.push_back(i);
  for (int i = 0; i < int(c); ++i)
    if (!used[n + r + i]) a2.push_back(n + r + i);
  for (int i = int(r - 1); i >= int(0); --i)
    if (!used[n + i]) a2.push_back(n + i);
  for (int i = int(c - 1); i >= int(0); --i)
    if (!used[r + i]) a2.push_back(r + i);
  for (int i = 0; i < int(int(a1.size())); ++i)
    dir1[a1[i]] = a1[int(a1.size()) - i - 1];
  for (int i = 0; i < int(int(a2.size())); ++i)
    dir2[a2[i]] = a2[int(a2.size()) - i - 1];
}
bool gao2(int *dir) {
  RST(vis);
  vector<vector<int> > target, start;
  for (int o = 0; o < int(int(cyc2.size())); ++o) {
    vector<int> &arr = cyc2[o];
    dump(arr, tmp);
    shift(arr, lex_smallest_head(tmp, int(arr.size())));
    start.push_back(arr);
  }
  for (int i = 0; i < int(n); ++i)
    if (!vis[i] && !used[i]) {
      vector<int> arr;
      dfs(i, dir, arr);
      dump(arr, tmp), shift(arr, lex_smallest_head(tmp, int(arr.size())));
      target.push_back(arr);
    }
  if (int(start.size()) != int(target.size())) return 0;
  SRT(start), SRT(target);
  for (int i = 0; i < int(int(start.size())); ++i)
    if (int(start[i].size()) != int(target[i].size())) return 0;
  for (int i = 0; i < int(int(start.size())); ++i)
    for (int j = 0; j < int(int(start[i].size())); ++j) {
      int s = start[i][j], t = target[i][j];
      pair<char, int> ss = di(s), tt = di(t);
      if (ss.first != tt.first) return 0;
      tt.second[ss.first == 'L' || ss.first == 'R' ? ans_r : ans_c] = ss.second;
    }
  return 1;
}
bool gao2() { return gen_dir(), gao2(dir1) || gao2(dir2); }
bool solve() {
  for (int i = 0; i < int(n); ++i)
    if (!vis[i]) {
      vector<int> cyc;
      dfs(i, link, cyc);
      if (iscyc1(cyc))
        cyc1.push_back(cyc);
      else
        cyc2.push_back(cyc);
    }
  return gao1(), gao2();
}
int main() {
  for (int n____ = int(n = RD(r) + RD(c)), i = 0; i < n____; ++i) {
    char s1, s2;
    RC(s1, s2);
    int x1 = id(s1, RD() - 1), x2 = id(s2, RD() - 1);
    link[x1] = x2, link[x2] = x1;
  }
  if (!solve())
    puts("No solution");
  else {
    for (int i = 0; i < int(r); ++i) OT(ans_r[i] + 1);
    puts("");
    for (int i = 0; i < int(c); ++i) OT(ans_c[i] + 1);
    puts("");
  }
}