#include <bits/stdc++.h>
using namespace std;
struct Edge {
  long long to, num;
  bool is_bridge;
  Edge* back;
  Edge() {}
  Edge(long long to, long long num) : to(to), num(num), is_bridge(false) {}
};
long long n, m;
vector<vector<Edge*>> gr;
vector<long long> comp, d, dp, euler;
vector<bool> used;
vector<vector<long long>> cgr;
vector<long long> dpth, firstpos;
void dfs1(long long v, Edge* p = nullptr) {
  used[v] = true;
  if (p) d[v] = d[p->back->to] + 1;
  dp[v] = d[v];
  dp[v] = d[v];
  for (auto& e : gr[v]) {
    if (!used[e->to]) {
      dfs1(e->to, e);
      dp[v] = min(dp[v], dp[e->to]);
    } else if (p && e != p->back) {
      dp[v] = min(dp[v], d[e->to]);
    }
  }
  if (p && dp[v] == d[v]) {
    p->is_bridge = p->back->is_bridge = true;
  }
}
void dfsBiconnect(long long v, long long cur_comp) {
  used[v] = true;
  comp[v] = cur_comp;
  for (auto& e : gr[v]) {
    if (e->is_bridge) {
      if (used[e->to]) {
        cgr[cur_comp].push_back(comp[e->to]);
        cgr[comp[e->to]].push_back(cur_comp);
      }
    } else if (!used[e->to]) {
      dfsBiconnect(e->to, cur_comp);
    }
  }
}
void eulerdfs(long long v, long long p = -1) {
  if (p != -1) {
    dpth[v] = dpth[p] + 1;
  }
  firstpos[v] = euler.size();
  euler.push_back(v);
  for (auto u : cgr[v]) {
    if (u != p) {
      eulerdfs(u, v);
      euler.push_back(v);
    }
  }
}
vector<long long> logs;
vector<vector<long long>> sparse;
inline long long MIN(long long u, long long v) {
  return dpth[u] < dpth[v] ? u : v;
}
long long ask(long long l, long long r) {
  long long level = logs[r - l + 1];
  return MIN(sparse[level][l], sparse[level][r - (1 << level) + 1]);
}
long long lca(long long u, long long v) {
  u = firstpos[u];
  v = firstpos[v];
  if (u > v) swap(u, v);
  return ask(u, v);
}
void solve() {
  cin >> n >> m;
  d.resize(n);
  dp.resize(n);
  comp.resize(n);
  used.resize(n);
  gr.resize(n);
  for (long long i = 0; i < m; i++) {
    long long u, v;
    cin >> u >> v;
    u--;
    v--;
    Edge* a = new Edge(u, i);
    Edge* b = new Edge(v, i);
    a->back = b;
    b->back = a;
    gr[v].push_back(a);
    gr[u].push_back(b);
  }
  dfs1(0);
  long long cur_comp = 0;
  fill(used.begin(), used.end(), false);
  for (long long i = 0; i < n; i++) {
    if (!used[i]) {
      cgr.push_back({});
      dfsBiconnect(i, cur_comp);
      cur_comp++;
    }
  }
  dpth.resize(cur_comp);
  firstpos.resize(cur_comp);
  eulerdfs(0);
  long long l = euler.size();
  logs.resize(l + 1);
  for (long long i = 2; i <= l; i++) {
    logs[i] = logs[i / 2] + 1;
  }
  sparse.resize(logs[l] + 1, vector<long long>(l));
  for (long long i = 0; i < l; i++) {
    sparse[0][i] = euler[i];
  }
  for (long long level = 1; (1 << level) <= l; level++) {
    for (long long i = 0; i + (1 << level) <= l; i++) {
      sparse[level][i] =
          MIN(sparse[level - 1][i], sparse[level - 1][i + (1 << (level - 1))]);
    }
  }
  long long m;
  cin >> m;
  while (m--) {
    long long u, v;
    cin >> u >> v;
    u--;
    v--;
    u = comp[u];
    v = comp[v];
    long long lc = lca(u, v);
    cout << dpth[u] - dpth[lc] + dpth[v] - dpth[lc] << "\n";
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cout << fixed;
  cout.precision(30);
  long long t = 1;
  while (t--) solve();
}
