Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func newGraph(nNodes int) *Graph {
	g := Graph{}
	g.nodes = make([]*GraphNode, nNodes)
	for iNode := 0; iNode < len(g.nodes); iNode++ {
		g.nodes[iNode] = &GraphNode{}
		g.nodes[iNode].key = GraphNodeKey(iNode)
	}
	return &g
}

var infty = 1000000000

type GraphNodeKey int

// GraphNode is a node for undirected graph
type GraphNode struct {
	key       GraphNodeKey
	adjacents []*GraphNode
	visited   bool
	d, f      int
	parent    *GraphNode
	cc        int
}

func (g *Graph) setAdjacent(l, r GraphNodeKey) {
	g.nodes[l].adjacents = append(g.nodes[l].adjacents, g.nodes[r])
}

// Graph is a undirected graph
type Graph struct {
	nodes []*GraphNode
}

func (g *Graph) initialize() {
	for iNode := 0; iNode < len(g.nodes); iNode++ {
		g.nodes[iNode].visited = false
		g.nodes[iNode].d = infty
		g.nodes[iNode].f = infty
		g.nodes[iNode].parent = nil
		g.nodes[iNode].cc = -1 // 22.3-12
	}
}

type QueueEntry struct {
	node *GraphNode
	next *QueueEntry
}

type Queue struct {
	head, tail *QueueEntry
}

func (q *Queue) enqueue(node *GraphNode) {
	entry := QueueEntry{}
	entry.node = node

	if q.tail == nil {
		q.head = &entry
		q.tail = &entry
		return
	}

	q.tail.next = &entry
	q.tail = q.tail.next
}

func (q *Queue) dequeue() *QueueEntry {
	if q.head == nil {
		return nil
	}
	poped := q.head
	q.head = q.head.next
	if q.head == nil {
		q.tail = nil
	}
	return poped
}

func (q *Queue) isEmpty() bool {
	return q.head == nil
}

var time = 0

func fillDistancesByDepthFirstSearch(g *Graph) {
	g.initialize()
	time = 0
	cc := 0

	for _, u := range g.nodes {
		if !u.visited {
			dfsVisit(g, u, cc)
			cc++
		}
	}
}

func dfsVisit(g *Graph, u *GraphNode, cc int) {
	time++
	u.d = time
	u.cc = cc

	u.visited = true
	for _, v := range u.adjacents {
		if !v.visited {
			v.parent = u
			dfsVisit(g, v, cc)
		}
	}
	time++
	u.f = time
}

