Problem p03321 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pair<int, int>>
#define gph map<int, vector<int>>
#define mp make_pair
#define FOR(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR1(i, n) for (int i = 1; i <= (int)(n); i++)
#define FORD0(i, n) for (int i = (int)n; i >= 0; i--)
#define FORD1(i, n) for (int i = (int)n; i >= 1; i--)
#define FORS(i, n) for (; i < (int)(n); i++)
#define debug(X)                                                               \
  { cout << #X << " = " << (X) << endl; }
#define printArr(A, n)                                                         \
  {                                                                            \
    cout << #A << " = ";                                                       \
    FOR(i, n) cout << A[i] << ' ';                                             \
    cout << endl;                                                              \
  }
using namespace std;
#define int long long int

int a, b;
vector<int> visited;
bool fail = false;
int n;
bool edges[701][701];
int cnt = 0;
void dfs(int cur, bool turn) {
  // debug(cur);
  if (visited[cur] == turn)
    return;
  if (visited[cur] != -1 && visited[cur] == !turn) {
    fail = true;
    return;
  }
  visited[cur] = turn;
  if (turn)
    a++;
  else
    b++;
  FOR(i, n) {
    if (i == cur)
      continue;
    if (!edges[i][cur]) {
      cnt++;
      dfs(i, !turn);
    }
    if (fail)
      return;
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  freopen("2.txt", "r", stdin);
  cin >> n;
  visited = vector<int>(n + 5, -1);
  int m;
  cin >> m;
  int u, v;
  FOR(i, m) {
    cin >> u >> v;
    u--, v--;
    edges[u][v] = edges[v][u] = true;
  }
  vector<pii> options;
  a = 0, b = 0;
  FOR(i, n) {
    if (visited[i] == -1)
      dfs(i, false);
    if (fail) {
      cout << -1 << endl;
      return 0;
    }
    if (a + b > 0)
      options.pb(mp(a, b));
    a = 0, b = 0;
  }
  const int lim = (n) / 2;
  assert(m * 2 + cnt == (n * (n - 1)));
  vector<bool> dp(lim + 1);
  dp[0] = true;
  int sum = 0;
  for (pii x : options) {
    vector<bool> dp2(lim + 1);
    sum += x.first + x.second;
    FORD1(i, lim) {
      if (x.first <= i)
        dp2[i] = dp2[i] | dp[i - x.first];
      if (x.second <= i)
        dp2[i] = dp2[i] | dp[i - x.second];
    }
    dp = dp2;
  }
  assert(sum == n);
  FORD1(i, lim) {
    if (dp[i]) {
      cout << i * (i - 1) / 2 + (n - i) * (n - i - 1) / 2 << endl;
      return 0;
    }
  }
}


Fixed submission:
#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pair<int, int>>
#define gph map<int, vector<int>>
#define mp make_pair
#define FOR(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR1(i, n) for (int i = 1; i <= (int)(n); i++)
#define FORD0(i, n) for (int i = (int)n; i >= 0; i--)
#define FORD1(i, n) for (int i = (int)n; i >= 1; i--)
#define FORS(i, n) for (; i < (int)(n); i++)
#define debug(X)                                                               \
  { cout << #X << " = " << (X) << endl; }
#define printArr(A, n)                                                         \
  {                                                                            \
    cout << #A << " = ";                                                       \
    FOR(i, n) cout << A[i] << ' ';                                             \
    cout << endl;                                                              \
  }
using namespace std;
#define int long long int

int a, b;
vector<int> visited;
bool fail = false;
int n;
bool edges[701][701];
int cnt = 0;
void dfs(int cur, bool turn) {
  // debug(cur);
  if (visited[cur] == turn)
    return;
  if (visited[cur] != -1 && visited[cur] == !turn) {
    fail = true;
    return;
  }
  visited[cur] = turn;
  if (turn)
    a++;
  else
    b++;
  FOR(i, n) {
    if (i == cur)
      continue;
    if (!edges[i][cur]) {
      cnt++;
      dfs(i, !turn);
    }
    if (fail)
      return;
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  //  freopen("2.txt", "r", stdin);
  cin >> n;
  visited = vector<int>(n + 5, -1);
  int m;
  cin >> m;
  int u, v;
  FOR(i, m) {
    cin >> u >> v;
    u--, v--;
    edges[u][v] = edges[v][u] = true;
  }
  vector<pii> options;
  a = 0, b = 0;
  FOR(i, n) {
    if (visited[i] == -1)
      dfs(i, false);
    if (fail) {
      cout << -1 << endl;
      return 0;
    }
    if (a + b > 0)
      options.pb(mp(a, b));
    a = 0, b = 0;
  }
  const int lim = (n) / 2;
  assert(m * 2 + cnt == (n * (n - 1)));
  vector<bool> dp(lim + 1);
  dp[0] = true;
  int sum = 0;
  for (pii x : options) {
    vector<bool> dp2(lim + 1);
    sum += x.first + x.second;
    FORD1(i, lim) {
      if (x.first <= i)
        dp2[i] = dp2[i] | dp[i - x.first];
      if (x.second <= i)
        dp2[i] = dp2[i] | dp[i - x.second];
    }
    dp = dp2;
  }
  assert(sum == n);
  FORD1(i, lim) {
    if (dp[i]) {
      cout << i * (i - 1) / 2 + (n - i) * (n - i - 1) / 2 << endl;
      return 0;
    }
  }
}