static int pushRelabel(int [][]C, int source, int sink) {
		int[][] F = new int[n][n];
		int []excess = new int[n];
		int []height = new int[n];
		int []list  = new int[n];
		int []seen  = new int[n];
		int i, p;

		for (i = 0, p = 0; i < n; i++){
			if((i != source) && (i != sink)) {
				list[p] = i;
				p++;
			}
		}

		height[source] = n;
		excess[source] = Integer.MAX_VALUE;
		for (i = 0; i < n; i++)
			push(C, F, excess, source, i);

		p = 0;
		while (p < n - 2) {
			int u = list[p];
			int old_height = height[u];
			discharge(C, F, excess, height, seen, u);
			if (height[u] > old_height) {
				moveToFront(p,list);
				p=0;
			}
			else
				p += 1;
		}
		int maxflow = 0;
		for (i = 0; i < n; i++)
			maxflow += F[source][i];

		return maxflow;
	}