#include <bits/stdc++.h>
using namespace std;

#define int long long

struct UnionFind{
  int n;
  vector<int> r,p;
  UnionFind(){}
  UnionFind(int sz):n(sz),r(sz,1),p(sz,0){iota(p.begin(),p.end(),0);}
  int find(int x){
    return (x==p[x]?x:p[x]=find(p[x]));
  }
  bool same(int x,int y){
    return find(x)==find(y);
  }
  void unite(int x,int y){
    x=find(x);y=find(y);
    if(x==y) return;
    if(r[x]<r[y]) swap(x,y);
    r[x]+=r[y];
    p[y]=x;
  }
  int size(int x){
    return r[find(x)];
  }
};

struct P {
  int x, y, z;
  P() {}
  P(int x, int y, int z) : x(x), y(y), z(z) {}  
};

int N, K, S;
vector<P> dat;
UnionFind uf;
vector<vector<int> > G;

bool contains(P a, P b) {
  return abs(a.x-b.x) <= S && abs(a.y-b.y) <= S && abs(a.z-b.z) <= S;  
}

int area(P a, P b) {
  int dx = S-abs(a.x-b.x), dy = S-abs(a.y-b.y), dz = S-abs(a.z-b.z);
  return (dx*dy + dy*dz + dz*dx) * 2;  
}

int calc(vector<int> g) {
  int sum = 0;
  int gs = g.size();  
  if ( gs == K ) {    
    for ( int i : g ) {
      P a = dat[i];
      for ( int j : G[i] ) {
	P b = dat[j];
	sum += area(a, b)/2;	
      }      
    }
    return sum;    
  }
  
  bool is_cycle = true;  
  vector<int> path;
  {
    int st = g[0];
    for ( int i : g ) {
      if ( G[i].size() == 1 ) {
	st = i;
	is_cycle = false;	
	break;	
      }
    }    
    int pre = -1;
    int v = st;
    path = {st};    
    while ( path.size() < gs ) {	
      for ( int i : G[v] ) {
	if ( i == st || i == pre ) continue;	
	path.push_back(i);	  
	pre = v;
	v = i;	
	break;
      }
    }
  }

  // for ( int i : path ) cout << i << " " << G[i].size() << endl;
  // cout << endl;  
  
  vector<int> cum(g.size(), 0);
  for ( int i = 0; i < gs-1; i++ ) {
    cum[i+1] = area(dat[path[i]], dat[path[i+1]]);
    if ( i ) cum[i+1] += cum[i];    
  }

  // for ( int i = 0; i < gs; i++ ) cout << cum[i] << " ";
  // cout << endl;  

  sum = cum[K-1];  
  // if ( is_cycle ) sum += area(dat[path[0]], dat[path[gs-1]]);
  // cout << is_cycle << endl;  
  for ( int i = 1; i < gs; i++ ) {
    if ( is_cycle ) {
      if ( i+K-1 > gs-1 ) {
	int tmp = cum[gs-1]-cum[i] + area(dat[path[0]], dat[path[gs-1]]);
	tmp += cum[i+K - gs - 1];
	sum = max(sum, tmp);	
      } else {
	sum = max(sum, cum[i+K-1]-cum[i]);
      }      
    } else {
      if ( i+K-1 > gs-1 ) continue;
      // cout << cum[i+K-1]-cum[i] << endl;      
      sum = max(sum, cum[i+K-1]-cum[i]);      
    }
  }

  return sum;
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);  

  while ( cin >> N >> K >> S, N ) {
    dat = vector<P>(N);    
    for ( int i = 0; i < N; i++ ) {
      cin >> dat[i].x >> dat[i].y >> dat[i].z;      
    }    

    uf = UnionFind(N);
    G = vector<vector<int> >(N);    
    for ( int i = 0; i < N; i++ ) {
      int cnt = 0;      
      for ( int j = i+1; j < N; j++ ) {
	P a = dat[i], b = dat[j];	
	if ( cnt == 2 ) break;
	if ( contains(a, b) || contains(b, a) ) {
	  uf.unite(i, j);
	  G[i].push_back(j);
	  G[j].push_back(i);
	}	
      }	           
    }

    vector<vector<int> > gr(N);    
    for ( int i = 0; i < N; i++ ) {
      gr[uf.find(i)].push_back(i);      
    }

    // for ( auto i : gr ) cout << i.size() << endl;    

    int ans = -1;    
    for ( int i = 0; i < N; i++ ) {
      if ( gr[i].size() < K ) continue;
      ans = max(ans, calc(gr[i]));      
    }
    // cout << S*S*6*K << endl;    
    if ( ans < 0 ) cout << ans << endl;
    else cout << S*S*6*K - ans << endl;    
  }  
  
  return 0;
}



Measured memory_bytes: 3280