// https://szkopul.edu.pl/problemset/problem/70I-ks8dXjgq3xwzRzLV1w4p/site/?key=statement
#include <bits/stdc++.h>
using namespace std;
#define int long long
constexpr int sizik = 1006;
#define ar std::array
#define pr std::pair
#define vec std::vector
// #define GARY_DBG
typedef vec<vec<int>> _kra;
constexpr ar<int, 4> dx = {0, 1, 0, -1};
constexpr ar<int, 4> dy = {1, 0, -1, 0};
int n;
int ans;
// [y][x]
char mapx[sizik][sizik];
bool visited[sizik][sizik];
int curr_num = 1;
int numer_spojnej[sizik][sizik];
// std::vector<int> rozmiar_spojnej;
int rozmiar_spojnej[sizik * sizik];
// vector<pair<int, int>> pairs;
int max_spojna = 0;
void DFS(int y, int x) {
if (visited[y][x]) return;
visited[y][x] = true;
numer_spojnej[y][x] = curr_num;
max_spojna = std::max(max_spojna, ++rozmiar_spojnej[curr_num]);
for (int dir = 0; dir < 4; dir++) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if (mapx[ny][nx] == 'B') {
DFS(ny, nx);
}
}
}
std::vector<int> zkim_sasiaduje_ar[sizik][sizik];
std::vector<int> zkim_sasiaduje(int x, int y) {
std::vector<int> xd;
for (int dir = 0; dir < 4; dir++) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if (mapx[ny][nx] == 'B') {
xd.push_back(numer_spojnej[ny][nx]);
}
}
return xd;
}
std::vector<int> combineUnique(const std::vector<int>& a, const std::vector<int>& b) {
std::unordered_set<int> seen;
std::vector<int> result;
for (int x : a)
if (seen.insert(x).second) result.push_back(x);
for (int x : b)
if (seen.insert(x).second) result.push_back(x);
return result;
}
void makeUnique(std::vector<int>& v1) {
std::unordered_set<int> uniqueElements(v1.begin(), v1.end());
v1.clear();
for (int val : uniqueElements) {
v1.push_back(val);
}
}
int combine_ans(const std::vector<int>& yui, int x, int y) {
const auto& zui = zkim_sasiaduje_ar[x][y];
auto xui = combineUnique(yui, zui);
int ansix = 2;
for (const auto& xik : xui) {
ansix += rozmiar_spojnej[xik];
}
return ansix;
}
ar<ar<ar<int, 2>, 2>, sizik * sizik> rogi;
void wyznacz_prostokaty() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (mapx[i][j] == 'B') {
rogi[numer_spojnej[i][j]][1] = {j, i};
const auto& [x, y] = rogi[numer_spojnej[i][j]][0];
if (x == 0 && y == 0) {
rogi[numer_spojnej[i][j]][0] = {j, i};
}
}
}
}
}
bool try_add_aisle(vector<vector<int>>& curAisles, const vector<int>& nextAisle, int curPool) {
for (auto& other : curAisles) {
if (includes(other.begin(), other.end(), nextAisle.begin(), nextAisle.end())) {
return false;
}
}
vector<int> addedAisle;
for (int v : nextAisle)
if (v != curPool) addedAisle.push_back(v);
curAisles.push_back(addedAisle);
return true;
}
int get_total_area(const vector<int>& pools) {
int result = 0;
for (int pool : pools)
result += rozmiar_spojnej[pool];
return result;
}
void main_loop() {
for (int idxsp = 2; idxsp < (int)rogi.size(); idxsp++) {
const auto& a = rogi[idxsp];
if (a[0][0] == 0) break;
std::vector<std::vector<int>> singleAisles, multAisles;
for (int p = a[0][0]; p <= a[1][0]; p++) {
for (int q = 0, add = -1; q <= 1; q++, add += 2) {
const std::vector<int>& neighbors = zkim_sasiaduje_ar[p][a[q][1] + add];
if (neighbors.size() == 1) continue;
(neighbors.size() == 2 ? singleAisles : multAisles).push_back(neighbors);
}
}
for (int p = a[0][1]; p <= a[1][1]; p++) {
for (int q = 0, add = -1; q <= 1; q++, add += 2) {
const std::vector<int>& neighbors = zkim_sasiaduje_ar[a[q][0] + add][p];
if (neighbors.size() == 1) continue;
(neighbors.size() == 2 ? singleAisles : multAisles).push_back(neighbors);
}
}
vector<vector<int>> feasibleAisles;
for (auto& aisle : multAisles)
try_add_aisle(feasibleAisles, aisle, idxsp);
vector<int> singleAlone;
for (auto& single : singleAisles) {
int v = (single[0] == idxsp ? single[1] : single[0]);
bool okay = true;
for (auto& mult : feasibleAisles) {
if (find(mult.begin(), mult.end(), v) != mult.end()) {
okay = false;
break;
}
}
if (okay) singleAlone.push_back(v);
}
int best1 = -1, best2 = -1;
for (int v : singleAlone) {
if (v == best1 || v == best2) continue;
if (best1 == -1 || rozmiar_spojnej[best1] < rozmiar_spojnej[v]) {
best2 = best1;
best1 = v;
} else if (best2 == -1 || rozmiar_spojnej[best2] < rozmiar_spojnej[v]) {
best2 = v;
}
}
if (best1 != -1) feasibleAisles.push_back({best1});
if (best2 != -1) feasibleAisles.push_back({best2});
int S = (int)feasibleAisles.size();
int result = 2 + rozmiar_spojnej[idxsp];
for (int fst = 0; fst < S; fst++) {
result = std::max(result, 2ll + rozmiar_spojnej[idxsp] + get_total_area(feasibleAisles[fst]));
for (int snd = fst + 1; snd < S; snd++) {
vector<int>&A1 = feasibleAisles[fst], A2 = feasibleAisles[snd];
vector<int> everything;
set_union(A1.begin(), A1.end(), A2.begin(), A2.end(), back_inserter(everything));
result = max(result, 2 + rozmiar_spojnej[idxsp] + get_total_area(everything));
}
}
ans = std::max(ans, result);
}
}
int32_t main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> n;
int o = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
std::cin >> mapx[i][j];
if (mapx[i][j] == 'A') {
o++;
}
}
}
if (o == 0 || o == 1 || o == 2) {
std::cout << n * n << '\n';
return 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (!visited[i][j] && mapx[i][j] == 'B') {
curr_num++;
DFS(i, j);
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
zkim_sasiaduje_ar[j][i] = zkim_sasiaduje(j, i);
std::sort(zkim_sasiaduje_ar[j][i].begin(), zkim_sasiaduje_ar[j][i].end());
}
}
ans = max_spojna + 2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// mapx[i][j]
if (mapx[i][j] != 'A') continue;
auto yui = zkim_sasiaduje_ar[j][i];
if (mapx[i][j + 1] == 'A') {
int ansix = combine_ans(yui, j + 1, i);
ans = std::max(ans, ansix);
}
if (mapx[i + 1][j] == 'A') {
int ansix = combine_ans(yui, j, i + 1);
ans = std::max(ans, ansix);
}
}
}
wyznacz_prostokaty();
main_loop();
std::cout << ans << '\n';
}