static Pair<Integer, Integer>[] find_stable_assignment(
			int[][] professor_preference, int[][] student_preference) {

		// stores currently free students.
		Queue<Integer> free_student = new LinkedList<Integer>();
		for (int i = 0; i < student_preference.length; ++i) {
			free_student.add(i);
		}

		// Records the professors that each student have asked.
		int[] student_pref_idx = new int[student_preference.length];
		Arrays.fill(student_pref_idx, 0);
		
		// Records the current student choice for each professor.
		int[] professor_choice = new int[professor_preference.length];
		Arrays.fill(professor_choice, -1);

		while (!free_student.isEmpty()) {
			int i = free_student.element(); // free student.
			int j = student_preference[i][student_pref_idx[i]]; // target professor.
			if (professor_choice[j] == -1) { // this professor is free.
				professor_choice[j] = i;
				free_student.remove();
			} else { // this professor has student now.
				int original_pref = find(professor_preference[j], professor_choice[j]);
				int new_pref = find(professor_preference[j], i);
				if (new_pref < original_pref) { // this professor prefers the new one.
					free_student.add(professor_choice[j]);
					professor_choice[j] = i;
					free_student.remove();
				}
			}
			++student_pref_idx[i];
		}

		Pair<Integer, Integer>[] match_result = new Pair[professor_choice.length];
		for (int j = 0; j < professor_choice.length; ++j) {
			match_result[j] = new Pair<Integer, Integer>(professor_choice[j], j);
		}
		return match_result;
	}