Go: package main

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

var (
	n     int
	G     [100000][]int
	color [100000]*int
)

func dfs(r int, c int) {
	S := Stack{}
	S.Push(r)
	color[r] = &c
	for !S.IsEmpty() {
		u := S.Pop()
		for i := 0; i < len(G[u]); i++ {
			v := G[u][i]
			if color[v] == nil {
				color[v] = &c
				S.Push(v)
			}
		}
	}
}

func assignColor() {
	id := 1
	for i := 0; i < n; i++ {
		color[i] = nil
	}
	for u := 0; u < n; u++ {
		if color[u] == nil {
			id++
			dfs(u, id)
		}
	}
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Scan()
	n, _ = strconv.Atoi(sc.Text())
	sc.Scan()
	r, _ := strconv.Atoi(sc.Text())

	for i := 0; i < r; 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)
	}
	assignColor()
	sc.Scan()
	qNum, _ := strconv.Atoi(sc.Text())
	for i := 0; i < qNum; i++ {
		sc.Scan()
		s, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		t, _ := strconv.Atoi(sc.Text())
		if color[s] == color[t] {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

// Stack is Stack
type Stack struct {
	stack []int
}

// Push new value
func (stack *Stack) Push(val int) {
	stack.stack = append(stack.stack, val)
}

// Pop new value
func (stack *Stack) Pop() int {
	val := stack.stack[len(stack.stack)-1]
	stack.stack = stack.stack[0 : len(stack.stack)-1]
	return val
}

// IsEmpty return true when stack is empty
func (stack *Stack) IsEmpty() bool {
	return len(stack.stack) == 0
}

C++: #include<vector>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#define INF 100000000000000
using namespace std;
typedef long long llong;

//int isalpha(char ch): ch がアルファベットなら true を返す
//int isdigit(char ch): ch が数字なら true を返す
//int islower(char ch): ch が小文字なら true を返す
//int isupper(char ch): ch が大文字なら true を返す
//int tolower(char ch): ch の小文字を返す
//int toupper(char ch): ch の大文字を返す

//string型
//size()	文字数を返す
//Insert()	（指定した場所に）文字・文字列を挿入する
//erase()	（指定した場所の）文字・文字列を削除する
//clear()	すべての文字を削除する
//substr()	文字列の（指定した）部分文字列を返す
//replace()	（指定した）部分文字列を新しい文字列に置換する
//文字列の比較は、<=や==などを使え
//replace関数を使い、簡単に文字列を置換
//リバース関数：reverse(str.begin(), str.end());
//map<type, type> dict;で宣言
//グラフ理論用変数
//vector<vector<llong> > graph(N);

//ソート
//降順sort(v.begin(), v.end(), std::greater<Type>());

//大文字から小文字へんかん
//w[i] = w[i]-'A'+'a';

//vector
//assignメソッド　引数：サイズ、値
//与えられたサイズと値でvectorを初期化する

void dfs(vector<vector<llong> > &graph, vector<bool> &seen, vector<llong> &color, llong node, llong now_color){
    if(seen[node]){
        return;
    }
    seen[node] = true;
    color[node] = now_color;
    for(int i=0; i<graph[node].size(); i++){
        dfs(graph, seen, color, graph[node][i], now_color);
    }
}

int main(){
    llong n,m;
    llong s,t;
    llong now_color=0;
    scanf("%lld %lld", &n, &m);
    vector<vector<llong> > graph(n);
    vector<bool> seen(n, false);
    vector<llong> color(n, 0);

    for(int i=0; i<m; i++){
        scanf("%lld %lld", &s, &t);
        graph[s].push_back(t);
        graph[t].push_back(s);
    }
    for(int i=0; i<n; i++){
        if(seen[i]){
            continue;
        }
        dfs(graph, seen, color, i, now_color);
        now_color++;
    }
    llong q;
    cin >> 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 <stdio.h>

int m[100000] = {0};

void init() {
	int i;
	for ( i = 0; i < 100000; ++i) {
		m[i] = i;
	}
}

int find(int a) {
	if ( a == m[a]) {
		return a;
	}
	return m[a] = find(m[a]);
}

int friend(int x, int y) {
	if ( find(x) == find(y)) {
		return 1;
	} else {
		return 0;
	}
}

void unit (int x, int y) {
	x = find(x);
	y = find(y);
	
	if ( x == y ) {
		return ;
	}
	m[y] = x;
}

int main() {
	int n, s, t, u, v, i;
	init();
	scanf("%d", &n);
	scanf("%d", &s);
	
	for ( i = 0; i < s; i++) {
		scanf("%d %d", &u, &v);
		unit( u, v);
	}
	
	scanf("%d", &t);
	
	for ( i = 0; i < s; i++) {
		scanf("%d %d", &u, &v);
		if ( friend( u, v) == 1) {
			printf("yes\n");
		} else {
			printf("no\n");
		}
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define MAX 100000
#define NIL -1

int n, m;
vector<int> V[MAX];
int color[MAX];

void search(int s){
  // init
  queue<int> Q;

  Q.push(s);
  int c = color[s] = s;
  while (!Q.empty()){
    int u = Q.front();
    Q.pop();
    for ( int i = 0; i < V[u].size(); i++){
      if ( color[V[u][i]] == NIL ){
        Q.push(V[u][i]);
        color[V[u][i]] = c;
      }
    }
  }
}

int main(){
  cin >> n >> m;

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

  for ( int i = 0; i < n; i++){ color[i] = NIL; }
  for ( int i = 0; i < n; i++){
    if ( color[i] == NIL){
      search(i);
    }
  }

  int q;
  cin >> 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 <vector>
#include <cstdio>
class union_find{
	std::vector<int> parent;
public:
	int root(int a){return parent[a]==a?a:(parent[a]=root(parent[a]));}
	union_find(int n):parent(n+1){for(int i=1;i<=n;i++)parent[i]=i;}
	int same(int a,int b){return root(a)==root(b);}
	int unite(int a,int b){
		int x=root(a),y=root(b);//if(x==y)return 0;
		parent[x]=y;
		return 1;
	}
};
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	union_find uf(n);
	int a,b;
	for(;m--;uf.unite(a,b))scanf("%d%d",&a,&b);
	for(scanf("%d",&m);m--;puts(uf.same(a,b)?"yes":"no"))scanf("%d%d",&a,&b);
}

C++: //
//
//  ad-algoD.cpp - created by us162022
//
#include <iostream>
using namespace std;
int find(int join[],int x){
  if(x==join[x])
    return x;

  return join[x];
}
int main(int argc, char *argv[])
{
  int n,m,join[100000],num[100000],s,t;
  cin >> n >> m;

  for(int i=0; i<n; i++){
    join[i] = i;
    num[i] = 0;
  }

  for(int i=0; i<m; i++){
    cin >> s >> t;
    s = find(join,s);
    t = find(join,t);

    if(s!=t){
      if(num[s] < num[t])
	join[s] = join[t];
      
      else{
	join[t]=join[s];
	if(num[s]==num[t])
	  num[s]++;
      }

    }
  }

  int q;
  cin >> q;

  for(int i=0; i<q; i++){
    cin >> s >> t;

    if(find(join,s)==find(join,t))
      cout << "yes\n";

    else
      cout << "no\n";
  }
}

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

bool DFS(vector<vector<int> >& G, int a, int b) {
    if (G[a].size() == 0) return false;

    stack<pair<int, int> > S;
    vector<bool> is_visited(G.size(), false);

    int idx = 0;
    do {
        if (idx >= G[a].size()) {
            a   = S.top().first;
            idx = S.top().second;
            S.pop();
            idx++;
            continue;
        }
        if (G[a][idx] == b) return true;
        if (!is_visited[G[a][idx]]) {
            is_visited[G[a][idx]] = true;
            S.push(make_pair(a, idx));
            a   = G[a][idx];
            idx = 0;
            continue;
        }
        idx++;
    } while (!S.empty());
    return false;
}


int main(){
    int n, m;
    cin >> n >> m;

    vector<vector<int> > G(n);
// bool D[100000][100000];

    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

// for (int i = 0; i < n; i++) {
//     cout << i << " : ";
//     for (set<int>::iterator it = G[i].begin(); it != G[i].end(); it++){
//         cout << *it << " ";
//     }
//     cout << endl;
// }



    int q;
    cin >> q;
    for (int i = 0; i < q; i++) {
        int a, b;
        cin >> a >> b;
        if (DFS(G, a, b)) {
            cout << "yes" << endl;
        } else {
            cout << "no"  << endl;
        }
    }
    return 0;
}