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;
// #define int long long
using ll=long long;
using vi=vector<int>;
using vl=vector<long long>;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
#define ITR(v,c) for(auto v=begin(c);v!=end(c);v++)
#define FORE(x,c) for(auto &x:c)
#define FOR(v,a,n) for(int v=a;v<(int)(n);v++)
#define REP(v,n) FOR(v,0,n)
#define RREP(v,n) for(int v=((int)(n)-1);v>=0;v--)
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define SZ(c) ((int)c.size())
const int DX[9]={0,1,0,-1,1,1,-1,-1,0}, DY[9]={-1,0,1,0,-1,1,1,-1,0};
const int INF=1e9; const long long INFLL=1e18;
template<class T> ostream& operator << (ostream &os, const vector<T> &v) {
    ITR(i,v) os<<*i<<(i==end(v)-1?"":" "); return os; }
template<class T> istream& operator >> (istream &is, vector<T> &v) {
    ITR(i,v) is>>*i; return is; }
//------------------------------------------------------------------------------

//-------- Union Find
struct UnionFind {
	vector<int> data;
	UnionFind(int size) : data(size, -1) { }
    bool unionSet(int x, int y) {
	    x = root(x); y = root(y);
        if(x != y) {
            if(data[y] < data[x]) swap(x, y);
            data[x] += data[y]; data[y] = x;
        }
        return x != y;
	}
	bool findSet(int x, int y) {
	    return root(x) == root(y);
    }
	int root(int x) {
        return data[x] < 0 ? x : data[x] = root(data[x]);
    }
    int size(int x) {
        return -data[root(x)];
    }
};

signed main() {
    int n,m;
    cin>>n>>m;
    UnionFind uf(n);
    REP(i,m) {
        int a,b;
        cin>>a>>b;
        a--,b--;
        uf.unionSet(a,b);
    }

    int q;
    cin>>q;
    REP(i,q) {
        int a,b;
        cin>>a>>b;
        a--,b--;
        if(uf.root(a)==uf.root(b)) {
            cout<<"yes"<<endl;
        }
        else {
            cout<<"no"<<endl;
        }
    }
    return 0;
}

C++: #include <iostream>
#include <stdio.h>
#include <stack>
#include <vector>

using namespace std;
const int nil = -1;

int total, n, m, q;

vector<int>* vecs;
typedef int Comm;
Comm* comms;

void find_connection(int from){
	stack<int> stk;
	stk.push(from);

	while(stk.size()){
		int top = stk.top();
		comms[top] = from;
		for(int i=0, sz=vecs[top].size(); i<=sz; ++i){
			if(i==sz){
				stk.pop();
				break;
			}
			if(comms[vecs[top][i]] == nil){
				stk.push(vecs[top][i]);
				break;
			}
		}
	}
}

int main()
{
	scanf("%d %d",&n,&m);
	vecs = new vector<int> [n];
	comms = new Comm [n];

	for(int i=0; i<n; ++i){
		comms[i] = nil;
	}

	for(int i=0; i<m; ++i){
		int id, f;
		scanf("%d %d",&id,&f);
		vecs[id].push_back(f);
		vecs[f].push_back(id);
	}

	scanf("%d",&q);
	for(int i=0; i<q;++i){
		int from, to;
		scanf("%d %d",&from,&to);
		if(comms[from]==nil && comms[to]==nil){
			find_connection(from);
			if(comms[from] == comms[to]){
				cout << "yes" << endl;
			}
			else{
				cout << "no" << endl;
			}
		}
		else if(comms[from] == comms[to]){
			cout << "yes" << endl;
		}
		else{
			cout << "no" << endl;
		}
	}

	delete[] comms;
	delete[] vecs;

	return 0;
}

C++: #include<iostream>
#include<vector>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAX 100000+5
int color[MAX];
vector<int> u[MAX];
int num;
void ranse(int p,int color_num){
	stack<int> s;
	int a;
	s.push(p);color[p]=color_num;
	while(!s.empty()){
		a=s.top();s.pop();
		for(int i=0;i<u[a].size();i++){
		if(color[u[a][i]]==-1){
			s.push(u[a][i]);color[u[a][i]]=color_num;
		}
	}
	}
}
int main(){
	int m;
	memset(color,-1,sizeof(color));
	cin>>num>>m;
	for(int i=0;i<m;i++){
		int a,b;
		cin>>a>>b;
		u[a].push_back(b);u[b].push_back(a);
	}
	int color_num=0;
	for(int i=0;i<num;i++){
		if(color[i]==-1){
			ranse(i,color_num);color_num++;
		}
	}
	int order_num;
	cin>>order_num;
	for(int i=0;i<order_num;i++){
		int a,b;
		cin>>a>>b;
		if(color[a]==color[b]) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
}

C++: //16D8103013E Sen Shunkou
#include<iostream>
#include<queue>
int main(){
    //input
    int n,m;
    std::cin>>n;
    std::cin>>m;
    int A[n][n];
    bool visited[n];
    int judge[n];

    for(int i=0;i<n;i++){
        judge[i]=-1;
        visited[i]=false;
        A[i][0]=0;
        for(int j=1;j<n;j++){
            A[i][0]=0;
            A[i][j]=-1;
        }    
    }

    int cnt_i=0,cnt_j=0;
    for(int k=0;k<m;k++){
        int i,j;
        std::cin>>i;
        std::cin>>j;
        A[i][0]++; cnt_i=A[i][0];
        A[j][0]++; cnt_j=A[j][0];
        A[i][cnt_i]=j;
        A[j][cnt_j]=i;
    }

    /*for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            std::cout<<" "<<A[i][j];
        }
        std::cout<<std::endl;
    }*/

    int n_2;
    std::cin>>n_2;
    for(int i=0;i<n_2;i++){
        int s,e;
        std::cin>>s;
        std::cin>>e;
        
        int cnt=0;
        for(int i=0;i<n;i++){
            judge[i]=-1;
            visited[i]=false;
        }
        
        std::queue<int> que;
        que.push(s);
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                //std::cout<<" "<<A[i][j];
            }
            //std::cout<<std::endl;
        }
        while(!que.empty()){
            int q=que.size();
            for(int k=0;k<q;k++){
                //std::cout<<"quesize"<<que.size()<<"\n";
                int i=que.front();
                que.pop();
                visited[i]=true;
                judge[i]=cnt;
                //std::cout<<i<<"cnt"<<cnt<<"\n";
                //std::cout<<A[i][0]<<"\n";
                if(A[i][0]!=0){
                    for(int j=0;j<A[i][0];j++){
                        if(visited[A[i][j+1]]!=true){
                            visited[A[i][j+1]]=true;
                            que.push(A[i][j+1]);
                        }
                    }
                }
            }
            cnt++;
        }
        if(judge[e]==-1){
            std::cout<<"no\n";
        }else std::cout<<"yes\n";
    }

    return 0;
}