Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Connected Components

Write a program which reads relations in a SNS (Social Network Service), and judges that given pairs of users are reachable each other through the network.

Input

In the first line, two integer $n$ and $m$ are given. $n$ is the number of users in the SNS and $m$ is the number of relations in the SNS. The users in the SNS are identified by IDs $0, 1, ..., n-1$.

In the following $m$ lines, the relations are given. Each relation is given by two integers $s$ and $t$ that represents $s$ and $t$ are friends (and reachable each other).

In the next line, the number of queries $q$ is given. In the following $q$ lines, $q$ queries are given respectively. Each query consists of two integers $s$ and $t$ separated by a space character.

Output

For each query, print "yes" if $t$ is reachable from $s$ through the social network, "no" otherwise.

Constraints

$2 \leq n \leq 100,000$

$0 \leq m \leq 100,000$

$1 \leq q \leq 10,000$

Sample 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

Sample Output

yes
yes
no

Solution in JAVA (judge verdict: Time Limit Exceeded)

import java.util.Scanner;
import java.util.HashMap;
import java.util.Queue;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

// AIZU friendly file, just remove first line
public class Main {
	static HashMap<Integer, Integer> components;
	static ArrayList<Integer> vertexToIndex;
	static Graph g;
	
	public static void buildComponents(Graph gr) {
		components = new HashMap<Integer, Integer>();
		g = gr;
		HashMap<Integer, ArrayList<Integer>> graph = g.getGraph();
		vertexToIndex = new ArrayList<Integer>();
		for(int i: graph.keySet()) {
			vertexToIndex.add(i);
		}
		
		int currentComponent = 0;
		int currentManualInsertion = 0;
		ArrayList<Integer> neighbors;
		Queue<Integer> toExplore = new ArrayDeque<Integer>();
		ArrayList<Integer> explored = new ArrayList<Integer>();
		
		while(explored.size() < g.getNumVertices()) {
			toExplore.add(vertexToIndex.get(currentManualInsertion));
			while(!toExplore.isEmpty()) {
				int currentVertexValue = toExplore.remove();
				explored.add(currentVertexValue);
				components.put(currentVertexValue, currentComponent);
				
				neighbors = graph.get(currentVertexValue);
				for(int i = 0; neighbors != null && i < neighbors.size(); i++) {
					if(!explored.contains(neighbors.get(i)))
						toExplore.add(neighbors.get(i));
				}
			}
			currentComponent++;
			while(currentManualInsertion < g.getNumVertices() && components.containsKey(vertexToIndex.get(currentManualInsertion)))
				currentManualInsertion++;
		}
	}
	
	public static String hasConnection(int node1, int node2) {
		String str = "no";
		if(components.get(node1) == components.get(node2) && components.get(node1) != null)
			str = "yes";
		return str;
	}
	
	public static void main(String [] args) {
		Scanner scan = new Scanner(System.in);
		Graph graph = new Graph();
		
		int users = scan.nextInt();
		int relations = scan.nextInt();
		
		for(int i = 0; i < relations; i++)
			graph.addConnection(new Vertex(scan.nextInt(), new int[] {scan.nextInt()}));
		
		buildComponents(graph);
		
		int queries = scan.nextInt();
		
		for(int i = 0; i < queries; i++)
			System.out.println(hasConnection(scan.nextInt(), scan.nextInt()));
		
		scan.close();
	}
}

class Graph {
	private HashMap<Integer, ArrayList<Integer>> graph;
	
	public Graph(ArrayList<Vertex> vertices) {
		graph = new HashMap<Integer, ArrayList<Integer>>();
		
		for(int i = 0; i < vertices.size(); i++) 
			addConnection(vertices.get(i));
	}
	public Graph() {
		graph = new HashMap<Integer, ArrayList<Integer>>();
	}
	
	public void addConnection(Vertex v) {
		ArrayList<Integer> currentConnections = graph.containsKey(v.getValue()) ? graph.get(v.getValue()) : new ArrayList<Integer>();
		int currentConnection = -1;
		for(int i = 0; i < v.getConnections().size(); i++) {
			currentConnection = v.getConnections().get(i);
			if(!currentConnections.contains(currentConnection))
				currentConnections.add(currentConnection);
			
			ArrayList<Integer> backwardsAddition = graph.containsKey(currentConnection) ? graph.get(currentConnection) : new ArrayList<Integer>();
			if(!backwardsAddition.contains(v.getValue()))
				backwardsAddition.add(v.getValue());
			graph.put(currentConnection,  backwardsAddition);
		}
		Collections.sort(currentConnections);
		graph.put(v.getValue(), currentConnections);
	}
	
	public Vertex getVertex(int value) {
		if(graph.containsKey(value))
			return new Vertex(value, graph.get(value));
		else
			return null;
	}
	public HashMap<Integer, ArrayList<Integer>> getGraph(){
		return graph;
	}
	public int getNumVertices() {
		return graph.size();
	}
	
	public String toString() {
		return graph.toString();
	}
}


class Vertex {
	int value;
	ArrayList<Integer> connections;
	
	public Vertex(int v, ArrayList<Integer> cs) {
		value = v;
		connections = cs;
	}
	public Vertex(int v, int[] cs) {
		value = v;
		connections = new ArrayList<Integer>();
		for(int i = 0; i < cs.length; i++)
			connections.add(cs[i]);
	}
	
	public int getValue() {
		return value;
	}
	public ArrayList<Integer> getConnections(){
		return connections;
	}
	
	public String toString() {
		return value + " -> " + connections;
	}
}