# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction

mod = 10 ** 9 + 7
mod1 = 998244353

# ------------------------------warmup----------------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n
avl=AvlTree()
#-----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a ,b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left)/ 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid]<=key):
            count = mid+1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c

def countGreater( arr,n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
n,m=map(int,input().split())
k=m
l=list(map(int,input().split()))
ind=defaultdict(int)
excess=defaultdict(int)
defi=defaultdict(int)
for i in range(n):
    ind[l[i]%m]+=1
for i in ind:
    if ind[i]>n//m:
        excess[i]=ind[i]-(n//m)
    else:
        defi[i]=(n//m)-ind[i]
t=m
defiu=defaultdict(list)
for i in sorted(defi,reverse=True):
    t=min(t,i)
    while(defi[i]>0):
        if excess[t%k]==0:
            t-=1
            continue
        defiu[t % k].append((i, min(excess[t % k], defi[i])))
        we=min(excess[t%k],defi[i])
        defi[i]-=we
        excess[t%k]-=we
        t-=1
    if (excess[(t+1)%k]>0):
        t+=1
ans=0
defiu1=defaultdict(list)
for j in defiu:
    for k in defiu[j]:
        for p in range(k[1]):
            defiu1[j].append(k[0])
for i in range(n):
    t=l[i]%m
    if len(defiu1[t])!=0:
        su=defiu1[t][-1]-t
        if su<0:
            su+=m
        l[i]+=su
        ans+=su
        defiu1[t].pop()
print(ans)
print(*l,sep=" ")


# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction

mod = 10 ** 9 + 7
mod1 = 998244353

# ------------------------------warmup----------------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n
avl=AvlTree()
#-----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a ,b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left)/ 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid]<=key):
            count = mid+1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c

def countGreater( arr,n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
n,m=map(int,input().split())
k=m
l=list(map(int,input().split()))
ind=defaultdict(int)
excess=defaultdict(int)
defi=defaultdict(int)
s=set([i for i in range(m)])
for i in range(n):
    ind[l[i]%m]+=1
    if l[i]%m in s:
        s.remove(l[i]%m)
for i in ind:
    if ind[i]>n//m:
        excess[i]=ind[i]-(n//m)
    else:
        defi[i]=(n//m)-ind[i]
for i in s:
    defi[i]=n//m
t=m
defiu=defaultdict(list)
for i in sorted(defi,reverse=True):
    t=min(t,i)
    while(defi[i]>0):
        if excess[t%k]==0:
            t-=1
            continue
        defiu[t % k].append((i, min(excess[t % k], defi[i])))
        we=min(excess[t%k],defi[i])
        defi[i]-=we
        excess[t%k]-=we
        t-=1
    if (excess[(t+1)%k]>0):
        t+=1
ans=0
defiu1=defaultdict(list)
for j in defiu:
    for k in defiu[j]:
        for p in range(k[1]):
            defiu1[j].append(k[0])
for i in range(n):
    t=l[i]%m
    if len(defiu1[t])!=0:
        su=defiu1[t][-1]-t
        if su<0:
            su+=m
        l[i]+=su
        ans+=su
        defiu1[t].pop()
print(ans)
print(*l,sep=" ")


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

n, m = i_ints()
a = list(i_ints())
r = [x % m for x in a]
c = Counter(r)
c = [c[i] for i in range(m)]

rem2ind = [[] for i in range(m)]
for i, x in enumerate(r):
    rem2ind[x].append(i)

R = n // m

for i, inds in enumerate(rem2ind):
    if len(inds) > R:
        next_big = i
        break
#for i in range(next_big + 1, next_big + m):
#    if len(rem2ind[i%m]) < R:
#        next_small = i
#        break

moves = 0
while next_big < m:
    next_small = max(next_small, next_big + 1)
    num = max(c[next_big] - R, 0)
    while num > 0:
        num2 = max(R - c[next_small%m], 0)
        delta = min(num, num2)
        num -= delta
        c[next_small%m] += delta
        step = next_small - next_big
        for i in rem2ind[next_big][num:num+delta]:
            a[i] += step
        moves += delta * step
        if c[next_small%m] >= R:
            next_small += 1
    next_big += 1

print(moves)
print( " ".join(map(str, a)))


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

n, m = i_ints()
a = list(i_ints())

r = [x % m for x in a]
c = Counter(r)
c = [c[i] for i in range(m)]

rem2ind = [[] for i in range(m)]
for i, x in enumerate(r):
    rem2ind[x].append(i)

R = n // m

for i, inds in enumerate(rem2ind):
    if len(inds) > R:
        next_big = i
        break
else:
    next_big = m
next_small = next_big + 1
#for i in range(next_big + 1, next_big + m):
#    if len(rem2ind[i%m]) < R:
#        next_small = i
#        break

moves = 0
while next_big < m:
    next_small = max(next_small, next_big + 1)
    num = max(c[next_big] - R, 0)
    while num > 0:
        num2 = max(R - c[next_small%m], 0)
        delta = min(num, num2)
        num -= delta
        c[next_small%m] += delta
        step = next_small - next_big
        for i in rem2ind[next_big][num:num+delta]:
            a[i] += step
        moves += delta * step
        if c[next_small%m] >= R:
            next_small += 1
#        print(next_big, next_small, delta, step, moves)
    next_big += 1

print(moves)
print( " ".join(map(str, a)))

#def distribute(k, i):
#    """ distribute i elements from position k to the following positions, not exceeding R"""
#    while i > 0:
#        c[k] -= i
#        moves[k] += i
#        k = (k+1) % m
#        c[k] += i
#        i = max(0, c[k] - R)
#
#moves = [0] * m
#
#for k in range(m):
#    if c[k] > R:
#        distribute(k, c[k] - R)
#
#print(sum(moves))
#
#for k, x in enumerate(a):
#    while moves[x%m]:
#        moves[x%m] -= 1
#        x += 1
#    a[k] = x
#
#print( " ".join(map(str, a)))


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

#n, m = i_ints()
#a = list(i_ints())

#n, m= 6, 3
#a = [3, 2, 0, 6, 10, 12]

n, m = 4, 2
a = [0, 1, 2, 3]

r = [x % m for x in a]
c = Counter(r)
c = [c[i] for i in range(m)]

rem2ind = [[] for i in range(m)]
for i, x in enumerate(r):
    rem2ind[x].append(i)

R = n // m

for i, inds in enumerate(rem2ind):
    if len(inds) > R:
        next_big = i
        break
else:
    next_big = m
next_small = next_big + 1
#for i in range(next_big + 1, next_big + m):
#    if len(rem2ind[i%m]) < R:
#        next_small = i
#        break

moves = 0
while next_big < m:
    next_small = max(next_small, next_big + 1)
    num = max(c[next_big] - R, 0)
    while num > 0:
        num2 = max(R - c[next_small%m], 0)
        delta = min(num, num2)
        num -= delta
        c[next_small%m] += delta
        step = next_small - next_big
        for i in rem2ind[next_big][num:num+delta]:
            a[i] += step
        moves += delta * step
        if c[next_small%m] >= R:
            next_small += 1
#        print(next_big, next_small, delta, step, moves)
    next_big += 1

print(moves)
print( " ".join(map(str, a)))

#def distribute(k, i):
#    """ distribute i elements from position k to the following positions, not exceeding R"""
#    while i > 0:
#        c[k] -= i
#        moves[k] += i
#        k = (k+1) % m
#        c[k] += i
#        i = max(0, c[k] - R)
#
#moves = [0] * m
#
#for k in range(m):
#    if c[k] > R:
#        distribute(k, c[k] - R)
#
#print(sum(moves))
#
#for k, x in enumerate(a):
#    while moves[x%m]:
#        moves[x%m] -= 1
#        x += 1
#    a[k] = x
#
#print( " ".join(map(str, a)))


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

n, m = i_ints()
a = list(i_ints())
r = [x % m for x in a]

R = n // m

def distribute(k, i):
    """ distribute i elements from position k to the following positions, not exceeding R"""
    while i > 0:
        c[k] -= i
        moves[k] += i
        k = (k+1) % m
        c[k] += i
        i = max(0, c[k] - R)

c = Counter(r)
moves = [0] * m

for k in range(m):
    if c[k] > R:
        distribute(k, c[k] - R)

print(sum(moves))

for k, x in enumerate(a):
    while moves[x%m]:
        moves[x%m] -= 1
        x += 1
    a[k] = x

print( " ".join(map(str, a)))


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

n, m = i_ints()
a = list(i_ints())

#n, m= 6, 3
#a = [3, 2, 0, 6, 10, 12]

r = [x % m for x in a]
c = Counter(r)
c = [c[i] for i in range(m)]

rem2ind = [[] for i in range(m)]
for i, x in enumerate(r):
    rem2ind[x].append(i)

R = n // m

for i, inds in enumerate(rem2ind):
    if len(inds) > R:
        next_big = i
        break
next_small = next_big + 1
#for i in range(next_big + 1, next_big + m):
#    if len(rem2ind[i%m]) < R:
#        next_small = i
#        break

moves = 0
while next_big < m:
    next_small = max(next_small, next_big + 1)
    num = max(c[next_big] - R, 0)
    while num > 0:
        num2 = max(R - c[next_small%m], 0)
        delta = min(num, num2)
        num -= delta
        c[next_small%m] += delta
        step = next_small - next_big
        for i in rem2ind[next_big][num:num+delta]:
            a[i] += step
        moves += delta * step
        if c[next_small%m] >= R:
            next_small += 1
#        print(next_big, next_small, delta, step, moves)
    next_big += 1

print(moves)
print( " ".join(map(str, a)))

#def distribute(k, i):
#    """ distribute i elements from position k to the following positions, not exceeding R"""
#    while i > 0:
#        c[k] -= i
#        moves[k] += i
#        k = (k+1) % m
#        c[k] += i
#        i = max(0, c[k] - R)
#
#moves = [0] * m
#
#for k in range(m):
#    if c[k] > R:
#        distribute(k, c[k] - R)
#
#print(sum(moves))
#
#for k, x in enumerate(a):
#    while moves[x%m]:
#        moves[x%m] -= 1
#        x += 1
#    a[k] = x
#
#print( " ".join(map(str, a)))


import sys
from collections import Counter

def i_ints():
    return map(int, sys.stdin.readline().split())

n, m = i_ints()
a = list(i_ints())
r = [x % m for x in a]
c = Counter(r)
c = [c[i] for i in range(m)]

rem2ind = [[] for i in range(m)]
for i, x in enumerate(r):
    rem2ind[x].append(i)

R = n // m

for i, inds in enumerate(rem2ind):
    if len(inds) > R:
        next_big = i
        break
for i in range(next_big + 1, next_big + m):
    if len(rem2ind[i%m]) < R:
        next_small = i
        break

moves = 0
while next_big < m:
    num = max(c[next_big] - R, 0)
    while num > 0:
        num2 = max(R - c[next_small%m], 0)
        delta = min(num, num2)
        num -= delta
        c[next_small%m] += delta
        step = next_small - next_big
        for i in rem2ind[next_big][num:num+delta]:
            a[i] += step
        moves += delta * step
        if c[next_small%m] >= R:
            next_small += 1
    next_big += 1

print(moves)
print( " ".join(map(str, a)))


from collections import deque

n, m = map(int, input().split())
a = [int(x) for x in input().split()]
ind = [deque() for r in range(m)]
c = m * [0]

for i, ai in enumerate(a):
    r = ai % m
    c[r] += 1
    ind[r].append(i)

q = deque()
ans = 0

for i in range(0, 2 * m):
    r = i % m

    while c[r] > n // m:
        q.append((i, ind[r].pop()))
        c[r] -= 1

    while c[r] < n // m and q:
        j, index = q.popleft()
        ind[r].append(index)
        c[r] += 1
        a[index] += i - j
        ans += i - j

print(ans)
print(*a)


#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <float.h>
#include <limits.h>
#include <malloc.h>
#include <memory.h>
#include <complex.h>
#include <errno.h>
#include <time.h>
int n,m,i,j,k,l;
long long ans,t,d[200005];
struct u
{
	long long a,b,c;
}a[200005];

int cmp(const void *x,const void *y)
{
	return ((struct u *)x)->c-((struct u *)y)->c;
}

int main()
{
	srand(time(NULL));
	scanf("%d %d",&n,&m);
	k=n/m;
	for (i=1;i<=n;i++)
	{
		scanf("%lld",&a[i].a);
		a[i].b=i;
		a[i].c=(long long)a[i].a%m;
	}
	for (i=n;i>=1;i--)
	{
		j=rand()%i+1;
		t=a[i].c; a[i].c=a[j].c; a[j].c=t;
		t=a[i].b; a[i].b=a[j].b; a[j].b=t;
		t=a[i].a; a[i].a=a[j].a; a[j].a=t;
	}
	qsort(&a[1],n,sizeof(struct u),cmp);
	for (i=ans=0,l=1;i<m;i++)
	for (j=0;j<k;j++)
	{
		t=a[l].c<=i ? (i-a[l].c) : (i+m-a[l].c);
		a[l].a+=t;
		ans+=t;
		l++;
	}
	for (i=1;i<=n;i++) d[a[i].b]=a[i].a;
	printf("%lld\n",ans);
	for (i=1;i<=n;i++) printf("%lld ",d[i]);
	puts("");
	return 0;
}


#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <float.h>
#include <limits.h>
#include <malloc.h>
#include <memory.h>
#include <complex.h>
#include <errno.h>
#include <time.h>
int n,m,i,j,k,l,f[200005],fa[200005],tt;
long long ans,t;
struct u
{
	long long a,b,c;
}a[200005];

int find(long long x)
{
	return fa[x]==x ? x : (fa[x]=find(fa[x]));
}

int main()
{
	memset(f,0,sizeof(f));
	srand(time(NULL));
	scanf("%d %d",&n,&m);
	k=n/m;
	for (i=1;i<=n;i++)
	{
		scanf("%lld",&a[i].a);
		a[i].b=i;
		a[i].c=(long long)a[i].a%m;
	}
	for (i=0;i<m;i++) fa[i]=i;
	for (i=1,ans=0;i<=n;i++)
	if (f[a[i].c]<k)
	{
		f[a[i].c]++;
		if (f[a[i].c]==k)
		{
			if (a[i].c==m-1) fa[a[i].c]=0;
			else fa[a[i].c]=a[i].c+1;
		}
	}
	else
	{
		tt=find(a[i].c);
		t=a[i].c<=tt ? (tt-a[i].c) : (tt+m-a[i].c);
		a[i].a+=t;
		ans+=t;
		f[tt]++;
		if (f[tt]==k)
		{
			if (tt==m-1) fa[tt]=0;
			else fa[tt]=tt+1;
		}
	}
	printf("%lld\n",ans);
	for (i=1;i<=n;i++) printf("%lld ",a[i].a);
	puts("");
	return 0;
}


#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <float.h>
#include <limits.h>
#include <malloc.h>
#include <memory.h>
#include <complex.h>
#include <errno.h>
#include <time.h>
int n,m,i,j,k,l,f[200005];
long long ans,t;
struct u
{
	long long a,b,c;
}a[200005];

int cmp(const void *x,const void *y)
{
	return ((struct u *)x)->c-((struct u *)y)->c;
}

int main()
{
	memset(f,0,sizeof(f));
	srand(time(NULL));
	scanf("%d %d",&n,&m);
	k=n/m;
	for (i=1;i<=n;i++)
	{
		scanf("%lld",&a[i].a);
		a[i].b=i;
		a[i].c=(long long)a[i].a%m;
	}
	for (i=1,ans=0;i<=n;i++)
	if (f[a[i].c]<k)
	{
		f[a[i].c]++;
	}
	else
	{
		t=0;
		while (f[a[i].c]>=k) a[i].c++,a[i].c%=m,t++;
		a[i].a+=t;
		ans+=t;
		f[a[i].c]++;
	}
	//for (i=1;i<=n;i++) printf("%lld ",a[i].c);
	/*for (i=n;i>=1;i--)
	{
		j=rand()%i+1;
		t=a[i].c; a[i].c=a[j].c; a[j].c=t;
		t=a[i].b; a[i].b=a[j].b; a[j].b=t;
		t=a[i].a; a[i].a=a[j].a; a[j].a=t;
	}
	qsort(&a[1],n,sizeof(struct u),cmp);
	for (i=ans=0,l=1;i<m;i++)
	for (j=0;j<k;j++)
	{
		t=a[l].c<=i ? (i-a[l].c) : (i+m-a[l].c);
		a[l].a+=t;
		ans+=t;
		l++;
	}
	for (i=1;i<=n;i++) d[a[i].b]=a[i].a;*/
	printf("%lld\n",ans);
	for (i=1;i<=n;i++) printf("%lld ",a[i].a);
	puts("");
	return 0;
}


#include <stdio.h>

unsigned n, m, c, i, j, moves = 0;
unsigned numbers[200000], count[200000] = {0}, next_remainder[200000];

unsigned get_next_remainder(unsigned curr) {
    if (count[curr] < c)
        return curr;
    unsigned next = get_next_remainder(next_remainder[curr]);
    next_remainder[curr] = next;
    return next;
}

int main() {
    scanf("%u %u", &n, &m);
    for (i = 0; i < m; i++) {
        next_remainder[i] = i + 1;
    }
    next_remainder[m - 1] = 0;
    c = n / m;
    for (i = 0; i < n; i++) {
        unsigned num, curr;
        scanf("%u", &num);
        curr = num % m;
        if (count[curr] < c) {
            numbers[i] = num;
            count[curr]++;
        } else {
            unsigned next = get_next_remainder(curr);
            unsigned move = (next > curr) ? (next - curr) : (m + next - curr);
            moves += move;
            numbers[i] = num + move;
            count[next]++;
        }
    }

    printf("%u\n", moves);
    for (i = 0; i < n; i++) {
        printf("%u ", numbers[i]);
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

unsigned n, m, c, i, j;
unsigned numbers[200000], count[200000] = {0}, next_remainder[200000];

unsigned get_next_remainder(unsigned curr) {
    if (count[curr] < c)
        return curr;
    unsigned next = get_next_remainder(next_remainder[curr]);
    next_remainder[curr] = next;
    return next;
}

int main() {
    long moves = 0;
    scanf("%u %u", &n, &m);
    for (i = 0; i < m; i++) {
        next_remainder[i] = i + 1;
    }
    next_remainder[m - 1] = 0;
    c = n / m;
    for (i = 0; i < n; i++) {
        unsigned num, curr;
        scanf("%u", &num);
        curr = num % m;
        if (count[curr] < c) {
            numbers[i] = num;
            count[curr]++;
        } else {
            unsigned next = get_next_remainder(curr);
            unsigned move = (next > curr) ? (next - curr) : (m + next - curr);
            moves += move;
            numbers[i] = num + move;
            count[next]++;
        }
    }

    printf("%ld\n", moves);
    for (i = 0; i < n; i++) {
        printf("%u ", numbers[i]);
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

int main() {
    unsigned n, m, c, i, j, moves = 0;
    unsigned numbers[200000], count[200000] = {0};
    scanf("%u %u", &n, &m);
    c = n / m;
    for (i = 0; i < n; i++) {
        unsigned curr;
        scanf("%u", &curr);
        if (count[curr % m] < c) {
            numbers[i] = curr;
            count[curr % m]++;
        } else {
            for (j = 1; j < m; j++) {
                unsigned next = curr + j;
                if (count[next % m] < c) {
                    moves += j;
                    numbers[i] = next;
                    count[next % m]++;
                    break;
                }
            }
        }
    }

    printf("%u\n", moves);
    for (i = 0; i < n; i++) {
        printf("%u ", numbers[i]);
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

unsigned n, m, c, i, j;
unsigned long moves = 0;
unsigned numbers[200000], count[200000] = {0}, next_remainder[200000];

unsigned get_next_remainder(unsigned curr) {
    if (count[curr] < c)
        return curr;
    unsigned next = get_next_remainder(next_remainder[curr]);
    next_remainder[curr] = next;
    return next;
}

int main() {
    scanf("%u %u", &n, &m);
    for (i = 0; i < m; i++) {
        next_remainder[i] = i + 1;
    }
    next_remainder[m - 1] = 0;
    c = n / m;
    for (i = 0; i < n; i++) {
        unsigned num, curr;
        scanf("%u", &num);
        curr = num % m;
        if (count[curr] < c) {
            numbers[i] = num;
            count[curr]++;
        } else {
            unsigned next = get_next_remainder(curr);
            unsigned move = (next > curr) ? (next - curr) : (m + next - curr);
            moves += move;
            numbers[i] = num + move;
            count[next]++;
        }
    }

    printf("%lu\n", moves);
    for (i = 0; i < n; i++) {
        printf("%u ", numbers[i]);
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

unsigned n, m, c, i, j;
unsigned numbers[200000], count[200000] = {0}, next_remainder[200000];

unsigned get_next_remainder(unsigned curr) {
    if (count[curr] < c)
        return curr;
    unsigned next = get_next_remainder(next_remainder[curr]);
    next_remainder[curr] = next;
    return next;
}

int main() {
    long long moves = 0;
    scanf("%u %u", &n, &m);
    for (i = 0; i < m; i++) {
        next_remainder[i] = i + 1;
    }
    next_remainder[m - 1] = 0;
    c = n / m;
    for (i = 0; i < n; i++) {
        unsigned num, curr;
        scanf("%u", &num);
        curr = num % m;
        if (count[curr] < c) {
            numbers[i] = num;
            count[curr]++;
        } else {
            unsigned next = get_next_remainder(curr);
            unsigned move = (next > curr) ? (next - curr) : (m + next - curr);
            moves += move;
            numbers[i] = num + move;
            count[next]++;
        }
    }

    printf("%I64d\n", moves);
    for (i = 0; i < n; i++) {
        printf("%u ", numbers[i]);
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

#define MAX_SIZE 200000

int a[MAX_SIZE], c[MAX_SIZE], next[MAX_SIZE];
int n, m, ac, i, ans = 0;

int get_pos(int r)
{
	if (c[r] < ac)
		return r;
	return next[r] = get_pos(next[r]);
}

int main()
{
	scanf("%d%d", &n, &m);
	for (i = 0; i != n; ++i)
		scanf("%d", &a[i]);
	for (i = 0; i != m; ++i)
		next[i] = (i + 1) % m;
	ac = n / m;
	for (i = 0; i != n; ++i){
		int r = a[i] % m;
		int pos = get_pos(r);
		++c[pos];
		int d = (pos - r + m) % m;
		ans += d;
		a[i] += d;
	}
	printf("%d\n", ans);
	for (i = 0; i != n - 1; ++i)
		printf("%d ", a[i]);
	printf("%d\n", a[n-1]);

	return 0;
}


#include <stdio.h>

#define MAX_SIZE 200000

int a[MAX_SIZE], c[MAX_SIZE], next[MAX_SIZE];
int n, m, ac, i;
long long ans = 0;

int get_pos(int r)
{
	if (c[r] < ac)
		return r;
	return next[r] = get_pos(next[r]);
}

int main()
{
	scanf("%d%d", &n, &m);
	for (i = 0; i != n; ++i)
		scanf("%d", &a[i]);
	for (i = 0; i != m; ++i)
		next[i] = (i + 1) % m;
	ac = n / m;
	for (i = 0; i != n; ++i){
		int r = a[i] % m;
		int pos = get_pos(r);
		++c[pos];
		int d = (pos - r + m) % m;
		ans += (long long)d;
		a[i] += d;
	}
	printf("%I64d\n", ans);
	for (i = 0; i != n - 1; ++i)
		printf("%d ", a[i]);
	printf("%d\n", a[n-1]);

	return 0;
}


import java.util.*;
import java.io.*;
public class template {
	public static void main(String[] args) throws Exception {
		FastScanner sc = new FastScanner();
		PrintWriter pw = new PrintWriter(System.out);
		int l = sc.nextInt();
		int div = sc.nextInt();
		i[] arr = new i[l];
		PriorityQueue<i> pq= new PriorityQueue<i>();
		ArrayList<Integer> leftover = new ArrayList<Integer>();
		for(int i=0;i<l;i++) {
			int b = sc.nextInt();
			i a = new i(b,b%div);
			arr[i] = a;
			pq.add(a);
		}
		long sum = 0;
		for(int i=0;i<l;i++) {
			i z = pq.poll();
			int goal = i/(l/div);
			while(goal<z.mod) {
				leftover.add(goal);
				i++;
				goal = i/div;
			}
			sum+=goal-z.mod;
			z.i+=goal-z.mod;
		}
		for(int a:leftover) {
			i z = pq.poll();
			sum+=a-z.mod+div;
			z.i+=a-z.mod+div;
		}
		pw.println(sum);
		for(i i:arr) {
			pw.print(i.i+" ");
		}
		pw.close();
	}
	static class i implements Comparable<i>{
		int i;
		int mod;
		public i(int a,int n) {
			i=a;
			mod=n;
		}
		@Override
		public int compareTo(i o) {
			// TODO Auto-generated method stub
			return Integer.compare(mod, o.mod);
		}
		public String toString() {
			return ""+i;
		}
	}
}
@SuppressWarnings("all")
class FastScanner {
    BufferedReader br;
    StringTokenizer st;
    public FastScanner(BufferedReader d) {
        br=d;
    }
    public FastScanner(String s) {
        try {
            br = new BufferedReader(new FileReader(s));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public FastScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String nextToken() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(nextToken());
    }

    long nextLong() {
        return Long.parseLong(nextToken());
    }

    double nextDouble() {
        return Double.parseDouble(nextToken());
    }
}


import java.util.*;
import java.io.*;
public class template {
	public static void main(String[] args) throws Exception {
		FastScanner sc = new FastScanner();
		PrintWriter pw = new PrintWriter(System.out);
		int l = sc.nextInt();
		int div = sc.nextInt();
		i[] arr = new i[l];
		PriorityQueue<i> pq= new PriorityQueue<i>();
		ArrayList<Integer> leftover = new ArrayList<Integer>();
		for(int i=0;i<l;i++) {
			int b = sc.nextInt();
			i a = new i(b,b%div);
			arr[i] = a;
			pq.add(a);
		}
		long sum = 0;
		for(int i=0;i<l;i++) {
			i z = pq.poll();
			int goal = i/(l/div);
			while(goal<z.mod) {
				leftover.add(goal);
				i++;
				goal = i/(l/div);
			}
			sum+=goal-z.mod;
			z.i+=goal-z.mod;
		}
		for(int a:leftover) {
			i z = pq.poll();
			sum+=a-z.mod+div;
			z.i+=a-z.mod+div;
		}
		pw.println(sum);
		for(i i:arr) {
			pw.print(i.i+" ");
		}
		pw.close();
	}
	static class i implements Comparable<i>{
		int i;
		int mod;
		public i(int a,int n) {
			i=a;
			mod=n;
		}
		@Override
		public int compareTo(i o) {
			// TODO Auto-generated method stub
			return Integer.compare(mod, o.mod);
		}
		public String toString() {
			return ""+i;
		}
	}
}
@SuppressWarnings("all")
class FastScanner {
    BufferedReader br;
    StringTokenizer st;
    public FastScanner(BufferedReader d) {
        br=d;
    }
    public FastScanner(String s) {
        try {
            br = new BufferedReader(new FileReader(s));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public FastScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String nextToken() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(nextToken());
    }

    long nextLong() {
        return Long.parseLong(nextToken());
    }

    double nextDouble() {
        return Double.parseDouble(nextToken());
    }
}


import java.util.*;
import java.io.*;
public class template {
	public static void main(String[] args) throws Exception {
		FastScanner sc = new FastScanner();
		PrintWriter pw = new PrintWriter(System.out);
		int l = sc.nextInt();
		int div = sc.nextInt();
		i[] arr = new i[l];
		PriorityQueue<i> pq= new PriorityQueue<i>();
		ArrayList<Integer> leftover = new ArrayList<Integer>();
		for(int i=0;i<l;i++) {
			int b = sc.nextInt();
			i a = new i(b,b%div);
			arr[i] = a;
			pq.add(a);
		}
		int sum = 0;
		for(int i=0;i<l;i++) {
			i z = pq.poll();
			int goal = i/(l/div);
			while(goal<z.mod) {
				leftover.add(goal);
				i++;
				goal = i/div;
			}
			sum+=goal-z.mod;
			z.i+=goal-z.mod;
		}
		for(int a:leftover) {
			i z = pq.poll();
			sum+=a-z.mod+div;
			z.i+=a-z.mod+div;
		}
		pw.println(sum);
		for(i i:arr) {
			pw.print(i.i+" ");
		}
		pw.close();
	}
	static class i implements Comparable<i>{
		int i;
		int mod;
		public i(int a,int n) {
			i=a;
			mod=n;
		}
		@Override
		public int compareTo(i o) {
			// TODO Auto-generated method stub
			return Integer.compare(mod, o.mod);
		}
		public String toString() {
			return ""+i;
		}
	}
}
@SuppressWarnings("all")
class FastScanner {
    BufferedReader br;
    StringTokenizer st;
    public FastScanner(BufferedReader d) {
        br=d;
    }
    public FastScanner(String s) {
        try {
            br = new BufferedReader(new FileReader(s));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public FastScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String nextToken() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(nextToken());
    }

    long nextLong() {
        return Long.parseLong(nextToken());
    }

    double nextDouble() {
        return Double.parseDouble(nextToken());
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    String fileName = "<name>";

    public void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        int[] cnt = new int[2 * m];
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = nextInt();
            cnt[a[i] % m]++;
            cnt[a[i] % m + m]++;
        }
        int border = n / m;
        TreeSet<Integer> set = new TreeSet<>();
        for (int i = 0; i < 2 * m; i++) {
            if (cnt[i] < border) {
                set.add(i);
            }
        }
        List<List<Integer>> g = new ArrayList<>(m);
        for (int i = 0; i < m; i++) {
            g.add(new ArrayList<>());
        }
        for (int i = 0; i < 2 * m; i++) {
            while (cnt[i] > border) {
                int to = set.higher(i);
                int from = i;
                g.get(from).add(to);
                to %= m;
                cnt[i % m]--;
                cnt[i % m + m]--;
                cnt[to]++;
                cnt[to + m]++;
                if (cnt[to] == border) {
                    set.remove(to);
                    set.remove(to + m);
                }
            }
        }
        int[] ind = new int[m];
        for (int i = 0; i < n; i++) {
            List<Integer> moves = g.get(a[i] % m);
            if (moves.size() > 0 && ind[a[i] % m] < moves.size()) {
                int to = moves.get(ind[a[i] % m]++);
                a[i] += to - a[i] % m;
            }
            out.print(a[i]);
            out.print(" ");
        }
    }

    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    BufferedReader br;
    StringTokenizer in;
    PrintWriter out;

    public String nextToken() throws IOException {
        while (in == null || !in.hasMoreTokens()) {
            in = new StringTokenizer(br.readLine());
        }
        return in.nextToken();
    }

    public int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    public double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    public long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    public static void main(String[] args) throws IOException {
        Locale.setDefault(Locale.US);
        new D().run();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    String fileName = "<name>";

    public void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        int[] cnt = new int[2 * m];
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = nextInt();
            cnt[a[i] % m]++;
            cnt[a[i] % m + m]++;
        }
        int border = n / m;
        TreeSet<Integer> set = new TreeSet<>();
        for (int i = 0; i < 2 * m; i++) {
            if (cnt[i] < border) {
                set.add(i);
            }
        }
        List<List<Integer>> g = new ArrayList<>(m);
        for (int i = 0; i < m; i++) {
            g.add(new ArrayList<>());
        }
        for (int i = 0; i < 2 * m; i++) {
            while (cnt[i] > border) {
                int to = set.higher(i);
                int from = i;
                g.get(from).add(to);
                to %= m;
                cnt[i % m]--;
                cnt[i % m + m]--;
                cnt[to]++;
                cnt[to + m]++;
                if (cnt[to] == border) {
                    set.remove(to);
                    set.remove(to + m);
                }
            }
        }
        int[] ind = new int[m];
        long total = 0;
        for (int i = 0; i < n; i++) {
            List<Integer> moves = g.get(a[i] % m);
            if (moves.size() > 0 && ind[a[i] % m] < moves.size()) {
                int to = moves.get(ind[a[i] % m]++);
                int add = to - a[i] % m;
                total += add;
                a[i] += add;
            }
        }
        out.println(total);
        for (int i = 0; i < n; i++) {
            out.print(a[i]);
            out.print(" ");
        }
    }

    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    BufferedReader br;
    StringTokenizer in;
    PrintWriter out;

    public String nextToken() throws IOException {
        while (in == null || !in.hasMoreTokens()) {
            in = new StringTokenizer(br.readLine());
        }
        return in.nextToken();
    }

    public int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    public double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    public long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    public static void main(String[] args) throws IOException {
        Locale.setDefault(Locale.US);
        new D().run();
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            long[] array = new long[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            List<List<Integer>> reminders = new ArrayList<>();
            for (int i = 0; i < m; i++) {
                reminders.add(new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                long remainingElements = n / m - reminders.get(lessIndex).size();
                for (int borrower : more) {
                    if (remainingElements > 0) {
                        long numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                        if (numbersBorrowed == reminders.get(borrower).size() - n / m) {
                            more.remove(borrower);
                        }
                        for (long j = 0; j < numbersBorrowed; j++) {
                            reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                            long difference = lessIndex == 0 ? m - lessIndex : lessIndex - borrower;
                            array[reminders.get(borrower).get(0)] += difference;
                            count += difference;
                            reminders.get(borrower).remove(0);
                        }
                        remainingElements -= numbersBorrowed;
                    }
                }
            }
            out.println(count);
            for (long num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, List<List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() * m < n) {
                    less.add(i);
                } else if (list.size() * m > n) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, long[] array, List<List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders.get((int) (x % m)).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Set;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            long[] array = new long[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            List<List<Integer>> reminders = new ArrayList<>();
            for (int i = 0; i < m; i++) {
                reminders.add(new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                int remainingElements = n / m - reminders.get(lessIndex).size();
                while (remainingElements > 0) {
                    int borrower = more.iterator().next();
                    int numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                    if (numbersBorrowed == reminders.get(borrower).size() - n / m) {
                        more.remove(borrower);
                    }
                    for (int j = 0; j < numbersBorrowed; j++) {
                        reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                        int difference = lessIndex == 0 ? m - lessIndex : lessIndex - borrower;
                        array[reminders.get(borrower).get(0)] += difference;
                        count += difference;
                        reminders.get(borrower).remove(0);
                    }
                    remainingElements -= numbersBorrowed;
                }
            }
            out.println(count);
            for (long num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, List<List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() * m < n) {
                    less.add(i);
                } else if (list.size() * m > n) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, long[] array, List<List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders.get((int) (x % m)).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            long[] array = new long[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            Map<Integer, List<Integer>> reminders = new HashMap<>();
            for (int i = 0; i < m; i++) {
                reminders.put(i, new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                long remainingElements = n / m - reminders.get(lessIndex).size();
                for (int borrower : more) {
                    if (remainingElements > 0) {
                        long numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                        if (numbersBorrowed == reminders.get(borrower).size() - n / m) {
                            more.remove(borrower);
                        }
                        for (long j = 0; j < numbersBorrowed; j++) {
                            reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                            long difference = lessIndex == 0 ? m - lessIndex : lessIndex - borrower;
                            array[reminders.get(borrower).get(0)] += difference;
                            count += difference;
                            reminders.get(borrower).remove(0);
                        }
                        remainingElements -= numbersBorrowed;
                    } else {
                        break;
                    }
                }
            }
            out.println(count);
            for (long num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, Map<Integer, List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() < n / m) {
                    less.add(i);
                } else if (list.size() > n / m) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, long[] array, Map<Integer, List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders.get((int) (x % m)).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            long[] array = new long[n];
            int[] reminders = new int[m];
            TreeSet<Integer> need = new TreeSet<>();
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders[(int) (x % m)]++;
            }
            for (int i = 0; i < m; i++) {
                if (reminders[i] < n / m) {
                    need.add(i);
                }
            }

            long ans = 0;
            for (int i = 0; i < n; i++) {
                int donar = (int) (array[i] % m);
                if (reminders[donar] > n / m) {
                    Integer borrower = need.higher(donar);
                    if (borrower == null) borrower = need.pollFirst();
                    long val = borrower > donar ? borrower - donar : m - donar + borrower;
                    reminders[donar]--;
                    reminders[borrower]++;
                    if (reminders[borrower] == n / m) need.remove(borrower);
                    array[i] += val;
                    ans += val;
                }
            }

            out.println(ans);
            for (long num : array) {
                out.print(num + " ");
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int[] array = new int[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            List<List<Integer>> reminders = new ArrayList<>();
            for (int i = 0; i < m; i++) {
                reminders.add(new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                int remainingElements = n / m - reminders.get(lessIndex).size();
                for (int i = 1; i < m; i++) {
                    int borrower = (lessIndex - i) % m;
                    if (more.contains(borrower)) {
                        int numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                        if (numbersBorrowed == reminders.get(borrower).size()) {
                            more.remove(borrower);
                        }
                        for (int j = 0; j < numbersBorrowed; j++) {
                            reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                            int difference = borrower == 0 ? -1 * (lessIndex - m) : borrower - lessIndex;
                            array[reminders.get(borrower).get(0)] += difference;
                            count += difference;
                            reminders.get(borrower).remove(0);
                        }
                    }
                }
            }
            out.println(count);
            for (int num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, List<List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() * m < n) {
                    less.add(i);
                } else if (list.size() * m > n) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, int[] array, List<List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                int x = in.nextInt();
                array[i] = x;
                reminders.get(x % m).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Set;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            long[] array = new long[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            Map<Integer, List<Integer>> reminders = new HashMap<>();
            for (int i = 0; i < m; i++) {
                reminders.put(i, new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                long remainingElements = n / m - reminders.get(lessIndex).size();
                while (remainingElements > 0) {
                    int borrower = more.iterator().next();
                    long numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                    if (numbersBorrowed == reminders.get(borrower).size() - n / m) {
                        more.remove(borrower);
                    }
                    for (long j = 0; j < numbersBorrowed; j++) {
                        reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                        long difference = lessIndex == 0 ? m - lessIndex : lessIndex - borrower;
                        array[reminders.get(borrower).get(0)] += difference;
                        count += difference;
                        reminders.get(borrower).remove(0);
                    }
                    remainingElements -= numbersBorrowed;
                }
            }
            out.println(count);
            for (long num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, Map<Integer, List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() < n / m) {
                    less.add(i);
                } else if (list.size() > n / m) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, long[] array, Map<Integer, List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders.get((int) (x % m)).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
//        int n = 200000;
//        int m = 100000;
            long[] array = new long[n];
            Set<Integer> less = new HashSet<>();
            Set<Integer> more = new HashSet<>();
            List<List<Integer>> reminders = new ArrayList<>();
            for (int i = 0; i < m; i++) {
                reminders.add(new ArrayList<>());
            }
            input(in, n, m, array, reminders);
            fillSets(n, m, less, more, reminders);
            long count = 0;
            for (int lessIndex : less) {
                long remainingElements = n / m - reminders.get(lessIndex).size();
                for (int borrower : more) {
                    if (remainingElements > 0) {
                        long numbersBorrowed = Math.min(reminders.get(borrower).size(), remainingElements);
                        if (numbersBorrowed == reminders.get(borrower).size() - n / m) {
                            more.remove(borrower);
                        }
                        for (long j = 0; j < numbersBorrowed; j++) {
                            reminders.get(lessIndex).add(reminders.get(borrower).get(0));
                            long difference = lessIndex == 0 ? m - lessIndex : lessIndex - borrower;
                            array[reminders.get(borrower).get(0)] += difference;
                            count += difference;
                            reminders.get(borrower).remove(0);
                        }
                        remainingElements -= numbersBorrowed;
                    } else {
                        break;
                    }
                }
            }
            out.println(count);
            for (long num : array) {
                out.print(num + " ");
            }
        }

        private void fillSets(int n, int m, Set<Integer> less, Set<Integer> more, List<List<Integer>> reminders) {
            for (int i = 0; i < reminders.size(); i++) {
                List<Integer> list = reminders.get(i);
                if (list.size() < n / m) {
                    less.add(i);
                } else if (list.size() > n / m) {
                    more.add(i);
                }
            }
        }

        private void input(InputReader in, int n, int m, long[] array, List<List<Integer>> reminders) {
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
                array[i] = x;
                reminders.get((int) (x % m)).add(i);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
//        int n = in.nextInt();
            int n = 200000;
//        int m = in.nextInt();
            int m = 2;
            long[] array = new long[n];
            int[] reminders = new int[m];
            TreeSet<Integer> need = new TreeSet<>();
            for (int i = 0; i < n; i++) {
//            long x = in.nextLong();
                long x = 1;
                array[i] = x;
                reminders[(int) (x % m)]++;
            }
            for (int i = 0; i < m; i++) {
                if (reminders[i] < n / m) {
                    need.add(i);
                }
            }

            long ans = 0;
            for (int i = 0; i < n; i++) {
                int donar = (int) (array[i] % m);
                if (reminders[donar] > n / m && need.size() > 0) {
                    Integer borrower = need.higher(donar);
                    if (borrower == null) borrower = need.first();
                    long val = borrower > donar ? borrower - donar : m - donar + borrower;
                    reminders[donar]--;
                    reminders[borrower]++;
                    if (reminders[borrower] == n / m) need.remove(borrower);
                    array[i] += val;
                    ans += val;
                }
            }

            out.println(ans);
            for (long num : array) {
                out.print(num + " ");
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author programajor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
//        int n = 200000;
            int m = in.nextInt();
//        int m = 2;
            long[] array = new long[n];
            int[] reminders = new int[m];
            TreeSet<Integer> need = new TreeSet<>();
            for (int i = 0; i < n; i++) {
                long x = in.nextLong();
//            long x = 1;
                array[i] = x;
                reminders[(int) (x % m)]++;
            }
            for (int i = 0; i < m; i++) {
                if (reminders[i] < n / m) {
                    need.add(i);
                }
            }

            long ans = 0;
            for (int i = 0; i < n; i++) {
                int donar = (int) (array[i] % m);
                if (reminders[donar] > n / m) {
                    Integer borrower = need.higher(donar);
                    if (borrower == null) borrower = need.first();
                    long val = borrower > donar ? borrower - donar : m - donar + borrower;
                    reminders[donar]--;
                    reminders[borrower]++;
                    if (reminders[borrower] == n / m) need.remove(borrower);
                    array[i] += val;
                    ans += val;
                }
            }

            out.println(ans);
            for (long num : array) {
                out.print(num + " ");
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}