#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool Up(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool Down(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
inline int getus() {
  int tmp, c;
  while (tmp = fgetc(stdin), tmp < '0' || tmp > '9')
    ;
  tmp -= '0';
  while (c = fgetc(stdin), '0' <= c && c <= '9') tmp = tmp * 10 + c - '0';
  return tmp;
}
inline int getint() {
  int tmp, c, flag;
  while (flag = fgetc(stdin), flag != '-' && (flag < '0' || flag > '9'))
    ;
  if (flag == '-')
    tmp = 0;
  else
    tmp = flag - '0';
  while (c = fgetc(stdin), '0' <= c && c <= '9') tmp = tmp * 10 + c - '0';
  return flag == '-' ? -tmp : tmp;
}
int N, M, bel[100022], dep[100022];
int Ncnt = 0;
vector<int> fir1[100022], fir2[100022];
namespace BCC {
int low[100022], dfn[100022], Tcnt = 0;
int lable[100022];
set<pair<int, int> > bridge;
void Tarjan(int x, int fa) {
  low[x] = dfn[x] = ++Tcnt;
  int y;
  bool flag = false;
  for (__typeof(fir1[x].begin()) i = fir1[x].begin(); i != fir1[x].end(); ++i)
    if (*i == fa && !flag)
      flag = true;
    else {
      if (!dfn[y = *i]) {
        Tarjan(y, x);
        Down(low[x], low[y]);
        if (low[y] == dfn[y])
          bridge.insert(pair<int, int>(min(x, y), max(x, y)));
      } else
        Down(low[x], dfn[y]);
    }
}
void BFS(int S) {
  int x, y;
  queue<int> q;
  for (q.push(S), bel[S] = ++Ncnt; !q.empty();) {
    x = q.front();
    q.pop();
    for (__typeof(fir1[x].begin()) e = fir1[x].begin(); e != fir1[x].end();
         ++e) {
      int y = *e;
      if (bel[y]) continue;
      if (bridge.count(pair<int, int>(min(x, y), max(x, y)))) continue;
      q.push(y);
      bel[y] = Ncnt;
    }
  }
}
void Main() {
  memset(dfn, 0, sizeof(dfn));
  memset(bel, 0, sizeof(bel));
  for (int i = (1); i <= (N); ++i)
    if (!dfn[i]) {
      Tarjan(i, -1);
    }
  for (int i = (1); i <= (N); ++i)
    if (!bel[i]) BFS(i);
  for (int x = (1); x <= (N); ++x)
    for (__typeof(fir1[x].begin()) e = fir1[x].begin(); e != fir1[x].end();
         ++e) {
      int la = bel[x];
      int lb = bel[*e];
      if (la != lb) fir2[la].push_back(lb);
    }
}
}  // namespace BCC
namespace LCA {
int sz[100022], fa[100022];
int Q[100022], Own[100022], weight[100022];
void Prepare() {
  int x, y, a, next, h = 0, t = 0, cnt;
  for (fa[1] = -1, dep[1] = 0, Q[++t] = 1; h < t;) {
    x = Q[++h];
    for (__typeof(fir2[x].begin()) e = fir2[x].begin(); e != fir2[x].end(); ++e)
      if ((y = *e) != fa[x]) {
        dep[y] = dep[x] + 1;
        fa[y] = x;
        Q[++t] = y;
      }
  }
  for (int i = (N); i >= (1); --i) {
    int &res = sz[x = Q[i]] = 1;
    for (__typeof(fir2[x].begin()) e = fir2[x].begin(); e != fir2[x].end(); ++e)
      if ((y = *e) != fa[x]) res += sz[y];
  }
  memset(Own, -1, sizeof(Own));
  for (int i = (1); i <= (N); ++i)
    if (Own[x = Q[i]] == -1)
      for (a = x, cnt = 0;; x = next) {
        next = -1;
        Own[x] = a;
        for (__typeof(fir2[x].begin()) e = fir2[x].begin(); e != fir2[x].end();
             ++e)
          if ((y = *e) != fa[x])
            if (next == -1 || sz[y] > sz[next]) next = y;
        if (next == -1) break;
      }
}
int Query(int x, int y) {
  for (;;) {
    if (dep[x] < dep[y]) swap(x, y);
    if (Own[x] == Own[y]) return y;
    if (dep[Own[x]] < dep[Own[y]]) swap(x, y);
    x = fa[Own[x]];
  }
  return x;
}
}  // namespace LCA
void Work() {
  BCC::Main();
  LCA::Prepare();
  int K = getint();
  while (K--) {
    int a = bel[getus()], b = bel[getus()];
    int fa = LCA::Query(a, b);
    printf("%d\n", dep[a] + dep[b] - 2 * dep[fa]);
  }
}
void Init() {
  int a, b;
  N = getus();
  M = getus();
  for (int i = (1); i <= (M); ++i) {
    a = getus();
    b = getus();
    fir1[a].push_back(b);
    fir1[b].push_back(a);
  }
}
int main() {
  Init();
  Work();
  return 0;
}
