Go: package main

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

func main() {
	var n,m int
	fmt.Scan(&n)
	group := make([]int, n)
	for i := 0; i < n; i++ {
		group[i] = i
	}
	
	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())

		if group[s] < group[t] {
			group[t] = group[s]
		} else {
			group[s] = group[t]
		}
	}

	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 root(s, &group) == root(t, &group) {
			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 <vector>
#include <math.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <iomanip>
#include <deque>
#include <map>

typedef long long ll;
#define rep(i, a, n) for(ll i = a; i<n; i++)
#define ALL(a) begin(a), end(a)
#define mii map<int, int>
#define msi map<string, int>
#define vi vector<int>
#define vl vector<ll>
#define MOD 1000000007
#define INF 1e9
#define showVector(v) rep(i,0,v.size()){p(v[i]);p(" ")} pl("")
#define p(s) std::cout << s ;
#define pl(s)  std::cout << s << endl;
using namespace std;

// 素数判定 O(√n)
bool is_prime(int n){
    for(int i = 2; i * i <= n; i++){
        if(n % i == 0) return false;
    }
    return true;
}

template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;

}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
class UnionFind {
public:
    vector<ll> par;
    void init(ll n) {
        rep(i, 0, n) {
            //par[i] == iのとき、iの親はiとなるから初期化では全て根であるとする。
            par.push_back(i);
        }
    }

    ll root(ll x) {
        if (par[x] == x) {
            return x;
        } else {
            return par[x] = root(par[x]);
        }
    }

    // これは併合するために使う
    bool unite(ll x, ll y) {
        x = root(x);
        y = root(y);
        // 併合済ならばfalse
        if (x == y) return false;

        par[y] = x;
        return true;
    }

    bool isSame(ll x, ll y) {
        return root(x) == root(y);
    }
};
int main() {
    ll n, m;;
    cin >> n >> m;
    UnionFind T;
    T.init(n);
    rep(i, 0, m) {
        ll b, c;
        cin >> b >> c;
        T.unite(b, c);
    }
    int q;
    cin >> q;
    rep(i, 0, q) {
        ll b, c;
        cin >> b >> c;
        if (T.isSame(b, c)) {
            cout << "yes" << endl;
        } else {
            cout << "no" << endl;
        }

    }
    return 0;
}

C++: #include <iostream>
#include <stdint.h>
#include <vector>

using namespace std;

#define GRAPH_MAX_SIZE 100000
#define WHITE -1

vector<uint32_t> vertexes[GRAPH_MAX_SIZE];
int32_t colors[GRAPH_MAX_SIZE];

void graph_connected_components_init()
{
  uint32_t i;
  for (i = 0; i < GRAPH_MAX_SIZE; i++) {
    vertexes[i].clear();
    colors[i] = WHITE;
  }
}

void graph_connected_components_add(uint32_t vertex, uint32_t connect_to)
{
  vertexes[vertex].push_back(connect_to);
  vertexes[connect_to].push_back(vertex);
}

uint32_t *graph_connected_components_connected_vertexes(uint32_t vertex)
{
  return &vertexes[vertex][0];
}

void colorize_connecting_vertex(vector<uint32_t> *connect_to, int32_t color)
{
  uint32_t i;
  for (i = 0; i < connect_to->size(); i++) {
    uint32_t index = (*connect_to)[i];
    if (colors[index] == WHITE) {
      colors[index] = color;
      colorize_connecting_vertex(&vertexes[index], color);
    }
  }
}

void graph_connected_components_colorize()
{
  int32_t i;
  for (i = 0; i < 20; i++) {
    if (colors[i] == WHITE) {
      colors[i] = i;
      vector<uint32_t> connect_to = vertexes[i];
      colorize_connecting_vertex(&connect_to, i);
    }
  }
}

bool graph_connected_components_is_connected(uint32_t index1, uint32_t index2)
{
  if (colors[index1] == colors[index2]) return true;
  return false;
}

