/* template.cpp {{{ */
#include <bits/stdc++.h>
using namespace std;
#define get_macro(a, b, c, d, name, ...) name
#define rep(...) get_macro(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep(...) get_macro(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)
#define rep1(n) rep2(i_, n)
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, s) for (ll i = (a); i < (ll)(b); i += (ll)(s))
#define rrep1(n) rrep2(i_, n)
#define rrep2(i, n) rrep3(i, 0, n)
#define rrep3(i, a, b) rrep4(i, a, b, 1)
#define rrep4(i, a, b, s) for (ll i = (ll)(b) - 1; i >= (ll)(a); i -= (ll)(s))
#define each(x, c) for (auto &&x : c)
#define fs first
#define sc second
#define all(c) begin(c), end(c)
using ui = unsigned;
using ll = long long;
using ul = unsigned long long;
using ld = long double;
const int inf = 1e9 + 10;
const ll inf_ll = 1e18 + 10;
const ll mod = 1e9 + 7;
const ll mod9 = 1e9 + 9;
//const int dx[]{-1, 0, 1, 0, -1, 1, 1, -1};
//const int dy[]{0, -1, 0, 1, -1, -1, 1, 1};
template<class T, class U> void chmin(T &x, const U &y){ x = min<T>(x, y); }
template<class T, class U> void chmax(T &x, const U &y){ x = max<T>(x, y); }
struct prepare_ { prepare_(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(12); } } prepare__;
/* }}} */
/* union_find.cpp {{{ */
class UnionFind {
public:
  UnionFind(int n = 0): cnt(n), data(n, -1){}
  int root(int x) const { return data[x] < 0 ? x : (data[x] = root(data[x])); }
  bool same(int x, int y) const { return root(x) == root(y); }
  bool unite(int x, int y){
    if ((x = root(x)) == (y = root(y))) return false;
    if (data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    cnt--;
    return true;
  }
  int count() const { return cnt; }
  int size(int x) const { return -data[root(x)]; }
private:
  int cnt;
  mutable vector<int> data;
};
/* }}} */

const int dx[]{-1, -1, 0, 0, 1, 1};
const int dy[]{-1, 0, -1, 1, 0, 1};

int n, c;
int s[10][10];
int id[10][10];
bool f[100];

int main(){
  while (cin >> n >> c, n){
    memset(id, -1, sizeof(id));
    rep(i, n) rep(j, i + 1) cin >> s[i][j];
    int ii = 0;
    rep(i, n) rep(j, i + 1) id[i][j] = ii++;
    int res = -inf;
    rep(i, n) rep(j, i + 1) rep(k, c, c + 1){
      if (s[i][j] != 0) continue;
      s[i][j] = k;
      UnionFind tr(ii);
      rep(x, n) rep(y, x + 1) rep(d, 6){
        int nx = x + dx[d], ny = y + dy[d];
        if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;
        if (id[nx][ny] == -1) continue;
        if (s[x][y] == s[nx][ny]) tr.unite(id[x][y], id[nx][ny]);
      }
      memset(f, 0, sizeof(f));
      rep(x, n) rep(y, x + 1) rep(d, 6){
        if (s[x][y] != 0) continue;
        int nx = x + dx[d], ny = y + dy[d];
        if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;
        if (id[nx][ny] == -1) continue;
        f[tr.root(id[x][y])] = true;
        f[tr.root(id[nx][ny])] = true;
      }
      //rep(x, n){
      //  rep(y, x + 1) cout << (!f[tr.root(id[x][y])] ? 0 : s[x][y]) << " ";
      //  cout << endl;
      //}
      int sm = 0;
      rep(x, n) rep(y, x + 1){
        if (f[tr.root(id[x][y])]) continue;
        sm += tr.same(id[i][j], id[x][y]) ? -1 : 1;
      }
      chmax(res, sm);
      s[i][j] = 0;
    }
    cout << res << endl;
  }
}

Measured memory_bytes: 3068