#include<iostream>
#include<string>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define ALL(C)     (C).begin(),(C).end()
#define FOR(it,o)  for(__typeof((o).begin()) it =(o).begin();it != (o).end();it++)
#define pb         push_back
#define mp         make_pair


typedef unsigned long long           ull;
typedef pair<string,string> pss;
typedef vector<pss>         vpss;

const ull tmp = 10007;

ull calchash(string &in){
  ull ret= 0;
  rep(i,(int)in.size()){
    ret=ret*tmp + in[i];
  }
  return ret;
}


bool isok[200][200];
int ed[200][200];
int cost[20][20];
int edit_distance(string tr,string tc){
  string r,c;
  r=' ';
  c=' ';
  rep(i,tr.size())r+=tr[i];
  rep(i,tc.size())c+=tc[i];
  rep(i,r.size())rep(j,c.size())cost[i][j]=(1<<21);

  rep(i,r.size())cost[i][0]=i;
  rep(i,c.size())cost[0][i]=i;

  REP(i,1,r.size()){
    REP(j,1,c.size()){
      int tmp =r[i]==c[j]?0:1;
      int opt[3];
      opt[0]=cost[i-1][j-1]+tmp;
      opt[1]=cost[i-1][j]+1;
      opt[2]=cost[i][j-1]+1;
      rep(k,3)cost[i][j]=min(cost[i][j],opt[k]);
    }
  }
  return cost[r.size()-1][c.size()-1];
}


void ed1(vector<string>&in,set<ull> S[]){
  rep(i,(int)in.size()){
    REP(j,i+1,(int)in.size()){
      if (S[j].find(calchash(in[i])) != S[j].end()){
	isok[i][j] = true;
      }
    }    
  }
}
	 
void ed2(vector<string> &in,set<ull> S[]){
  rep(i,(int)in.size()){
    REP(j,i+1,(int)in.size()){
      if (isok[i][j]||ed[i][j] > 4)continue;
      FOR(it,S[i]){
	if (S[j].find( *it) != S[j].end()){
	  isok[i][j]=true;
	  break;
	}
      }
    }
  }
}

void del_string(string &in,set<ull>&S){
  rep(i,(int)in.size()){
    string tmp = in;
    tmp.erase(tmp.begin()+i);
    S.insert(calchash(tmp));
  }
}

void insert_string(string &in,set<ull>&S){
  rep(i,(int)in.size()+1){
    rep(j,26){
      string tmp=in.substr(0,i);
      tmp+='a'+j;
      //tmp+=string(1,'a'+j);
      string tmp2=in.substr(i);
      rep(k,tmp2.size())tmp+=(char)tmp2[k];
      //tmp=string(tmp)+string(in.substr(i));
      S.insert(calchash(tmp));
    }
  }
}

void replace_string(string &in,set<ull>&S){
  rep(i,(int)in.size()){
    char tmp = in[i];
    rep(j,26){
      in[i]='a'+j;
      S.insert(calchash(in));
    }
    in[i]=tmp;
  }
}

void swap_string(string&in,set<ull>&S){
  rep(i,(int)in.size()-1){
    swap(in[i],in[i+1]);
    S.insert(calchash(in));
    swap(in[i],in[i+1]);
  }
}

void make_string(vector<string>& in,set<ull> S[]){
  rep(i,(int)in.size()){
    del_string(in[i],S[i]);
    insert_string(in[i],S[i]);
    replace_string(in[i],S[i]);
    swap_string(in[i],S[i]);
  }
}

void solve(vector<string>in,set<ull>S[],int d){
  int n=(int)in.size();
  rep(i,n){
    REP(j,i+1,n){
      ed[i][j]=edit_distance(in[i],in[j]);
      if (ed[i][j] <= d)isok[i][j]=true;
    }
  }
  
  make_string(in,S);
  ed1(in,S);
  if (d==2)ed2(in,S);
  int cnt=0;
  rep(i,n){
    rep(j,n)if (isok[i][j])cnt++,cout<<in[i]<<","<<in[j]<<endl;
  }
  cout << cnt << endl;
}

void test(){
  string in="test";
  set<ull> S;
  insert_string(in,S);
}

main(){
  //test();
  int n,d;
  while(cin>>n>>d && n){
    vector<string> in;
    rep(i,n)rep(j,n)isok[i][j]=false,ed[i][j]=(1<<21);
    set<ull> S[n];
    rep(i,n){
      string tmp;
      cin>>tmp;
      in.pb(tmp);
    }
    sort(ALL(in));
    rep(i,(int)in.size())S[i].insert(calchash(in[i]));
    solve(in,S,d);
  }
}

Measured memory_bytes: 5732