#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n)-1;i>=0;i--)
#define rrep2(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define all(a) (a).begin(),(a).end()

typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pll> vp;
typedef vector<ll> vll;

const int MAX_V = 10000;

int V, E;
vi G[MAX_V];
vi rG[MAX_V];
vi vs;
bool used[MAX_V];
int cmp[MAX_V];

void addEdge(int from, int to) {
    G[from].emplace_back(to);
    rG[to].emplace_back(from);
}

void dfs(int v) {
    used[v] = true;
    rep(i, G[v].size()) {
        if (!used[G[v][i]]) dfs(G[v][i]);
    }
    vs.emplace_back(v);
}

void rdfs(int v, int k) {
    used[v] = true;
    cmp[v] = k;
    rep(i, rG[v].size()) {
        if (!used[rG[v][i]]) rdfs(rG[v][i], k);
    }
    vs.emplace_back(v);
}

int scc() {
    memset(used, 0, sizeof(used));
    vs.clear();
    rep(v, V) {
        if (!used[v]) dfs(v);
    }
    memset(used, 0, sizeof(used));
    int k = 0;
    for (int i = vs.size() - 1; i >= 0; i--) {
        if (!used[vs[i]]) rdfs(vs[i], k++);
    }
    return k;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    cin >> V >> E;
    rep(i, E) {
        int s, t;
        cin >> s >> t;
        addEdge(s, t);
    }

    scc();

    int Q;
    cin >> Q;
    rep(i, Q) {
        int u, v;
        cin >> u >> v;
        cout << (cmp[u] == cmp[v]) << endl;
    }

}
#include <bits/stdc++.h>
#define owo(i,a, b) for(int i=(a);i<(b); ++i)
#define uwu(i,a, b) for(int i=(a)-1; i>=(b); --i)
#define senpai push_back
#define ttgl pair<int, int>
#define ayaya cout<<"ayaya~"<<endl
 
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
gpu_hash_map<int, int> mp;*/
using ll = long long;
using ld = long double;
const ll MOD = 1000000007;
const ll root = 62;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
ll binpow(ll a,ll b){ll res=1;while(b){if(b&1)res=(res*a)%MOD;a=(a*a)%MOD;b>>=1;}return res;}
ll modInv(ll a){return binpow(a, MOD-2);}
const double PI = acos(-1);
const double eps = -1e6;
const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const ll NINFLL = 0xc0c0c0c0c0c0c0c0;
const int mxN = 1001;
int board[mxN][mxN];
int dist[mxN][mxN];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int h, w;
bool inside(int x, int y) {
    return x>=0&&x<h&&y>=0&&y<w;
}
int main() {
    //freopen("file.in", "r", stdin);
    //freopen("file.out", "w", stdout);
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    cin.tie(0)->sync_with_stdio(0);
    cin>>h>>w;
    string s;
    queue<ttgl> Q;
    memset(dist, INF, sizeof(dist));
    owo(i, 0, h) {
            cin>>s;
        owo(j, 0, w) {
            board[i][j] = s[j]=='#';
            if(s[j]=='#') {
                Q.push({i, j});
                dist[i][j] = 0;
            }
        }
    }
    int ans = 0;
    while(!Q.empty()) {
        auto p = Q.front();
        Q.pop();
        ans = dist[p.first][p.second];
        owo(d, 0, 4) {
            if(inside(p.first+dx[d], p.second+dy[d])) {
                if(dist[p.first+dx[d]][p.second+dy[d]]==INF) {
                    dist[p.first+dx[d]][p.second+dy[d]] = dist[p.first][p.second]+1;
                    Q.push({p.first+dx[d], p.second+dy[d]});
                }
            }
        }
    }
    cout<<ans<<"\n";
    return 0;
}