#include <bits/stdc++.h>
using namespace std;
inline int sqr(int x) { return x * x; }
inline int cube(int x) { return x * x * x; }
inline long long sqrLL(long long x) { return x * x; }
inline long long cubeLL(long long x) { return x * x * x; }
const long long LLINF = 9223372036854775807LL;
const long long LLINF17 = 100000000000000000LL;
const int INF = 1000000000;
const int INF9 = 1000000000;
long long MOD = 1000000007;
const double eps = 1e-7;
const double PI = acos(-1.0);
template <typename T>
void check(T &a, const T &b) {
  if (a >= b) {
    a %= b;
  }
}
template <typename T>
void read(T &x) {
  register T c = getchar();
  x = 0;
  int t = 0;
  if (c == '-') t = 1, c = getchar();
  for (; (c < 48 || c > 57); c = getchar())
    ;
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
  if (t) x = -x;
}
template <typename T>
T gcd(T u, T v) {
  if (u == v) return u;
  if (u == 0) return v;
  if (v == 0) return u;
  if (~u & 1) {
    if (v & 1)
      return gcd(u >> 1, v);
    else
      return gcd(u >> 1, v >> 1) << 1;
  }
  if (~v & 1) return gcd(u, v >> 1);
  if (u > v) return gcd((u - v) >> 1, v);
  return gcd((v - u) >> 1, u);
}
long long mulmod(long long a, long long b, long long m) {
  long long q = (long long)(((long double)a * (long double)b) / (long double)m);
  long long r = a * b - q * m;
  if (r > m) r %= m;
  if (r < 0) r += m;
  return r;
}
template <typename T, typename S>
T expo(T e, S n) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = x * p;
    p = p * p;
    n >>= 1;
  }
  return x;
}
template <typename T>
T powerL(T e, T n, T &m) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = mulmod(x, p, m);
    p = mulmod(p, p, m);
    n >>= 1;
  }
  return x;
}
template <typename T>
T InverseEuler(T a, T &m) {
  return (a == 1 ? 1 : power(a, m - 2, m));
}
const int LIM = 10000000;
bool isPrime[LIM + 10];
int factors[10000010], P[LIM], _P[LIM];
void sieve() {
  memset(isPrime, true, sizeof(isPrime));
  isPrime[0] = false;
  isPrime[1] = false;
  isPrime[2] = true;
  for (int i = 2; i * i <= LIM; i++) {
    if (isPrime[i]) {
      factors[i] = i;
      for (int j = i * i; j <= LIM; j += i)
        if (!factors[j]) {
          isPrime[j] = false, factors[j] = i;
        }
    }
  }
  for (int i = 3; i <= LIM; i++) {
    if (isPrime[i]) {
      factors[i] = i;
    }
  }
  return;
}
int main() {
  int n, m, MAXNUM = -1;
  read(n), read(m);
  vector<int> a, b;
  sieve();
  for (int(i) = (0); (i) < (n); (i)++) {
    int t_;
    read(t_);
    a.push_back(t_);
    (MAXNUM) = max((MAXNUM), (t_));
    while (t_ > 1) {
      int alpha = factors[t_];
      while (factors[t_] == alpha) {
        t_ /= alpha;
        P[alpha]++;
      }
    }
  }
  for (int(i) = (0); (i) < (m); (i)++) {
    int t_;
    read(t_);
    b.push_back(t_);
    (MAXNUM) = max((MAXNUM), (t_));
    while (t_ > 1) {
      int alpha = factors[t_];
      while (alpha == factors[t_]) {
        t_ /= alpha;
        _P[alpha]++;
      }
    }
  }
  for (int(i) = (0); (i) < (n); (i)++) {
    int num = 1, t = a[i];
    while (t != 1) {
      int fact = factors[t];
      if (!_P[fact]) {
        num *= fact;
      } else {
        _P[fact]--;
      }
      t /= fact;
    }
    a[i] = num;
  }
  for (int(i) = (0); (i) < (m); (i)++) {
    int num = 1, t = b[i];
    while (t != 1) {
      int fact = factors[t];
      if (!P[fact]) {
        num *= fact;
      } else {
        P[fact]--;
      }
      t /= fact;
    }
    b[i] = num;
  }
  printf("%d %d\n", n, m);
  for (auto i : a) {
    printf("%d ", i);
  }
  printf("\n");
  for (auto i : b) {
    printf("%d ", i);
  }
  return 0;
}
