#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
#define minim(a, b) ((a < b) ? a : b)
#define CLEAR(x) memset(x, 0, sizeof(x))
#define pb push_back
#define INF 900000000
#define NMax 32005
#define LG 16
int N, t[NMax], dep[NMax], uz[NMax], log[NMax], timp, conex, rad;
int A[LG][NMax], up[LG][NMax], c[NMax], low[NMax], U[NMax], deg[NMax];
int t_in[NMax], t_out[NMax];
vector<int> G[NMax], GT[NMax];
void bucla_infinita(void)
{ for (;;); }
int cmp(const int& a, const int& b)
{ return t[a] > t[b]; }
void df_times(int nod, int graf)
{
vector<int>::iterator it;
uz[nod] = 1;
if (!graf) // parcurgere in G
{
for (it = G[nod].begin(); it != G[nod].end(); it++)
if (!uz[*it])
df_times(*it, graf);
t[++timp] = nod;
}
else // parcurgere in GT
{
for (it = GT[nod].begin(); it != GT[nod].end(); it++)
if (!uz[*it])
df_times(*it, graf);
t[nod] = (++timp);
}
}
void df_gt(int nod)
{
vector<int>::iterator it;
c[nod] = conex;
for (it = GT[nod].begin(); it != GT[nod].end(); it++)
if (!c[*it])
df_gt(*it);
}
void df_levels(int nod)
{
vector<int>::iterator it;
for (it = GT[nod].begin(); it != GT[nod].end(); it++)
if (!dep[*it])
{
U[*it] = nod;
dep[*it] = dep[nod] + 1;
df_levels(*it);
}
}
void df(int nod)
{
int h;
vector<int>::iterator it;
up[0][nod] = U[nod];
for (h = 1; h <= log[dep[nod]-1]; h++)
up[h][nod] = up[h-1][up[h-1][nod]];
uz[nod] = 1;
for (it = GT[nod].begin(); it != GT[nod].end(); it++)
if (U[*it] == nod)
{
if (dep[low[*it]] > dep[nod])
low[*it] = nod;
df(*it);
if (dep[low[nod]] > dep[low[*it]])
low[nod] = low[*it];
}
}
void df_up(int nod, int lev)
{
int h;
vector<int>::iterator it;
deg[nod] = lev; A[0][nod] = low[nod];
t_in[nod] = (++timp);
for (h = 1; h <= log[lev-1]; h++)
A[h][nod] = A[h-1][A[h-1][nod]];
for (it = G[nod].begin(); it != G[nod].end(); it++)
df_up(*it, lev+1);
t_out[nod] = (++timp);
}
int LCA(int x, int y)
{
int h;
for (; dep[x] > dep[y]; x = up[log[dep[x]-dep[y]]][x]);
for (; dep[y] > dep[x]; y = up[log[dep[y]-dep[x]]][y]);
if (x == y) return x;
for (h = log[dep[x]-1]; h >= 0; h--)
if (up[h][x] != up[h][y])
x = up[h][x], y = up[h][y];
return up[0][x];
}
int stramos(int x, int y)
{ return t_in[x] <= t_in[y] && t_out[y] <= t_out[x]; }
int main(void)
{
int M, T, L, i, u, v, bst;
vector<int>::iterator it;
freopen("obiective.in", "r", stdin);
freopen("obiective.out", "w", stdout);
for (i = 2; i < NMax-1; i++)
log[i] = log[i/2] + 1;
scanf("%d %d", &N, &M);
for (; M; M--)
{
scanf("%d %d", &u, &v);
G[u].pb(v); GT[v].pb(u);
}
for (i = 1; i <= N; i++)
if (!uz[i])
df_times(i, 0);
for (i = N, timp = 0; i >= 1; i--)
if (!c[t[i]])
{ ++conex; df_gt(t[i]); }
for (i = 1; i <= N; i++)
GT[i].clear();
for (i = 1; i <= N; i++)
for (it = G[i].begin(); it != G[i].end(); it++)
if (c[i] != c[*it])
{
GT[c[i]].pb(c[*it]);
deg[c[*it]]++;
}
CLEAR(uz); CLEAR(t);
for (i = 1, timp = 0; i <= N; i++)
if (!uz[i])
df_times(i, 1);
for (i = 1; i <= conex; i++)
sort(GT[i].begin(), GT[i].end(), cmp);
for (i = 1; i <= conex; i++)
if (!deg[i])
{
if (rad)
bucla_infinita();
rad = i;
}
dep[rad] = 1; df_levels(rad);
dep[conex+1] = INF;
for (i = 1; i <= conex; i++)
low[i] = conex+1;
for (i = 1; i <= conex; i++)
for (it = GT[i].begin(); it != GT[i].end(); it++)
if (U[*it] != i && dep[low[*it]] > dep[i]) // muchie inainte
low[*it] = i;
CLEAR(uz); CLEAR(deg);
low[rad] = 1; df(rad);
for (i = 1; i <= N; i++) G[i].clear();
for (i = 2; i <= N; i++)
G[low[i]].pb(i);
timp = 0; df_up(rad, 1);
for (scanf("%d", &T); T; T--)
{
scanf("%d %d", &u, &v);
u = c[u]; v = c[v];
L = LCA(u, v);
if (u == L)
printf("0\n");
else
{
bst = deg[u];
for (i = log[deg[u]-1]; i >= 0; i--)
if (A[i][u] && !stramos(A[i][u], L))
u = A[i][u];
u = A[0][u];
bst -= deg[u];
printf("%d\n", bst);
}
}
return 0;
}