#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i,a) for (auto& i : a)
#define FOR(i,a,b) for (ll i=(a);i<(b);i++)
#define RFOR(i,a,b) for (ll i=(b)-1;i>=(a);i--)
#define REP(i,n) for (ll i=0;i<(n);i++)
#define RREP(i,n) for (ll i=(n)-1;i>=0;i--)
#define debug(x) cout<<#x<<": "<<x<<endl
#define pb push_back
#define ALL(a) (a).begin(),(a).end()

const ll linf = 1e18;
const int inf = 1e9;
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, vector<T>& vec) {
    REP(i,vec.size()) {
        if (i) os << " ";
        os << vec[i];
    }
    return os;
}
template<typename T>
ostream& operator<<(ostream& os, vector< vector<T> >& vec) {
    REP(i,vec.size()) {
        if (i) os << endl;
        os << vec[i];
    }
    return os;
}
class MaxFlow {
    struct Edge {
        ll to, cap, rev;
    };
    ll V;
    vector<vector<Edge>> G;
    vector<ll> bfs(ll s) {
        vector<ll> dist(V, linf);
        dist[s] = 0;
        queue<ll> Q; Q.push(s);
        while ( !Q.empty() ) {
            ll v = Q.front(); Q.pop();
            EACH(e, G[v]) {
                if (e.cap > 0 && dist[e.to] == linf) {
                    dist[e.to] = dist[v]+1;
                    Q.push(e.to);
                }
            }
        }
        return dist;
    }
    ll dfs(ll v, ll t, ll f, const vector<ll>& dist) {
        if (v == t) return f;
        EACH(e, G[v]) {
            if (e.cap > 0 && dist[e.to] == dist[v]+1) {
                ll d = dfs(e.to, t, min(f, e.cap), dist);
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
public:
    const vector<vector<Edge>> Graph() {
        return G;
    }
    MaxFlow(ll V) : V(V), G(V) {}
    void init(ll n) {
        V = n;
        G.assign(V, vector<Edge>());
    }
    void add(ll from, ll to, ll cap) {
        assert(V > 0);
        G[from].pb({to, cap, (ll)G[to].size()});
        G[to].pb({from, 0, (ll)G[from].size()-1});
    }
    ll flow(ll s, ll t, ll f=linf) {
        ll res = 0;
        while (1) {
            vector<ll> dist = bfs(s);
            if (dist[t] == linf) break;
            while (1) {
                ll df = dfs(s, t, f, dist);
                if (df == 0) break;
                f -= df;
                res += df;
            }
        }
        return res;
    }
};
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    ll m, n;
    while (cin >> m >> n, m || n) {
        vector<ll> A(m), B(n); cin >> A >> B;
        ll s = m+n, t = s+1;
        MaxFlow mf(t+1);
        REP(i, m) REP(j, n) {
            if (gcd(A[i], B[j]) > 1) {
                mf.add(i, m+j, 1);
            }
        }
        REP(i, m) mf.add(s, i, 1);
        REP(i, n) mf.add(m+i, t, 1);
        cout << mf.flow(s, t) << endl;
    }
}

Measured memory_bytes: 11352