func_code_string: #include <bits/stdc++.h>   using namespace std;   int getint() {     unsigned int c;     int x = 0;     while (((c = getchar()) -  0 ) >= 10) {       if (c ==  - ) return -getint();       if (!~c) exit(0);     }     do {       x = (x << 3) + (x << 1) + (c -  0 );     } while (((c = getchar()) -  0 ) < 10);     return x;   }   const int N = 100111;   struct Bridge {     struct edge {       int to, rv;       edge() {}       edge(int to, int rv) : to(to), rv(rv) {}     };     int nv, cnt;     vector<edge> graph[N];     int dis[N], low[N], par[N];     void init(int v = N) {       nv = v;       for (v = 0; v < nv; v++) graph[v].clear();     }     void add_edge(int u, int v) {       if (u == v) return;       int tu = graph[u].size(), tv = graph[v].size();       graph[u].push_back(edge(v, tv)), graph[v].push_back(edge(u, tu));     }     void proc() {       cnt = 0;       fill(dis, dis + nv, ~0);       for (int u = 0; u < nv; u++)         if (!~dis[u]) dfs(u, -1, -1);     }     void dfs(int u, int p, int pe) {       dis[u] = low[u] = cnt++, par[u] = p;       for (int i = 0; i < graph[u].size(); i++) {         int v = graph[u][i].to;         if (i == pe) continue;         if (~dis[v]) {           low[u] = min(low[u], dis[v]);         } else {           dfs(v, u, graph[u][i].rv);           low[u] = min(low[u], low[v]);         }       }     }     bool is_bridge(int u, int v) {       if (dis[u] > dis[v]) swap(u, v);       return (u == par[v] and dis[v] <= low[v]);     }   };   struct UnionFind {     vector<int> par;     void init(int n) { par.assign(n, ~0); }     int root(int x) { return par[x] < 0 ? x : par[x] = root(par[x]); }     bool connect(int x, int y) {       x = root(x), y = root(y);       if (x == y) return 0;       if (par[y] < par[x]) swap(x, y);       par[x] += par[y], par[y] = x;       return 1;     }     bool same(int x, int y) { return root(x) == root(y); }     int size(int x) { return -par[root(x)]; }   };   int n, m, k;   int us[N], vs[N];   int as[N], bs[N];   Bridge brg;   UnionFind uf;   struct LowestCommonAncestor {     static const int LOGV = 20;     static const int V = 100111;     vector<int> graph[V];     int par[LOGV][V], dep[V], nv;     void init(int v) {       nv = v, memset(par, ~0, sizeof(par));       for (v = 0; v < nv; v++) graph[v].clear();     }     void add_edge(int u, int v) {       graph[u].push_back(v);       graph[v].push_back(u);     }     void dfs(int u, int p, int d) {       par[0][u] = p, dep[u] = d;       for (int i = 0; i < graph[u].size(); i++)         if (p != graph[u][i]) dfs(graph[u][i], u, d + 1);     }     void prepare(int root) {       dfs(root, ~0, 0);       for (int k = 0; k + 1 < LOGV; k++)         for (int v = 0; v < nv; v++) {           if (!~par[k][v])             par[k + 1][v] = ~0;           else             par[k + 1][v] = par[k][par[k][v]];         }     }     int get(int u, int v) {       if (dep[u] > dep[v]) swap(u, v);       for (int k = 0; k < LOGV; k++)         if (dep[v] - dep[u] >> k & 1) v = par[k][v];       if (u == v) return u;       for (int k = LOGV - 1; ~k; --k)         if (par[k][u] != par[k][v]) u = par[k][u], v = par[k][v];       return par[0][u];     }   };   LowestCommonAncestor lca;   int name[N];   int main() {     int i, j, tcc, tc = 1 << 28;     for (tcc = 0; tcc < tc; tcc++) {       n = getint(), m = getint();       brg.init(n);       for (i = 0; i < m; i++) {         us[i] = getint() - 1;         vs[i] = getint() - 1;         brg.add_edge(us[i], vs[i]);       }       brg.proc();       k = getint();       for (i = 0; i < k; i++) {         as[i] = getint() - 1;         bs[i] = getint() - 1;       }       uf.init(n);       for (i = 0; i < m; i++)         if (!brg.is_bridge(us[i], vs[i])) {           uf.connect(us[i], vs[i]);         }       int M = 0;       for (i = 0; i < n; i++)         if (uf.root(i) == i) {           name[i] = M++;         }       lca.init(M);       for (i = 0; i < m; i++)         if (brg.is_bridge(us[i], vs[i])) {           int uu = name[uf.root(us[i])];           int vv = name[uf.root(vs[i])];           lca.add_edge(uu, vv);         }       lca.prepare(0);       for (i = 0; i < k; i++) {         int uu = name[uf.root(as[i])];         int vv = name[uf.root(bs[i])];         int a = lca.dep[uu];         int b = lca.dep[vv];         int c = lca.dep[lca.get(uu, vv)];         printf( %d n , a + b - 2 * c);       }     }     return 0;   }   