#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 LCA{ vector> g; vector d; vector> p; int log; int n; LCA(const vector> &g):n(g.size()), g(g), d(g.size()){ log=0; while(1<(n)); } void dfs(int x, int prev){ for(auto y:g[x]){ if(y==prev) continue; d[y]=d[x]+1; p[0][y]=x; dfs(y, x); } } void build(){ dfs(0, -1); for(int i=1; id[b]) swap(a, b); int dd=d[b]-d[a], i=0; int a1=a, b1=b; while(dd){ if(dd&1) b1=p[i][b1]; dd>>=1; i++; } if(a1==b1) return a1; for(int j=log-1; j>=0; j--){ if(p[j][a1]!=p[j][b1]){ a1=p[j][a1], b1=p[j][b1]; } } return p[0][a1]; } int dist(int a, int b){ return d[a]+d[b]-2*d[lca(a, b)]; } }; 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.lca(x1, y1); int ans=d[x1]+d[y1]-2*d[p1]; if(p1