public Tree<String> buildTree(List<String> sentence, int i, int j, int parentIndex, Map<String, int[]>[][] back){
		String parent = indexer.get(parentIndex);
		int[] trace = back[i][j].get(parent);
			if (parentIndex == rootIndex && trace == null){
				return new Tree<String> (parent);
			}
			if (i==j-1){ 
				if (trace == null){
//						return new Tree<String>(parent, Collections.singletonList(new Tree<String>(sentence.get(i))));
					return new Tree<String>(sentence.get(i));
					} else {
						List<String> path = uc.getPath(new UnaryRule(parent,indexer.get(trace[0])));
						List<Tree<String>> emptyList = Collections.emptyList();
						Tree<String> leaf = new Tree<String>(sentence.get(i), emptyList);
						return buildUnaryTree(path.subList(0, path.size() - 1), Collections.singletonList(leaf));
					}
			}
			if (trace.length == 1){
				Tree<String> leaves = buildTree(sentence, i, j, trace[0], back);
				UnaryRule unaryRule = new UnaryRule(parent, indexer.get(trace[0]));
				List<String> path = uc.getPath(unaryRule);
				Tree<String> unaryTree = buildUnaryTree(path.subList(0, path.size() - 1), Collections.singletonList(leaves));
				return unaryTree;
			}
			else{
				// for binary rule
				Tree<String> leftTree = buildTree(sentence, i, trace[0], trace[1], back);
				Tree<String> rightTree = buildTree(sentence, trace[0], j, trace[2], back);
				List<Tree<String>> childrenList = new ArrayList<Tree<String>>(2);
				childrenList.add(leftTree);
				childrenList.add(rightTree);
				return new Tree<String>(parent, childrenList);
			}

	}