func main() {
	scanner.Split(bufio.ScanWords)

	nUsers := nextInt()
	nEdges := nextInt()
	graph := newGraph(nUsers)
	for iEdge := 0; iEdge < nEdges; iEdge++ {
		l := GraphNodeKey(nextInt())
		r := GraphNodeKey(nextInt())
		graph.setAdjacent(l, r)
		graph.setAdjacent(r, l)
	}

	fillDistancesByDepthFirstSearch(graph)

	nQueries := nextInt()
	for iQuery := 0; iQuery < nQueries; iQuery++ {
		l := GraphNodeKey(nextInt())
		r := GraphNodeKey(nextInt())

		// fmt.Println(graph.nodes[l].d, graph.nodes[r].d, graph.nodes[r].f, graph.nodes[l].f)
		if graph.nodes[l].cc == graph.nodes[r].cc {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

Python: import sys
import itertools
sys.setrecursionlimit(1000000000)
from heapq import heapify,heappop,heappush,heappushpop
import math
import collections
import copy

class UnionFind():
    
    def __init__(self,n):
        self.n = n
        self.parents = [-1]*n #各要素の親要素の番号を格納するリスト
    
    #要素xが属するグループの根を返す
    def find(self,x):
        if self.parents[x]<0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]
    
    #要素xと要素yが属するグループを併合する   
    def union(self,x,y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return
        
        if self.parents[x]>self.parents[y]:
            x,y = y,x
        
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    #要素xが属するグループのサイズを返す
    def size(self,x):
        return -self.parents[self.find(x)]
    
    #要素x,yが同じグループかどうかを返す
    def same(self,x,y):
        return self.find(x) == self.find(y)
    
    #要素xと同じグループのメンバーを返す
    def members(self,x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
    
    #すべての根の要素を返す
    def roots(self):
        return [i for i,x in enumerate(self.parents) if x<0]
    
    #グループの数を返す
    def group_count(self):
        return len(self.roots())
    
    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}
    
    def __str__(self):
        return "\n".join("{}: {}".format(r,self.members(r)) for r in self.roots())


if __name__  == "__main__":
    input = sys.stdin.readline
    n,m = map(int,input().split())
    UF = UnionFind(n)
    for i in range(m):
        a,b = map(int,input().split())
        UF.union(a,b)
    q = int(input())
    for i in range(q):
        c,d = map(int,input().split())
        if UF.same(c,d):
            print("yes")
        else:
            print("no")

Python: import sys
input_lines = [[int(i) for i in line.split()] for line in sys.stdin.read().splitlines()]
[user_num, rel_num] = input_lines[0]
rel_list = input_lines[1:rel_num+1]
ques_num = input_lines[rel_num+1][0]
ques_list = input_lines[rel_num+2:]
color_list = [-1] * user_num
adja_list = [set() for i in range(user_num)]

def dfs(id, color):
    if color_list[id] == -1:
        color_list[id] = color
        for a_id in adja_list[id]:
            dfs(a_id, color)



for rel in rel_list:
    adja_list[rel[0]].add(rel[1])
    adja_list[rel[1]].add(rel[0])

color = 0
for id in range(user_num):
    dfs(id, color)
    color += 1

for ques in ques_list:
    if color_list[ques[0]] == color_list[ques[1]]:
        print('yes')
    else:
        print('no')

Python: #!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
10 9
0 1
0 2
3 4
5 7
5 6
6 7
6 8
7 8
8 9
3
0 1
5 9
1 3

output:
yes
yes
no

"""

import sys


def assign_color():
    _color = 1
    for v in range(vertices):
        if color[v] == -1:
            graph_dfs(v, _color)
            _color += 1
    return None


def graph_dfs(vertex, _color):
    vertices_stack = list()
    vertices_stack.append(vertex)
    _color[vertex] = _color

    while vertices_stack:
        current_vertex = vertices_stack.pop()
        for v in adj_table[current_vertex]:
            if _color[v] == -1:
                _color[v] = _color
                vertices_stack.append(v)
    return None


def solve():
    for relation in relation_info:
        key, value = map(int, relation)
        adj_table[key].append(value)
        adj_table[value].append(key)

    assign_color()

    # print(adj_list)
    for question in questions:
        start, target = map(int, question)
        if color[start] == color[target]:
            print("yes")
        else:
            print("no")
    return color


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    vertices, relations = map(int, _input[0].split())

    relation_info = map(lambda x: x.split(), _input[1:relations + 1])

    q_num = int(_input[relations + 1])
    questions = map(lambda x: x.split(), _input[relations + 2:])

    adj_table = tuple([] for _ in range(vertices))
    color = [-1] * vertices
    ans = solve()

Python: # -*- coding: utf-8 -*-
"""

"""

import sys
sys.setrecursionlimit(1000000)


n,m=[int(i) for i in input().split()]
graph=[[] for i in range(n)]

for i in range(m):
    relation=[int(j) for j in input().split()]
    graph[relation[0]].append(relation[1])
    graph[relation[1]].append(relation[0])


check=[0 for i in range(n)]
rabel=0
stack=[]

#深さ優先探索
def dfs(graph,i):
    global stack
    global n
    global rabel

    if check[i]==0:

        #行った足跡をつける
        check[i]=rabel

        #今いる場所の情報
        now=graph[i]

        #スタックに入れる
        stack.append(now)

        #今いる場所から到達できる地点のうち、まだ行っていないとこ全部でdfs
        for j in now:
            if check[j]==0:
                dfs(graph,j)

        stack.pop()

for i in range(n):
    if check[i]==0:
        rabel+=1
        dfs(graph,i)
# print(check)



num=int(input())
for i in range(num):
    a,b=[int(j) for j in input().split()]
    if check[a]==check[b]:
        print("yes")
    else:
        print("no")