private ArrayList<ArrayList<Integer>> fx(int[] num, P p) {
		if (cache.containsKey(p)) {
			return cache.get(p);
		}
		ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
		ArrayList<Integer> empty = new ArrayList<Integer>();
		result.add(empty);
		Set<String> set = new HashSet<String>();
		set.add(listToString(empty));

		if (p.e == p.s) {
			cache.put(p, result);
			return result;
		}

		if (p.e == p.s + 1) {
			ArrayList<Integer> one = new ArrayList<Integer>();
			one.add(num[p.s]);
			result.add(one);
			cache.put(p, result);
			return result;
		}

		for (int i = p.s + 1; i < p.e; i++) {
			ArrayList<ArrayList<Integer>> left = fx(num, new P(p.s, i));
			ArrayList<ArrayList<Integer>> right = fx(num, new P(i, p.e));
			for (ArrayList<Integer> l : left) {
				for (ArrayList<Integer> r : right) {
					ArrayList<Integer> lr = new ArrayList<Integer>();
					lr.addAll(l);
					lr.addAll(r);
					Collections.sort(lr);
					String slr = listToString(lr);
					if (set.contains(slr)) {
						continue;
					}
					set.add(slr);
					result.add(lr);
				}
			}
		}

		cache.put(p, result);
		return result;
	}