Problem p03718 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define ll long long
#define inf 1000000001
using namespace std;
#define N 205
#define M 100005
int n, m, cnt = 1, s, t, head[N], vis[N];
char str[N];
struct edge {
  int to, nxt, c;
} e[N << 1];
void adde(int x, int y, int z) {
  e[++cnt].to = y;
  e[cnt].nxt = head[x];
  e[cnt].c = z;
  head[x] = cnt;
}
void ins(int x, int y, int z) {
  adde(x, y, z);
  adde(y, x, 0);
}
int dfs(int u, int flow) {
  if (u == t)
    return flow;
  int w, used = 0;
  for (int i = head[u], v; i; i = e[i].nxt) {
    v = e[i].to;
    if (e[i].c && vis[v] == vis[u] + 1) {
      w = dfs(v, min(flow - used, e[i].c));
      e[i].c -= w;
      e[i ^ 1].c += w;
      used += w;
      if (flow == used)
        return used;
    }
  }
  if (!used)
    vis[u] = -1;
  return used;
}
bool bfs() {
  queue<int> q;
  q.push(s);
  rep(i, 1, t) vis[i] = -1;
  vis[s] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u], v; i; i = e[i].nxt) {
      v = e[i].to;
      if (e[i].c && vis[v] == -1)
        vis[v] = vis[u] + 1, q.push(v);
    }
  }
  return vis[t] != -1;
}
int dinic() {
  int ret = 0;
  while (bfs())
    ret += dfs(s, inf);
  return ret;
}
int main() {
  scanf("%d%d", &n, &m);
  s = n + m + 1, t = n + m + 2;
  rep(i, 1, n) {
    scanf("%s", str + 1);
    rep(j, 1, m) {
      if (str[j] == 'o')
        ins(i, j + n, 1), ins(j + n, i, 1);
      if (str[j] == 'S')
        ins(s, i, inf), ins(s, j + n, inf), ins(i, j + n, inf),
            ins(j + n, i, inf);
      if (str[j] == 'T')
        ins(j + n, t, inf), ins(i, t, inf), ins(i, j + n, inf),
            ins(j + n, i, inf);
    }
  }
  int ans = dinic();
  if (ans >= inf)
    puts("-1");
  else
    cout << ans << '\n';
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = (x); i <= (y); i++)
#define ll long long
#define inf 1000000001
using namespace std;
#define N 205
#define M 100005
int n, m, cnt = 1, s, t, head[N], vis[N];
char str[N];
struct edge {
  int to, nxt, c;
} e[M << 1];
void adde(int x, int y, int z) {
  e[++cnt].to = y;
  e[cnt].nxt = head[x];
  e[cnt].c = z;
  head[x] = cnt;
}
void ins(int x, int y, int z) {
  adde(x, y, z);
  adde(y, x, 0);
}
int dfs(int u, int flow) {
  if (u == t)
    return flow;
  int w, used = 0;
  for (int i = head[u], v; i; i = e[i].nxt) {
    v = e[i].to;
    if (e[i].c && vis[v] == vis[u] + 1) {
      w = dfs(v, min(flow - used, e[i].c));
      e[i].c -= w;
      e[i ^ 1].c += w;
      used += w;
      if (flow == used)
        return used;
    }
  }
  if (!used)
    vis[u] = -1;
  return used;
}
bool bfs() {
  queue<int> q;
  q.push(s);
  rep(i, 1, t) vis[i] = -1;
  vis[s] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u], v; i; i = e[i].nxt) {
      v = e[i].to;
      if (e[i].c && vis[v] == -1)
        vis[v] = vis[u] + 1, q.push(v);
    }
  }
  return vis[t] != -1;
}
int dinic() {
  int ret = 0;
  while (bfs())
    ret += dfs(s, inf);
  return ret;
}
int main() {
  scanf("%d%d", &n, &m);
  s = n + m + 1, t = n + m + 2;
  rep(i, 1, n) {
    scanf("%s", str + 1);
    rep(j, 1, m) {
      if (str[j] == 'o')
        ins(i, j + n, 1), ins(j + n, i, 1);
      if (str[j] == 'S')
        ins(s, i, inf), ins(s, j + n, inf), ins(i, j + n, inf),
            ins(j + n, i, inf);
      if (str[j] == 'T')
        ins(j + n, t, inf), ins(i, t, inf), ins(i, j + n, inf),
            ins(j + n, i, inf);
    }
  }
  int ans = dinic();
  if (ans >= inf)
    puts("-1");
  else
    cout << ans << '\n';
  return 0;
}