diff --git a/labs/04-priority-queues-exercises.ipynb b/labs/04-priority-queues-exercises.ipynb
index 6a121d1b583cdd7373f1bdfcb46afc1f1357ded3..27cfebfe560b2f083939d50a973dc821bb6d1d46 100644
--- a/labs/04-priority-queues-exercises.ipynb
+++ b/labs/04-priority-queues-exercises.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "994d4d0c",
+   "id": "b805152f",
    "metadata": {},
    "source": [
     "NAME:"
@@ -142,7 +142,7 @@
    "source": [
     "## Exercise 2: Implement your own priority queue\n",
     "\n",
-    "Implement your own priority queue class and compare it to the Python module `PriorityQueue` use previously. Use the stack (or the queue) we have seen in the previous lab."
+    "Implement your own priority queue class and compare it to the Python module `PriorityQueue` used previously. To write the class, you may re-use the stack (or the queue) classes we have seen previously."
    ]
   },
   {
@@ -175,7 +175,7 @@
    "id": "9e2f1c19-1f64-4de1-b9e8-1ed2e167cf40",
    "metadata": {},
    "source": [
-    "Write comparisons with the `PriorityQueue` module:"
+    "Write code that compare the results with the `PriorityQueue` module:"
    ]
   },
   {
@@ -214,9 +214,9 @@
    "source": [
     "## Exercise 3: Tasks scheduler\n",
     "\n",
-    "In this exercise we want to write an algorithm that will schedule some tasks. Think of a tasks as an event with a name (eg `\"Task 1\"`, a `start` time and an `end` time). To keep it simple, we will consider times as `int`. The goal will be to write a scheduler that will decide which task to do, with an important condition: tasks cannot overlap (ie at any given moment, only 1 task can be picked).  You'll start by defining a `Task` class and then the `TaskScheduler` class that manages the list of tasks you picked and that do not overlap.\n",
+    "In this exercise we want to write an algorithm that will schedule some tasks. Think of a task as an event with a name (eg `\"Task 1\"`), a `start` time and an `end` time. To keep it simple, we will consider times as `int`. The goal will be to write a scheduler that will decide which task to do from the ones that are added, with an important condition: tasks cannot overlap (ie at any given moment, only 1 task can be picked).  You'll start by defining a `Task` class and then the `TaskScheduler` class that manages the list of tasks you picked and that do not overlap.\n",
     "\n",
-    "Start by writing the `Task` class and in particular include a way to compare tasks by overriding the [comparison operator](https://docs.python.org/3/library/operator.html):\n",
+    "Start by writing the `Task` class with its properties, and include a way to compare tasks by `start` value by overriding the [comparison operator](https://docs.python.org/3/library/operator.html):\n",
     "\n",
     "```python\n",
     "    def __lt__(self, other):\n",
@@ -268,11 +268,11 @@
    "id": "7563c27b-c412-4899-acb3-57c10f2abb8d",
    "metadata": {},
    "source": [
-    "Now write the `TaskScheduler` class. You can use the `PriorityQueue` or your own implementation of a priority queue. Tip: write 3 methods:\n",
+    "Now write the `TaskScheduler` class. You can use the `PriorityQueue` or your own implementation of a priority queue. Tip: write 3 methods that:\n",
     "\n",
-    "1. add a task\n",
+    "1. add a task and use the **start time as priority**\n",
     "2. check if overlapping\n",
-    "3. return the non-overlapping tasks"
+    "3. return the list of non-overlapping tasks"
    ]
   },
   {
@@ -345,9 +345,9 @@
    "source": [
     "## Exercise 4: Merge sorted lists (using heaps)\n",
     "\n",
-    "The `heapq` [(doc)](https://docs.python.org/3/library/heapq.html) module provides an efficient implementation of priority queue using the heap sorting algorithm, that use can use instead of the `PriorityQueue` class. Here is an example on how to use the heap. The operations complexity are are:\n",
-    "- `heapify` $O(n)$ as it find the smallest value (only) to return next\n",
-    "- `heappop` $O(log(n))$ as it finds again the smallest value (only) to return next, but in an efficient way"
+    "The `heapq` [(doc)](https://docs.python.org/3/library/heapq.html) module provides an efficient implementation of priority queue using the heap sorting algorithm, that can be used instead of the `PriorityQueue` class. The operations complexity are are:\n",
+    "- `heapify` (equivalent to put) $O(n)$ as it finds the smallest value (only) to return next\n",
+    "- `heappop` (equivalent to get) $O(log(n))$ as it finds again the smallest value (only) to return next, but in an efficient way"
    ]
   },
   {
@@ -369,15 +369,15 @@
    "id": "327aa702-5699-42ba-96e1-b75079d31050",
    "metadata": {},
    "source": [
-    "Write a function `merge_sorted_lists(lists)` that takes a list of sorted lists, and uses `heapq` to merge them into a single sorted list as a result.\n",
+    "Write a function `merge_sorted_lists(lists)` that takes a list of sorted lists, and uses `heapq` to merge them into a single sorted list as a result. You may follow those steps:\n",
     "\n",
     "1. Use `heapq` to store the first element of each list.\n",
     "2. Store each element in the heap as a tuple `(value, list_index, element_index)`:\n",
     "   - `value` is the element value,\n",
     "   - `list_index` is the index of the list it comes from,\n",
-    "   - `element_index` is the position of the element in its original list.\n",
-    "3. At each step, extract the smallest element from the heap and add it to the result list.\n",
-    "4. Insert the next element from the same list into the heap until all lists are empty."
+    "   - `element_index` is the position of the element in its original list\n",
+    "3. At each step, extract the smallest element from the heap and add it to the result list\n",
+    "4. Insert the next element from the same list into the heap until all lists are empty"
    ]
   },
   {
@@ -385,6 +385,17 @@
    "execution_count": null,
    "id": "4b20f11a-47b8-419a-b94a-902943048c76",
    "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "87555eb29812a46b740436e1eed31a4e",
+     "grade": false,
+     "grade_id": "cell-593558331d679bb2",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
     "tags": []
    },
    "outputs": [],
@@ -392,22 +403,8 @@
     "import heapq\n",
     "\n",
     "def merge(lists):\n",
-    "    min_heap = []\n",
-    "    merged_list = []\n",
-    "\n",
-    "    for i, lst in enumerate(lists): # each first element in heap\n",
-    "        if lst:\n",
-    "            heapq.heappush(min_heap, (lst[0], i, 0))  # (value, list_index, element_index)\n",
-    "\n",
-    "    while min_heap:\n",
-    "        val, list_index, element_index = heapq.heappop(min_heap)\n",
-    "        merged_list.append(val)\n",
-    "\n",
-    "        if element_index + 1 < len(lists[list_index]):\n",
-    "            next_val = lists[list_index][element_index + 1]\n",
-    "            heapq.heappush(min_heap, (next_val, list_index, element_index + 1))\n",
-    "\n",
-    "    return merged_list"
+    "    # YOUR CODE HERE\n",
+    "    raise NotImplementedError()"
    ]
   },
   {
@@ -442,6 +439,19 @@
     "assert merge([[]]) == []\n",
     "assert merge([[1, 2, 3]]) == [1, 2, 3]"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b318e23f-4ab5-455c-9607-90e75245df21",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "## Exercise 5 (BONUS) \n",
+    "\n",
+    "- Re-implement previous exercises that involve a priority queue using heaps\n",
+    "- Compare performance in execution time"
+   ]
   }
  ],
  "metadata": {