Problem p00744 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <limits>
#include <vector>

using namespace std;
using ll = long long;
template <typename T> constexpr T INF = numeric_limits<T>::max() / 100;

class Flow {
public:
  using T = ll;
  struct Edge {
    Edge(const int from_, const int to_, const int reverse_, const T capacity_,
         bool is_reverse = false)
        : from{from_}, to{to_}, reverse{reverse_}, capacity{capacity_}, flow{0},
          is_reverse(is_reverse) {}
    int from;
    int to;
    int reverse;
    T capacity;
    T flow;
    bool is_reverse;
  };

  Flow(const int v) : V{v} { edge.resize(v); }
  void addEdge(const int from, const int to, const T capacity) {
    edge[from].push_back(Edge{from, to, (int)edge[to].size(), capacity, false});
    edge[to].push_back(Edge{to, from, (int)edge[from].size() - 1, 0, true});
  }

  T FordFulkerson(const int s, const int t) {
    vector<bool> checked(V);
    T flow = 0;
    while (true) {
      for (int i = 0; i < V; i++) {
        checked[i] = false;
      }
      const T f = dfs_ff(s, t, INF<T>, checked);
      if (f == 0) {
        break;
      }
      flow += f;
    }
    return flow;
  }

  const int V;
  vector<vector<Edge>> edge;

private:
  T dfs_ff(const int pos, const int t, const T flow, vector<bool> &checked) {
    if (pos == t) {
      return flow;
    }
    checked[pos] = true;
    for (auto &e : edge[pos]) {
      if (not checked[e.to]) {
        const T res = e.capacity - e.flow;
        if (res > 0) {
          const T d = dfs_ff(e.to, t, min(flow, res), checked);
          if (d > 0) {
            e.flow += min(d, res);
            edge[e.to][e.reverse].flow -= min(d, res);
            return d;
          }
        }
      }
    }
    return 0;
  }
};

template <typename T> T gcd(const T a, const T b) {
  return (b != 0) ? gcd(b, a % b) : a;
}

int main() {
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 and n == 0) {
      break;
    }
    Flow flow(m + n + 2);
    vector<ll> b(m);
    for (int i = 0; i < m; i++) {
      flow.addEdge(m + n, i, 1);
      cin >> b[i];
    }
    vector<ll> r(m);
    for (int i = 0; i < n; i++) {
      flow.addEdge(i + m, m + n + 1, 1);
      cin >> r[i];
    }

    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (gcd(b[i], r[j]) > 1) {
          flow.addEdge(i, m + j, 1);
        }
      }
    }
    cout << flow.FordFulkerson(m + n, m + n + 1) << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <limits>
#include <vector>

using namespace std;
using ll = long long;
template <typename T> constexpr T INF = numeric_limits<T>::max() / 100;

class Flow {
public:
  using T = ll;
  struct Edge {
    Edge(const int from_, const int to_, const int reverse_, const T capacity_,
         bool is_reverse = false)
        : from{from_}, to{to_}, reverse{reverse_}, capacity{capacity_}, flow{0},
          is_reverse(is_reverse) {}
    int from;
    int to;
    int reverse;
    T capacity;
    T flow;
    bool is_reverse;
  };

  Flow(const int v) : V{v} { edge.resize(v); }
  void addEdge(const int from, const int to, const T capacity) {
    edge[from].push_back(Edge{from, to, (int)edge[to].size(), capacity, false});
    edge[to].push_back(Edge{to, from, (int)edge[from].size() - 1, 0, true});
  }

  T FordFulkerson(const int s, const int t) {
    vector<bool> checked(V);
    T flow = 0;
    while (true) {
      for (int i = 0; i < V; i++) {
        checked[i] = false;
      }
      const T f = dfs_ff(s, t, INF<T>, checked);
      if (f == 0) {
        break;
      }
      flow += f;
    }
    return flow;
  }

  const int V;
  vector<vector<Edge>> edge;

private:
  T dfs_ff(const int pos, const int t, const T flow, vector<bool> &checked) {
    if (pos == t) {
      return flow;
    }
    checked[pos] = true;
    for (auto &e : edge[pos]) {
      if (not checked[e.to]) {
        const T res = e.capacity - e.flow;
        if (res > 0) {
          const T d = dfs_ff(e.to, t, min(flow, res), checked);
          if (d > 0) {
            e.flow += min(d, res);
            edge[e.to][e.reverse].flow -= min(d, res);
            return d;
          }
        }
      }
    }
    return 0;
  }
};

template <typename T> T gcd(const T a, const T b) {
  return (b != 0) ? gcd(b, a % b) : a;
}

int main() {
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 and n == 0) {
      break;
    }
    Flow flow(m + n + 2);
    vector<ll> b(m);
    for (int i = 0; i < m; i++) {
      flow.addEdge(m + n, i, 1);
      cin >> b[i];
    }
    vector<ll> r(n);
    for (int i = 0; i < n; i++) {
      flow.addEdge(i + m, m + n + 1, 1);
      cin >> r[i];
    }

    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (gcd(b[i], r[j]) > 1) {
          flow.addEdge(i, m + j, 1);
        }
      }
    }
    cout << flow.FordFulkerson(m + n, m + n + 1) << endl;
  }
  return 0;
}