Go: package main

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

func main() {
	var n,m int
	fmt.Scan(&n)
	group := make([]int, n)
	g := make([][]int, n)
	for i := 0; i < n; i++ {
		g[i] = []int{}
		group[i] = -1
	}
	
	fmt.Scan(&m)
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	for i := 0; i < m; i++ {
		sc.Scan()
		s, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		t, _ := strconv.Atoi(sc.Text())
		
		g[s] = append(g[s], t)
		g[t] = append(g[t], s)
	}
	for i := 0; i < n; i++ {
		if group[i] != -1 {
			continue
		}
		q := []int{i}
		for len(q) > 0 {
			pop := q[0]
			if len(q) > 1 {
				q = q[1:]
			} else {
				q = []int{}
			}
			if group[pop] == -1 {
				q = append(q, g[pop]...)
				group[pop] = i
			}
		}
	}
	sc.Scan()
	q, _ := strconv.Atoi(sc.Text())
	for i := 0; i < q; i++ {
		sc.Scan()
		s, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		t, _ := strconv.Atoi(sc.Text())

		if group[s] == group[t] {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

func root(i int, group *[]int) int {
	if i == (*group)[i] {
		return i
	}
	(*group)[i] = root((*group)[i], group)
	return (*group)[i]
}

C++: #include <iostream>
#include <vector>
using namespace std;
vector<int> G[100];
vector<int> A;
int isVisited[100];

void setupVisited(int n)
{
    for (int i = 0; i < n; i++) {
	isVisited[i] = 0;
    }
}
bool enableConnection(int l, int o)
{
    for (int i = 0; i < G[l].size(); i++) {
	if (G[l][i] == o) {
	    return true;
	}
	if (isVisited[l] == 1) {
	    return false;
	}
	isVisited[l] = 1;
	if (enableConnection(G[l][i], o) || enableConnection(o, G[l][i])) {
	    return true;
	}
    }
    return false;
}

int main()
{
    int a, c;
    cin >> a;
    cin >> c;
    //setup
    for (int i = 0; i < c; i++) {
	int n;
	int m;
	cin >> n >> m;
	G[n].push_back(m);
	G[m].push_back(n);
	isVisited[i] = 0;
    }

    //then
    int b = 0;
    cin >> b;
    for (int i = 0; i < b; i++) {
	int l;
	int o;
	cin >> l;
	cin >> o;
	setupVisited(c);
	if (enableConnection(l, o) || enableConnection(o, l)) {
	    cout << "yes" << endl;
	} else {
	    cout << "no" << endl;
	}
    }
    return 0;
}

C++: #include <stdio.h>
#define rep(i, n) for(int i = 0; i < n; ++i)
 
int main(void) {
  int n, m;
  scanf("%d%d", &n, &m);
  int uf[n];
  rep(i, n) uf[i] = i;
  rep(i, m) {
    int s, t, nows, nowt;
    scanf("%d%d", &s, &t);
    nows = s, nowt = t;
    while(uf[nows] != nows) {
      nows = uf[nows];
    }
    while(uf[nowt] != nowt) {
      nowt = uf[nowt];
    }
    uf[nowt] = nows;
  }
  rep(i, n) {
    int nows = i;
    while(uf[nows] != nows) {
      nows = uf[nows];
    }
    uf[i] = nows;
  }
  /*rep(i, n) printf("%d ", uf[i]);
  printf("\n");*/
  int q;
  scanf("%d", &q);
  rep(i, q) {
    int s, t;
    scanf("%d%d", &s, &t);
    if(uf[s] != uf[t]) printf("no\n");
    else printf("yes\n");
  }
  return 0;
}

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

void dfs(int root, int node, vector<vector<int> >& adjlist, vector<int>& used){

    for(int i = 0; i < adjlist[node].size(); i++){
        if(used[adjlist[node][i]] == -1){
            used[adjlist[node][i]] = root;
            dfs(root, adjlist[node][i], adjlist, used);
        }
    }
}

int main(){

    int n, m; cin >> n >> m;

    vector<vector<int> > adjlist(n);               

    //入力
    for(int i = 0; i < m; i++){
        int a, b; cin >> a >> b;                   // a ←→ b に辺がある
        adjlist[a].push_back(b);
        adjlist[b].push_back(a);
        
    }

    vector<int> used(n, -1);

    for(int i = 0; i < n; i++){
        if(used[i] == -1){
            used[i] = i;
            dfs(i, i, adjlist, used);
        }
    }

    /*for(int i = 0; i < n; i++){
        cout << i << " " << used[i] << endl;
    }*/

    //質問
    int q; cin >> q;
    for(int i = 0; i < q; i++){
        int a, b; cin >> a >> b;
        
        
        if(used[a] == used[b]) cout << "yes" << endl;
        else cout << "no" << endl;
    }

    return 0;
}

C++: #include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <numeric>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define ll long long
#define ull unsigned long long
#define INF (1 << 30)
#define LLINF (1LL << 62)
#define MOD7 1000000007
#define MOD9 1000000009
#define eps 1e-9
#define P pair<int, int>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pul pair<ull, ull>
#define all(a) (a).begin(), (a).end()
#define FOR(i,a,b) for (int i=(a);i<(b);++i)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);--i)
#define REP(i,n) for (int i=0;i<(n);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)

void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void yes() { cout << "yes" << endl; }
void no() { cout << "no" << endl; }

template<class T>
class UnDirectedGraph {
public:
	class Edge {
	public:
		int to;
		T cost;

		Edge(int t, T c) : to(t), cost(c) {}

		bool operator<(const Edge& right) const {
			return cost == right.cost ? to < right.to : cost < right.cost;
		}
	};

	vector<vector<Edge>> G;
	int V;

	UnDirectedGraph(int n = 0) {
		resize(n);
	}

	void resize(int n) {
		V = n;
		G.resize(n);
	}

	void addEdge(int from, int to, T cost = 0) {
		int v = max(from, to);
		if (v >= V)
			resize(v + 1);
		G[from].push_back(Edge(to, cost));
		G[to].push_back(Edge(from, cost));
	}

	vector<int> visit;
	int col = 0;
	void dfs(int s) {
		//vector<int> visit(V);
		visit.resize(V);
		col++;
		calcDfs(visit, s);
	}

	void calcDfs(vector<int>& visit, int s) {
		if (visit[s])
			return;

		//visit[s] = 1;
		visit[s] = col;
		for (int i = 0; i < G[s].size(); ++i) {
			calcDfs(visit, G[s][i].to);
		}
	}

	vector<int> bfs(int s) {
		vector<int> dist(V);
		queue<int> que;

		fill(dist.begin(), dist.end(), -1);
		dist[s] = 0;
		que.push(s);
		while (!que.empty()) {
			int from = que.front();
			que.pop();
			for (int i = 0; i < G[from].size(); ++i) {
				int to = G[from][i].to;
				if (dist[to] != -1)
					continue;
				dist[to] = dist[from] + 1;
				que.push(to);
			}
		}

		return dist;
	}
};

int main() {
	int n, m, from, to;
	cin >> n >> m;
	UnDirectedGraph<int> g(n);
	while (m--) {
		cin >> from >> to;
		g.addEdge(from, to);
	}
	
	for (int i = 0; i < n; ++i)
		g.dfs(i);

	int q;
	cin >> q;
	while (q--) {
		cin >> from >> to;
		if (g.visit[from] == g.visit[to])
			yes();
		else
			no();
	}

	return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

#define Vi vector<int>
#define FOR(i,s,e) for (int i=s; i<e; i++)
#define ITER(v) v.begin(), v.end()

constexpr int N_MAX = 100'000;

Vi adj[N_MAX];

int n;
bool isconnected(const int a, const int b) {
    bool isqueued[N_MAX] = {false};
    queue<int> q;
    q.push(a);
    isqueued[a] = true;
    while (!q.empty()) {
        const int i = q.front();
        //cout << "#" << i << endl;
        if (i == b) { return true; }
        for (const int j : adj[i]) {
            if (isqueued[j]) { continue; }
            q.push(j);
            isqueued[j] = true;
        }
        q.pop();
    }
    return false;
}

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

    int m;
    cin >> n >> m;

    int a, b;
    FOR(i,0,m) {
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    /*
    cout << "adj read." << endl;
    FOR(i,0,n) {
        for (const int j : adj[i]) {
            cout << " " << j;
        }
        cout << endl;
    }
    */

    int q;
    cin >> q;
    FOR(i,0,q) {
        cin >> a >> b;
        cout << (isconnected(a, b) ? "yes" : "no") << endl;
    }

    return 0;
}