private Iterable<int[]> adj(int i, int j) {
    Bag<int[]> result = new Bag<>();

    if (i > 0 && j > 0) {
      result.add(new int[] {i - 1, j - 1});
    }
    if (i > 0) {
      result.add(new int[] {i - 1, j});
    }
    if (i > 0 && j < N - 1) {
      result.add(new int[] {i - 1, j + 1});
    }
    if (j > 0) {
      result.add(new int[] {i, j - 1});
    }
    if (j < N - 1) {
      result.add(new int[] {i, j + 1});
    }
    if (i < M - 1 && j > 0) {
      result.add(new int[] {i + 1, j - 1});
    }
    if (i < M - 1) {
      result.add(new int[] {i + 1, j});
    }
    if (i < M - 1 && j < N - 1) {
      result.add(new int[] {i + 1, j + 1});
    }

    return result;
  }
  private void dfs(int i, int j) {
    marked[i][j] = true;
    if (wordTo[i][j].length() > 2 && dict.contains(wordTo[i][j])) {
      wordsFromCell.add(wordTo[i][j]);
    }

    if (dict.keysWithPrefix(wordTo[i][j]).iterator().hasNext()) {
      Iterable<int[]> adj = adj(i, j);
      for (int[] a : adj) {
        if (!marked[a[0]][a[1]]) {
          String letter = board.getLetter(a[0], a[1]) + "";
          if (Objects.equals(letter, "Q")) {
            wordTo[a[0]][a[1]] = wordTo[i][j] + "QU";
          } else {
            wordTo[a[0]][a[1]] = wordTo[i][j] + letter;
          }
          dfs(a[0], a[1]);
        }
      }
    }
    marked[i][j] = false;
  }