import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.TreeSet;
import java.io.InputStream;
/**
* Built using CHelper plug-in
* Actual solution is at the top
*
* @author dauom
*/
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
TaskF solver = new TaskF();
solver.solve(1, in, out);
out.close();
}
static class TaskF {
private final int R = 3;
private final int L = 2;
private final int D = 1;
private final int U = 0;
public final void solve(int testNumber, InputReader in, PrintWriter out) {
final int n = in.nextInt();
final int m = in.nextInt();
char[][] g = in.nextCharMatrix(n, m);
UnionFind uf = new WeightedUnionFind((int) 5e6 + 5);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == '.') {
for (int k = 0; k < 4; k++) {
int ni = i + Constants.DX4[k];
int nj = j + Constants.DY4[k];
if (ni >= 0 && nj >= 0 && ni < n && nj < m) {
int curDir = k;
while (ni >= 0 && nj >= 0 && ni < n && nj < m && (g[ni][nj] == '/' || g[ni][nj] == '\\')) {
if (g[ni][nj] == '/') {
switch (curDir) {
case L: {
curDir = D;
ni++;
break;
}
case R: {
curDir = U;
ni--;
break;
}
case U: {
curDir = R;
nj++;
break;
}
case D: {
curDir = L;
nj--;
break;
}
}
} else {
if (g[ni][nj] == '\\') {
switch (curDir) {
case R: {
curDir = D;
ni++;
break;
}
case L: {
curDir = U;
ni--;
break;
}
case D: {
curDir = R;
nj++;
break;
}
case U: {
curDir = L;
nj--;
break;
}
}
}
}
}
if (ni < 0 || nj < 0 || ni >= n || nj >= m || g[ni][nj] != '.' || (ni == i && nj == j)) {
continue;
}
uf.join(hash(i, j, k), hash(ni, nj, curDir));
}
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == '.') {
for (int k = 0; k < 4; k++) {
int ni = i + Constants.DX4[k];
int nj = j + Constants.DY4[k];
if (ni >= 0 && nj >= 0 && ni < n && nj < m && g[ni][nj] == '.') {
uf.join(hash(i, j, 4), hash(ni, nj, k));
}
}
}
}
}
TreeSet<Integer>[] sizes = new TreeSet[(int) 5e6 + 5];
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == '.') {
for (int k = 0; k < 5; k++) {
int h = uf.find(hash(i, j, k));
if (sizes[h] == null) {
sizes[h] = new TreeSet<>();
}
sizes[h].add(i * 1000 + j);
if (sizes[h].size() > ans) {
ans = sizes[h].size();
}
}
}
}
}
out.println(ans);
}
private int hash(int x, int y, int dir) {
return (1000 * x + y) * 5 + dir;
}
}
static interface UnionFind {
int find(int i);
boolean join(int i, int j);
}
static class Constants {
public static final int[] DX4 = new int[]{-1, 1, 0, 0};
public static final int[] DY4 = new int[]{0, 0, -1, 1};
}
static class WeightedUnionFind implements UnionFind {
public int n;
public int cc;
public int offset;
public int[] parent;
public int[] size;
public WeightedUnionFind(int size) {
this(size, 0);
}
public WeightedUnionFind(int size, int offset) {
this.offset = offset;
this.n = size + offset;
this.cc = size;
this.parent = new int[n];
this.size = new int[n];
for (int i = 0; i < n; ++i) {
this.parent[i] = i;
this.size[i] = 1;
}
}
public int find(int i) {
if (i == parent[i]) {
return i;
}
return parent[i] = find(parent[i]);
}
public boolean join(int i, int j) {
i = find(i);
j = find(j);
if (i == j) {
return false;
}
if (size[i] > size[j]) {
size[i] += size[j];
parent[j] = i;
} else {
size[j] += size[i];
parent[i] = j;
}
--cc;
return true;
}
}
static final class InputReader {
private final InputStream stream;
private final byte[] buf = new byte[1 << 18];
private int curChar;
private int numChars;
public InputReader() {
this.stream = System.in;
}
public InputReader(final InputStream stream) {
this.stream = stream;
}
private int read() {
if (this.numChars == -1) {
throw new UnknownError();
} else {
if (this.curChar >= this.numChars) {
this.curChar = 0;
try {
this.numChars = this.stream.read(this.buf);
} catch (IOException ex) {
throw new InputMismatchException();
}
if (this.numChars <= 0) {
return -1;
}
}
return this.buf[this.curChar++];
}
}
public final int nextInt() {
int c;
for (c = this.read(); isSpaceChar(c); c = this.read()) {
}
byte sgn = 1;
if (c == 45) { // 45 == '-'
sgn = -1;
c = this.read();
}
int res = 0;
while (c >= 48 && c <= 57) { // 48 == '0', 57 == '9'
res *= 10;
res += c - 48; // 48 == '0'
c = this.read();
if (isSpaceChar(c)) {
return res * sgn;
}
}
throw new InputMismatchException();
}
public final String next() {
int c;
while (isSpaceChar(c = this.read())) {
}
StringBuilder result = new StringBuilder();
result.appendCodePoint(c);
while (!isSpaceChar(c = this.read())) {
result.appendCodePoint(c);
}
return result.toString();
}
private static boolean isSpaceChar(final int c) {
return c == 32 || c == 10 || c == 13 || c == 9
|| c == -1; // 32 == ' ', 10 == '\n', 13 == '\r', 9 == '\t'
}
public final char[] nextCharArray() {
return next().toCharArray();
}
public final char[][] nextCharMatrix(final int n, final int m) {
char[][] res = new char[n][m];
for (int i = 0; i < n; ++i) {
res[i] = nextCharArray();
}
return res;
}
}
}
Copy