#include <bits/stdc++.h>
using namespace std;
const int inf = 1 << 28;
const double INF = 1e12, EPS = 1e-9;
struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight = 0) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge& e, const Edge& f) {
  return e.weight != f.weight ? e.weight > f.weight
         : e.src != f.src     ? e.src < f.src
                              : e.dst < f.dst;
}
void visit(const vector<vector<Edge> >& g, int v, int u, vector<Edge>& brdg,
           vector<vector<int> >& tecomp, stack<int>& roots, stack<int>& S,
           vector<bool>& inS, vector<int>& num, int& time) {
  num[v] = ++time;
  S.push(v);
  inS[v] = true;
  roots.push(v);
  for (__typeof((g[v]).begin()) e = (g[v]).begin(); e != (g[v]).end(); e++) {
    int w = e->dst;
    if (num[w] == 0)
      visit(g, w, v, brdg, tecomp, roots, S, inS, num, time);
    else if (u != w && inS[w])
      while (num[roots.top()] > num[w]) roots.pop();
  }
  if (v == roots.top()) {
    brdg.push_back(Edge(u, v));
    tecomp.push_back(vector<int>());
    while (1) {
      int w = S.top();
      S.pop();
      inS[w] = false;
      tecomp.back().push_back(w);
      if (v == w) break;
    }
    roots.pop();
  }
}
void bridge(const vector<vector<Edge> >& g, vector<Edge>& brdg,
            vector<vector<int> >& tecomp) {
  const int n = g.size();
  vector<int> num(n);
  vector<bool> inS(n);
  stack<int> roots, S;
  int time = 0;
  for (int u = 0; u < n; u++)
    if (num[u] == 0) {
      visit(g, u, n, brdg, tecomp, roots, S, inS, num, time);
      brdg.pop_back();
    }
}
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
struct Query {
  int u, v, w;
  Query(int u, int v) : u(u), v(v), w(-1) {}
};
void visit(const vector<vector<Edge> >& g, int u, int w, vector<Query>& qs,
           vector<int>& color, vector<int>& ancestor, UnionFind& uf) {
  ancestor[uf.root(u)] = u;
  for (__typeof((g[u]).begin()) e = (g[u]).begin(); e != (g[u]).end(); e++)
    if (e->dst != w) {
      visit(g, e->dst, u, qs, color, ancestor, uf);
      uf.unionSet(e->src, e->dst);
      ancestor[uf.root(u)] = u;
    }
  color[u] = 1;
  for (__typeof((qs).begin()) q = (qs).begin(); q != (qs).end(); q++) {
    int w = (q->v == u ? q->u : q->u == u ? q->v : -1);
    if (w >= 0 && color[w]) q->w = ancestor[uf.root(w)];
  }
}
void leastCommonAncestor(const vector<vector<Edge> >& g, int r,
                         vector<Query>& qs) {
  UnionFind uf(g.size());
  vector<int> color(g.size()), ancestor(g.size());
  visit(g, r, -1, qs, color, ancestor, uf);
}
int dp[100010], a[100010], b[100010];
void run() {
  int n, m, k;
  cin >> n >> m;
  vector<vector<Edge> > g(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(Edge(a, b));
    g[b].push_back(Edge(b, a));
  }
  vector<Edge> bs;
  vector<vector<int> > dummy;
  bridge(g, bs, dummy);
  UnionFind uf(n);
  set<Edge> ss;
  for (int i = 0; i < bs.size(); i++) ss.insert(bs[i]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < g[i].size(); j++)
      if (!ss.count(Edge(g[i][j].src, g[i][j].dst)) &&
          !ss.count(Edge(g[i][j].dst, g[i][j].src))) {
        uf.unionSet(g[i][j].src, g[i][j].dst);
      }
  map<int, int> ms;
  int cnt = 0;
  for (int i = 0; i < n; i++) ms[uf.root(i)] = 0;
  for (__typeof((ms).begin()) i = (ms).begin(); i != (ms).end(); i++)
    i->second = cnt++;
  UnionFind uf2(cnt);
  vector<vector<Edge> > t(cnt);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < g[i].size(); j++) {
      int a = uf.root(g[i][j].src), b = uf.root(g[i][j].dst);
      a = ms[a];
      b = ms[b];
      if (uf2.root(a) == uf2.root(b)) continue;
      uf2.unionSet(a, b);
      t[a].push_back(Edge(a, b));
      t[b].push_back(Edge(b, a));
    }
  queue<pair<int, int> > q;
  q.push(make_pair(ms[uf.root(0)], -1));
  while (!q.empty()) {
    int c = q.front().first, p = q.front().second;
    q.pop();
    for (int i = 0; i < t[c].size(); i++)
      if (t[c][i].dst != p) {
        dp[t[c][i].dst] = dp[c] + 1;
        q.push(make_pair(t[c][i].dst, c));
      }
  }
  cin >> k;
  vector<Query> qs;
  for (int i = 0; i < k; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
    a[i] = ms[uf.root(a[i])];
    b[i] = ms[uf.root(b[i])];
    qs.push_back(Query(a[i], b[i]));
  }
  leastCommonAncestor(t, ms[uf.root(0)], qs);
  for (int i = 0; i < k; i++) {
    cout << dp[a[i]] + dp[b[i]] - 2 * dp[qs[i].w] << endl;
  }
}
int main() { run(); }
