#include <stdio.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <string>
#include <bitset>
#include <algorithm>
using namespace std;

struct xyz_t {
    int x;
    int y;
    int z;
    double length;       //一乗
};

struct first_t {
    int sec;
    long long w;
};

bool asc(const xyz_t& left,const xyz_t& right);
int next(int p,int q);
int root(int p);
void unite(int p,int q);
int same(int p,int q);
void pr(vector<vector<int> > pri);
void nnn();

vector<xyz_t> a;
vector<int> tree;
vector<int> endd;
vector<vector<int> > tree_f;
vector<vector<int> > kaburi;
vector<vector<int> > tree_r;
vector<int> num;
vector<int> flg;
long long ans;
int n,k,s;
double LE;
long long sum;
int rr;

int main(){
  scanf ("%d %d %d",&n,&k,&s);
  while(n){
    ans=0;
    LE=sqrt(s*s*3.0);
    xyz_t aaa={0,0,0,0};
    a.assign(n,aaa);
    tree.assign(n,-1);
    endd.assign(n,-1);
    tree_f.assign(n,vector<int>(1,0));
    kaburi.assign(n,vector<int>(n,0));
    tree_r.assign(n,vector<int>(0,0));
    num.assign(n,1);
    flg.assign(n,0);
    for(int t=0;t<n;t++){
      scanf ("%d %d %d",&a[t].x,&a[t].y,&a[t].z);
      a[t].length=sqrt(a[t].x*a[t].x*1.0+a[t].y*a[t].y*1.0+a[t].z*a[t].z*1.0);
    }
    sort(a.begin(),a.end(),asc);
    for(int i=0;i<n;i++){
      tree[i]=i;
      endd[i]=i;
    }

    switch(k){
      case 1:
        printf("%d\n",s*s*6);
        break;
      case 3:
        for(int t=0;t<n-1;++t){
          for(int s=t+1;(a[s].length<a[t].length+LE&&s<n);++s){
            int xx=next(a[t].x,a[s].x);
            int yy=next(a[t].y,a[s].y);
            int zz=next(a[t].z,a[s].z);
            if(xx&&yy&&zz){
              if(same(t,s)==0){
                int ee;
                int eee;
                  if(tree[t]==t&&tree[s]==s){
                    //printf("%d %d\n",endd[t],endd[s]);
                    ee=num[tree[t]];
                    eee=num[tree[s]];
                    num[tree[t]]=0;
                    num[tree[s]]=0;
                    num[endd[t]]=ee+eee;
                    tree[t]=endd[t];
                    tree[endd[t]]=endd[t];
                    endd[endd[t]]=endd[s];
                    unite(s,t);
                  }
                  else if(tree[t]!=t&&tree[s]==s){
                    num[tree[t]]=num[tree[t]]+num[s];
                    num[tree[s]]=0;
                    endd[tree[t]]=endd[s];
                    unite(s,t);
                    //printf("%d\n",tree[t]);
                  }
                  else if(tree[t]==t&&tree[s]!=s){
                    num[tree[s]]=num[t]+num[tree[s]];
                    num[tree[t]]=0;
                    endd[tree[s]]=endd[t];
                    unite(t,s);
                    //printf("%d\n",tree[s]);
                  }
                  else if(tree[t]!=t&&tree[s]!=s){
                    num[tree[t]]=num[tree[t]]+num[tree[s]];
                    num[tree[s]]=0;
                    endd[tree[t]]=tree[s];
                    unite(s,t);
                    //printf("%d %d %d %d\n",t,s,tree[t],endd[tree[t]]);
                  }
                kaburi[s][t]=xx*yy+yy*zz+zz*xx;
                  kaburi[t][s]=kaburi[s][t];
                  tree_r[t].push_back(s);
                  tree_r[s].push_back(t);
                  //printf("%d %d %d\n",kaburi[q].back());
                  //printf("%d %d %d\n",xx,yy,zz);
                }
              else{
                kaburi[s][t]=xx*yy+yy*zz+zz*xx;
                kaburi[t][s]=kaburi[s][t];
                tree_r[t].push_back(s);
                tree_r[s].push_back(t);
                flg[tree[t]]=1;
              }
            }
          }
        }
        //pr(kaburi);
        for(int t=0;t<n;++t){
          sum=0;
          if(num[t]>=k){
            if(flg[t]==0){
              int u=t;
              int uu=t;
              tree_f[t][0]=t;
              for(int r=0;r<k-1;++r){
                rr=0;
                if(tree_r[u][rr]==uu){
                  ++rr;
                }
                sum+=kaburi[u][tree_r[u][rr]];
                tree_f[t].push_back(tree_r[u][rr]);
                uu=u;
                u=tree_r[u][rr];
              }
              for(int r=k-1;r<num[t]-1;++r){
                rr=0;
                if(tree_r[u][rr]==uu){
                  ++rr;
                }
                tree_f[t].push_back(tree_r[u][rr]);
                uu=u;
                u=tree_r[u][rr];
              }
              if(ans<sum){
                ans=sum;
              }
              for(int r=0;r+k<num[t];++r){
                sum=sum-kaburi[tree_f[t][r]][tree_f[t][r+1]]+kaburi[tree_f[t][r+k-1]][tree_f[t][r+k]];
                if(ans<sum){
                  ans=sum;
                }
              }
            }
            else{
              if(num[t]!=k){
                int u=t;
                int uu=t;
                tree_f[t][0]=t;
                for(int r=0;r<k-1;++r){
                  rr=0;
                  if(tree_r[u][rr]==uu){
                    ++rr;
                  }
                  sum+=kaburi[u][tree_r[u][rr]];
                  tree_f[t].push_back(tree_r[u][rr]);
                  uu=u;
                  u=tree_r[u][rr];
                }
                for(int r=k-1;r<num[t]*2;++r){
                  rr=0;
                  if(tree_r[u][rr]==uu){
                    ++rr;
                  }
                  tree_f[t].push_back(tree_r[u][rr]);
                  uu=u;
                  u=tree_r[u][rr];
                }
                if(ans<sum){
                  ans=sum;
                }
                for(int r=0;r<num[t];++r){
                  sum=sum-kaburi[tree_f[t][r]][tree_f[t][r+1]]+kaburi[tree_f[t][r+k-1]][tree_f[t][r+k]];
                  if(ans<sum){
                    ans=sum;
                  }
                  //printf("%lld\n",sum);
                }
                //pr(tree_f);
              }
              else{
                if(num[t]!=3){
                  int u=t;
                  int uu=t;
                  tree_f[t][0]=t;
                  for(int r=0;r<k;++r){
                    rr=0;
                    if(tree_r[u][rr]==uu){
                      ++rr;
                    }
                    sum+=kaburi[u][tree_r[u][rr]];
                    uu=u;
                    u=tree_r[u][rr];
                  }
                  if(ans<sum){
                    ans=sum;
                  }
                }
                else{
                  int u=t;
                  int uu=t;
                  tree_f[t][0]=t;
                  for(int r=0;r<k;++r){
                    rr=0;
                    if(tree_r[u][rr]==uu){
                      ++rr;
                    }
                    sum+=kaburi[u][tree_r[u][rr]];
                    tree_f[t].push_back(tree_r[u][rr]);
                    uu=u;
                    u=tree_r[u][rr];
                  }
                  int xxx=s+min({a[tree_f[t][0]].x,a[tree_f[t][1]].x,a[tree_f[t][2]].x})-max({a[tree_f[t][0]].x,a[tree_f[t][1]].x,a[tree_f[t][2]].x});
                  int yyy=s+min({a[tree_f[t][0]].y,a[tree_f[t][1]].y,a[tree_f[t][2]].y})-max({a[tree_f[t][0]].y,a[tree_f[t][1]].y,a[tree_f[t][2]].y});
                  int zzz=s+min({a[tree_f[t][0]].z,a[tree_f[t][1]].z,a[tree_f[t][2]].z})-max({a[tree_f[t][0]].z,a[tree_f[t][1]].z,a[tree_f[t][2]].z});
                  sum=sum-(xxx*yyy+yyy*zzz+zzz*xxx);
                  if(ans<sum){
                    ans=sum;
                  }
                }
              }
            }
          }
        }
        if(ans==0){
          printf("-1\n");
        }
        else{
          printf("%lld\n",s*s*6*k-ans*2);
        }
        break;
      default:
        for(int t=0;t<n-1;++t){
          for(int s=t+1;(a[s].length<a[t].length+LE&&s<n);++s){
            int xx=next(a[t].x,a[s].x);
            int yy=next(a[t].y,a[s].y);
            int zz=next(a[t].z,a[s].z);
            if(xx&&yy&&zz){
              if(same(t,s)==0){
                /*if(num[t]==1){
                  ++num[tree[s]];
                  num[t]=0;
                  unite(t,s);
                  endd[tree[s]]=t;
                }
                else if(num[s]==1){
                  ++num[tree[t]];
                  num[s]=0;
                  unite(s,t);
                  endd[tree[t]]=s;
                }*/
                int ee;
                int eee;
                  if(tree[t]==t&&tree[s]==s){
                    //printf("%d %d\n",endd[t],endd[s]);
                    ee=num[tree[t]];
                    eee=num[tree[s]];
                    num[tree[t]]=0;
                    num[tree[s]]=0;
                    num[endd[t]]=ee+eee;
                    tree[t]=endd[t];
                    tree[endd[t]]=endd[t];
                    endd[endd[t]]=endd[s];
                    unite(s,t);
                  }
                  else if(tree[t]!=t&&tree[s]==s){
                    num[tree[t]]=num[tree[t]]+num[s];
                    num[tree[s]]=0;
                    endd[tree[t]]=endd[s];
                    unite(s,t);
                    //printf("%d\n",tree[t]);
                  }
                  else if(tree[t]==t&&tree[s]!=s){
                    num[tree[s]]=num[t]+num[tree[s]];
                    num[tree[t]]=0;
                    endd[tree[s]]=endd[t];
                    unite(t,s);
                    //printf("%d\n",tree[s]);
                  }
                  else if(tree[t]!=t&&tree[s]!=s){
                    num[tree[t]]=num[tree[t]]+num[tree[s]];
                    num[tree[s]]=0;
                    endd[tree[t]]=tree[s];
                    unite(s,t);
                    //printf("%d %d %d %d\n",t,s,tree[t],endd[tree[t]]);
                  }
                kaburi[s][t]=xx*yy+yy*zz+zz*xx;
                kaburi[t][s]=kaburi[s][t];
                tree_r[t].push_back(s);
                tree_r[s].push_back(t);
                //printf("%d %d %d\n",kaburi[q].back());
                //printf("%d %d %d\n",xx,yy,zz);
              }
              else{
                kaburi[s][t]=xx*yy+yy*zz+zz*xx;
                kaburi[t][s]=kaburi[s][t];
                flg[tree[t]]=1;
                tree_r[t].push_back(s);
                tree_r[s].push_back(t);
              }
              //nnn();
            }
          }
        }
        for(int t=0;t<n;++t){
          root(t);
        }
        /*for(int t=0;t<n-1;++t){
          printf("%d ",num[t]);
        }
        printf("%d\n",num[n-1]);
        pr(tree_r);
        printf("\n");
        for(int t=0;t<n-1;++t){
          printf("%d ",tree[t]);
        }
        printf("%d\n",tree[n-1]);
        printf("\n");*/
        //pr(kaburi);
        //printf("\n");
        //pr(tree_r);
        for(int t=0;t<n;++t){
          sum=0;
          if(num[t]>=k){
            //printf("%d\n",flg[t]);
            //printf("%d\n",t);
            if(flg[t]==0){
              int u=t;
              int uu=t;
              tree_f[t][0]=t;
              for(int r=0;r<k-1;++r){//k-1
                rr=0;
                if(tree_r[u][rr]==uu){
                  ++rr;
                }
                sum+=kaburi[u][tree_r[u][rr]];
                tree_f[t].push_back(tree_r[u][rr]);
                uu=u;
                u=tree_r[u][rr];
              }

              /*for(int t=0;t<1;++t){
                printf("%d ",tree_r[u][t]);
              }
              printf("%d\n",tree_r[u][1]);
              printf("%d\n",t);*/
              for(int r=k-1;r<num[t]-1;++r){
                rr=0;
                if(tree_r[u][rr]==uu){
                  ++rr;
                }
                tree_f[t].push_back(tree_r[u][rr]);
                uu=u;
                u=tree_r[u][rr];
              }
              if(ans<sum){
                ans=sum;
              }
              //printf("%lld\n",sum);
              for(int r=0;r+k<num[t];++r){
                sum=sum-kaburi[tree_f[t][r]][tree_f[t][r+1]]+kaburi[tree_f[t][r+k-1]][tree_f[t][r+k]];
                //printf("%lld\n",sum);
                if(ans<sum){
                  ans=sum;
                }
              }
            }
            else{
              if(num[t]!=k||k==2){
                int u=t;
                int uu=t;
                tree_f[t][0]=t;
                for(int r=0;r<k-1;++r){
                  rr=0;
                  if(tree_r[u][rr]==uu){
                    ++rr;
                  }
                  sum+=kaburi[u][tree_r[u][rr]];
                  tree_f[t].push_back(tree_r[u][rr]);
                  uu=u;
                  u=tree_r[u][rr];
                }
                for(int r=k-1;r<num[t]*2;++r){
                  rr=0;
                  if(tree_r[u][rr]==uu){
                    ++rr;
                  }
                  tree_f[t].push_back(tree_r[u][rr]);
                  uu=u;
                  u=tree_r[u][rr];
                }
                if(ans<sum){
                  ans=sum;
                }
                for(int r=0;r<num[t];++r){
                  sum=sum-kaburi[tree_f[t][r]][tree_f[t][r+1]]+kaburi[tree_f[t][r+k-1]][tree_f[t][r+k]];
                  if(ans<sum){
                    ans=sum;
                  }
                  //printf("%lld\n",sum);
                }
                //pr(tree_f);
              }
              else{
                int u=t;
                int uu=t;
                tree_f[t][0]=t;
                for(int r=0;r<k;++r){
                  rr=0;
                  if(tree_r[u][rr]==uu){
                    ++rr;
                  }
                  sum+=kaburi[u][tree_r[u][rr]];
                  uu=u;
                  u=tree_r[u][rr];
                  //printf("%lld\n",sum);
                }
                if(ans<sum){
                  ans=sum;
                }
              }
            }
          }
        }
        if(ans==0){
          printf("-1\n");
        }
        else{
          printf("%lld\n",s*s*6*k-ans*2);
        }
    }
    scanf ("%d %d %d",&n,&k,&s);
  }
}
/*
環状 k=3の時 それ以外の時


*/


bool asc(const xyz_t& left,const xyz_t& right){
  return left.length<right.length;
}

int next(int p,int q){
  if(-s<=(p-q)&&(p-q)<=s){
    if((p-q)>=0){
      return s-(p-q);
    }
    else{
      return s-(q-p);
    }
  }
  else{
    return 0;
  }
}

int root(int p){
  if (tree[p] == p){// 根
    return p;
  }
  else {
    return tree[p] = root(tree[p]); // 経路圧縮
  }
}

void unite(int p, int q){
  p = root(p);
  q = root(q);
  if (p == q){}
  else{
    tree[p] = q;     //pの親をqの親にする
  }
}

int same(int p, int q){
  return root(p) == root(q);
}



void pr(vector<vector<int> > pri){
  for(int t=0;t<int(pri.size());++t){
    for(int s=0;s<int(pri[t].size())-1;++s){
      printf("%d ",pri[t][s]);
    }
    printf("%d\n",pri[t][pri[t].size()-1]);
  }
  printf("\n");
}

void nnn(){
  for(int t=0;t<n-1;++t){
    printf("%d ",num[t]);
  }
  printf("%d\n",num[n-1]);
}



Measured memory_bytes: 7096