diff --git a/mapbuilder/pom.xml b/mapbuilder/pom.xml
index 523013e73f4d10126fdf1eeff9ece035df745060..c89e4ee59ac0836a19cb73e8a7230e1434f0142f 100644
--- a/mapbuilder/pom.xml
+++ b/mapbuilder/pom.xml
@@ -18,6 +18,13 @@
   </properties>
 
   <dependencies>
+
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.10.1</version>
+    </dependency>
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
@@ -34,16 +41,12 @@
       <artifactId>json</artifactId>
       <version>20230227</version>
     </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>2.10.1</version>
-    </dependency>
-    <dependency>
+	  <dependency>
       <groupId>de.fuberlin.navigator</groupId>
       <artifactId>proto</artifactId>
-      <version>1.00.05</version>
+      <version>1.00.08</version>
     </dependency>
+
   </dependencies>
 
 
@@ -79,4 +82,31 @@
       <url>https://git.imp.fu-berlin.de/api/v4/projects/8345/packages/maven</url>
     </repository>
 	</repositories>
+
+
+
+  <dependencyManagement>
+  
+
+    <dependencies>
+    
+
+      <dependency>
+        <groupId>com.google.protobuf</groupId>
+        <artifactId>protobuf-java</artifactId>
+        <version>3.22.2</version>
+      </dependency>
+
+      <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
+  <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.10</version>
+  </dependency>
+
+
+
+    </dependencies>
+
+  </dependencyManagement>
 </project>
diff --git a/mapbuilder/src/main/java/map/builder/App.java b/mapbuilder/src/main/java/map/builder/App.java
index 01ec7d2b690fcede4d60cc55946a9e5a3e9c3d2a..cb773aa8823867387a29871121bb12e9b3ccbc84 100644
--- a/mapbuilder/src/main/java/map/builder/App.java
+++ b/mapbuilder/src/main/java/map/builder/App.java
@@ -1,52 +1,79 @@
 package map.builder;
 
+import static map.builder.utilities.Config.ROAD_NETWORK_OUTPUT_PATH;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
 import de.fuberlin.navigator.protos.map_builder.RoadNetwork;
+import map.builder.osm.OSMConnectedComponentParser;
 import map.builder.osm.OSMFetcher;
 import map.builder.osm.OSMParser;
 import map.builder.osm.json.model.OSMJsonDto;
 import map.builder.utilities.BoundingBox;
 import map.builder.utilities.Config;
+import map.builder.utilities.ConnectedComponentGraph;
 import map.builder.utilities.FileHandler;
 
