#include <bits/stdc++.h>
using namespace std;
const int V = 2e5;
const int UNVISITED = -1;
vector<int> dfs_low, dfs_num, dfs_parent, articulation_vertex;
vector<vector<pair<int, int>>> AdjList(V);
int dfsNumberCounter, dfsRoot, rootChildren;
set<pair<int, int>> bridges;
void articulationPointAndBridge(int u) {
  dfs_low[u] = dfs_num[u] = dfsNumberCounter++;
  for (int j = 0; j < (int)AdjList[u].size(); j++) {
    pair<int, int> v = AdjList[u][j];
    if (dfs_num[v.first] == UNVISITED) {
      dfs_parent[v.first] = u;
      if (u == dfsRoot) rootChildren++;
      articulationPointAndBridge(v.first);
      if (dfs_low[v.first] >= dfs_num[u]) articulation_vertex[u] = true;
      if (dfs_low[v.first] > dfs_num[u]) {
        bridges.insert({u, v.first});
        bridges.insert({v.first, u});
      }
      dfs_low[u] = min(dfs_low[u], dfs_low[v.first]);
    } else if (v.first != dfs_parent[u])
      dfs_low[u] = min(dfs_low[u], dfs_num[v.first]);
  }
}
struct LCA {
  vector<int> height, euler, first, segtree, d_to_r;
  vector<bool> visited;
  int n;
  LCA(vector<vector<pair<int, int>>> &adj, int root = 0) {
    n = adj.size();
    d_to_r.resize(n);
    height.resize(n);
    first.resize(n);
    euler.reserve(n * 2);
    visited.assign(n, false);
    d_to_r[root] = 0;
    dfs(adj, root);
    int m = euler.size();
    segtree.resize(m * 4);
    build(1, 0, m - 1);
  }
  void dfs(vector<vector<pair<int, int>>> &adj, int node, int h = 0) {
    visited[node] = true;
    height[node] = h;
    first[node] = euler.size();
    euler.push_back(node);
    for (auto to : adj[node]) {
      if (!visited[to.first]) {
        d_to_r[to.first] = d_to_r[node] + to.second;
        dfs(adj, to.first, h + 1);
        euler.push_back(node);
      }
    }
  }
  void build(int node, int b, int e) {
    if (b == e) {
      segtree[node] = euler[b];
    } else {
      int mid = (b + e) / 2;
      build(node << 1, b, mid);
      build(node << 1 | 1, mid + 1, e);
      int l = segtree[node << 1], r = segtree[node << 1 | 1];
      segtree[node] = (height[l] < height[r]) ? l : r;
    }
  }
  int query(int node, int b, int e, int L, int R) {
    if (b > R || e < L) return -1;
    if (b >= L && e <= R) return segtree[node];
    int mid = (b + e) >> 1;
    int left = query(node << 1, b, mid, L, R);
    int right = query(node << 1 | 1, mid + 1, e, L, R);
    if (left == -1) return right;
    if (right == -1) return left;
    return height[left] < height[right] ? left : right;
  }
  int lca(int u, int v) {
    int left = first[u], right = first[v];
    if (left > right) swap(left, right);
    return query(1, 0, euler.size() - 1, left, right);
  }
  int dist(int u, int v) {
    return d_to_r[u] + d_to_r[v] - 2 * d_to_r[lca(u, v)];
  }
};
int main() {
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v, u--;
    v--;
    AdjList[u].push_back({v, 1}), AdjList[v].push_back({u, 1});
  }
  dfsNumberCounter = 0;
  dfs_num.assign(V, UNVISITED);
  dfs_low.assign(V, 0);
  dfs_parent.assign(V, 0);
  articulation_vertex.assign(V, 0);
  for (int i = 0; i < V; i++) {
    if (dfs_num[i] == UNVISITED) {
      dfsRoot = i;
      rootChildren = 0;
      articulationPointAndBridge(i);
      articulation_vertex[dfsRoot] = (rootChildren > 1);
    }
  }
  vector<vector<pair<int, int>>> AdjList2(n);
  for (int cur = 0; cur < n; cur++) {
    for (auto nxt : AdjList[cur]) {
      pair<int, int> edge = {cur, nxt.first};
      if (bridges.count(edge)) continue;
      AdjList2[cur].push_back(nxt);
    }
  }
  map<int, int> i2c;
  set<int> done;
  int cpt = 0;
  for (int i = 0; i < n; i++) {
    if (done.count(i)) continue;
    queue<int> q;
    q.push(i);
    done.insert(i);
    while (!q.empty()) {
      int cur = q.front();
      q.pop();
      i2c[cur] = cpt;
      for (auto nxt : AdjList2[cur]) {
        if (done.count(nxt.first)) continue;
        done.insert(nxt.first);
        q.push(nxt.first);
      }
    }
    cpt++;
  }
  vector<vector<pair<int, int>>> adj(cpt);
  for (auto it : bridges) adj[i2c[it.first]].push_back({i2c[it.second], 1});
  LCA lca(adj);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int u, v;
    cin >> u >> v, cout << lca.dist(i2c[u - 1], i2c[v - 1]) << "\n";
  }
  return 0;
}