#if !defined(TEST)
#include <iostream>
using namespace std;
int32_t main(void)
{
  graph_connected_components_init();

  int32_t users, connections;
  cin >> users >> connections;

  uint32_t i;
  for (i = 0; i < connections; i++) {
    uint32_t index, connection;
    cin >> index >> connection;
    graph_connected_components_add(index, connection);
  }
  graph_connected_components_colorize();

  int32_t questions;
  cin >> questions;
  for (i = 0; i < questions; i++) {
    uint32_t index1, index2;
    cin >> index1 >> index2;
    if (graph_connected_components_is_connected(index1, index2)) {
      cout << "yes" << endl;
    } else {
      cout << "no" << endl;
    }
  }

  return 0;
}
#endif

C++: #include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
#define int ll

int rabel[100010], now_rabel;
bool is_search[100010];
vector<int> s, t;

void dfs(int p) {
  //cout << "now p = " << p << endl;
  //cout << "rabel[" << p << "] = " << now_rabel << endl;
  is_search[p] = true;
  rabel[p] = now_rabel;

  for (int i = 0; i < s.size(); i++) {
    if (s[i] > p) break;
    if (s[i] == p && is_search[t[i]] == false) {
      //cout << s[i] << " " << t[i] << endl;
      dfs(t[i]);
    }
  }
  //cout << "end p = " << p << endl;
}

signed main(void) {
  int n, m, o, p, q;

  cin >> n >> m;

  for (int i = 0; i < m; i++) {
    cin >> o >> p;
    s.push_back(o);
    t.push_back(p);
  }

  int k = 0, i;

  while(1) {
    dfs(k);

    for (i = 0; i < n; i++) {
      if (is_search[i] == false) {
        k = i;
        break;
      }
    }
    if(i == n) break;
    now_rabel = k;
    //cout << "rabel changed\n";
  }

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

  cin >> q;

  for (int i = 0; i < q; i++) {
    cin >> o >> p;
    if(rabel[o] == rabel[p]) {
      cout << "yes\n";
    } else {
      cout << "no\n";
    }
  }
  return 0;
}

C++: 
#include<iostream>
#include<vector>
#include<cinttypes>
#include<numeric>


using ui32 = std::uint32_t;

class union_find {
public:
	using size_type = decltype(std::declval<std::vector<int>>().size());
private:
	std::vector<size_type> par;
	std::vector<size_type> size_;

public:
	union_find() :par{}, size_{} {}
	union_find(size_type s) :union_find{} {
		par.resize(s);
		std::iota(std::begin(par), std::end(par), 0);

		size_.resize(s, 1);
	}

	auto root(size_type index_)->size_type {
		if (par[index_] == index_)
			return
				par[index_];
		else
			return
				par[index_] = root(par[index_]);
	}

	auto size(size_type index_) {
		return size_[root(index_)];
	}

	auto same(size_type ai, size_type bi) {
		return root(ai) == root(bi);
	}

	auto unite(size_type ai, size_type bi) {
		auto ar = root(ai);
		auto br = root(bi);

		if (ar == br)
			return;

		const auto as = size(ar);
		const auto bs = size(br);

		if (as >= bs)
			std::swap(ar, br);

		par[br] = par[ar];

		if(as == bs)
			size_[ar] = size_[br] = as + bs + 1;

	}

};

int main() {

	ui32 n, m, q;

	std::cin >> n >> m;
	union_find uf(n);
	for (ui32 i{}; i < m; ++i) {
		ui32 s, t;
		std::cin >> s >> t;
		uf.unite(s, t);
	}

	std::cin >> q;
	for (ui32 i{}; i < q; ++i) {
		ui32 s, t; 
		std::cin >> s >> t;
		const auto ans = uf.same(s, t)?"yes":"no";
		std::cout << ans << "\n";
	}
	return 0;
}