-import java.io.IOException;
-import java.util.List;
-
-import static map.builder.utilities.Config.ROAD_NETWORK_OUTPUT_PATH;
-
 public class App {
     public static void main(String[] args) throws IOException {
         System.out.println("Map builder started!");
         Config.load();
 
         RoadNetwork.Builder roadNetworkBuilder = RoadNetwork.newBuilder();
-        OSMParser parser = new OSMParser(roadNetworkBuilder);
+        OSMParser parser = new OSMParser();
 
         // A small BBox inside Cottbus
         /*
-        float minLat = 51.765120241998865f;
-        float minLon = 14.32669617537409f;
-        float maxLat = 51.77116774623326f;
-        float maxLon = 14.330334220133722f;
+         * float minLat = 51.765120241998865f;
+         * float minLon = 14.32669617537409f;
+         * float maxLat = 51.77116774623326f;
+         * float maxLon = 14.330334220133722f;
          */
 
-        // BBox around Central + South Brandenburg (about 1.2GB in size)
-        float minLat = 52.788831211664586f;
-        float minLon = 11.333053381241731f;
-        float maxLat = 50.92993593954551f;
-        float maxLon = 14.714574575766516f;
+        // smaller BBox inside Cottbus, better for the debug tool
+        float minLat = 51.754092326645475f;
+        float minLon = 14.300615062713623f;
+        float maxLat = 51.766591637718435f;
+        float maxLon = 14.314413070678711f;
+
+        // BBox around Cottbus
+        /*
+         * float minLat = 51.714692361306376f;
+         * float minLon = 14.26197052001953f;
+         * float maxLat = 51.79290380494767f;
+         * float maxLon = 14.415779113769531f;
+         */
 
         BoundingBox bbox = new BoundingBox(minLat, minLon, maxLat, maxLon);
 
         List<OSMJsonDto> restrictions = OSMFetcher.fetchTurnRestrictions(bbox);
         List<OSMJsonDto> roads = OSMFetcher.fetchNodesAndWays(bbox);
 
-
         System.out.println("Starting to parse.");
         parser.parseTurnRestrictions(restrictions);
         parser.parseRoads(roads);
         System.out.println("Parsed road network.");
 
-        RoadNetwork roadNetwork = roadNetworkBuilder.build();
+        // set it to 0 so that it can be collected by garbage collector
+        restrictions = null;
+        roads = null;
+        bbox = null;
+
+        // create the nodes graph in order to run LCC on it
+        ConnectedComponentGraph graph = new ConnectedComponentGraph();
+        OSMConnectedComponentParser.addNodes(parser.nodes, graph);
+        OSMConnectedComponentParser.addEdges(parser.segments, graph);
+
+        ArrayList<Long> component = graph.getSCCs();
+
+        // cleanup
+        graph = null;
+        OSMConnectedComponentParser.cleanUp(parser.nodes, parser.segments, component);
+
+        RoadNetwork roadNetwork = roadNetworkBuilder.putAllNodes(parser.nodes).putAllSegments(parser.segments)
+                .addAllTurnRestrictions(parser.restrictions).build();
         System.out.println("Turn restrictions count: " + roadNetwork.getTurnRestrictionsCount());
         System.out.println("Nodes count: " + roadNetwork.getNodesCount());
         System.out.println("Segments count: " + roadNetwork.getSegmentsCount());
diff --git a/mapbuilder/src/main/java/map/builder/osm/OSMConnectedComponentParser.java b/mapbuilder/src/main/java/map/builder/osm/OSMConnectedComponentParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..d66ab80b4f87499c1a2847d93bbd13a0a0f42a85
--- /dev/null
+++ b/mapbuilder/src/main/java/map/builder/osm/OSMConnectedComponentParser.java
@@ -0,0 +1,46 @@
+package map.builder.osm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
+import de.fuberlin.navigator.protos.map_builder.Node;
+import de.fuberlin.navigator.protos.map_builder.Segment;
+import map.builder.utilities.ConnectedComponentGraph;
+
+public class OSMConnectedComponentParser {
+
+    public static void addNodes(Map<Long, Node> nodesMap, ConnectedComponentGraph graph) {
+        for (Long nodeId : nodesMap.keySet()) {
+            graph.addNode(nodeId);
+        }
+    }
+
+    public static void addEdges(Map<Long, Segment> segmentsMap, ConnectedComponentGraph graph) {
+        for (Long edgeId : segmentsMap.keySet()) {
+            Segment segment = segmentsMap.get(edgeId);
+            Long startNode = segment.getStartNode();
+            Long endNode = segment.getEndNode();
+            graph.addEdge(startNode, endNode);
+            if (!segment.getOneWay()) {
+                graph.addEdge(endNode, startNode);
+            }
+        }
+    }
+
+    public static void cleanUp(Map<Long, Node> nodesMap, Map<Long, Segment> segmentsMap, ArrayList<Long> component) {
+        nodesMap.keySet().retainAll(Collections.unmodifiableCollection(component));
+
+        ArrayList<Long> segmentIDsToRemove = new ArrayList<Long>();
+        for (Long key : segmentsMap.keySet()) {
+            Segment segment = segmentsMap.get(key);
+            Long startNodeID = segment.getStartNode();
+            Long endNodeID = segment.getEndNode();
+            if ((!component.contains(startNodeID)) && (!component.contains(endNodeID))) {
+                segmentIDsToRemove.add(key);
+            }
+        }
+        segmentsMap.keySet().removeAll(segmentIDsToRemove);
+    }
+
+}
\ No newline at end of file
diff --git a/mapbuilder/src/main/java/map/builder/osm/OSMFetcher.java b/mapbuilder/src/main/java/map/builder/osm/OSMFetcher.java
index a867735a15176fdc919889f34986b5ea98e938f6..d7760b3b100cb128a1911638aeec4c95a1d18b63 100644
--- a/mapbuilder/src/main/java/map/builder/osm/OSMFetcher.java
+++ b/mapbuilder/src/main/java/map/builder/osm/OSMFetcher.java
@@ -1,6 +1,8 @@
 package map.builder.osm;
 
-import java.io.BufferedReader;
+import static map.builder.osm.json.serialization.OSMJsonDtoDeserializer.Mode.NODES_AND_WAYS;
+import static map.builder.osm.json.serialization.OSMJsonDtoDeserializer.Mode.TURN_RESTRICTIONS;
+
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileWriter;
@@ -16,15 +18,11 @@ import java.util.stream.Collectors;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.stream.JsonReader;
+
 import map.builder.osm.json.model.OSMJsonDto;
 import map.builder.osm.json.serialization.OSMJsonDtoDeserializer;
-import org.json.JSONObject;
-
 import map.builder.utilities.BoundingBox;
 
-import static map.builder.osm.json.serialization.OSMJsonDtoDeserializer.Mode.NODES_AND_WAYS;
-import static map.builder.osm.json.serialization.OSMJsonDtoDeserializer.Mode.TURN_RESTRICTIONS;
-
 public class OSMFetcher {
     private final static String OverpassURL = "https://overpass.kumi.systems/api/interpreter";
     private final static String nodeQuery = "[out:json];way[highway](%s);(._;>;);out;";
@@ -35,7 +33,7 @@ public class OSMFetcher {
 
     public static List<OSMJsonDto> fetchTurnRestrictions(BoundingBox boundingBox) throws IOException {
         System.out.println("Start to fetch turn restrictions.");
-        List<OSMJsonDto>  dtos = OSMFetcher.runQueryForBBox(OSMFetcher.relationQuery, boundingBox, TURN_RESTRICTIONS);
+        List<OSMJsonDto> dtos = OSMFetcher.runQueryForBBox(OSMFetcher.relationQuery, boundingBox, TURN_RESTRICTIONS);
         System.out.println("Turn restrictions fetched.");
 
         return dtos;
@@ -49,7 +47,8 @@ public class OSMFetcher {
         return dtos;
     }
 
-    private static List<OSMJsonDto> runQueryForBBox(String query, BoundingBox bbox, OSMJsonDtoDeserializer.Mode mode) throws IOException {
+    private static List<OSMJsonDto> runQueryForBBox(String query, BoundingBox bbox, OSMJsonDtoDeserializer.Mode mode)
+            throws IOException {
         InputStream response = requestData(query, bbox);
 
         JsonReader jsonReader = new JsonReader(new InputStreamReader(response));
@@ -104,11 +103,10 @@ public class OSMFetcher {
         FileWriter file = new FileWriter(path);
         file.write(
                 "[" +
-                data.stream()
-                        .map(OSMJsonDto::toJson)
-                        .collect(Collectors.joining(", "))
-                + "]"
-        );
+                        data.stream()
+                                .map(OSMJsonDto::toJson)
+                                .collect(Collectors.joining(", "))
+                        + "]");
         file.close();
     }
 }
diff --git a/mapbuilder/src/main/java/map/builder/osm/OSMParser.java b/mapbuilder/src/main/java/map/builder/osm/OSMParser.java
index 3e050ad3deb1f44cb3bb0e6844632165013d0cef..b8bc958a985d8bc8e1277d8c0b9c84efaf76a7e6 100644
--- a/mapbuilder/src/main/java/map/builder/osm/OSMParser.java
+++ b/mapbuilder/src/main/java/map/builder/osm/OSMParser.java
@@ -4,24 +4,28 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
-import map.builder.osm.json.model.*;
-
 import de.fuberlin.navigator.protos.map_builder.Coordinates;
 import de.fuberlin.navigator.protos.map_builder.Node;
 import de.fuberlin.navigator.protos.map_builder.Restriction;
-import de.fuberlin.navigator.protos.map_builder.RoadNetwork;
 import de.fuberlin.navigator.protos.map_builder.Segment;
+import map.builder.osm.json.model.OSMJsonDto;
+import map.builder.osm.json.model.OSMJsonMemberDto;
+import map.builder.osm.json.model.OSMJsonNodeDto;
+import map.builder.osm.json.model.OSMJsonTurnRestrictionDto;
+import map.builder.osm.json.model.OSMJsonWayDto;
 import map.builder.utilities.ComputationalUtils;
 
-
 public class OSMParser {
     private final Coordinates.Builder coordinatesBuilder;
     private final HashMap<Long, Node> nodesDump;
-    RoadNetwork.Builder roadNetworkBuilder;
 
-    public OSMParser(RoadNetwork.Builder roadNetworkBuilder) {
-        this.roadNetworkBuilder = roadNetworkBuilder;
+    // maps to put the entries
 
+    public HashMap<Long, Node> nodes = new HashMap<Long, Node>();
+    public HashMap<Long, Segment> segments = new HashMap<Long, Segment>();
+    public ArrayList<Restriction> restrictions = new ArrayList<Restriction>();
+
+    public OSMParser() {
         this.coordinatesBuilder = Coordinates.newBuilder();
         this.nodesDump = new HashMap<>();
     }
@@ -50,6 +54,7 @@ public class OSMParser {
                 }
             }
         }
+
     }
 
     private void splitSegment(OSMJsonWayDto dto) {
@@ -73,8 +78,7 @@ public class OSMParser {
 
         try {
             line = this.findNodePositions(geometry);
-        }
-        catch (NullPointerException e) {
+        } catch (NullPointerException e) {
             System.out.println("Dropping segment with ID " + osmId);
             System.out.println(e.getMessage());
             return;
@@ -86,7 +90,12 @@ public class OSMParser {
         boolean oneWay = SegmentUtils.isSegmentOneway(dto);
         int maxSpeed = SegmentUtils.getMaxSpeed(dto);
 
-        int internalId = this.roadNetworkBuilder.getSegmentsCount();
+        System.out.printf("Max speed: %d \n", maxSpeed);
+        System.out.printf("Way id: %d, Start node id : %d, End node id: %d \n", osmId,
+                this.nodes.get(startNodeId).getId(),
+                this.nodes.get(endNodeId).getId());
+
+        long internalId = this.segments.size();
 
         Segment segment = Segment.newBuilder()
                 .setOsmId(osmId)
@@ -100,19 +109,19 @@ public class OSMParser {
                 .setLength(this.computeSegmentLength(line))
                 .build();
 
-        this.roadNetworkBuilder.putSegments(internalId, segment);
+        this.segments.put(internalId, segment);
     }
 
     private void moveNodeToProto(Node node) {
         long osmId = node.getOsmId();
-        this.roadNetworkBuilder.putNodes(osmId, node);
+        this.nodes.put(osmId, node);
     }
 
     private void createNode(OSMJsonNodeDto dto) {
         Coordinates position = this.createLocationFromElement(dto.getLon(), dto.getLat());
 
         Node node = Node.newBuilder()
-                .setId(this.roadNetworkBuilder.getNodesCount())
+                .setId(this.nodes.size() + this.nodesDump.size())
                 .setOsmId(dto.getOsmId())
                 .setPosition(position)
                 .build();
@@ -134,8 +143,10 @@ public class OSMParser {
     }
 
     /**
-     * Returns an array list of array lists of geometries. If the outer list has only one entry, it means the segment
+     * Returns an array list of array lists of geometries. If the outer list has
+     * only one entry, it means the segment
      * doesn't need to be split, otherwise it needs to.
+     * 
      * @param nodeIds
      * @return
      * @throws NullPointerException
@@ -168,12 +179,11 @@ public class OSMParser {
     private Node findParsedNodeById(long osmId) throws NullPointerException {
         if (this.nodesDump.containsKey(osmId)) {
             Node node = this.nodesDump.get(osmId);
-
             return node;
         }
 
-        if (this.roadNetworkBuilder.getNodesMap().containsKey(osmId)) {
-            return this.roadNetworkBuilder.getNodesMap().get(osmId);
+        if (this.nodes.containsKey(osmId)) {
+            return this.nodes.get(osmId);
         }
 
         throw new NullPointerException("Node with id " + osmId + " not found!");
@@ -210,7 +220,7 @@ public class OSMParser {
                 }
             }
             Restriction restriction = Restriction.newBuilder().setFromId(from).setToId(to).build();
-            this.roadNetworkBuilder.addTurnRestrictions(restriction);
+            this.restrictions.add(restriction);
         }
     }
 
diff --git a/mapbuilder/src/main/java/map/builder/utilities/ComputationalUtils.java b/mapbuilder/src/main/java/map/builder/utilities/ComputationalUtils.java
index 706865e78abdb592c2f15cfef075ca60857f069a..371b6e3358ee70d1b79fb7377b46d1bcb9911aed 100644
--- a/mapbuilder/src/main/java/map/builder/utilities/ComputationalUtils.java
+++ b/mapbuilder/src/main/java/map/builder/utilities/ComputationalUtils.java
@@ -3,8 +3,6 @@ package map.builder.utilities;
 import de.fuberlin.navigator.protos.map_builder.Coordinates;
 
 public class ComputationalUtils {
-    private ComputationalUtils() {
-    }
 
     public static double haversine(Coordinates position_0,
             de.fuberlin.navigator.protos.map_builder.Coordinates position_1) {
diff --git a/mapbuilder/src/main/java/map/builder/utilities/ConnectedComponentGraph.java b/mapbuilder/src/main/java/map/builder/utilities/ConnectedComponentGraph.java
new file mode 100644
index 0000000000000000000000000000000000000000..9504289a703259db68c28ad8783f63c2ca125eac
--- /dev/null
+++ b/mapbuilder/src/main/java/map/builder/utilities/ConnectedComponentGraph.java
@@ -0,0 +1,165 @@
+package map.builder.utilities;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+// Code from : https://www.geeksforgeeks.org/strongly-connected-components/
+// Java implementation of Kosaraju's algorithm to print all SCCs
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Stack;
+
+//TODO: change data structure here to be more appropriate
+// This class represents a directed ConnectedComponentGraph using adjacency list
+// representation
+public class ConnectedComponentGraph {
+    private HashMap<Long, LinkedList<Long>> adj; // Adjacency List
+
+    // Constructor
+    public ConnectedComponentGraph() {
+        adj = new HashMap<Long, LinkedList<Long>>();
+    }
+
+    public void addNode(Long v) {
+        adj.put(v, new LinkedList<Long>());
+    }
+
+    // Function to add an edge into the ConnectedComponentGraph
+    public void addEdge(Long v, Long w) {
+        adj.get(v).add(w);
+    }
+
+    // A recursive function to print DFS starting from v
+    public ArrayList<Long> DFSUtil(Long v, HashMap<Long, Boolean> visited) {
+        // Mark the current node as visited and print it
+        visited.put(v, true);
+
+        ArrayList<Long> component = new ArrayList<Long>();
+        Long n;
+
+        // Recur for all the vertices adjacent to this vertex
+        Iterator<Long> i = adj.get(v).iterator();
+        while (i.hasNext()) {
+            n = i.next();
+            if (!visited.get(n))
+                component = DFSUtil(n, visited, component);
+        }
+        component.add(v);
+        return component;
+    }
+
+    public ArrayList<Long> DFSUtil(Long v, HashMap<Long, Boolean> visited, ArrayList<Long> list) {
+        // Mark the current node as visited and print it
+        visited.put(v, true);
+        Long n;
+
+        // Recur for all the vertices adjacent to this vertex
+        Iterator<Long> i = adj.get(v).iterator();
+        while (i.hasNext()) {
+            n = i.next();
+            if (!visited.get(n))
+                DFSUtil(n, visited, list);
+        }
+        list.add(v);
+        return list;
+    }
+
+    // Function that returns reverse (or transpose) of this ConnectedComponentGraph
+    public ConnectedComponentGraph getTranspose() {
+        ConnectedComponentGraph g = new ConnectedComponentGraph();
+        for (Long v : adj.keySet()) {
+            g.addNode(v);
+        }
+        for (Long v : adj.keySet()) {
+            // Recur for all the vertices adjacent to this vertex
+            Iterator<Long> i = adj.get(v).listIterator();
+            while (i.hasNext()) {
+                Long next = i.next();
+                g.adj.get(next).add(v);
+            }
+        }
+        return g;
+    }
+
+    public void fillOrder(Long v, HashMap<Long, Boolean> visited, Stack<Long> stack) {
+        // Mark the current node as visited and print it
+        visited.put(v, true);
+
+        // Recur for all the vertices adjacent to this vertex
+        Iterator<Long> i = adj.get(v).iterator();
+        while (i.hasNext()) {
+            Long n = i.next();
+            if (!visited.get(n))
+                fillOrder(n, visited, stack);
+        }
+
+        // All vertices reachable from v are processed by now,
+        // push v to Stack
+        stack.push(v);
+    }
+
+    // The main function that finds and prints all strongly
+    // connected components
+    public ArrayList<Long> getSCCs() {
+        Stack<Long> stack = new Stack<Long>();
+
+        // Mark all the vertices as not visited (For first DFS)
+        HashMap<Long, Boolean> visited = new HashMap<Long, Boolean>();
+        for (Long i : this.adj.keySet()) {
+            visited.put(i, false);
+        }
+
+        // Fill vertices in stack according to their finishing
+        // times
+        for (Long i : this.adj.keySet())
+            if (visited.get(i) == false)
+                fillOrder(i, visited, stack);
+
+        // Create a reversed ConnectedComponentGraph
+        ConnectedComponentGraph gr = getTranspose();
+
+        // Mark all the vertices as not visited (For second DFS)
+        for (Long i : this.adj.keySet())
+            visited.put(i, false);
+
+        // Now process all vertices in order defined by Stack
+        ArrayList<Long> largestComponent = new ArrayList<Long>();
+        int maxLength = 0;
+        while (stack.empty() == false) {
+            // Pop a vertex from stack
+            Long v = stack.pop();
+
+            // Print Strongly connected component of the popped vertex
+            if (visited.get(v) == false) {
+                ArrayList<Long> component = gr.DFSUtil(v, visited);
+                if (maxLength < component.size()) {
+                    maxLength = component.size();
+                    largestComponent = component;
+                }
+            }
+        }
+        return largestComponent;
+    }
+
+    // Driver method
+    public static void main(String args[]) {
+        // Create a ConnectedComponentGraph given in the above diagram
+        ConnectedComponentGraph g = new ConnectedComponentGraph();
+        // add nodes
+        g.addNode((long) 0);
+        g.addNode((long) 1);
+        g.addNode((long) 2);
+        g.addNode((long) 3);
+        g.addNode((long) 4);
+
+        g.addEdge((long) 1, (long) 0);
+        g.addEdge((long) 0, (long) 2);
+        g.addEdge((long) 2, (long) 1);
+        g.addEdge((long) 0, (long) 3);
+        g.addEdge((long) 3, (long) 4);
+
+        System.out.println("Following are strongly connected components " +
+                "in given ConnectedComponentGraph ");
+        g.getSCCs();
+    }
+}
+// This code is contributed by Aakash Hasija
\ No newline at end of file