#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define popcount __builtin_popcount using namespace std; typedef long long int ll; typedef pair P; using G=vector>; struct LowLink { const G &g; vector< int > used, ord, low; vector< int > articulation; vector< pair< int, int > > bridge; LowLink(const G &g) : g(g) {} int dfs(int idx, int k, int par) { used[idx] = true; ord[idx] = k++; low[idx] = ord[idx]; bool is_articulation = false; int cnt = 0; for(auto &to : g[idx]) { if(!used[to]) { ++cnt; k = dfs(to, k, idx); low[idx] = min(low[idx], low[to]); is_articulation |= ~par && low[to] >= ord[idx]; if(ord[idx] < low[to]) bridge.emplace_back(minmax(idx, (int) to)); } else if(to != par) { low[idx] = min(low[idx], ord[to]); } } is_articulation |= par == -1 && cnt > 1; if(is_articulation) articulation.push_back(idx); return k; } virtual void build() { used.assign(g.size(), 0); ord.assign(g.size(), 0); low.assign(g.size(), 0); int k = 0; for(int i = 0; i < g.size(); i++) { if(!used[i]) k = dfs(i, k, -1); } } }; template< typename G > struct BiConnectedComponents : LowLink { using LL = LowLink; vector< int > used; vector< vector< pair< int, int > > > bc; vector< pair< int, int > > tmp; BiConnectedComponents(const G &g) : LL(g) {} void dfs(int idx, int par) { used[idx] = true; for(auto &to : this->g[idx]) { if(to == par) continue; if(!used[to] || this->ord[to] < this->ord[idx]) { tmp.emplace_back(minmax(idx, to)); } if(!used[to]) { dfs(to, idx); if(this->low[to] >= this->ord[idx]) { bc.emplace_back(); for(;;) { auto e = tmp.back(); bc.back().emplace_back(e); tmp.pop_back(); if(e.first == min(idx, to) && e.second == max(idx, to)) { break; } } } } } } void build() override { LL::build(); used.assign(this->g.size(), 0); for(int i = 0; i < used.size(); i++) { if(!used[i]) dfs(i, -1); } } }; struct DoublingLowestCommonAncestor { const int LOG; vector< int > dep; const G &g; vector< vector< int > > table; DoublingLowestCommonAncestor(const G &g) : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) { table.assign(LOG, vector< int >(g.size(), -1)); } void dfs(int idx, int par, int d) { table[0][idx] = par; dep[idx] = d; for(auto &to : g[idx]) { if(to != par) dfs(to, idx, d + 1); } } void build() { dfs(0, -1, 0); for(int k = 0; k + 1 < LOG; k++) { for(int i = 0; i < table[k].size(); i++) { if(table[k][i] == -1) table[k + 1][i] = -1; else table[k + 1][i] = table[k][table[k][i]]; } } } int query(int u, int v) { if(dep[u] > dep[v]) swap(u, v); for(int i = LOG - 1; i >= 0; i--) { if(((dep[v] - dep[u]) >> i) & 1) v = table[i][v]; } if(u == v) return u; for(int i = LOG - 1; i >= 0; i--) { if(table[i][u] != table[i][v]) { u = table[i][u]; v = table[i][v]; } } return table[0][u]; } }; int main() { int n, m; cin>>n>>m; int u[50050], v[50050]; G g(n); for(int i=0; i>u[i]>>v[i]; u[i]--; v[i]--; g[u[i]].push_back(v[i]); g[v[i]].push_back(u[i]); } BiConnectedComponents bcc(g); bcc.build(); int b[50050]; fill(b, b+n, -1); int n1=0; for(int x:bcc.articulation){ b[x]=n1++; } n1=bcc.articulation.size()+bcc.bc.size(); vector> g1(n1); for(int i=0; ivoid{ for(auto y:g1[x]){ if(y!=p){ d[y]=d[x]; if(y>q; while(q--){ int x, y; cin>>x>>y; x--; y--; int x1=b[x], y1=b[y]; if(x1==y1){ printf("0\n"); continue; } int p1=lca.query(x1, y1); int ans=d[x1]+d[y1]-2*d[p1]; if(p1