#include <bits/stdc++.h>
using namespace std;
template <typename T>
string toString(T x) {
  if (x == 0) return "0";
  bool negative = x < 0;
  string res;
  while (x) {
    res.push_back('0' + x % 10);
    x /= 10;
  }
  if (negative) res.push_back('-');
  reverse(res.begin(), res.end());
  return res;
}
void ioFromFile(string inputFileName, string outputFileName) {
  ifstream fin(inputFileName);
  ofstream fout(outputFileName);
  cin.rdbuf(fin.rdbuf());
  cout.rdbuf(fout.rdbuf());
}
int read() {
  int res;
  scanf("%d", &res);
  return res;
}
void write(int x) { printf("%d ", x); }
template <typename T>
T gcd(T a, T b) {
  return a == 0 ? b : gcd(b % a, a);
}
template <typename T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
struct MyVec {
  int* arr;
  int n;
  MyVec() : n(0), arr(nullptr) {}
  void push(int x) {
    int* newArr = new int[n + 1];
    for (int i = 0; i < n; i++) {
      newArr[i] = arr[i];
    }
    newArr[n] = x;
    delete[] arr;
    arr = newArr;
    n++;
  }
};
const int N = 10000000;
bool isPrime[N + 1];
bool seen[N + 1];
int numa[N + 1];
int numb[N + 1];
MyVec primeDivisors[N + 1];
int main() {
  memset(isPrime, true, sizeof(isPrime));
  for (int i = 2; i <= N; i++) {
    if (!isPrime[i]) continue;
    for (int j = i * 2; j <= N; j += i) {
      isPrime[j] = false;
    }
  }
  int n = read(), m = read();
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    int x = read();
    a[i] = x;
    seen[x] = true;
  }
  vector<int> b(m);
  for (int i = 0; i < m; i++) {
    int x = read();
    b[i] = x;
    seen[x] = true;
  }
  for (int i = 2; i <= N; i++) {
    if (!isPrime[i]) continue;
    for (int j = i; j <= N; j += i) {
      if (seen[j]) primeDivisors[j].push(i);
    }
  }
  for (int i = 0; i < n; i++) {
    int x = a[i];
    const MyVec& v = primeDivisors[x];
    for (int di = 0; di < v.n; di++) {
      int d = v.arr[di];
      while (x % d == 0) {
        numa[d]++;
        x /= d;
      }
    }
  }
  for (int i = 0; i < m; i++) {
    int x = b[i];
    const MyVec& v = primeDivisors[x];
    for (int di = 0; di < v.n; di++) {
      int d = v.arr[di];
      while (x % d == 0) {
        numb[d]++;
        x /= d;
      }
    }
  }
  for (int i = 2; i <= N; i++) {
    int minn = min(numa[i], numb[i]);
    numa[i] -= minn;
    numb[i] -= minn;
  }
  vector<int> resa(n);
  for (int i = 0; i < n; i++) {
    int target = a[i];
    int at = 1;
    for (int di = 0; di < primeDivisors[target].n; di++) {
      int d = primeDivisors[target].arr[di];
      while (numa[d] > 0 && target % (at * d) == 0) {
        at *= d;
        numa[d]--;
      }
    }
    resa[i] = at;
  }
  vector<int> resb(m);
  for (int i = 0; i < m; i++) {
    int target = b[i];
    int at = 1;
    for (int di = 0; di < primeDivisors[target].n; di++) {
      int d = primeDivisors[target].arr[di];
      while (numb[d] > 0 && target % (at * d) == 0) {
        at *= d;
        numb[d]--;
      }
    }
    resb[i] = at;
  }
  write(n);
  write(m);
  for (int x : resa) write(x);
  for (int x : resb) write(x);
  return 0;
}
