#include <bits/stdc++.h>
using namespace std;
const int N = 400010;
struct edge {
  int to, next;
  long long w;
} e[N * 2];
int head[N], ecnt;
inline void adde(int from, int to, long long w) {
  e[++ecnt] = (edge){to, head[from], w}, head[from] = ecnt;
}
int tot, vis[N];
long long dis[N];
inline void Dijkstra(int s) {
  for (int i = 1; i <= tot; i++) dis[i] = 2e18, vis[i] = 0;
  dis[s] = 0;
  priority_queue<pair<int, int> > q;
  q.push(pair<int, int>(0, s));
  while (!q.empty()) {
    int u = q.top().second;
    q.pop();
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[u]; i; i = e[i].next)
      if (dis[e[i].to] > dis[u] + e[i].w)
        dis[e[i].to] = dis[u] + e[i].w,
        q.push(pair<int, int>(-dis[e[i].to], e[i].to));
  }
}
int x, y;
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int exgcd(int a, int b) {
  if (!b) return x = 1, y = 0, a;
  int d = exgcd(b, a % b), t = x;
  x = y, y = t - a / b * y;
  return d;
}
inline long long solve(vector<pair<int, int> > A, int n, int m) {
  if (!A.size()) return 2e18;
  set<int> s;
  vector<pair<int, int> > p = A;
  for (auto t : A) s.insert(t.first);
  for (auto t : A) {
    int tp = ((t.first - m) % n + n) % n;
    if (!s.count(tp)) s.insert(tp), p.push_back(pair<int, int>(tp, 2));
  }
  sort(p.begin(), p.end()), exgcd(m, n), ecnt = 0;
  int st = p.size() + 1, all = p.size();
  for (int i = 1; i <= st; i++) head[i] = 0;
  for (int i = 1; i <= all; i++)
    if (p[i - 1].second <= 1) adde(st, i, p[i - 1].first);
  static int id[N], tmp[N];
  for (int i = 1; i <= all; id[i] = i, i++) {
    int tx = (long long)x * (p[i - 1].first - p[0].first) % n;
    if (tx < 0) tx += n;
    tmp[i] = tx;
  }
  sort(id + 1, id + all + 1, [](int a, int b) { return tmp[a] < tmp[b]; });
  for (int i = 1; i <= all; i++) {
    int t = tmp[id[i < all ? i + 1 : 1]] - tmp[id[i]];
    if (t < 0) t += n;
    adde(id[i], id[i < all ? i + 1 : 1], (long long)t * m);
  }
  ::tot = st, Dijkstra(st);
  long long res = -1;
  for (int i = 1; i <= all; i++)
    if (p[i - 1].second == 0 || p[i - 1].second == 2) res = max(res, dis[i]);
  return res;
}
inline long long solve(vector<int> A, vector<int> B, int n, int m) {
  set<int> s;
  vector<pair<int, int> > L, R;
  for (auto t : A) L.push_back(pair<int, int>(t, 1)), s.insert(t);
  for (auto t : B)
    if (!s.count(t % n)) s.insert(t % n), L.push_back(pair<int, int>(t % n, 0));
  s.clear();
  for (auto t : B) R.push_back(pair<int, int>(t, 1)), s.insert(t);
  for (auto t : A)
    if (!s.count(t % m)) s.insert(t % m), R.push_back(pair<int, int>(t % m, 0));
  return max(solve(L, n, m), solve(R, m, n));
}
vector<int> zjk[N], wkr[N];
int main() {
  int n, m, t1, t2;
  scanf("%d%d", &n, &m);
  vector<int> A, B;
  scanf("%d", &t1);
  for (int i = 1, a; i <= t1; i++) scanf("%d", &a), A.push_back(a);
  scanf("%d", &t2);
  for (int i = 1, a; i <= t2; i++) scanf("%d", &a), B.push_back(a);
  int g = gcd(n, m);
  if (g > t1 + t2) return puts("-1"), 0;
  for (auto t : A) zjk[t % g].push_back(t / g);
  for (auto t : B) wkr[t % g].push_back(t / g);
  long long res = 0;
  for (int i = 0; i < g; i++) {
    long long tmp = solve(zjk[i], wkr[i], n / g, m / g);
    if (tmp < 0) continue;
    if (tmp > 1e18) return puts("-1"), 0;
    res = max(res, tmp * g + i);
  }
  printf("%lld\n", res);
}
