#include <iostream>
#include <cstdio>
#include <vector>
#include <bitset>
#include <algorithm>
#define MAXN 32050
#define MAXLOG 19
using namespace std;
int n, m, nq, root;
bitset<MAXN> viz;
vector<int> graf[MAXN];
vector<int> trg[MAXN];
vector<int> dag[MAXN];
vector<int> postOrd;
vector<int> euler;
int gToDag[MAXN], loc[MAXN], depth[MAXN], pos[MAXN];
int rmq[MAXLOG][2*MAXN], lg[2*MAXN], low[MAXN], parent[MAXLOG][MAXN];
/// pos[i] => prima aparitie a nodului i din DAG in parcurgerea euler
void citire()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d %d", &x, &y);
graf[x].push_back(y);
trg[y].push_back(x);
}
}
void dfsRaw(int nod)
{
viz[nod] = 1;
for (int i = 0, t = graf[nod].size(); i < t; i++)
if (!viz[graf[nod][i]])
dfsRaw(graf[nod][i]);
postOrd.push_back(nod);
}
void dfsTraw(int nod)
{
viz[nod] = 1;
gToDag[nod] = nq;
for (int i = 0, t = trg[nod].size(); i < t; i++)
if (!viz[trg[nod][i]])
dfsTraw(trg[nod][i]);
}
void buildDAG()
{
for (int i = 1; i <= n; i++)
if (!viz[i])
dfsRaw(i);
viz = 0;
for (int i = postOrd.size()-1; i >= 0; i--)
if (!viz[postOrd[i]])
{
nq++;
dfsTraw(postOrd[i]);
}
for (int i = 1; i <= n; i++)
for (int j = 0, t = graf[i].size(); j < t; j++)
if (gToDag[i] != gToDag[graf[i][j]])
dag[gToDag[i]].push_back(gToDag[graf[i][j]]);
}
void agat()
{
viz = 0;
for (int i = 1; i <= nq; i++)
for (int j = 0, t = dag[i].size(); j < t; j++)
viz[dag[i][j]] = 1;
for (int i = 1; i <= nq; i++)
if (!viz[i]) {
root = i;
break;
}
}
void dfs(int nod)
{
viz[nod] = 1;
for (int i = 0, t = dag[nod].size(); i < t; i++)
if (!viz[dag[nod][i]])
dfs(dag[nod][i]);
postOrd.push_back(nod);
}
bool cmp(int e, int f)
{
return loc[e] < loc[f];
}
void topologic()
{
viz = 0;
postOrd.clear();
for (int i = 1; i <= nq; i++)
if (!viz[i])
dfs(i);
for (int i = 0, t = postOrd.size()-1; t >= 0; t--, i++)
loc[postOrd[t]] = i;
for (int i = 1; i <= nq; i++) {
sort(dag[i].begin(), dag[i].end(), cmp);
vector<int> :: iterator last = unique(dag[i].begin(), dag[i].end());
dag[i].erase(last, dag[i].end());
}
}
void eulerS(int nod, int d)
{
pos[nod] = euler.size();
depth[nod] = d;
euler.push_back(d);
for (int i = 0, t = dag[nod].size(); i < t; i++)
{
int y = dag[nod][i];
if (pos[y] == 0) {
low[y] = d;
parent[0][y] = nod;
eulerS(y, d+1);
euler.push_back(d);
}
if (d < low[y]) {
low[y] = d;
parent[0][y] = nod;
}
}
}
void anotherOne(int nod)
{
for (int i = 0, t = dag[nod].size(); i < t; i++)
anotherOne(dag[nod][i]);
for (int i = 0, t = dag[nod].size(); i < t; i++) {
int y = dag[nod][i];
if (low[y] < low[nod])
{
low[nod] = low[y];
parent[0][nod] = parent[0][y];
}
}
}
void prepareRmq()
{
int sz = euler.size()-1;
for (int i = 1; i <= sz; i++)
rmq[0][i] = euler[i];
for (int i = 1; i < MAXLOG; i++) {
for (int j = 1; j+(1<<(i-1)) <= sz; j++) {
rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
}
}
for (int i = 2; i <= sz; i++)
lg[i] = lg[i>>1]+1;
}
int LCA(int x, int y)
{
int p1 = pos[x], p2 = pos[y], dist;
if (p1 > p2) swap(p1, p2);
dist = lg[p2-p1+1];
return min(rmq[dist][p1], rmq[dist][p2+1-(1<<dist)]);
}
void buildStra(int x = root)
{
parent[0][root] = 0;
for (int i = 1; i < MAXLOG; i++)
for (int j = 1; j <= nq; j++)
parent[i][j] = parent[i-1][parent[i-1][j]];
}
int solve(int x, int y)
{
x = gToDag[x], y = gToDag[y];
int prag = LCA(x, y);
if (depth[x] == prag) return 0;
//if (low[x] <= prag) return 1;
int rez = 0;
for (int i = lg[depth[x]-prag]; i >=0 ; i--)
if (parent[i][x] != 0 && depth[parent[i][x]] > prag) {
rez += (1<<i);
x = parent[i][x];
}
return rez+1;
}
int main()
{
freopen("obiective.in", "r", stdin);
freopen("obiective.out", "w", stdout);
citire();
buildDAG();
agat();
topologic();
euler.push_back(-1);
eulerS(root, 1);
anotherOne(root);
buildStra();
prepareRmq();
int t;
scanf("%d", &t);
while (t--) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", solve(x, y));
}
return 0;
}