#include <bits/stdc++.h>
using namespace std;
class BridgeDetect {
 public:
  BridgeDetect(int n) {
    n_ = n;
    adj_ = new vector<int>[n];
  }
  void AddBiEdge(int a, int b) {
    int i = ((int)from_.size());
    from_.push_back(a);
    to_.push_back(b);
    adj_[a].push_back(i);
    adj_[b].push_back(i);
  }
  vector<pair<int, int> > Solve() {
    int m = ((int)from_.size());
    is_tree_ = new int[m];
    for (int i = 0; i < m; ++i) is_tree_[i] = 0;
    vis_ = new int[n_];
    for (int i = 0; i < n_; ++i) vis_[i] = 0;
    val_ = new int[n_];
    sc_ = n_;
    low_ = new int[n_];
    hi_ = new int[n_];
    desc_ = new int[n_];
    par_ = new int[n_];
    for (int i = 0; i < n_; ++i)
      if (!vis_[i]) {
        par_[i] = -1;
        Span(i);
      }
    while (!s_.empty()) {
      int node = s_.front();
      s_.pop();
      desc_[node] = 1;
      low_[node] = hi_[node] = val_[node];
      for (typeof((adj_[node]).begin()) it = (adj_[node]).begin();
           it != (adj_[node]).end(); it++) {
        if (is_tree_[*it]) {
          int to = GetTo(*it, node);
          if (par_[node] == to) continue;
          desc_[node] += desc_[to];
          low_[node] = min((low_[node]), (low_[to]));
          hi_[node] = max((hi_[node]), (hi_[to]));
        }
      }
      for (typeof((adj_[node]).begin()) it = (adj_[node]).begin();
           it != (adj_[node]).end(); it++) {
        if (!is_tree_[*it]) {
          int to = GetTo(*it, node);
          low_[node] = min((low_[node]), (val_[to]));
          hi_[node] = max((hi_[node]), (val_[to]));
        }
      }
    }
    vector<pair<int, int> > ret;
    for (int(i) = 0; (i) < (((int)from_.size())); ++(i)) {
      if (!is_tree_[i]) continue;
      int f = from_[i];
      int t = to_[i];
      if (val_[f] > val_[t]) swap(f, t);
      if (low_[t] == val_[t] && hi_[t] < val_[t] + desc_[t]) {
        ret.push_back(make_pair(min(f, t), max(f, t)));
      }
    }
    delete[] low_;
    delete[] hi_;
    delete[] desc_;
    delete[] val_;
    delete[] is_tree_;
    delete[] vis_;
    delete[] par_;
    return ret;
  }

 private:
  int GetTo(int index, int fr) {
    assert(from_[index] == fr || to_[index] == fr);
    if (from_[index] == fr)
      return to_[index];
    else
      return from_[index];
  }
  void Span(int node) {
    vis_[node] = 1;
    for (typeof((adj_[node]).begin()) it = (adj_[node]).begin();
         it != (adj_[node]).end(); it++) {
      int k = GetTo(*it, node);
      if (!vis_[k]) {
        is_tree_[*it] = 1;
        par_[k] = node;
        Span(k);
      }
    }
    val_[node] = sc_;
    --sc_;
    s_.push(node);
  }
  int n_;
  vector<int> from_;
  vector<int> to_;
  vector<int>* adj_;
  int* is_tree_;
  int* vis_;
  int* val_;
  queue<int> s_;
  int sc_;
  int* low_;
  int* hi_;
  int* desc_;
  int* par_;
};
class DisjointSet {
 public:
  explicit DisjointSet(int n) {
    whichset_ = vector<int>(n);
    height_ = vector<int>(n, 1);
    for (int i = 0; i < n; ++i) whichset_[i] = i;
  }
  int Find(int node) {
    if (whichset_[node] == node) return node;
    return (whichset_[node] = Find(whichset_[node]));
  }
  void Merge(int first_node, int second_node) {
    int h1 = height_[Find(first_node)];
    int h2 = height_[Find(second_node)];
    if (h1 < h2) {
      whichset_[Find(first_node)] = Find(second_node);
      return;
    }
    whichset_[Find(second_node)] = Find(first_node);
    if (h2 < h1) return;
    ++height_[Find(second_node)];
  }

