diff --git a/src/cell.c b/src/cell.c
index 900389f7f59e5de8ff7f842b2949c4b020c71e5d..6807e2da3721ddf317d0f9371ed18fd06860a9db 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -2017,48 +2017,6 @@ void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
   } /* Otherwise, pair interation */
 }
 
-/**
- * @brief Drift the multipoles that will be used in a M-M task.
- *
- * @param ci The first #cell we update.
- * @param cj The second #cell we update.
- * @param s The task #scheduler.
- */
-void cell_activate_grav_mm_task(struct cell *ci, struct cell *cj,
-                                struct scheduler *s) {
-  /* Some constants */
-  const struct engine *e = s->space->e;
-  // const integertime_t ti_current = e->ti_current;
-
-  /* Anything to do here? */
-  if (!cell_is_active_gravity_mm(ci, e) && !cell_is_active_gravity_mm(cj, e))
-    error("Inactive MM task being activated");
-
-  /* /\* Atomically drift the multipoles in the progenies of ci *\/ */
-  /* for (int i = 0; i < 8; i++) { */
-  /*   struct cell *cpi = ci->progeny[i]; */
-  /*   if (cpi != NULL) { */
-  /*     lock_lock(&cpi->mlock); */
-  /*     if (cpi->ti_old_multipole < ti_current) cell_drift_multipole(cpi, e);
-   */
-  /*     if (lock_unlock(&cpi->mlock) != 0) error("Impossible to unlock
-   * m-pole"); */
-  /*   } */
-  /* } */
-
-  /* /\* Atomically drift the multipoles in the progenies of cj *\/ */
-  /* for (int j = 0; j < 8; j++) { */
-  /*   struct cell *cpj = cj->progeny[j]; */
-  /*   if (cpj != NULL) { */
-  /*     lock_lock(&cpj->mlock); */
-  /*     if (cpj->ti_old_multipole < ti_current) cell_drift_multipole(cpj, e);
-   */
-  /*     if (lock_unlock(&cpj->mlock) != 0) error("Impossible to unlock
-   * m-pole"); */
-  /*   } */
-  /* } */
-}
-
 /**
  * @brief Traverse a sub-cell task and activate the gravity drift tasks that
  * are required by a self gravity task.
@@ -2523,9 +2481,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
         (cj_active && cj_nodeID == nodeID)) {
 
       scheduler_activate(s, t);
-
-      /* Drift the multipoles */
-      cell_activate_grav_mm_task(ci, cj, s);
     }
   }
 
