Go: package main

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

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	nNodes := scanInt(sc)
	nConns := scanInt(sc)

	graph := make([][]int, nNodes)
	for i := 0; i < nConns; i++ {
		a, b := scanInt(sc), scanInt(sc)
		graph[a] = append(graph[a], b)
		graph[b] = append(graph[b], a)
	}

	groups := make([]int, nNodes)

	var setGroups func(int, int)
	setGroups = func(u int, groupId int) {
		if groups[u] > 0 {
			return
		}
		groups[u] = groupId

		for _, v := range graph[u] {
			setGroups(v, groupId)
		}
	}
	for i := 0; i < nNodes; i++ {
		setGroups(i, i+1)
	}

	nQuestions := scanInt(sc)

	w := bufio.NewWriter(os.Stdout)
	var ans string
	for i := 0; i < nQuestions; i++ {
		a, b := scanInt(sc), scanInt(sc)
		if groups[a] == groups[b] {
			ans = "yes"
		} else {
			ans = "no"
		}
		fmt.Fprintln(w, ans)
	}
	w.Flush()
}

func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

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

#define rep(i,n) for(int i = 0; i < n; i++)
#define Rep(i,n) for(int i = 1; i <= n; i++)
#define sz(x) int(x.size())
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define YesorNo(a) printf(a ? "Yes\n" : "No\n")
#define endl '\n'
#define fi first
#define se second
using ll = long long;
using P = pair<int,int>;
using Pl = pair<ll,ll>;
template<class T> using V = vector<T>;
const int dx[] = {0,1,0,-1,1,1,-1,-1};
const int dy[] = {1,0,-1,0,1,-1,-1,1};
const int inf = (1<<30)-1;
const ll infll = (1LL<<62)-1;
ll ceil(const ll &a, const ll &b){return ((a)+(b)-1)/b;}
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; }


struct UnionFind { // UnionFindTree
  vector<int> d;
  UnionFind(int n): d(n,-1) {}
  int find(int x) {
    if(d[x] < 0) return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return false;
    if(-d[x] < -d[y]) swap(x,y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -d[find(x)]; }
};


int main(){
    int n, m;
    cin >> n >> m;
    UnionFind uf(n);
    rep(i,m) {
        int a, b;
        cin >> a >> b;
        uf.unite(a,b);
    }
    
    int q;
    cin >> q;
    rep(i,q) {
        int a, b;
        cin >> a >> b;
        if(uf.same(a,b))
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}

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();
	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 <iostream>
#include <vector>
#define N 100000
#define white 0
using namespace std;

int color[N], n, S[N];
vector<int> c[N];



void tansaku_2(int a, int b) {
    int i, t, co, u;
    S[0] = a;
    t = 0;
    co = 1;
    while (1) {
        u = S[t];
        for (i = 0; i < c[u].size(); ++i) {
            if (color[c[u][i]] == white){
                color[c[u][i]] = b;
                S[co++] = c[u][i];
            }
        }
        S[t++] = 0;
        if (t == co) break;
    }
}

void tansaku() {
    int i, d;
    d = 1;
    
    for (i = 0; i < n; ++i) {
        if (color[i] == white) {
            color[i] = d;
            tansaku_2(i , d++);
        }
    }
}

int main() {
    int m, q, i, a, b;
    
    cin >> n >> m;
    for (i = 0; i < n; ++i) {
        color[i] = white;
    }
    for (i = 0; i < m; ++i) {
        cin >> a >> b;
        c[a].push_back(b);
        c[b].push_back(a);
    }
    tansaku();
    
    cin >> q;
    
    for (i = 0; i < q; ++i) {
        scanf("%d %d", &a, &b);
        if (color[a] == color[b]) {
            cout << "yes" << endl;
        }
        else{
            cout << "no" << endl;
        }
    }
    return 0;
}

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

using namespace std;

#define MAX 100000
const int NIL = -1;

int n;
vector<int> G[MAX];
int color[MAX];
void assignColor();
void bfs(int,int);

int main(){
  int s,t,m,q,i;
  cin >> n >> m;
  for(i = 0; i < m; i++){
    cin >> s >> t;
    G[s].push_back(t);
    G[t].push_back(s);
  }
  assignColor();
  cin >> q;
  for(i = 0; i < q; i++){
    cin >> s >> t;
    if( color[s] == color[t]){
      cout << "yes" << endl;
    }
    else{
      cout << "no" << endl;
    }
  }
  return 0;
}

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

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

C++: //#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
#define rep(i, n) for(int i=0; i<n; ++i)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
using namespace std;
using ll = int64_t;
using ld = long double;
using P = pair<int, int>;
using vs = vector<string>;
using vi = vector<int>;
using vvi = vector<vi>;
const int INF = 100010001;
const ll LINF = (ll)INF*INF*10;

struct UnionFind {
    vector<int> par; // 親を指すvector,-par[親]は木のサイズ
    UnionFind(int n):par(n, -1) {} // uniteで親を埋め込んでいく必要あり
    int root(int x) { // 親をたどる&データの整理
        if(par[x] < 0) return x;
        return par[x] = root(par[x]);
    }
    bool unite(int x, int y) { // データの結合
        x = root(x);
        y = root(y);
        if(x == y) return false;
        if(par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    bool same(int x, int y) {return root(x) == root(y);} // 所属判定
    int size(int x) {return -par[root(x)];} // 木のサイズ
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    UnionFind uft(n);
    rep(i, m) {
        int s, t;
        cin >> s >> t;
        uft.unite(s, t);
    }
    int q;
    cin >> q;
    while(q--) {
        int i, j;
        cin >> i >> j;
        cout << (uft.same(i, j)?"yes":"no") << endl;
    }
}