Source Code
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));
                uf.join(hash(i, j, 4), hash(ni, nj, curDir));
              }
            }
          }
        }
      }

      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
Mirrors dauom
Java 11
119 ms
73.0 MB
Wrong Answer