Go: package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

// Node 頂点
type Node struct {
	gid  int   // グループID
	edge []int // 隣接辺
}

// NoID グループIDなし
const NoID = -1

// NewNode 頂点の生成
func NewNode() *Node {
	return &Node{gid: NoID, edge: []int{}}
}

func parseNode(nodes []*Node, gid int, queue []int) {
	if len(queue) == 0 {
		return
	}
	var nextQ []int
	for _, id := range queue {
		node := nodes[id]
		if node.gid == NoID {
			node.gid = gid
			for _, edge := range node.edge {
				nextQ = append(nextQ, edge)
			}
		}
	}
	parseNode(nodes, gid, nextQ)
	return
}
func digNode(nodes []*Node, id, gid int) {
	node := nodes[id]
	if node.gid != NoID {
		// 探索済み
		return
	}
	node.gid = gid
	for _, edge := range node.edge {
		digNode(nodes, edge, gid)
	}
	return
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	n, m := eGetInt2(scanner)

	nodes := make([]*Node, n)
	for i := 0; i < n; i++ {
		nodes[i] = NewNode()
	}

	for i := 0; i < m; i++ {
		a, b := eGetInt2(scanner)
		nodes[a].edge = append(nodes[a].edge, b)
		nodes[b].edge = append(nodes[b].edge, a)
	}

	for i := 0; i < n; i++ {
		// 幅優先探索
		// gid := i
		// queue := []int{i}
		// parseNode(nodes, gid, queue)

		// 深さ優先探索
		digNode(nodes, i, i)
	}

	q := eGetInt(scanner)
	for i := 0; i < q; i++ {
		a, b := eGetInt2(scanner)
		if nodes[a].gid == nodes[b].gid {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

func eGetInt(scanner *bufio.Scanner) int {
	t := eAtoi(strings.Fields(eGetline(scanner)))
	return t[0]
}
func eGetInt2(scanner *bufio.Scanner) (int, int) {
	t := eAtoi(strings.Fields(eGetline(scanner)))
	return t[0], t[1]
}

func eGetline(p *bufio.Scanner) string {
	if !p.Scan() {
		if err := p.Err(); err != nil {
			log.Fatal(err.Error())
		}
		return ""
	}
	return p.Text()
}

func eAtoi(s []string) []int {
	ints := make([]int, len(s))
	var err error
	for i, e := range s {
		ints[i], err = strconv.Atoi(e)
		if err != nil {
			log.Fatal(err.Error())
		}
	}
	return ints
}

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

/*
// grp[i]:i番目の強連結成分に含まれる頂点一覧 iはトポロジカル順
class SCC {
	public:
	static const int MV = 100000;
	vector<vector<int> > grp; int NV,cmp[MV];
	vector<int> E[MV], RE[MV], NUM; int vis[MV];
	void init(int NV) { this->NV=NV; for(int i=0;i<MV;i++) { E[i].clear(); RE[i].clear();}}
	void add(int x,int y) { E[x].push_back(y); RE[y].push_back(x); }
	void dfs(int cu) { vis[cu]=1; for(int i=0;i<E[cu].size();i++) if(!vis[E[cu][i]]) dfs(E[cu][i]); NUM.push_back(cu); }
	void revdfs(int cu, int ind) {vis[cu]=1; cmp[cu]=ind; grp[ind].push_back(cu);
		for(int i=0;i<RE[cu].size();++i) if(!vis[RE[cu][i]]) revdfs(RE[cu][i],ind);}
	void scc() {
		int c=0; grp.clear(); grp.resize(MV); NUM.clear();
		memset(vis,0,sizeof(vis)); for(int i=0;i<NV;i++) if(!vis[i]) dfs(i);
		memset(vis,0,sizeof(vis)); for(int i=NUM.size()-1;i>=0;i--) if(!vis[NUM[i]])
			{ grp[c].clear(); revdfs(NUM[i],c); sort(grp[c].begin(),grp[c].end()); c++;}
		grp.resize(c);
	}
};
 */

int n, m, a, b, q, c[100100];
vector<int> e[100100];

/*
vector<int> scc(int n, vector<int> e[]) {
	int sz = 0, s = 0;
	vector<int> rg[n], stk, cmp(n, -1), added(n), visited(n), ord(n);
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < e[i].size(); ++j) rg[e[i][j]].push_back(i);
		sz += e[i].size();
	}
	stk.resize(n + sz), sz = 0;
	for (int i = 0; i < n; i++) {
		if (visited[i]) continue;
		stk[s = 1] = i;
		while (s != 0) {
			int v = stk[s - 1];
			visited[v] = true;
			bool pushed = false;
			for (int j = 0; j < e[v].size(); ++j) {
				int dst = e[v][j];
				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 i = 0; i < n; ++i) {
		if (cmp[ord[i]] != -1) continue;
		s = 0, stk[s++] = ord[i];
		while (s != 0) {
			int v = stk[--s];
			cmp[v] = k;
			for (int j = 0; j < rg[v].size(); ++j) {
				int d = rg[v][j];
				if (cmp[d] == -1) stk[s++] = d;
			}
		}
		++k;
	}
	return cmp;
}
*/

// paint
void rec(int v, int x) {
	c[v] = x;
	for (int i = 0; i < e[v].size(); ++i)
		if (c[e[v][i]]==0) rec(e[v][i],x);
}

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; ++i) {
		cin >> a >> b;
		e[a].push_back(b), e[b].push_back(a);
	}
	
	int nm = 0;
	for (int i = 0; i < n; ++i) {
		if (c[i]==0) rec(i,++nm);
	}
	
	cin >> q;
	while (q--) {
		cin >> a >> b;
		cout << (c[a]==c[b] ? "yes" : "no") << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <stack>
#include <string>
#include <string.h>
using namespace std;
vector< vector<int> > v(10001);
//stack<int> st;
int n, m;
bool f[10001] = { false };

int main() {
	cin >> n >> m;
	for (int i = 0;i < m; i++) {
		int a, b; cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	int q; cin >> q;
	vector<string> Ans(q);
	for (int i = 0; i < q; i++) {
		int s, t; cin >> s >> t;

		stack<int> st;
		st.push(s);
		while (!st.empty()) {
			int a = st.top(); st.pop();
			f[a] = true;
			if (a == t) { break; }
			for (int i = 0; i < v[a].size();i++) {
				if (f[v[a][i]] == false) {
					st.push(v[a][i]);
				}
			}
		}
		if (f[t] == true) { Ans[i] = "yes"; memset(f, false, n); }
		else { Ans[i] = "no"; memset(f, false, n); }
	
	}
	for (int i = 0; i < q;i++) {
		cout << Ans[i] << endl;
	}
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <unordered_set>

using namespace std;

template<typename ISTREAM>
void readGraphListFromFriendInfo(ISTREAM& cin, vector< unordered_set<int> >& friendGraphList) {
	size_t n;
	cin >> n;
	friendGraphList = vector< unordered_set<int> >(n);
	size_t m;
	cin >> m;
	for (auto& s : friendGraphList)s.reserve(m);
	for (size_t i = 0; i != m; ++i) {
		size_t s,t;
		cin >> s >> t;
		friendGraphList.at(s).insert(t);
		friendGraphList.at(t).insert(s);
	}
}

bool checkFriendAccesibility(const vector<unordered_set<int>>& graphList, const int s, const int t) {
	const size_t n = graphList.size();
	queue<int> nodeQueue;
	//vector<int> distanceList(n, -1);//
	vector<bool> isVisitList(n, false);//距離に興味はないのでbool
	nodeQueue.push(s);
	while (!nodeQueue.empty()) {
		const int id = nodeQueue.front();
		isVisitList.at(id).flip();//trueにする
		const auto& adjList = graphList.at(id);
		for (const auto& adjID : adjList) {
			if (isVisitList.at(adjID))continue;
			if (graphList.at(adjID).find(id) == graphList.at(adjID).end())continue;
			if (adjID == t)return true;
			nodeQueue.push(adjID);
		}
		nodeQueue.pop();
	}
	return false;
}

template<typename T>
void execute(T& cin) {
	vector< unordered_set<int> > graphList;
	readGraphListFromFriendInfo(cin, graphList);
	int q, s, t;
	cin >> q;
	for (int i = 0; i != q; ++i) {
		cin >> s >> t;
		cout << (checkFriendAccesibility(graphList, s, t) ? "yes" : "no") << endl;
	}
}

int main()
{
	execute(cin);
	return 0;
}