1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 typedef long long LL; 8 9 typedef pair<int, int> PII; 10 11 const int MAXV = 10010; 12 const int MAXE = 200010; 13 14 int ans[MAXV]; 15 vector<PII> query[MAXV << 1]; 16 17 struct SccGraph { 18 int head[MAXV << 1], fa[MAXV << 1], ecnt; 19 bool vis[MAXV << 1]; 20 int to[MAXE << 1], next[MAXE << 1]; 21 int dep[MAXV << 1]; 22 23 void init(int n) { 24 memset(head, -1, sizeof(int) * (n + 1)); 25 memset(vis, 0, sizeof(bool) * (n + 1)); 26 for(int i = 1; i <= n; ++i) fa[i] = i; 27 ecnt = 0; 28 } 29 30 int find_set(int x) { 31 return fa[x] == x ? x : fa[x] = find_set(fa[x]); 32 } 33 34 void add_edge(int u, int v) { 35 to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++; 36 to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++; 37 } 38 39 void lca(int u, int f, int deep) { 40 dep[u] = deep; 41 for(int p = head[u]; ~p; p = next[p]) { 42 int &v = to[p]; 43 if(v == f || vis[v]) continue; 44 lca(v, u, deep + 1); 45 fa[v] = u; 46 } 47 vis[u] = true; 48 for(vector<PII>::iterator it = query[u].begin(); it != query[u].end(); ++it) { 49 if(vis[it->first]) { 50 ans[it->second] = (dep[u] + dep[it->first] - 2 * dep[find_set(it->first)]) / 2; 51 } 52 } 53 } 54 } G; 55 56 int head[MAXV], lowlink[MAXV], pre[MAXV], ecnt, dfs_clock; 57 int sccno[MAXV], scc_cnt; 58 int to[MAXE], next[MAXE], scc_edge[MAXE]; 59 bool vis[MAXE], iscut[MAXV]; 60 int stk[MAXE], top; 61 int n, m, q; 62 63 void init() { 64 memset(head, -1, sizeof(int) * (n + 1)); 65 memset(pre, 0, sizeof(int) * (n + 1)); 66 memset(iscut, 0, sizeof(bool) * (n + 1)); 67 memset(vis, 0, sizeof(bool) * (2 * m)); 68 ecnt = scc_cnt = dfs_clock = 0; 69 } 70 71 void add_edge(int u, int v) { 72 to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++; 73 to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++; 74 } 75 76 void tarjan(int u, int f) { 77 pre[u] = lowlink[u] = ++dfs_clock; 78 int child = 0; 79 for(int p = head[u]; ~p; p = next[p]) { 80 if(vis[p]) continue; 81 vis[p] = vis[p ^ 1] = true; 82 stk[++top] = p; 83 int &v = to[p]; 84 if(!pre[v]) { 85 ++child; 86 tarjan(v, u); 87 lowlink[u] = min(lowlink[u], lowlink[v]);\ 88 if(pre[u] <= lowlink[v]) { 89 iscut[u] = true; 90 ++scc_cnt; 91 while(true) { 92 int t = stk[top--]; 93 scc_edge[t] = scc_edge[t ^ 1] = scc_cnt; 94 if(t == p) break; 95 } 96 } 97 } else lowlink[u] = min(lowlink[u], pre[v]); 98 } 99 if(f < 1 && child == 1) iscut[u] = false; 100 } 101 102 void build() { 103 G.init(scc_cnt); 104 for(int p = 0; p != ecnt; ++p) { 105 int &v = to[p]; 106 if(iscut[v]) G.add_edge(sccno[v], scc_edge[p]); 107 } 108 } 109 110 void solve() { 111 for(int i = 1; i <= n; ++i) 112 if(!pre[i]) tarjan(i, 0); 113 for(int u = 1; u <= n; ++u) 114 if(iscut[u]) sccno[u] = ++scc_cnt; 115 } 116 117 int main() { 118 while(scanf("%d%d", &n, &m) != EOF) { 119 if(n == 0 && m == 0) break; 120 init(); 121 for(int i = 1; i <= m; ++i) { 122 int u, v; 123 scanf("%d%d", &u, &v); 124 add_edge(u, v); 125 } 126 solve(); 127 build(); 128 for(int i = 0; i <= scc_cnt; ++i) query[i].clear(); 129 scanf("%d", &q); 130 for(int i = 0; i < q; ++i) { 131 int x, y; 132 scanf("%d%d", &x, &y); 133 x = scc_edge[x * 2 - 2]; y = scc_edge[y * 2 - 2]; 134 query[x].push_back(make_pair(y, i)); 135 query[y].push_back(make_pair(x, i)); 136 } 137 for(int i = 1; i <= scc_cnt; ++i) if(!G.vis[i]) G.lca(i, 0, 0); 138 for(int i = 0; i < q; ++i) printf("%d\n", ans[i]); 139 } 140 }