#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
#define CLEAR(x) memset(x, 0, sizeof(x))
#define NMax 32768
int N, M, uz[NMax], timp[NMax], t, ctc, comp[NMax], rad;
int up[16][NMax], nivel[NMax], lg[NMax], bst;
int get_high[16][NMax], highest[NMax], dep[NMax], t_in[NMax], t_out[NMax];
vector<int> G[NMax], GT[NMax];
int cmp_nodes(const int& a, const int& b)
{ return t_out[a] > t_out[b]; }
void df1(int nod)
{
int i, sz, x;
uz[nod] = 1;
for (sz = G[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = G[nod][i]])
df1(x);
timp[++t] = nod;
}
void df2(int nod)
{
int i, sz, x;
uz[nod] = 1; comp[nod] = ctc;
for (sz = GT[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = GT[nod][i]])
df2(x);
}
int det_root(void)
{
int i, j, sz;
CLEAR(uz);
for (i = 1; i <= N; ++i)
for (sz = GT[i].size(), j = 0; j < sz; ++j)
uz[GT[i][j]] = 1;
for (i = 1; i <= N; ++i)
if (!uz[i])
return i;
return -1; // should never arrive here
}
void df_time(int nod)
{
int i, sz, x;
uz[nod] = 1;
for (sz = GT[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = GT[nod][i]])
df_time(x);
t_out[nod] = (++t);
}
void df3(int nod)
{
int i, sz, x;
uz[nod] = 1;
for (i = 0; ; ++i)
{
if (!up[i][ up[i][nod] ]) break;
up[i+1][nod] = up[i][ up[i][nod] ];
}
for (sz = GT[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = GT[nod][i]])
{
up[0][x] = nod;
nivel[x] = nivel[nod] + 1;
df3(x);
}
}
int LCA(int x, int y)
{
for (; nivel[x] > nivel[y]; x = up[ lg[nivel[x]-nivel[y]] ][x]);
for (; nivel[y] > nivel[x]; y = up[ lg[nivel[y]-nivel[x]] ][y]);
if (x == y) return x;
int log;
for (log = lg[nivel[x]]; log >= 0; --log)
if (up[log][x] != up[log][y])
x = up[log][x],
y = up[log][y];
if (x != y) x = up[0][x];
return x;
}
void df4(int nod)
{
int i, sz, x;
uz[nod] = 1;
for (sz = GT[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = GT[nod][i]])
{
df4(x);
if (nivel[ highest[x] ] < nivel[ highest[nod] ])
highest[nod] = highest[x];
}
}
void df5(int nod)
{
int i, sz, x;
for (i = 0; ; ++i)
{
if (!get_high[i][ get_high[i][nod] ]) break;
get_high[i+1][nod] = get_high[i][ get_high[i][nod] ];
}
uz[nod] = 1;
for (sz = G[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = G[nod][i]])
{
get_high[0][x] = nod;
dep[x] = dep[nod] + 1;
df5(x);
}
}
void df6(int nod)
{
int i, sz, x;
uz[nod] = 1; t_in[nod] = (++t);
for (sz = GT[nod].size(), i = 0; i < sz; ++i)
if (!uz[x = GT[nod][i]])
df6(x);
t_out[nod] = (++t);
}
int stramos(int x, int y)
{ return t_in[x] <= t_in[y] && t_out[y] <= t_out[x]; }
int main(void)
{
int T, i, j, k, sz, log;
freopen("obiective.in", "r", stdin);
freopen("obiective.out", "w", stdout);
scanf("%d %d", &N, &M);
for (; M; --M)
{
scanf("%d %d", &i, &j);
G[i].push_back(j);
GT[j].push_back(i);
}
for (i = 1; i <= N; ++i)
if (!uz[i])
df1(i);
CLEAR(uz);
for (i = N; i; --i)
if (!uz[j = timp[i]])
{
++ctc;
df2(j);
}
for (i = 1; i <= N; ++i)
GT[i].clear();
for (i = 1; i <= N; ++i)
for (sz = G[i].size(), j = 0; j < sz; ++j)
if (comp[i] != comp[G[i][j]])
GT[comp[i]].push_back( comp[G[i][j]] );
N = ctc;
rad = det_root();
t = 0;
CLEAR(uz);
df_time(rad);
for (i = 1; i <= N; ++i)
sort(GT[i].begin(), GT[i].end(), cmp_nodes);
CLEAR(uz);
df3(rad);
for (i = 2; i< NMax; ++i)
lg[i] = lg[i/2]+1;
for (i = 1; i <= N; ++i)
highest[i] = up[0][i];
for (i = 1; i <= N; ++i)
for (sz = GT[i].size(), j = 0; j < sz; ++j)
if (up[0][ GT[i][j] ] != i)
{
if (nivel[i] < highest[ GT[i][j] ])
highest[ GT[i][j] ] = i;
}
CLEAR(uz);
df4(rad);
for (i = 1; i <= N; ++i)
G[i].clear();
for (i = 1; i <= N; ++i)
{
if (!highest[i]) continue;
G[highest[i]].push_back(i);
}
CLEAR(uz);
df5(rad);
t = 0;
CLEAR(uz);
CLEAR(t_out);
df6(rad);
for (scanf("%d", &T); T; --T)
{
scanf("%d %d", &i, &j);
i = comp[i]; j = comp[j];
if (i == j)
{
printf("0\n");
continue;
}
k = LCA(i, j);
if (i == k)
{
printf("0\n");
continue;
}
for (bst = 0, log = lg[dep[i]]; log >= 0; )
{
for (; log >= 0 && stramos(get_high[log][i], k); --log);
if (log >= 0)
i = get_high[log][i],
bst += (1<<log),
log--;
}
printf("%d\n", bst+1);
}
return 0;
}