import java.util.Set;
import java.util.TreeSet;
import java.util.Collection;
import java.util.List;
import java.util.LinkedList;

abstract class Graph <E extends Edge> {
	abstract boolean hasEdge(int i, int j);
	abstract Set<E> edgesFrom(int i);
	abstract void addEdge(E e);
	
	public List<Integer> depthFirstTraversal(int i) {
		LinkedList<Integer> stack = new LinkedList<>();
		LinkedList<Integer> result = new LinkedList<>();
		stack.push(i);
		while (!stack.isEmpty()) {
			int currElem = stack.pop();
			result.add(currElem);
			for (E target : edgesFrom(currElem)) {
				if (!result.contains(target.getTarget())) {
					stack.push(target.getTarget());
				}
			}
		}
		return result;
	}
}