#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > g;
int d[100024], low[100024], bcc[100024], h[100024], comp[100024 * 2], cont_d;
void _dfs(int no, int p) {
  bcc[no] = low[no] = d[no] = cont_d++;
  for (int i = 0; i < (int)g[no].size(); i++)
    if (p != g[no][i]) {
      if (d[g[no][i]] == 0) {
        h[no]++;
        comp[bcc[no] = cont_d++] = no;
        _dfs(g[no][i], no);
        low[no] = min(low[no], low[g[no][i]]);
      } else
        low[no] = min(low[no], bcc[g[no][i]]);
    }
}
void _dfs2(int no, int p) {
  bcc[no] = -1;
  if (d[p] > low[no]) low[no] = low[p];
  for (int i = 0; i < (int)g[no].size(); i++)
    if (bcc[g[no][i]] > 0) _dfs2(g[no][i], no);
}
void init() {
  cont_d = 1;
  for (int i = 0; i < (int)g.size() * 2; i++) comp[i] = -1;
  for (int i = 0; i < (int)g.size(); i++) d[i] = h[i] = 0;
  for (int i = 0; i < (int)g.size(); i++)
    if (d[i] == 0) _dfs(i, -1);
  for (int i = 0; i < (int)g.size(); i++)
    if (bcc[i] > 0) _dfs2(i, i);
}
map<int, int> mapeo;
vector<vector<int> > vec;
void compoentesBiConexas() {
  vec.clear();
  int cont = 1;
  mapeo.clear();
  for (int i = 0; i < (int)g.size(); i++) {
    if (low[i] >= d[i]) continue;
    if (mapeo[low[i]] == 0) {
      mapeo[low[i]] = cont++;
      vec.push_back(vector<int>(1, comp[low[i]]));
    }
    vec[mapeo[low[i]] - 1].push_back(i);
  }
  return;
}
vector<vector<int> > lista, lista2;
vector<int> enQueBico;
int vec5[20][1 << (20 + 1)];
int mn(int i, int j) {
  int p = 31 - __builtin_clz(j - i);
  return min(vec5[p][i], vec5[p][j - (1 << p)]);
}
void mn_init(int n) {
  int mp = 31 - __builtin_clz(n);
  for (int p = 0; p < (int)mp; p++)
    for (int x = 0; x < (int)n - (1 << p); x++)
      vec5[p + 1][x] = min(vec5[p][x], vec5[p][x + (1 << p)]);
}
vector<vector<int> > hijos;
vector<int> distALaRoot;
int p[1 << (20 + 1)];
int n2n[1 << (20 + 1)];
int cont_nodos, ulti_pos;
void dfs(int nodo, int padre) {
  int val = cont_nodos++;
  p[nodo] = ulti_pos;
  n2n[val] = nodo;
  vec5[0][ulti_pos++] = val;
  for (int i = 0; i < (int)hijos[nodo].size(); i++)
    if (hijos[nodo][i] != padre) {
      dfs(hijos[nodo][i], nodo);
      vec5[0][ulti_pos++] = val;
    }
}
void lca_init(int root) {
  cont_nodos = 0;
  ulti_pos = 0;
  dfs(root, -1);
  mn_init(ulti_pos);
}
int lca(int i, int j) { return n2n[mn(min(p[i], p[j]), max(p[i], p[j]) + 1)]; }
int padresUF[200010];
void initUF(int n) {
  for (int i = 0; i < (int)n; i++) padresUF[i] = i;
}
int find(int a) {
  if (padresUF[a] != a) padresUF[a] = find(padresUF[a]);
  return padresUF[a];
}
void join(int a, int b) { padresUF[find(a)] = find(b); }
void dfs2() {
  int t = 0;
  int n2 = lista.size();
  distALaRoot.clear();
  distALaRoot.resize(n2, -1);
  hijos.resize(n2);
  vector<bool> toc(n2, false);
  toc[0] = true;
  queue<int> cola;
  cola.push(0);
  distALaRoot[0] = 0;
  while (!cola.empty()) {
    t = cola.front();
    cola.pop();
    for (int i = 0; i < (int)lista[t].size(); i++)
      if (toc[lista[t][i]] == false) {
        toc[lista[t][i]] = true;
        cola.push(lista[t][i]);
        hijos[t].push_back(lista[t][i]);
        distALaRoot[lista[t][i]] = distALaRoot[t] + 1;
      }
  }
  return;
}
vector<int> aux;
map<int, int> mapeo2, yata;
vector<int> bicoesta;
int main() {
  int n, m, a, b;
  cin >> n >> m;
  g.clear();
  g.resize(n);
  for (int i = 0; i < (int)n; i++) g[i].clear();
  for (int i = 0; i < (int)m; i++) {
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  init();
  compoentesBiConexas();
  enQueBico.resize(n);
  for (int i = 0; i < (int)n; i++) enQueBico[i] = -1;
  initUF(n * 2);
  for (int i = 0; i < (int)vec.size(); i++) {
    for (int j = 0; j < (int)vec[i].size(); j++) {
      if (enQueBico[vec[i][j]] == -1)
        enQueBico[vec[i][j]] = i;
      else {
        a = min(find(i), find(enQueBico[vec[i][j]]));
        b = max(find(i), find(enQueBico[vec[i][j]]));
        join(b, a);
        enQueBico[vec[i][j]] = i;
      }
    }
  }
  for (int i = 0; i < (int)n; i++)
    if (enQueBico[i] != -1) enQueBico[i] = find(enQueBico[i]);
  for (int i = 0; i < (int)n; i++)
    if (enQueBico[i] == -1) {
      vector<int> vec2(1, i);
      vec.push_back(vec2);
      enQueBico[i] = vec.size() - 1;
    }
  bicoesta.clear();
  bicoesta.resize(n, -2);
  for (int i = 0; i < (int)n; i++) bicoesta[enQueBico[i]] = -1;
  int rrr = 0;
  for (int i = 0; i < (int)n; i++) {
    if (bicoesta[i] == -1) {
      bicoesta[i] = rrr;
      rrr++;
    }
  }
  for (int i = 0; i < (int)n; i++) enQueBico[i] = bicoesta[enQueBico[i]];
  int n2 = vec.size();
  lista2.resize(n2);
  for (int i = 0; i < (int)n2; i++) lista2[i].clear();
  for (int i = 0; i < (int)n; i++)
    for (int j = 0; j < (int)g[i].size(); j++)
      if (enQueBico[i] != enQueBico[g[i][j]]) {
        lista2[enQueBico[i]].push_back(enQueBico[g[i][j]]);
      }
  lista.clear();
  mapeo2.clear();
  yata.clear();
  int rr = 0;
  for (int i = 0; i < (int)n2; i++) {
    if (!lista2[i].empty()) {
      mapeo2[i] = rr;
      yata[i] = i + 1;
      rr++;
    }
  }
  for (int i = 0; i < (int)n2; i++)
    if (yata[i] == i + 1) {
      aux.clear();
      for (int j = 0; j < (int)lista2[i].size(); j++) {
        aux.push_back(lista2[i][j]);
      }
      lista.push_back(aux);
    }
  dfs2();
  lca_init(0);
  int k;
  cin >> k;
  for (int i = 0; i < (int)k; i++) {
    cin >> a >> b;
    a--;
    b--;
    a = enQueBico[a];
    b = enQueBico[b];
    cout << distALaRoot[a] + distALaRoot[b] - distALaRoot[lca(a, b)] * 2
         << endl;
  }
  return 0;
}