 private:
  vector<int> whichset_;
  vector<int> height_;
};
vector<pair<int, int> > edges;
const int kMaxN = 120000;
vector<int> adj[kMaxN];
DisjointSet* ds;
int retret[kMaxN];
int p[kMaxN];
vector<int> members[kMaxN];
int guna[kMaxN];
void Dfs(int node) {
  for (typeof((adj[node]).begin()) it = (adj[node]).begin();
       it != (adj[node]).end(); it++) {
    if (p[*it] == -2) {
      p[*it] = node;
      Dfs(*it);
    }
  }
}
pair<map<int, int>*, int> Merge(pair<map<int, int>*, int> a,
                                pair<map<int, int>*, int> b) {
  if (a.first->size() < b.first->size()) return Merge(b, a);
  for (typeof(((*(b.first))).begin()) it = ((*(b.first))).begin();
       it != ((*(b.first))).end(); it++) {
    if (!a.first->count(it->first)) {
      a.first->operator[](it->first) = it->second + b.second - a.second;
    } else {
      retret[it->first] =
          it->second + b.second + a.second + a.first->operator[](it->first);
      a.first->erase(it->first);
    }
  }
  delete b.first;
  return a;
}
pair<map<int, int>*, int> SuperDFS(int node) {
  pair<map<int, int>*, int> ret;
  ret.first = new map<int, int>();
  ret.second = 0;
  for (typeof((members[node]).begin()) it = (members[node]).begin();
       it != (members[node]).end(); it++)
    ret.first->operator[](*it) = 0;
  for (typeof((adj[node]).begin()) it = (adj[node]).begin();
       it != (adj[node]).end(); it++)
    if (p[node] != *it) {
      ret = Merge(ret, SuperDFS(*it));
    }
  ret.second += 1;
  return ret;
}
int main() {
  int n, m;
  cin >> n >> m;
  BridgeDetect bd(n);
  for (int(i) = 0; (i) < (m); ++(i)) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    edges.push_back(make_pair(min(a, b), max(a, b)));
    bd.AddBiEdge(a, b);
  }
  vector<pair<int, int> > bridges = bd.Solve();
  set<pair<int, int> > bs;
  for (typeof((bridges).begin()) it = (bridges).begin(); it != (bridges).end();
       it++)
    bs.insert(*it);
  ds = new DisjointSet(n);
  for (typeof((edges).begin()) it = (edges).begin(); it != (edges).end(); it++)
    if (!bs.count(*it)) {
      ds->Merge(it->first, it->second);
    }
  for (typeof((edges).begin()) it = (edges).begin(); it != (edges).end(); it++)
    if (ds->Find(it->first) != ds->Find(it->second)) {
      int x = ds->Find(it->first);
      int y = ds->Find(it->second);
      adj[x].push_back(y);
      adj[y].push_back(x);
    }
  for (int(i) = 0; (i) < (n); ++(i)) guna[i] = 0;
  for (int(i) = 0; (i) < (n); ++(i)) guna[ds->Find(i)] = 1;
  for (int(i) = 0; (i) < (n); ++(i)) p[i] = -2;
  int root = -1;
  for (int(i) = 0; (i) < (n); ++(i))
    if (p[i] == -2 && guna[i]) {
      p[i] = -1;
      Dfs(i);
      root = i;
      break;
    }
  assert(root != -1);
  int merchants;
  cin >> merchants;
  for (int(i) = 0; (i) < (merchants); ++(i)) {
    int a, b;
    scanf("%d%d", &a, &b);
    if (a == b) {
      retret[i] = 0;
      continue;
    }
    --a;
    --b;
    members[ds->Find(a)].push_back(i);
    members[ds->Find(b)].push_back(i);
  }
  SuperDFS(root);
  for (int(i) = 0; (i) < (merchants); ++(i)) {
    cout << retret[i] << endl;
  }
}
