#include <bits/stdc++.h>
#define NMAX 32002
#define LOGMAX 20
#define INF INT_MAX
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
int N,M,T;
vector <int> G[NMAX],Gt[NMAX],Gctc[NMAX],Gctct[NMAX];
int ctc[NMAX];
vector <int> S;
char vis[NMAX];
int depth[NMAX];
long long sz[NMAX];
int sparse[LOGMAX][NMAX];
int tin[NMAX],tout[NMAX];
int t = 0;
void sort_top(int node,vector <int> &S)
{
vis[node] = 1;
for(int x : G[node]){
if(!vis[x]) sort_top(x,S);
}
S.push_back(node);
}
void dfs(int node,vector <int> *G,const int c)
{
vis[node] = 1;
ctc[node] = c;
for(int x : G[node]){
if(!vis[x]) dfs(x, G, c);
}
return;
}
bool cmp(int x,int y)
{
return sz[x] > sz[y];
}
void fix(int node,vector <int> * G)
{
sz[node] = 1;
for(int x : G[node]){
if(sz[x] == 0){
fix(x, G);
}
sz[node] += sz[x];
}
sort(G[node].begin(),G[node].end(),cmp);
}
void build1(int node,vector <int> * G, vector <int> * Gt)
{
tin[node] = ++t;
vis[node] = 1;
for(int x : G[node]){
if(!vis[x]){
depth[x] = depth[node] + 1;
sparse[0][x] = node;
build1(x,G, Gt);
}
}
tout[node] = t;
}
void build2(int node,vector <int> *G, vector <int> *Gt)
{
vis[node] = 1;
for(int x : Gt[node]){
if(depth[x] < depth[sparse[0][node]]){
sparse[0][node] = x;
}
}
for(int x : G[node]){
if(!vis[x]){
build2(x,G, Gt);
if(depth[sparse[0][x]] < depth[sparse[0][node]]){
sparse[0][node] = sparse[0][x];
}
}
}
}
int LA(int node,int K)
{
for(int i=0;i<20;i++){
if(K & (1<<i)){
node = sparse[i][node];
}
}
return node;
}
int caut_bin(int x, int y)
{
int le =0;
int ri = N;
int ret = -1;
while(le <= ri){
int mid = (le+ri)/2;
int z = LA(x,mid);
if(tin[z] <= tin[y] && tout[y] <= tout[z]){
ret = mid;
ri = mid-1;
}else{
le = mid+1;
}
}
if(ret == -1)exit(88);
return ret;
}
int main()
{
fin >> N >> M;
for(int i=1;i<=M;i++){
int x,y;
fin >> x>> y;
G[x].push_back(y);
Gt[y].push_back(x);
}
for(int i=1;i<=N;i++){
if(!vis[i]) sort_top(i,S);
}
reverse(S.begin(),S.end());
memset(vis, 0 , sizeof(vis));
int cnt = 0;
for(int node : S){
if(!vis[node]){
dfs(node, Gt, ++cnt);
}
}
for(int node=1;node<=N;node++){
for(int x : G[node]){
if(ctc[x] != ctc[node]){
Gctc[ctc[node]].push_back(ctc[x]);
Gctct[ctc[x]].push_back(ctc[node]);
}
}
}
fix(1, Gctc);
memset(vis, 0 , sizeof(vis));
build1(1,Gctc, Gctct);
memset(vis, 0 , sizeof(vis));
build2(1,Gctc, Gctct);
tout[0] = INF;
for(int node=1;node<=cnt;node++){
for(int i=1;(1<<i) <=depth[node];i++){
sparse[i][node] = sparse[i-1][sparse[i-1][node]];
}
}
fin >> T;
while(T--){
int x,y;
fin >> x >> y;
x = ctc[x];
y = ctc[y];
///de la x la y
fout << caut_bin(x,y) << "\n";
}
// for(int i=1;i<=N;i++){
// cout << i << " : " << ctc[i] << " " << tin[ctc[i]] << " " << tout[ctc[i]] << "\n";
// }
// for(int i=1;i<=cnt;i++){
// cout << i << " : ";
// for(int j =0;j<=3;j++){
// cout << sparse[j][i] << " ";
// }
// cout << "\n";
// }
}