#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <cstdlib>
#include <map>
using namespace std;

class Point {
public:
    int x, y, z;
    Point(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
};

class Cube {
public:
    Point p;
    int s;
    int vx[4] = {0, 1, 1, 0}, vy[4] = {0, 0, 1, 1}, vz[2] = {0, 1};
    Cube(Point p = Point(), int s = 0) : p(p), s(s) {}

    bool isIn(const Cube &c) {
        return ((abs(p.x - c.p.x) < s) && (abs(p.y - c.p.y) <= s) && (abs(p.z - c.p.z) <= s) &&
                (abs(p.x - c.p.x) <= s) && (abs(p.y - c.p.y) < s) && (abs(p.z - c.p.z) <= s) &&
                (abs(p.x - c.p.x) <= s) && (abs(p.y - c.p.y) <= s) && (abs(p.z - c.p.z) < s));
    }

    long long shareS(Cube &c) {
        long long ret = 0;
        Point a, b;
        a = p; b = c.p;

        if (a.x > b.x) swap(a.x, b.x);
        if (a.y > b.y) swap(a.y, b.y);
        if (a.z > b.z) swap(a.z, b.z);

        ret += abs((a.x + s - b.x) * (a.z + s - b.z) * 2);
        ret += abs((a.y + s - b.y) * (a.z + s - b.z) * 2);
        ret += abs((a.x + s - b.x) * (a.y + s - b.y) * 2);
        return ret;
    }

};

int n, k, s, x, y, z;
long long ans;
vector<Cube> c;
vector<vector<int> > subg;
vector<bool> used;
vector<deque<int> > graph;
deque<int> que;

inline void makegraph() {
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (c[i].isIn(c[j])) {
                subg[j].push_back(i);
                subg[i].push_back(j);
            }
        }
    }
}

// make path
void dfs(int v, bool f) {
    used[v] = true;
    int size_ = subg[v].size();
    bool flag = false;

    for (int i = 0; i < size_; ++i) {
        if (!used[subg[v][i]]) {
            // ???????????¢?´¢?????????????????£??????
            if (!flag && !f) {
                dfs(subg[v][i], false);
                que.push_front(v);
                flag = true;
            }
            else {
                que.push_front(subg[v][i]);
                dfs(subg[v][i], true);
            }
        }
    }

    if (!flag && !f) que.push_front(v);
}

// is graph[graphid] cycle ?
inline bool isCycle(int graphid) {
    int size_ = graph[graphid].size();

    // if all vertex's degree are two, this graph has closed path.
    for (int i = 0; i < size_; ++i) {
        if (subg[graph[graphid][i]].size() != 2) return false;
    }

    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (cin >> n >> k >> s, n | k | s) {
        c.resize(n);
        subg.resize(n);
        que.clear();
        used.assign(n, false);
        ans = int(1e15);

        for (int i = 0; i < n; ++i) {
            cin >> x >> y >> z;
            c[i] = {Point(x, y, z), s};    
        }

        makegraph();

        for (int i = 0; i < n; ++i) {
            if (!used[i]) {
                dfs(i, false);
                graph.push_back(que);
                que.clear();
            }
        }

        int gsize = graph.size(), qsize, upper;
        long long share;
        bool isGraphCycle = false;

        for (int i = 0; i < gsize; ++i) {
            qsize = graph[i].size();
            isGraphCycle = isCycle(i);

            if (qsize < k) continue;

            for (int j = 0; j < qsize; ++j) {
                share = 0;
                //cout << "isGraphCycle " << isGraphCycle << endl;
                if (!isGraphCycle && j + k - 1 >= qsize) continue;

                for (int l = 0; l < k - 1; ++l) {
                    //cout << (j + l) % qsize << ", " << (j + l + 1) % qsize << endl;
                    share += c[graph[i][(j + l) % qsize]].shareS(c[graph[i][(j + l + 1) % qsize]]);
                }


                if (isGraphCycle && qsize == k) {
                    share += c[graph[i][j % qsize]].shareS(c[graph[i][(j + qsize - 1) % qsize]]);
                }

                ans = min(ans, 6 * s * s * k - share);
            }
        }

        if (n == 1) ans = 6 * s * s;
        if (ans == int(1e15)) ans = -1;

        cout << ans << endl;
        //cout << endl;

        c.clear();
        graph.clear();
        subg.clear();
        used.clear();
    }

    return 0;
}

Measured memory_bytes: 3656