#include <bits/stdc++.h>
// #include "push_relabel.h"

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define each(i,a) for (auto&& i : a)
#define FOR(i,a,b) for (ll i=(a),__last_##i=(b);i<__last_##i;i++)
#define RFOR(i,a,b) for (ll i=(b)-1,__last_##i=(a);i>=__last_##i;i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,0,n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(),(a).end()
#define chmin(x,v) x = min(x, v)
#define chmax(x,v) x = max(x, v)

const ll linf = 1e18;
const double eps = 1e-12;
const double pi = acos(-1);

template<typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  each(x,vec) is >> x;
  return is;
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
  rep(i,vec.size()) {
    if (i) os << " ";
    os << vec[i];
  }
  return os;
}
template<typename T>
ostream& operator<<(ostream& os, const vector< vector<T> >& vec) {
  rep(i,vec.size()) {
    if (i) os << endl;
    os << vec[i];
  }
  return os;
}

class PushRelabel {
  struct Edge {
    int to, cap, rev;
  };
  int fsum;
  std::vector<std::vector<Edge>> G;
  std::vector<int> h, f;
  void relabel(int v);
  bool push(int v, bool force=false);
  Edge& rev(const Edge& e);
public:
  PushRelabel(int node_count);
  void add(int from, int to, int cap);
  int flow(int s, int t);
};
PushRelabel::PushRelabel(int node_count) : fsum(0), G(node_count), h(node_count, 0), f(node_count, 0) {}
void PushRelabel::add(int from, int to, int cap) {
  G[from].pb({to, cap, int(G[to].size())});
  G[to].pb({from, 0, int(G[from].size())-1});
}
int PushRelabel::flow(int s, int t) {
  const int n = G.size();
  h[s] = n+2, h[t] = 0;
  f[s] = int(1e9);
  push(s, true);
  while (true) {
    // cout << h << endl;
    // cout << f << endl;
    // cout << endl;
    bool is_updated = false;
    rep(i, n) {
      if (i == s || i == t) continue;
      if (f[i] > 0) {
        if (!push(i)) {
          relabel(i);
          push(i);
        }
        is_updated = true;
      }
    }
    if (!is_updated) break;
  }
  return f[t];
}
bool PushRelabel::push(int v, bool force) {
  bool res = false;
  each(e, G[v]) {
    if ((h[v] == h[e.to] + 1 && e.cap > 0) || force) {
      ll use = min(e.cap, f[v]);
      e.cap -= use;
      rev(e).cap += use;
      f[e.to] += use;
      f[v] -= use;
      res = true;
    }
  }
  return res;
}
void PushRelabel::relabel(int v) {
  int nh = int(1e9);
  each(e, G[v]) {
    if (e.cap > 0) chmin(nh, h[e.to]+1);
  }
  assert(nh > h[v]);
  h[v] = nh;
}
PushRelabel::Edge& PushRelabel::rev(const Edge& e) {
  return G[e.to][e.rev];
}

ll gcd(ll a, ll b) {
  return b == 0 ? a : gcd(b, a % b);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  ll n, m;
  while (cin >> n >> m, n || m) {
    vector<ll> a(n), b(m); cin >> a >> b;
    ll s = n + m, t = s + 1;
    PushRelabel pr(t+1);
    rep(i, n) rep(j, m) {
      if (gcd(a[i], b[j]) > 1) {
        pr.add(i, n+j, 1);
      }
    }
    rep(i, n) pr.add(s, i, 1);
    rep(i, m) pr.add(n+i, t, 1);
    cout << pr.flow(s, t) << endl;
  }
}



Measured memory_bytes: 7304