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

struct Edge {
	int src, dst;
	Edge() : src(0), dst(0) {}
	Edge(int s, int d) : src(s), dst(d) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;

vector<int> kosaraju(const Graph &g) {
	int n = g.size(), sz = 0; Graph rg(n);
	vector<int> stk, cmp(n, -1), added(n), visited(n), ord(n);
	for(auto &es : g) {
		sz += es.size();
		for(const Edge &e : es) rg[e.dst].emplace_back(e.dst, e.src);
	}
	stk.resize(n + sz); sz = 0;
	for(int i = 0; i < n; i++) {
		if(visited[i]) continue;
		int s = 0; stk[s++] = i;
		while(s != 0) {
			int v = stk[s - 1]; visited[v] = true;
			bool pushed = false;
			for(auto &e : g[v]) {
				int dst = e.dst;
				if(!visited[dst]) { stk[s++] = dst; pushed = true; }
			}
			if(pushed) continue;
			int t = stk[s - 1];
			if(!added[t]) { added[t] = true; ord[n - ++sz] = t; }
			--s;
		}
	}
	int k = 0;
	for(int &u : ord) {
		if(cmp[u] != -1) continue;
		int s = 0; stk[s++] = u;
		while(s != 0) {
			int v = stk[--s]; cmp[v] = k;
			for(auto &e : rg[v]) {
				int d = e.dst;
				if(cmp[d] == -1) stk[s++] = d;
			}
		}
		++k;
	}
	return cmp;
}

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

	int V, E, Q;
	cin >> V >> E;

	Graph G(V);
	for(int i = 0; i < E; i++) {
		int u, v;
		cin >> u >> v;
		G[u].push_back({ u, v });
	}

	auto res = kosaraju(G);
	cin >> Q;
	while(Q--) {
		int u, v;
		cin >> u >> v;
		cout << (res[u] == res[v]) << endl;
	}
}
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> G[1000000];
vector<pair<int, int> > bridge;
vector<int> articulation;
int ord[1000000], low[1000000];
bool vis[1000000];

void dfs(int v, int p, int &k)
{
	vis[v] = true;
	
	ord[v] = k++;
	low[v] = ord[v];
	
	bool isArticulation = false;
	int ct = 0;
	
	for (int i = 0; i < G[v].size(); i++){
		if (!vis[G[v][i]]){
			ct++;
			dfs(G[v][i], v, k);
			low[v] = min(low[v], low[G[v][i]]);
			if (~p && ord[v] <= low[G[v][i]]) isArticulation = true;
			if (ord[v] < low[G[v][i]]) bridge.push_back(make_pair(min(v, G[v][i]), max(v, G[v][i])));
		}
		else if (G[v][i] != p){
			low[v] = min(low[v], ord[G[v][i]]);
		}
	}
	
	if (p == -1 && ct > 1) isArticulation = true;
	if (isArticulation) articulation.push_back(v);
}

int main()
{
	int n, m;
	
	scanf("%d %d", &n, &m);
	
	for (int i = 0; i < m; i++){
		int x, y;
		scanf("%d %d", &x, &y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	
	int k = 0;
	for (int i = 0; i < n; i++){
		if (!vis[i]) dfs(i, -1, k);
	}
	
	sort(bridge.begin(), bridge.end());
	sort(articulation.begin(), articulation.end());
	
	//printf("%d\n", articulation.size());
	
	for (int i = 0; i < articulation.size(); i++)
		printf("%d\n", articulation[i]);
	
	//printf("%d\n", bridge.size());
	
	/*for (int i = 0; i < bridge.size(); i++)
		printf("%d %d\n", bridge[i].first + 1, bridge[i].second + 1);
	*/
	
	return (0);
}