#include <bits/stdc++.h>
using namespace std;
const int maxn = 100022;
struct iedge {
  int x, y;
  int value;
  int id;
};
struct inex {
  int nodeid;
  int edgeid;
  int value;
};
int n, m, k;
iedge edge[maxn];
int far[maxn];
vector<inex> nex[maxn];
int totedge;
int tmpx, tmpy, curx, cury, tmpedgeid, tmpnodeid, curedgeid, curnodeid;
iedge curedge, tmpedge;
inex curnex, tmpnex;
void addedge(int tmpx, int tmpy) {
  ++totedge;
  tmpedge.x = tmpx;
  tmpedge.y = tmpy;
  tmpedge.value = 1;
  tmpedge.id = totedge;
  edge[totedge] = tmpedge;
  tmpnex.edgeid = totedge;
  tmpnex.nodeid = tmpx;
  nex[tmpy].push_back(tmpnex);
  tmpnex.nodeid = tmpy;
  nex[tmpx].push_back(tmpnex);
}
set<int> nodeset;
vector<inex> nexque;
bool used[maxn];
bool inque[maxn];
void dfs(int x) {
  for (int i = 0; i < nex[x].size(); ++i) {
    tmpnex = nex[x][i];
    tmpedgeid = tmpnex.edgeid;
    int tmpnodeid = tmpnex.nodeid;
    if (!used[tmpedgeid]) {
      used[tmpedgeid] = true;
      if (!inque[tmpnodeid]) {
        inque[tmpnodeid] = true;
        nexque.push_back(tmpnex);
        dfs(tmpnodeid);
        nexque.pop_back();
        inque[tmpnodeid] = false;
      } else {
        edge[tmpedgeid].value = 0;
        int j = nexque.size() - 1;
        while (j >= 0 && nexque[j].nodeid != tmpnodeid) {
          curnex = nexque[j];
          curedgeid = curnex.edgeid;
          curnodeid = curnex.nodeid;
          edge[curedgeid].value = 0;
          --j;
        }
      }
      used[tmpedgeid] = false;
    }
  }
}
bool cmp(iedge tmpx, iedge tmpy) { return tmpx.value > tmpy.value; }
iedge myway[maxn];
int totmyway;
int gf(int x) {
  while (x != far[x]) x = far[x];
  return x;
}
void kruskal() {
  totmyway;
  for (int i = 1; i <= totedge; ++i) {
    tmpx = edge[i].x;
    tmpy = edge[i].y;
    if (gf(tmpx) != gf(tmpy)) {
      far[gf(tmpx)] = gf(tmpy);
      ++totmyway;
      myway[totmyway] = edge[i];
    }
  }
}
vector<inex> nexway[maxn];
int dis[maxn];
int myfar[maxn];
list<int> que;
void mf() {
  for (int i = 1; i <= n; ++i) {
    nexway[i].clear();
    myfar[i] = i;
  }
  for (int i = 1; i <= totmyway; ++i) {
    tmpedge = myway[i];
    tmpx = tmpedge.x;
    tmpy = tmpedge.y;
    tmpnex.edgeid = tmpedge.id;
    tmpnex.value = tmpedge.value;
    tmpnex.nodeid = tmpx;
    nexway[tmpy].push_back(tmpnex);
    tmpnex.nodeid = tmpy;
    nexway[tmpx].push_back(tmpnex);
  }
  for (int i = 1; i <= n; ++i) dis[i] = -1;
  que.clear();
  que.push_back(1);
  dis[1] = 0;
  while (!que.empty()) {
    curx = que.front();
    que.pop_front();
    for (int i = 0; i < nexway[curx].size(); ++i) {
      curnex = nexway[curx][i];
      tmpx = curnex.nodeid;
      tmpy = curnex.value;
      if (dis[tmpx] == -1) {
        dis[tmpx] = dis[curx] + tmpy;
        que.push_back(tmpx);
        myfar[tmpx] = curx;
      }
    }
  }
}
set<int> haha;
int lca(int tmpx, int tmpy) {
  haha.clear();
  while (tmpx != myfar[tmpx]) {
    haha.insert(tmpx);
    tmpx = myfar[tmpx];
  }
  while (tmpy != myfar[tmpy] && haha.find(tmpy) == haha.end())
    tmpy = myfar[tmpy];
  return tmpy;
}
int main() {
  scanf("%d%d", &n, &m);
  totedge = 0;
  for (int i = 1; i <= n; ++i) nex[i].clear();
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &tmpx, &tmpy);
    addedge(tmpx, tmpy);
  }
  nodeset.clear();
  nodeset.insert(1);
  nexque.clear();
  tmpnex.edgeid = 0;
  tmpnex.nodeid = 1;
  nexque.push_back(tmpnex);
  memset(used, false, sizeof(used));
  memset(inque, false, sizeof(inque));
  inque[1] = true;
  dfs(1);
  for (int i = 1; i <= n; ++i) far[i] = i;
  sort(edge + 1, edge + 1 + n, cmp);
  kruskal();
  mf();
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; ++i) {
    scanf("%d%d", &tmpx, &tmpy);
    printf("%d\n", dis[tmpx] + dis[tmpy] - 2 * dis[lca(tmpx, tmpy)]);
  }
  return 0;
}
