public void search(int source) {
        layers.clear();
        distances = new int[graph.getVerticesCount()];

        Queue<Integer> q1 = new LinkedList<>();
        Queue<Integer> q2 = new LinkedList<>();
        Queue<Integer> currentQueue = q1;
        Queue<Integer> anotherQueue = q2;
        currentQueue.add(source);

        Set<Integer> visitedVertices = new HashSet<>();
        Set<Edge> visitedEdges = new HashSet<Edge>();

        int layerNumber = 0;
        while (!(q1.isEmpty() && q2.isEmpty())) {
            if (currentQueue.size() == 0) {
                currentQueue = q1.size() > 0 ? q1 : q2;
                anotherQueue = q1.size() == 0 ? q1 : q2;
                layerNumber++;
            }

            int currentVertex = currentQueue.poll();
            visitVertex(currentVertex);

            if (layerNumber >= layers.size()) layers.add(new ArrayList<>());
            layers.get(layerNumber).add(currentVertex);

            distances[currentVertex] = layerNumber;

            for (Edge edge : graph.getEdges(currentVertex)) {
                if (!visitedEdges.contains(edge)) {
                    visitEdge(edge);
                    visitedEdges.add(edge);

                    int anotherVertex =  edge.getAnotherVertex(currentVertex);
                    if (!visitedVertices.contains(anotherVertex)) {
                        anotherQueue.add(anotherVertex);
                        visitedVertices.add(anotherVertex);
                    }
                }
            }
        }
    }