// https://szkopul.edu.pl/problemset/problem/E0WdV0P4l3hYG2WAuFWyQ-TV/site/?key=statement
#include <bits/stdc++.h>
using namespace std;
constexpr int sizik = 1511;
#define ar std::array
#define pr std::pair
#define vec std::vector
typedef long long ll;
typedef vec<vec<int>> _kra;
struct B {
int pos, cnt;
B(int pos1 = 0, int cnt1 = 0) {
pos = pos1;
cnt = cnt1;
}
};
template<typename T>
struct DrzewoPrzedzialoweNaPrzedziale {
T d[4 * sizik];
int ll = 1;
T op(const T& a, const T& b) { return std::max(a, b); }
T na_przedziale(int o, int x, int y, int A, int B) {
if (A <= x && y <= B) {
return d[o];
} else if (B < x || y < A) {
// return neutral_element;
return 0;
} else {
return op(na_przedziale(o * 2, x, (x + y) / 2, A, B), na_przedziale(o * 2 + 1, (x + y) / 2 + 1, y, A, B));
}
}
T na_przedziale(int A, int B) { return na_przedziale(1, 1, ll, A, B); }
void akt(int v, const T& a) {
v += this->ll - 1;
d[v] = a;
while (v > 1) {
v /= 2;
d[v] = op(d[2 * v], d[2 * v + 1]);
}
}
DrzewoPrzedzialoweNaPrzedziale(int n = sizik) {
while (ll < n) {
ll *= 2;
}
}
};
template<typename T>
struct DrzewoPrzedzialowe {
T d[4 * sizik];
int ll = 1;
T op(const T& a, const T& b) { return std::max(a, b); }
void akt(int o, int x, int y, int A, int B, const T& a) {
if (A <= x && y <= B) {
d[o] = op(d[o], a);
return;
}
if (B < x || y < A) return;
akt(2 * o, x, (x + y) / 2, A, B, a);
akt(2 * o + 1, (x + y) / 2 + 1, y, A, B, a);
}
void akt(int A, int B, const T& a) {
if (A <= B) akt(1, 1, ll, A, B, a);
}
T w_punkcie(int v) {
v += ll - 1;
T res = 0;
while (v > 0) {
res = op(res, d[v]);
v /= 2;
}
return res;
}
DrzewoPrzedzialowe(int n) {
while (ll < n) {
ll *= 2;
}
}
};
int col[sizik], row[sizik];
char mapa[sizik][sizik], mapa_temp[sizik][sizik];
std::array<std::array<B, 3>, sizik> best_row, best_col;
int n;
DrzewoPrzedzialowe<int> max_c(sizik), max_r(sizik);
DrzewoPrzedzialoweNaPrzedziale<int> max_c1[sizik], max_r1[sizik];
int ans = 0;
std::vector<int> tmp1, tmp2;
void gen(), gen_row(), gen_col(), dbg1();
void solve() {
int m;
std::cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
std::cin >> mapa[i][j];
mapa_temp[i][j] = mapa[i][j];
}
}
gen();
if (m == 1) {
int ans1 = 0;
for (int i = 1; i <= n; i++) {
ans1 = std::max({ans1, best_col[i][0].cnt, best_row[i][0].cnt});
}
std::cout << ans1 << '\n';
return;
}
for (int i = 1; i <= n; i++) {
int local_tmp = max_r.w_punkcie(i);
for (int j = 0; j < best_col[i].size(); j++) {
const auto& alfa = best_col[i][j];
int local_tmp2 = std::max(max_c1[i].na_przedziale(1, alfa.pos - 1), max_c1[i].na_przedziale(alfa.pos + alfa.cnt, n));
for (int k = alfa.cnt; k >= 1; k--) {
int q = alfa.cnt - k;
int local_tmp3 = std::max(max_c1[i].na_przedziale(alfa.pos, alfa.pos + q - 1),
max_c1[i].na_przedziale(alfa.pos + alfa.cnt - q, alfa.pos + alfa.cnt - 1));
ans = std::max(ans, std::min(k, std::max({local_tmp, local_tmp2, local_tmp3})));
}
}
}
for (int i = 1; i <= n; i++) {
int local_tmp = max_c.w_punkcie(i);
for (int j = 0; j < best_row[i].size(); j++) {
const auto& alfa = best_row[i][j];
int local_tmp2 = std::max(max_r1[i].na_przedziale(1, alfa.pos - 1), max_r1[i].na_przedziale(alfa.pos + alfa.cnt, n));
for (int k = alfa.cnt; k >= 1; k--) {
int q = alfa.cnt - k;
int local_tmp3 = std::max(max_r1[i].na_przedziale(alfa.pos, alfa.pos + q - 1),
max_r1[i].na_przedziale(alfa.pos + alfa.cnt - q, alfa.pos + alfa.cnt - 1));
ans = std::max(ans, std::min(k, std::max({local_tmp, local_tmp2, local_tmp3})));
}
}
}
std::cout << ans << '\n';
}
int32_t main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
int t = 1;
// std::cin >> t;
for (; t > 0; t--) {
solve();
}
return 0;
}
void gen_row() {
for (int i = 1; i <= n; i++) {
int prev = 0;
std::vector<B> av{0};
for (int j = 1; j <= n + 1; j++) {
if (mapa[i][j] == '.') {
prev++;
} else {
av.push_back({j - prev, prev});
prev = 0;
}
}
std::sort(av.begin(), av.end(), [](const auto& a, const auto& b) { return std::greater<int>()(a.cnt, b.cnt); });
for (int k = 0; k < (int)best_row[i].size(); k++) {
best_row[i][k] = av[k];
tmp1.push_back(av[k].cnt);
}
for (const auto& b : av) {
max_r.akt(1, b.pos - 1, b.cnt);
max_r.akt(b.pos + b.cnt, n, b.cnt);
for (int z = b.pos; z < b.pos + b.cnt; z++) {
max_c1[z].akt(i, b.cnt);
}
}
}
}
void gen_col() {
for (int j = 1; j <= n; j++) {
int prev = 0;
std::vector<B> av{0};
for (int i = 1; i <= n + 1; i++) {
if (mapa[i][j] == '.') {
prev++;
} else {
av.push_back({i - prev, prev});
prev = 0;
}
}
std::sort(av.begin(), av.end(), [](const auto& a, const auto& b) { return std::greater<int>()(a.cnt, b.cnt); });
for (int k = 0; k < (int)best_col[j].size(); k++) {
best_col[j][k] = av[k];
tmp2.push_back(av[k].cnt);
}
for (const auto& b : av) {
max_c.akt(1, b.pos - 1, b.cnt);
max_c.akt(b.pos + b.cnt, n, b.cnt);
for (int z = b.pos; z < b.pos + b.cnt; z++) {
max_r1[z].akt(j, b.cnt);
}
}
}
}
void gen() {
gen_row();
gen_col();
std::sort(tmp1.begin(), tmp1.end(), std::greater<int>());
std::sort(tmp2.begin(), tmp2.end(), std::greater<int>());
ans = std::max({ans, tmp1[0] / 2, tmp1[1], tmp2[0] / 2, tmp2[1]});
}
void dbg1() {
std::cout << "START -~ BEST_ROW[sm]\n";
for (int cnt = 1; cnt <= n; cnt++) {
const auto& arr = best_row[cnt];
std::cout << cnt << "\n";
for (const auto& g : arr) {
std::cout << g.cnt << " " << g.pos << '\n';
}
std::cout << '\n';
}
std::cout << "START -~ BEST_COL[sm]\n";
for (int cnt = 1; cnt <= n; cnt++) {
const auto& arr = best_col[cnt];
std::cout << cnt << "\n";
for (const auto& g : arr) {
std::cout << g.cnt << " " << g.pos << '\n';
}
std::cout << '\n';
}
}