Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = collections.deque([s]) #queue.Queue()
        #que.put(s)
        while que: #.empty():
            v = que.popleft() #.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0]) # put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))

Fixed submission:
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = collections.deque([s]) #queue.Queue()
        #que.put(s)
        while que: #.empty():
            v = que.popleft() #.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0]) # put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = queue.Queue()
        que.put(s)
        while not que.empty():
            v = que.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))

Fixed submission:
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = collections.deque([s]) #queue.Queue()
        #que.put(s)
        while que: #.empty():
            v = que.popleft() #.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0]) # put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = queue.Queue()
        que.put(s)
        while not que.empty():
            v = que.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))

Fixed submission:
# -*- coding: utf-8 -*-
import collections
import queue


class Dinic:
    def __init__(self, N):
        self.N = N
        self.edges = collections.defaultdict(list)
        self.level = [0 for _ in range(self.N)]
        self.iter = [0 for _ in range(self.N)]

    def add(self, u, v, c, directed=True):
        if directed:
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u])-1])
        else:  # TODO: must be Verified
            self.edges[u].append([v, c, len(self.edges[v])])
            self.edges[v].append([u, 0, len(self.edges[u]) - 1])
            self.edges[v].append([u, c, len(self.edges[u])])
            self.edges[u].append([v, 0, len(self.edges[v]) - 1])

    def bfs(self, s):
        self.level = [-1 for _ in range(self.N)]
        self.level[s] = 0
        que = collections.deque([s]) #queue.Queue()
        #que.put(s)
        while que: #.empty():
            v = que.popleft() #.get(s)
            for i in range(len(self.edges[v])):
                e = self.edges[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0]) # put(e[0])

    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.edges[v])):
            self.iter[v] = i
            e = self.edges[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.edges[e[0]][e[2]][1] += d
                    return d
        return 0

    def maxFlow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.N)]
            f = self.dfs(s, t, float('inf'))
            while f > 0:
                flow += f
                f = self.dfs(s, t, float('inf'))


H, W = map(int, input().split())
graph = Dinic(2*H*W + 2)
delta = [-1, 1, W, -W]
goal = 2 * H * W + 1
for i in range(H):
    S = str(input())
    for j, s in enumerate(S):
        curEdge = i * W + j + 1
        if s == '.':
            graph.add(curEdge, curEdge+H*W, 1)
        else:
            if i == 0 or i == H-1 or j == 0 or j == W-1:
                print(-1)
                quit()
            graph.add(curEdge, curEdge+H*W, float('inf'))
            graph.add(0, curEdge, float('inf'))
        for d in delta:
            if 0 < curEdge+d < 2*H*W+1:
                graph.add(curEdge+H*W, curEdge+d, float('inf'))

for i in range(1, W+1):
    graph.add(i+H*W, goal, float('inf'))
    graph.add(i+(2*H-1)*W, goal, float('inf'))

for i in range(1, H-1):
    graph.add((i+H)*W+1, goal, float('inf'))
    graph.add((i+H+1)*W, goal, float('inf'))


print(graph.maxFlow(0, goal))