diff --git a/src/runner.c b/src/runner.c
index fc22bd8014edc49612a50fc4ee84d948eaff2205..259343b34008f852fbafd35909d888d28daf7fc1 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -2273,7 +2273,7 @@ void *runner_main(void *data) {
           runner_do_grav_long_range(r, t->ci, 1);
           break;
         case task_type_grav_mm:
-          runner_dopair_grav_mm_progenies(r, t->ci, t->cj);
+          runner_dopair_grav_mm_progenies(r, t->flags, t->ci, t->cj);
           break;
         case task_type_cooling:
           runner_do_cooling(r, t->ci, 1);
diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h
index ed8f935872496adc538a0bde9cca9c3db10070bf..26e3cfdca0dc37449c90e1c85fa9fb0597ff68a8 100644
--- a/src/runner_doiact_grav.h
+++ b/src/runner_doiact_grav.h
@@ -1308,13 +1308,21 @@ static INLINE void runner_dopair_grav_mm(struct runner *r,
     runner_dopair_grav_mm_nonsym(r, cj, ci);
 }
 
+/**
+ * @brief Computes all the M-M interactions between all the well-separated (at
+ * rebuild) pairs of progenies of the two cells.
+ *
+ * @param r The #runner thread.
+ * @param flags The task flag containing the list of well-separated pairs as a
+ * bit-field.
+ * @param ci The first #cell.
+ * @param cj The second #cell.
+ */
 static INLINE void runner_dopair_grav_mm_progenies(struct runner *r,
+                                                   const long long flags,
                                                    struct cell *restrict ci,
                                                    struct cell *restrict cj) {
 
-  const struct engine *e = r->e;
-  const struct space *s = e->s;
-
   /* Loop over all pairs of progenies */
   for (int i = 0; i < 8; i++) {
     if (ci->progeny[i] != NULL) {
@@ -1324,11 +1332,10 @@ static INLINE void runner_dopair_grav_mm_progenies(struct runner *r,
           struct cell *cpi = ci->progeny[i];
           struct cell *cpj = cj->progeny[j];
 
-          /* Did we agree to use an M-M interaction here at the last rebuild? */
-          if (cell_can_use_pair_mm_rebuild(cpi, cpj, e, s)) {
+          const int flag = i * 8 + j;
 
-            runner_dopair_grav_mm(r, cpi, cpj);
-          }
+          /* Did we agree to use an M-M interaction here at the last rebuild? */
+          if (flags & (1LL << flag)) runner_dopair_grav_mm(r, cpi, cpj);
         }
       }
     }
diff --git a/src/scheduler.c b/src/scheduler.c
index a5da777f45f8075c7c577988eaa5dfbd7d1ca5ed..c0e4175ebd398c8e3a475216bfa73240ff001115 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -906,6 +906,7 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
            * progeny pairs */
           t->type = task_type_grav_mm;
           t->subtype = task_subtype_none;
+          t->flags = 0;
 
           /* Make a task for every other pair of progeny */
           for (int i = 0; i < 8; i++) {
@@ -913,11 +914,22 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
               for (int j = 0; j < 8; j++) {
                 if (cj->progeny[j] != NULL) {
 
-                  /* But only for pairs that cannot be replaced by a M-M
-                   * interaction */
-                  if (!cell_can_use_pair_mm_rebuild(ci->progeny[i],
-                                                    cj->progeny[j], e, sp)) {
+                  /* Can we use a M-M interaction here? */
+                  if (cell_can_use_pair_mm_rebuild(ci->progeny[i],
+                                                   cj->progeny[j], e, sp)) {
 
+                    /* Flag this pair as being treated by the M-M task */
+                    /* We use the 64 bits in the task->flags field to store */
+                    /* this information. The corresponding taks will unpack the
+                     */
+                    /* information and operate according to the choices made
+                     * here. */
+                    const int flag = i * 8 + j;
+                    t->flags |= (1LL << flag);
+
+                  } else {
+
+                    /* Ok, we actually have to create a task */
                     scheduler_splittask_gravity(
                         scheduler_addtask(s, task_type_pair, task_subtype_grav,
                                           0, 0, ci->progeny[i], cj->progeny[j]),
@@ -927,6 +939,16 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
               }
             }
           }
+
+          /* Can none of the progenies use M-M calculations? */
+          if (t->flags == 0) {
+            t->type = task_type_none;
+            t->subtype = task_subtype_none;
+            t->ci = NULL;
+            t->cj = NULL;
+            t->skip = 1;
+          }
+
         } /* Split the pair */
       }
     } /* pair interaction? */
diff --git a/src/task.c b/src/task.c
index 10f2ddf5cec885ec23c4f65db5cdea50f0e5097b..018a09b5c74f8dc72093f411d24e31abd767b3d0 100644
--- a/src/task.c
+++ b/src/task.c
@@ -366,7 +366,7 @@ int task_lock(struct task *t) {
         char buff[MPI_MAX_ERROR_STRING];
         int len;
         MPI_Error_string(err, buff, &len);
-        error("Failed to test request on send/recv task (tag=%i, %s).",
+        error("Failed to test request on send/recv task (tag=%lld, %s).",
               t->flags, buff);
       }
       return res;
diff --git a/src/task.h b/src/task.h
index 58ea3a8cbb93b38b47ab7b6a243c3ee6c85d40b7..b66fe87d353bab589ab4023e749e17f62f16d3af 100644
--- a/src/task.h
+++ b/src/task.h
@@ -128,6 +128,9 @@ struct task {
   /*! List of tasks unlocked by this one */
   struct task **unlock_tasks;
 
+  /*! Flags used to carry additional information (e.g. sort directions) */
+  long long flags;
+
 #ifdef WITH_MPI
 
   /*! Buffer for this task's communications */
@@ -138,9 +141,6 @@ struct task {
 
 #endif
 
-  /*! Flags used to carry additional information (e.g. sort directions) */
-  int flags;
-
   /*! Rank of a task in the order */
   int rank;