#include #define rep(i,n) for(int i=0;i initialized; vector E; vector> G; map> dist; BFS01(int _n) : n(_n), m(0), initialized(n, false), G(n){} void add_edge(int from, int to, int cost){ assert(cost == 0 or cost == 1); Edge_BFS01 e(from, to, cost); E.push_back(e); G[from].emplace_back(m); m++; } void calc(int s){ initialized[s] = true; dist[s] = vector(n, INF); deque> de; de.emplace_back(0, s, -1); while(de.size()){ auto [cost, from, index] = de.front(); de.pop_front(); if(dist[s][from] <= cost) continue; dist[s][from] = cost; for(int index : G[from]){ int to = E[index].to; int cost_plus = E[index].cost; if(dist[s][to] <= cost + cost_plus) continue; if(cost_plus == 0) de.emplace_front(cost + cost_plus, to, index); if(cost_plus == 1) de.emplace_back(cost + cost_plus, to, index); } } } int get_dist(int s, int t){ if(!initialized[s]) calc(s); return dist[s][t]; } }; const int D = 1000; int main(){ auto convert = [&](int x, int y){ return D * x + y; }; BFS01 graph(D * D + 2); int sv = D * D; int tv = D * D + 1; int n; cin >> n; rep(i, n){ int x, y; cin >> x >> y; graph.add_edge(sv, convert(x, y), 0); } int m; cin >> m; rep(i, m){ int x, y; cin >> x >> y; graph.add_edge(convert(x, y), tv, 0); } rep(x, D) rep(y, D - 1){ graph.add_edge(convert(x, y), convert(x, y + 1), 1); graph.add_edge(convert(x, y + 1), convert(x, y), 1); } rep(y, D) rep(x, D - 1){ graph.add_edge(convert(x, y), convert(x + 1, y), 1); graph.add_edge(convert(x + 1, y), convert(x, y), 1); } int ans = graph.get_dist(sv, tv); cout << ans << "\n"; return 0; }