here is an example about how to use signal with many to many field (post like and post comments models),
and in my example i have :
- like model (Intermediary table for User and Post tables) : the user can add 1 record only in Intermediary table for each post , which means (unique_together = ['user_like', 'post_like']) for this type of many to many relations you can use 'm2m_changed' signals , 
- comment model (Intermediary table for User and Post tables): the user can add many records in Intermediary table for each post , (without unique_together ), for this i just use 'post_save, post_delete' signals , but you can use also 'pre_save, pre_delete' if you like , 
and here is both usage example :
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save, post_delete, m2m_changed
from django.dispatch import receiver
class Post(models.Model):
    post_user = models.ForeignKey(User,related_name='post_user_related', on_delete=models.CASCADE)
    post_title = models.CharField(max_length=100)
    post_description = models.TextField()
    post_image = models.ImageField(upload_to='post_dir', null=True, blank=True)
    post_created_date = models.DateTimeField(auto_now_add=True)
    post_updated_date = models.DateTimeField(auto_now=True)
    post_comments = models.ManyToManyField(
        User,
        through="Comments",
        related_name="post_comments"
        )
    p_like = models.ManyToManyField(
        User, blank=True,
        through="LikeIntermediary",
        related_name="post_like_rel"
        )
class LikeIntermediary(models.Model):
    user_like = models.ForeignKey(User ,related_name="related_user_like", on_delete=models.CASCADE)
    post_like = models.ForeignKey(Post ,related_name="related_post_like", on_delete=models.CASCADE)
    created =  models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return f"{self.user_like} - {self.post_like} "
    class Meta:
        unique_together = ['user_like', 'post_like']
@receiver(m2m_changed, sender=LikeIntermediary)
def like_updated_channels(sender, instance, **kwargs):
    print('this m2m_changed receiver is called, the instance is post id', instance.id)
class Comments(models.Model):
    cmt_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="related_comments_user") 
    cmt_post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="related_comments_post")
    cmt_created_date = models.DateTimeField(auto_now_add=True)
    cmt_comment_body = models.TextField()
    cmt_created =  models.DateTimeField(auto_now_add=True)
    cmt_updated =  models.DateTimeField(auto_now=True)
@receiver(post_save, sender=Comments)
def comments_updated_channels(sender, instance, created, **kwargs):
   print('this post_save receiver is called, the instance post id', instance.cmt_post.id)
@receiver(post_delete, sender=Comments)
def comments_deleted_channels(sender, instance, **kwargs):
   print('this post_save receiver is called, the instance post id', instance.cmt_post.id)
notes :
- the instance with 'm2m_changed' it is a post object .
- the instance with 'post_save and post_delete' it is a comment object
this is just an example , and change it based on your case/requirements.
i hope this helpful