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 <cstdio>
#include <algorithm>
#define rep(i, n) for(int i=0; i<(n); ++i)

int parent[100005];

int find(int x){
   if( parent[x] == x )return x;
   return parent[x] = find( parent[x] );
}

void unite(int x, int y)
{
   x = find(x);
   y = find(y);

   if(x == y)return;
   parent[x] = y;
}

int main()
{
   int N, M;
   int x, y, tmp;
   scanf("%d%d", &N, &M);
   std::iota(parent, parent + N, 0);

   rep(i, M){
      scanf("%d%d", &x, &y);
      unite(x, y);
   }

   int Q;
   scanf("%d", &Q);
   while(Q--){
      scanf("%d%d", &x, &y);
      puts( find(x) == find(y) ? "yes" : "no" );
   }
}

C++: #include <iostream>
#include <cstdio>
using namespace std;

const int maxm = 100000 + 5;
const int maxn = 100000 + 5;

struct Edge{
	int to,next;
}G[maxm<<1];

int head[maxn],cnt = 0;
int color[maxn];
bool vis[maxn];

void Insert(int u,int v){
	G[++cnt].next = head[u];
	G[cnt].to = v;
	head[u] = cnt;
}

void Dfs(int u,int c){
	vis[u] = true;
	color[u] = c;
	for(int e = head[u];e; e = G[e].next){
		int v = G[e].to;
		if(!vis[v]){
			Dfs(v,c);
		}
	}
}

int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= m; i++){
		int u,v;
		scanf("%d%d",&u,&v);
		Insert(u,v);
		Insert(v,u);
	}
	for(int i = 1;i <= n; i++){
		if(!vis[i]){
			Dfs(i,i);	
		}
	}
	int q;
	scanf("%d",&q);
	for(int i = 1;i <= q; i++){
		int u,v;
		scanf("%d%d",&u,&v);
		if(color[u] == color[v])printf("yes\n");
		else printf("no\n");
	}
}

C++: #include<iostream>
#include<vector>
#include<stack>
using namespace std;
static const int MAX = 100000;
static const int NIL = -1;

int n;
vector<int> G[MAX];
int color[MAX];

void dfs(int r,int c){
  stack<int> S;
  S.push(r);
  color[r] = c;
  while(!S.empty()){
    int u = S.top();
    S.pop();
    for(int i = 0;i<G[u].size();i++){
      int v = G[u][i];
      if(color[v]==NIL){
	color[v] = c;
	S.push(v);
      }
    }
  }
}

void assignColor(){
  int id = 1;
  for(int i = 0; i< n; i++) color[i] = NIL;
  for(int u = 0; u<n;u++){
    if(color[u] == NIL) dfs(u,id++);
  }
}

int main(){
  int s,t,m,q;

  cin>>n>>m;

  for(int i = 0;i<m;i++){
    cin>>s>>t;
    G[s].push_back(t);
    G[t].push_back(s);
  }
  assignColor();

  sin>>q;

  for(int i = 0;i<q;i++){
    cin>>s>>t;
    if(color[s] == color[t]){
      cout<<"yes"<<endl;
    }else{
      cout<<"no"<<endl;
    }
  }
  return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;

vector<int> g[100005];
int color[100005];
const int INF = 1001001001;
int nc = 0;

void dfs(int x, int b=-1){
    color[x] = nc;
    if(g[x].empty())return;
    for (int i = 0; i < g[x].size(); i++){
        int v = g[x][i];
        if(color[v] != INF)continue;
        color[v] = nc;
        dfs(v, x);
    }
    return;
}

int main() {
    int n, m; cin >> n >> m;
    rep(i, m){
        int s, t; cin >> s >> t;
        g[s].push_back(t);
        g[t].push_back(s);
    }

    rep(i, n){
        color[i] = INF;
    }

    rep(i, n){
        if(color[i] == INF){
            dfs(i);
            nc++;
        }
    }
    
    int q; cin >> q;
    rep(i, q){
        int s, t; cin >> s >> t;
        if(color[s] == color[t]){
            cout << "yes" << endl;
        } else {
            cout << "no" << endl;
        }
    }

    
    return 0;
}

C++: #include <iostream>
#include <vector>
using namespace std;

vector< int > connections;

void addConnection(int a, int b) {
  if (connections[a] == a && connections[b] == b)
    a < b ? connections[b] = a : connections[a] = b;
  else if (connections[a] == a)
    addConnection(a, connections[b]);
  else if (connections[b] == b)
    addConnection(connections[a], b);
  else
    addConnection(connections[a], connections[b]);
}

bool checkConnection(int a, int b) {
  if (connections[a] == a && connections[b] == b) {
    if (a == b)
      return true;
    else
      return false;
  } else if (connections[a] == a) {
    return checkConnection(a, connections[b]);
  } else if (connections[b] == b) {
    return checkConnection(connections[a], b);
  } else
    return checkConnection(connections[a], connections[b]);
}

int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  connections = vector< int > (n, -1);
  for (int i = 0; i < n; i++)
    connections[i] = i;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    addConnection(a, b);
  }
  int q;
  cin >> q;
  // for (int i = 0; i < n; i++)
  //   cout << connections[i] << ' ';
  // cout << endl;
  for (int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b;
    // cout << a << ' ' << b << endl;
    if (checkConnection(a, b))
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }
  return 0;
}

C++: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int maxx=100100;
vector<int> A[maxx];
int color[maxx];
int n,c=1;

void dfs(int u){
	if(color[u]!=-1) return ;//当该节点已经属于某一联通分量时，不需要染色
	color[u]=c;
	int si=A[u].size();
	for(int i=0;i<si;i++){
		if(color[A[u][i]]==-1){//注意是对A[u][i]进行染色
			dfs(A[u][i]);
		}
	}
	return ;
}

int main(){
	int q,a,b;//这里有个问题，n如果放在global里定义的话会出现问题，只能在main里定义，不知道为什么
	cin>>n>>q;
//	
//	cout<<&n<<endl<<&color<<endl<<&color[109]<<endl;
//	cout<<n<<endl;
	for(int i=0;i<=maxx;i++) color[i]=-1;
//	cout<<n<<endl;
	for(int i=1;i<=q;i++){
		cin>>a>>b;
		A[a].push_back(b);
		A[b].push_back(a);
	}
	for(int i=0;i<n;i++){
		dfs(i);
		c++;
	}
	cin>>q;
	for(int i=1;i<=q;i++){
		cin>>a>>b;
		if(color[a]==color[b]) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
	return 0;
}