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 <cstdint>
#include <vector>

using namespace std;

#define GRAPH_SIZE 100000

enum state_t {
  WHITE,
  GRAY,
  BLACK,
};

struct vertex_t {
  uint32_t color;
  vector<uint32_t> connections;
};

static vertex_t graph[GRAPH_SIZE];
static state_t state[GRAPH_SIZE];

static void colorize(uint32_t index, uint32_t color)
{
  if (state[index] == WHITE) {
    state[index] = GRAY;
    graph[index].color = color;
    for (uint32_t i = 0; i < graph[index].connections.size(); i++) {
      colorize(graph[index].connections[i], color);
    }
    state[index] = BLACK;
  }
}

void check_connection(size_t num)
{
  for (uint32_t i = 0; i < num; i++) {
    state[i] = WHITE;
  }

  uint32_t color = 1;
  for (uint32_t i = 0; i < num; i++) {
    colorize(i, color);
    color++;
  }
}

#include <iostream>

int32_t main()
{
  uint32_t n, m;
  cin >> n >> m;

  for (uint32_t i = 0; i < m; i++) {
    uint32_t index, to;
    cin >> index >> to;
    graph[index].connections.push_back(to);
  }

  check_connection(n);

  uint32_t qs;
  cin >> qs;

  for (uint32_t i = 0; i < qs; i++) {
    uint32_t from, to;
    cin >> from >> to;

    if (graph[from].color == graph[to].color) {
      cout << "yes" << endl;
    } else {
      cout << "no" << endl;
    }
  }

  return 0;
}

C++: #include <stdio.h>

#define MAX_USER (100000)

/*

1)initial state

	0    1    2    3    4    5...

2)create friendship 
	friend: 0 and 1
	friend: 2 and 3

	0    2    4
    |    |
	1    3

3)and more
	friend: 2 and 4

	0       2      5
	|      / \
	1     3---4

*/



struct UserInfo
{
	long uid;
	UserInfo* next;
	UserInfo* prev;
};

int examine_friendship( const UserInfo* user_info , long uid1 , long uid2 )
{
	UserInfo* uid_ptr = user_info[ uid1 ].next;

	while( uid_ptr->uid != uid1 )
	{
		if( uid_ptr->uid == uid2 )
		{
			return 1;
		}
		uid_ptr = uid_ptr->next;
	}
	return 0;
}

int main( int argc , char** argv )
{
	//read setting
	long user_count;
	long friendship_count;
	scanf( "%ld %ld" , &user_count , &friendship_count );

	//initialize
	UserInfo*  user_info = new UserInfo[ user_count ];
	for( long i = 0 ; i < user_count ; i++ )
	{
		user_info[ i ].uid = i;
		user_info[ i ].next = &user_info[ i ];
		user_info[ i ].prev = &user_info[ i ];
	}

	//read user friendship
	for( long i = 0 ; i < friendship_count ; i++ )
	{
		long uid1;
		long uid2;
		scanf( "%ld %ld" , &uid1 , &uid2 );

		if( !examine_friendship( user_info , uid1 , uid2 ) )
		{
			//update internal data
			UserInfo* uid1_ptr = &user_info[ uid1 ];
			UserInfo* uid2_ptr = &user_info[ uid2 ];
			UserInfo* uid1_prev_ptr = uid1_ptr->prev;
			UserInfo* uid2_next_ptr = uid2_ptr->next;

			uid1_ptr->prev = uid2_ptr;
			uid2_ptr->next = uid1_ptr;

			uid1_prev_ptr->next = uid2_next_ptr;
			uid2_next_ptr->prev = uid1_prev_ptr;
		}
	}

	//read number of question
	long question_count;
	scanf( "%ld" , &question_count );

	//process question
	for( long i = 0 ; i < question_count ; i++ )
	{
		long uid1;
		long uid2;
		scanf( "%ld %ld" , &uid1 , &uid2 );

		if( examine_friendship( user_info , uid1 ,uid2 ) )
		{
			printf( "yes\n" );
		}
		else
		{
			printf( "no\n" );
		}
	}

	delete[] user_info;
	return 0;
}

C++: #include<iostream>
using namespace std;
#include<stdio.h>

typedef struct box { int val; box *prev, *next; } box_t;

box_t* init()
{
    box_t* head = new box_t;
    head->val = -1;
    head->next = NULL;
    head->prev = NULL;
    return head;
}

box_t* make_tail(box_t* head)
{
    box_t* tail = new box_t;
    tail->val = -1;
    head->next = tail;
    tail->next = NULL;
    tail->prev = head;
    return tail;
}

bool isEmpty(box_t* head, box_t* tail)
{
    return (head->next == tail ? true : false);
}

box_t* f_insert(box_t* head, int data)
{
    box_t* box = new box_t;
    box->val = data;
    box->next = head->next;
    box->prev = head;
    head->next->prev = box;
    head->next = box;
    return box;
}

int b_pop(box_t* tail)
{
    if(!(tail->prev->prev)) return -1;
    box_t* box = tail->prev;
    int val;
    val = tail->prev->val;
    tail->prev = box->prev;
    box->prev->next = tail;
    delete box;
    return val;
}

void clear(box_t* head, box_t* tail)
{
    box_t* box1 = head->next;
    box_t* box2;
    if(box1 == tail) return;
    while(box1 != tail){
        box2 = box1->next;
        delete box1;
        box1 = box2;
    };
    head->next = tail;
    tail->prev = head;
    return;
}

int main()
{
    int G[100000][100000];
    int dist[100000];

    box_t* head = init();
    box_t* tail = make_tail(head);

    int n, i, j, e, q, v1, v2;
    scanf("%d", &n);
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){ G[i][j] = 0; } }
    int m;
    scanf("%d", &m);
    for(int k = 0; k < m; k++){
        scanf("%d %d", &i, &j);
        G[i][0]++; G[j][0]++;
        G[i][G[i][0]] = j;
        G[j][G[j][0]] = i;
    }
    scanf("%d", &q);
    int self, friends;
    bool is_connected;

    for(int k = 0; k < q; k++){
        for(j = 0; j < n; j++) dist[j] = -1;

        scanf("%d %d", &self, &friends);
        f_insert(head, self);
        dist[self] = 0;
        is_connected = false;

        while(1){
            v1 = b_pop(tail);
            e = G[v1][0];
            for(i = 1; i <= e; i++){
                v2 = G[v1][i];
                if(dist[v2] < 0){
                    dist[v2] = dist[v1] + 1;
                    f_insert(head, v2);
                }
            }
            if(dist[friends] > 0){
                is_connected = true;
                break;
            }
            if(isEmpty(head, tail)) break;
        };
        if(is_connected){ printf("yes\n"); }else{ printf("no\n"); }
        if(!isEmpty(head, tail)) clear(head, tail);
    }

    return 0;
}