private void graphGrid(ArrayList<ArrayList<Position>> grid) throws InterruptedException {
    System.out.println(
        "Size of file by rows = " + grid.size() + ", columns = " + grid.get(0).size());
    final long current = System.currentTimeMillis();
    // System.out.println("Time for parsing file: " + ((current - startParseTime) / 1000) + " sec");
    // long afterEdge = 0;
    // long timeFindEdge = 0;

    ArrayList<Integer> ranges = findRanges();
    final Cell<Integer> threadsActive = new Cell<Integer>(threads);
    class EdgeThread extends Thread {

      int startRow = 0;
      int endRow = 0;

      public EdgeThread(int startRow, int endRow) {
        this.startRow = startRow;
        this.endRow = endRow;
      }

      public void run() {
        System.out.println("Thread: " + this.getId());
        findEdges(startRow, endRow);
        boolean lastThread;
        synchronized (threadsActive) {
          lastThread = --threadsActive.object == 0;
        }
        if (lastThread) {
          System.out.println("Last Thread: " + this.getId());
          long afterEdge = System.currentTimeMillis();
          long timeFindEdge = (afterEdge - current) / 1000;
          System.out.println("Time for findEdges: " + timeFindEdge + " sec");

          colorSCC();
          long afterColor = System.currentTimeMillis();
          long timeForColor = (afterColor - afterEdge) / 1000;
          System.out.println("Time for coloring and find CC: " + timeForColor + " sec");
          // findConnectedComponents();
          create();
          long timeForCreate = (System.currentTimeMillis() - afterColor) / 1000;
          System.out.println("Time for creating map: " + timeForCreate + " sec");
        }
      }
    }
    for (int i = 0; i < threads; i++) {
      EdgeThread thread = new EdgeThread(ranges.get(2 * i), ranges.get(2 * i + 1));
      thread.start();
    }

    Thread.currentThread().join();
  }
  private static <a> ArrayList<ArrayList<a>> transpose(ArrayList<ArrayList<a>> matrix) {
    ArrayList<ArrayList<a>> grid2 = new ArrayList<ArrayList<a>>();
    if (matrix.isEmpty()) return grid2;
    for (int i = 0; i < matrix.get(0).size(); i++) {

      grid2.add(new ArrayList<a>(matrix.size()));
    }
    System.out.println(grid2);
    for (int i = 0; i < matrix.size(); i++) {

      ArrayList<a> row = matrix.get(i);
      for (int j = 0; j < row.size(); j++) {

        grid2.get(j).add(row.get(j)); // .set(i, row.get(j));
      }
    }

    return grid2;
  }
  public void parseInput(String file, int threads, int limit)
      throws FileNotFoundException, InterruptedException {
    // long startParseTime = System.currentTimeMillis();
    m_jgAdapter = new JGraphModelAdapter<Position, DefaultEdge>(graph);
    jgraph = new JGraph(m_jgAdapter);
    this.threads = threads;

    Scanner input = new Scanner(new File(file));
    try {
      for (int r = 0; input.hasNextLine() && r < limit; r++) {
        Scanner line = new Scanner(input.nextLine());
        try {

          ArrayList<Position> row = new ArrayList<Position>();
          grid.add(row);

          System.out.println("Row " + r);

          for (int c = 0; line.hasNextInt() && c < limit; c++) {
            Position position = new Position(r, c, line.nextInt());
            row.add(position);
            graph.addVertex(position);
            positionVertexAt(position, position.column * 5, position.row * 5);
          }
        } finally {
          line.close();
        }
      }
    } finally {
      input.close();
    }

    graphGrid(grid);

    // ArrayList<ArrayList<Position>> grid2 = transpose(grid);
    // outputGrid(grid2);

  }
 private ArrayList<Integer> findRanges() {
   int rowsPerRange = (int) Math.ceil((grid.size()) / (double) threads);
   ArrayList<Integer> ranges = new ArrayList<Integer>();
   int startRow = 0, endRow = rowsPerRange;
   for (int i = 0; i < threads; i++) {
     ranges.add(startRow);
     ranges.add(endRow);
     startRow = endRow;
     ;
     endRow += rowsPerRange;
   }
   ranges.set(ranges.size() - 1, Math.min(grid.size(), ranges.get(ranges.size() - 1)));
   System.out.println(ranges);
   return ranges;
 }