#include <bits/stdc++.h>
using namespace std;
class ufds {
 private:
  vector<int> parent;
  vector<int> size;
  int qty_disjoint_sets;

 public:
  ufds() {}
  ufds(int N) {
    parent.resize(N);
    size.assign(N, 1);
    qty_disjoint_sets = N;
    for (int n = 0; n < N; n++) parent[n] = n;
  }
  int find_set(int n) {
    if (parent[n] == n) return n;
    return parent[n] = find_set(parent[n]);
  }
  bool is_same_set(int n, int m) { return find_set(n) == find_set(m); }
  void union_sets(int n, int m) {
    int nId = find_set(n);
    int mId = find_set(m);
    if (!is_same_set(nId, mId)) {
      if (size[nId] > size[mId]) swap(nId, mId);
      parent[nId] = mId;
      size[mId] += size[nId];
      qty_disjoint_sets--;
    }
  }
  int set_size(int n) { return size[find_set(n)]; }
  int count() { return qty_disjoint_sets; }
};
class sparse_table {
 private:
  vector<int> A;
  int N;
  vector<vector<int>> table;
  int range_combination(int i, int j) { return A[i] < A[j] ? i : j; }
  void build() {
    int P = (int)floor(log2(N));
    table.assign(P + 1, vector<int>(N));
    for (int n = 0; n < N; n++) table[0][n] = n;
    for (int p = 1; p <= P; p++)
      for (int n = 0; n + (1 << (p)) <= N; n++) {
        table[p][n] = range_combination(table[p - 1][n],
                                        table[p - 1][n + (1 << (p - 1))]);
      }
  }

 public:
  sparse_table() {}
  sparse_table(vector<int> const &A) {
    this->A = A;
    N = (int)A.size();
    build();
  }
  int range_query(int l, int r) {
    int size = r - l + 1;
    int p = (int)floor(log2(size));
    return range_combination(table[p][l], table[p][r - (1 << (p)) + 1]);
  }
};
class lca {
 private:
  vector<vector<int>> adj_list;
  int V;
  int e;
  vector<int> tour_depth;
  vector<int> tour_vertex;
  vector<int> depth;
  vector<int> last_e;
  vector<bool> seen;
  sparse_table st;
  void process(int u, int u_depth) {
    tour_vertex[e] = u;
    tour_depth[e] = u_depth;
    last_e[u] = e++;
  }
  void dfs(int u, int u_depth = 0) {
    seen[u] = true;
    depth[u] = u_depth;
    process(u, u_depth);
    for (int v : this->adj_list[u])
      if (!seen[v]) {
        dfs(v, u_depth + 1);
        process(u, u_depth);
      }
  }
  void build(int root) {
    last_e.resize(V);
    depth.resize(V);
    e = 0;
    tour_depth.resize(2 * V - 1);
    tour_vertex.resize(2 * V - 1);
    seen.assign(V, false);
    dfs(root);
    st = sparse_table(vector<int>(tour_depth.begin(), tour_depth.end()));
  }

 public:
  lca() {}
  lca(vector<vector<int>> const &adj_list, int root = 0) {
    this->adj_list = adj_list;
    V = adj_list.size();
    build(root);
  }
  int query_lca(int u, int v) {
    int l = min(last_e[u], last_e[v]);
    int r = max(last_e[u], last_e[v]);
    return tour_vertex[st.range_query(l, r)];
  }
  int query_dist(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[query_lca(u, v)];
  }
};
vector<vector<int>> given_adj_list;
int V;
vector<vector<int>> new_adj_list;
ufds sets;
vector<pair<int, int>> bridges;
const int UNVISITED = -1;
vector<int> order;
vector<int> low;
vector<int> parent;
int count_order;
void dfs(int u) {
  low[u] = order[u] = count_order++;
  for (int v : given_adj_list[u]) {
    if (order[v] == UNVISITED) {
      parent[v] = u;
      dfs(v);
      low[u] = min(low[u], low[v]);
      if (order[u] < low[v])
        bridges.push_back(make_pair(u, v));
      else
        sets.union_sets(u, v);
    } else if (v != parent[u])
      low[u] = min(low[u], low[v]);
  }
}
int main() {
  int E;
  cin >> V >> E;
  given_adj_list.assign(V, vector<int>());
  for (int _ = 0; _ < E; _++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    given_adj_list[u].push_back(v);
    given_adj_list[v].push_back(u);
  }
  sets = ufds(V);
  count_order = 0;
  order.assign(V, -1);
  low.assign(V, -1);
  parent.assign(V, -1);
  dfs(0);
  int root = -1;
  new_adj_list.assign(V, vector<int>());
  for (auto bridge : bridges) {
    int u = sets.find_set(bridge.first);
    int v = sets.find_set(bridge.second);
    new_adj_list[u].push_back(v);
    new_adj_list[v].push_back(u);
    root = u;
  }
  lca l;
  if (root != -1) l = lca(new_adj_list, root);
  int Q;
  cin >> Q;
  while (Q--) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    if (root == -1)
      cout << "0" << endl;
    else
      cout << l.query_dist(sets.find_set(u), sets.find_set(v)) << endl;
  }
  return 0;
}
