public boolean solve() {
		quit = false;
		Util.dprint("Solving process started");
		Util.dprint("Starting grid:");
		sudoku.print();

		// Sure hits
		solveSure(sudoku);
		Util.dprint("Time[solveSure]: " + timeSolveSure + "ms");
		if (sudoku.validateField()) {
			Util.dprint("Got it without guessing! Result:");
			sudoku.print();
			return true;
		}
		
		// List possible options for remaining slots
		Util.dprint("We will have to guess to fill in the remaining slots:");
		sudoku.print();
		Util.dprint("Number of missing fields: " + Util.countEmptySlots(sudoku));
		Util.printMaybe(maybe);
		
		// Fill in the empty slots to the array and initialise numTries to 0
		for (Entry<Integer, ArrayList<Integer>> e : maybe.entrySet()) {
			emptySlots.add(e.getKey());
			numTries.put(e.getKey(), 0);
		}
		
		// Start guessing the remaining slots
		Util.dprint("Going to guess");
		try {
			solveGuess();
			Util.dprint("Time[solveGuess]: " + timeSolveSure + "ms");
		} catch (StackOverflowError e) {
			Util.dprint("<<ERROR: STACKOVERFLOW>>");
		}

		// Final result
		Util.dprint("Final product:");
		sudoku.print();
		return sudoku.validateField();
	}