Problem:
Problem B:
RabbitWalking
うさぎの住んでいる都市には, $V$ 個の交差点と $E$ 本の道がある. 交差点は 1-indexed で番号が付けられている. $i$ 番目の道は交差点 $a_i$ と交差点 $b_i$ を bidirectional につないでいる.
うさぎは, 散歩と奇数が好きである．うさぎはある交差点から出発し, 道を奇数本辿り, 出発した頂点に戻るような経路に沿って散歩したいと思っている．
この都市の市長であるねこは, 都市内の移動を効率化するために異なる2 つの交差点を結ぶ道をたくさん追加しようとしている．ただし，ある交差点の組に対して敷設することが出来る道は高々1本までである．また， ねこはいたずら好きなので，道を奇数本辿り, 出発した頂点に戻るような経路が含まれないようにしたいと思っている．
最大で何本道を付け加えられるか求めよ. ただし，最初からうさぎの要求が満たされている場合は-1 を出力せよ.
Constraints
$V$ will be between 1 and 100,000, inclusive.
$E$ will be between 0 and 100,000, inclusive.
$a_i$ and $b_i$ will be distinct.
No two roads connect the same pair of intersections.
Input
入力は以下の形式で与えられる:
$V$ $E$
$a_1$ $b_1$
...
$a_E$ $b_E$
Output
道を追加できる本数の最大値を表す整数を 1 行に出力せよ. 最初からうさぎの要求が満たされている場合は -1 を出力せよ.
Sample Input 1
8 5
1 2
6 5
6 4
1 3
4 7
Sample Output 1
11
Sample Input 2
5 8
2 1
2 4
1 3
5 4
4 1
2 3
3 5
2 5
Sample Output 2
-1

Submitted solutions:

code_snippet: // AOJ #2370
// RabbitWalking 2025.2.10

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int V, E;
    cin >> V >> E;

    if(E == 0) {
        ll a = V / 2, b = V - a;
        cout << a * b << endl;
        return 0;
    }

    vector<vector<int>> graph(V+1);
    for (int i = 0; i < E; i++){
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    
    vector<int> color(V+1, -1);
    vector<pair<int,int>> comps;
    bool bipartite = true;
    
    for (int i = 1; i <= V; i++){
        if(color[i] == -1){
            int cnt0 = 0, cnt1 = 0;
            queue<int> q;
            color[i] = 0;
            cnt0++;
            q.push(i);
            while(!q.empty()){
                int cur = q.front();
                q.pop();
                for (int nxt : graph[cur]){
                    if(color[nxt] == -1){
                        color[nxt] = 1 - color[cur];
                        if(color[nxt] == 0) cnt0++;
                        else cnt1++;
                        q.push(nxt);
                    } else {
                        if(color[nxt] == color[cur]){
                            bipartite = false;
                            break;
                        }
                    }
                }
                if(!bipartite) break;
            }
            if(!bipartite) break;
            comps.push_back({cnt0, cnt1});
        }
    }
    
    if(!bipartite){
        cout << -1 << endl;
        return 0;
    }
    
    bitset<100001> dp;
    dp.reset();
    dp[0] = 1;
    
    for(auto &comp : comps){
        int a = comp.first, b = comp.second;
        bitset<100001> dpA = (dp << a);
        if(a == b) dp = dpA;
        else {
            bitset<100001> dpB = (dp << b);
            dp = dpA | dpB;
        }
    }
    
    int bestS = 0;
    ll bestProd = -1;
    for (int s = 0; s <= V; s++){
        if(dp[s]){
            ll prod = (ll)s * (V - s);
            if(prod > bestProd){
                bestProd = prod;
                bestS = s;
            }
        }
    }
    ll ans = bestProd - E;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 9556
final_rank: 2

code_snippet: // AOJ #2370
// RabbitWalking 2025.2.10

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int V, E;
    cin >> V >> E;
    vector<vector<int>> graph(V+1);
    for (int i = 0; i < E; i++){
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    
    vector<int> color(V+1, -1);
    vector<pair<int,int>> comps;
    bool bipartite = true;
    
    for (int i = 1; i <= V; i++){
        if(color[i] == -1){
            int cnt0 = 0, cnt1 = 0;
            queue<int> q;
            color[i] = 0;
            cnt0++;
            q.push(i);
            while(!q.empty()){
                int cur = q.front();
                q.pop();
                for (int nxt : graph[cur]){
                    if(color[nxt] == -1){
                        color[nxt] = 1 - color[cur];
                        if(color[nxt] == 0) cnt0++;
                        else cnt1++;
                        q.push(nxt);
                    } else {
                        if(color[nxt] == color[cur]){
                            bipartite = false;
                            break;
                        }
                    }
                }
                if(!bipartite) break;
            }
            if(!bipartite) break;
            comps.push_back({cnt0, cnt1});
        }
    }
    
    if(!bipartite){
        cout << -1 << endl;
        return 0;
    }
    
    bitset<100001> dp;
    dp.reset();
    dp[0] = 1;
    
    for(auto &comp : comps){
        int a = comp.first, b = comp.second;
        bitset<100001> dpA = (dp << a);
        if(a == b) dp = dpA;
        else {
            bitset<100001> dpB = (dp << b);
            dp = dpA | dpB;
        }
    }
    
    int bestS = 0;
    ll bestProd = -1;
    for (int s = 0; s <= V; s++){
        if(dp[s]){
            ll prod = (ll)s * (V - s);
            if(prod > bestProd){
                bestProd = prod;
                bestS = s;
            }
        }
    }
    
    ll ans = bestProd - E;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 9552
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
int v, e, col[100010];
vector<int> edge[100010], grp[100010];
bool dfs(int now, int rt){
    bool res = false;
    for(auto to: edge[now]){
        if(col[to]==-1){
            col[to] = col[now]^1;
            grp[rt].push_back(to);
            res |= dfs(to, rt);
        } else if(col[now]==col[to]) res = true;
    }
    return res;
}
int main(){
    cin >> v >> e;
    int a, b;
    for(int i=0;i<e;i++){
        cin >> a >> b;
        edge[--a].push_back(--b);
        edge[b].push_back(a);
    }
    memset(col, -1, sizeof(col));
    bool nasi=false;
    for(int i=0;i<v;i++){
        if(col[i]==-1){
            col[i] = 0;
            grp[i].push_back(i);
            nasi |= dfs(i, i);
        }
    }
    if(nasi) cout << -1 << endl;
    else{
        int sum[2]={};
        bitset<100010> bs;
        bs[0] = 1;
        for(int i=0;i<v;i++){
            if(grp[i].size()==0) continue;
            for(auto gi: grp[i]) sum[col[gi]]++;
            bs = bs<<sum[0] | bs<<sum[1];
            sum[0] = sum[1] = 0;
        }
        long long ans = 0;
        for(int i=1;i<=v/2;i++){
            if(bs[i]) ans = i;
        }
        cout << ans*(v-ans)-e << endl;
    }
    return(0);
}
accuracy: 1
time_ms: 290
memory_kb: 12752
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
int v, e;
vector<int> edge[100010], grp[100010];
int col[100010], sum[2][100010];
bool dfs(int now, int rt){

    bool res = false;
    for(auto to: edge[now]){
        if(col[to]==-1){
            col[to] = col[now]^1;
            grp[rt].push_back(to);
            res |= dfs(to, rt);
        } else if(col[now]==col[to]){
            res = true;
        }
    }

    return res;
}
int main(){

    cin >> v >> e;
    int a, b;
    for(int i=0;i<e;i++){
        cin >> a >> b;
        a--;
        b--;
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    memset(col, -1, sizeof(col));
    bool nasi=false;
    for(int i=0;i<v;i++){
        if(col[i]==-1){
            col[i] = 0;
            grp[i].push_back(i);
            nasi |= dfs(i, i);
        }
    }
    if(nasi){
        cout << -1 << endl;
    } else{
        for(int i=0;i<v;i++){
            for(auto gi: grp[i]) sum[col[gi]][i]++;
        }

        bitset<100010> bs;
        bs[0] = 1;
        for(int i=0;i<v;i++){
            bs = bs<<sum[0][i] | bs<<sum[1][i];
        }

        long long ans = 0;
        for(int i=1;i<=v/2;i++){
            if(bs[i]) ans = i;
        }

        cout << ans*(v-ans)-e << endl;

    }

    return(0);
}
accuracy: 1
time_ms: 280
memory_kb: 12960
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 100010

int n, m;
vector <int> adj[N];
int cnt[3];
int color[N];
bool vis[N];
bool oddCycle;
bitset <N + 5> bs;

void dfs(int u, int c){
	vis[u] = 1;
	color[u] = c;
	cnt[c] ++;
	for (int i = 0; i < adj[u].size(); i++){
		int v = adj[u][i];
		if (color[u] == color[v]) {
			oddCycle = 1;
		}
		if (vis[v]) continue;
		if (color[v]) continue;
		dfs(v,  3 - c);
	}
}

int main(){
	cin >> n >> m;
	for (int i = 1; i <= m; i++){
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	bs[0] = 1;
	for (int i = 1; i <= n; i++){
		if (vis[i]) continue;
		cnt[1] = cnt[2] = 0;
		dfs(i, 1);
		bs = (bs << cnt[1]) | (bs << cnt[2]);
	}
	int mn = n / 2;
	while (bs[mn] == 0) mn --;
	if (oddCycle) puts("-1");
	else cout << 1ll * mn * (n - mn) - m << endl;
}
accuracy: 1
time_ms: 280
memory_kb: 9960
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 100010

int n, m;
vector <int> adj[N];
int cnt[3];
int color[N];
bool vis[N];
bool oddCycle;
bitset <N + 5> bs;

void dfs(int u, int c){
	vis[u] = 1;
	color[u] = c;
	cnt[c] ++;
	for (int i = 0; i < adj[u].size(); i++){
		int v = adj[u][i];
		if (color[u] == color[v]) {
			oddCycle = 1;
		}
		if (vis[v]) continue;
		if (color[v]) continue;
		dfs(v,  3 - c);
	}
}

int main(){
	cin >> n >> m;
	for (int i = 1; i <= m; i++){
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	bs[0] = 1;
	for (int i = 1; i <= n; i++){
		if (vis[i]) continue;
		cnt[1] = cnt[2] = 0;
		dfs(i, 1);
		bs = (bs << cnt[1]) | (bs << cnt[2]);
	}
	int mn = n / 2;
	while (bs[mn] == 0) mn --;
	if (oddCycle) puts("-1");
	else cout << mn * (n - mn) - m << endl;
}
accuracy: 0.8205128205128205
time_ms: 260
memory_kb: 6212
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 100010

int n, m;
vector <int> adj[N];
int cnt[3];
int color[N];
bool vis[N];
bool oddCycle;
bitset <N + 5> bs;

void dfs(int u, int c){
	vis[u] = 1;
	color[u] = c;
	cnt[c] ++;
	for (int i = 0; i < adj[u].size(); i++){
		int v = adj[u][i];
		if (vis[v]) continue;
		if (color[u] == color[v]) {
			oddCycle = 1;
		}
		if (color[v]) continue;
		dfs(v,  3 - c);
	}
}

int main(){
	cin >> n >> m;
	for (int i = 1; i <= m; i++){
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	bs[0] = 1;
	for (int i = 1; i <= n; i++){
		if (vis[i]) continue;
		cnt[1] = cnt[2] = 0;
		dfs(i, 1);
		bs = (bs << cnt[1]) | (bs << cnt[2]);
	}
	int mn = n / 2;
	while (bs[mn] == 0) mn --;
	if (oddCycle) puts("-1");
	else cout << mn * (n - mn) - m << endl;
}
accuracy: 0.8205128205128205
time_ms: 240
memory_kb: 6296
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 200010

int n, m;
vector <int> adj[N];
int cnt[3];
int color[N];
bool vis[N];
bool oddCycle;
bitset <N + 5> bs;

void dfs(int u, int c){
	vis[u] = 1;
	color[u] = c;
	cnt[c] ++;
	for (int i = 0; i < adj[u].size(); i++){
		int v = adj[u][i];
		if (vis[v]) continue;
		if (color[u] == color[v]) {
			oddCycle = 1;
		}
		if (color[v]) continue;
		dfs(v,  3 - c);
	}
}

int main(){
	cin >> n >> m;
	for (int i = 1; i <= m; i++){
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	bs[0] = 1;
	for (int i = 1; i <= n; i++){
		if (vis[i]) continue;
		cnt[1] = cnt[2] = 0;
		dfs(i, 1);
		bs = (bs << cnt[1]) | (bs << cnt[2]);
	}
	int mn = n / 2;
	while (bs[mn] == 0) mn --;
	cout << mn * (n - mn) - m << endl;
}
accuracy: 0.8205128205128205
time_ms: 620
memory_kb: 8600
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
    int N, M;
    cin >> N >> M;
    vector<vector<int>> G(N);
    rep(i,0,M) {
        int A, B;
        cin >> A >> B;
        A--, B--;
        G[A].push_back(B);
        G[B].push_back(A);
    }
    vector<int> X(N,-1);
    int ID = 0;
    queue<int> Q;
    rep(i,0,N) {
        if (X[i] >= 0) continue;
        X[i] = ID * 2;
        Q.push(i);
        while(!Q.empty()) {
            int A = Q.front();
            Q.pop();
            for(int B : G[A]) {
                if (X[B] == X[A]) {
                    cout << -1 << endl;
                    return 0;
                }
                if (X[B] == -1) {
                    X[B] = X[A] ^ 1;
                    Q.push(B);
                }
            }
        }
        ID++;
    }
    vector<pair<int,int>> P(ID, {0,0});
    rep(i,0,N) {
        if (X[i] % 2 == 0) P[X[i]/2].first++;
        else P[X[i]/2].second++;
    }
    bitset<100010> BS(0);
    BS.set(0);
    rep(i,0,ID) {
        if (P[i].first > P[i].second) swap(P[i].first, P[i].second);
        BS <<= P[i].first;
        BS |= (BS<<(P[i].second-P[i].first));
    }
    ll ANS = 0;
    rep(i,0,N+1) {
        if (BS[i]) chmax(ANS, (ll)i * (ll)(N-i));
    }
    cout << ANS - M << endl;
}
accuracy: 1
time_ms: 200
memory_kb: 9744
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
using vll=vector<ll>;
using vvll=vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)

int main(){
    
    ll N,M;
    cin>>N>>M;
    vvll G(N);
    rep(i,M){
        ll a,b;
        cin>>a>>b;
        a--;b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    bitset<100000> B;
    B[0]=1;
    vector<bool> seen(N,0);
    vll col(N,-1);
    bool bi=1;
    rep(i,N)if(!seen[i]){
        col[i]=0;
        queue<ll> Q;
        Q.push(i);
        ll X=0,Y=0;
        while(!Q.empty()){
            ll q=Q.front();
            Q.pop();
            if(seen[q])continue;
            seen[q]=1;
            (col[q]==0?X:Y)++;
            for(auto v:G[q]){
                if(col[v]!=-1&&col[v]==col[q])bi=0;
                col[v]=1-col[q];
                if(!seen[v])Q.push(v);
            }
        }
        B=(B<<X)|(B<<Y);
    }
    ll an=0;
    rep(i,N+1)if(B[i])an=max(an,i*(N-i)-M);
    cout<<(bi?an:-1)<<endl;
}
accuracy: 1
time_ms: 250
memory_kb: 10480
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
using vll=vector<ll>;
using vvll=vector<vll>;
using vvvll=vector<vvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)

int main(){
    
    ll N,M;
    cin>>N>>M;
    vvll G(N);
    rep(i,M){
        ll a,b;
        cin>>a>>b;
        a--;b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    bitset<100000> B;
    B[0]=1;

    vector<bool> seen(N,0);
    vll col(N,-1);
    rep(i,N){
        if(seen[i])continue;
        col[i]=0;
        queue<ll> Q;
        Q.push(i);
        ll X=0,Y=0;
        bool bi=1;
        while(!Q.empty()){
            ll q=Q.front();
            Q.pop();
            if(bi==0)break;
            if(seen[q])continue;
            seen[q]=1;
            (col[q]==0?X:Y)++;
            for(auto v:G[q]){
                if(col[v]!=-1&&col[v]==col[q]){
                    bi=0;
                    break;
                }
                col[v]=1-col[q];
                if(seen[v])continue;
                Q.push(v);
            }
        }
        if(!bi){
            cout<<-1<<endl;
            return 0;
        }
        if(bi){
            B=(B<<X)|(B<<Y);
        }
    }
    ll an=0;
    rep(i,N+1){
        if(B[i]){
            an=max(an,i*(N-i)-M);
        }
    }
    cout<<an<<endl;


}
accuracy: 1
time_ms: 270
memory_kb: 10504
final_rank: 7

code_snippet: #include <bits/stdc++.h>

int main() {
    int N, M;
    std::cin >> N >> M;
    std::vector<std::vector<int>> g(N);
    for (int _{} ; _ < M ; _++) {
        int a, b;
        std::cin >> a >> b;
        a--; b--;
        g[a].emplace_back(b);
        g[b].emplace_back(a);
    }
    std::vector<int> col(N, -1);
    std::vector<std::vector<int>> comp;
    auto dfs{[&](auto dfs, int v, int c) -> bool {
        col[v] = c;
        comp.back().push_back(v);
        for (auto x : g[v]) {
            if (col[x] == -1 and !dfs(dfs, x, c ^ 1)) return false;
            if (col[v] == col[x]) return false;
        } 
        return true;
    }};
    bool ok{true};
    for (int i{} ; i < N ; i++) {
        if (col[i] == -1) {
            comp.emplace_back();
            ok &= dfs(dfs, i, 0);
        }
    }
    if (!ok) {
        std::cout << -1 << '\n';
        return 0;
    }
    std::vector<int> white(comp.size()), black(comp.size());
    std::vector<int> cnt(N + 1);
    int base{};
    for (int i{} ; i < (int)comp.size() ; i++) {
        for (auto x : comp[i]) {
            if (col[x] == 1) white[i]++;
            else if (col[x] == 0) black[i]++;
            else assert(false);
        }
        base += std::min(white[i], black[i]);
        if (white[i] != black[i]) cnt[std::abs(white[i] - black[i])]++;
    }
    constexpr int S{100010};
    std::bitset<S> bst;
    bst[base] = true;
    for (int i{} ; i <= N ; i++) {
        for (int j{1} ; j <= cnt[i] ; j <<= 1) {
            bst |= (bst << (j * i));
            cnt[i] -= j;
        }
        if (cnt[i] > 0) bst |= (bst << (cnt[i] * i));
    }
    long long ans{};
    for (int i{} ; i <= N ; i++) {
        if (bst.test(i)) {
            ans = std::max(ans, (long long)i * (N - i));
        }
    }
    ans -= M;
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 13164
final_rank: 1

code_snippet: #include <bits/stdc++.h>

// https://ei1333.github.io/library/math/fft/fast-fourier-transform.hpp
namespace FastFourierTransform {
    using namespace std;
    using real = double;

    struct C {
        real x, y;

        C() : x(0), y(0) {}

        C(real x, real y) : x(x), y(y) {}

        inline C operator+(const C &c) const { return C(x + c.x, y + c.y); }

        inline C operator-(const C &c) const { return C(x - c.x, y - c.y); }

        inline C operator*(const C &c) const {
            return C(x * c.x - y * c.y, x * c.y + y * c.x);
        }

        inline C conj() const { return C(x, -y); }
    };

    const real PI = acosl(-1);
    int base = 1;
    vector<C> rts = {{0, 0}, {1, 0}};
    vector<int> rev = {0, 1};

    void ensure_base(int nbase) {
        if (nbase <= base) return;
        rev.resize(1 << nbase);
        rts.resize(1 << nbase);
        for (int i = 0; i < (1 << nbase); i++) {
            rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
        }
        while (base < nbase) {
            real angle = PI * 2.0 / (1 << (base + 1));
            for (int i = 1 << (base - 1); i < (1 << base); i++) {
                rts[i << 1] = rts[i];
                real angle_i = angle * (2 * i + 1 - (1 << base));
                rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
            }
            ++base;
        }
    }

    void fft(vector<C> &a, int n) {
        assert((n & (n - 1)) == 0);
        int zeros = __builtin_ctz(n);
        ensure_base(zeros);
        int shift = base - zeros;
        for (int i = 0; i < n; i++) {
            if (i < (rev[i] >> shift)) {
                swap(a[i], a[rev[i] >> shift]);
            }
        }
        for (int k = 1; k < n; k <<= 1) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    C z = a[i + j + k] * rts[j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j] = a[i + j] + z;
                }
            }
        }
    }

    vector<int64_t> multiply(const vector<int64_t> &a, const vector<int64_t> &b) {
        int need = (int)a.size() + (int)b.size() - 1;
        int nbase = 1;
        while ((1 << nbase) < need) nbase++;
        ensure_base(nbase);
        int sz = 1 << nbase;
        vector<C> fa(sz);
        for (int i = 0; i < sz; i++) {
            int x = (i < (int)a.size() ? a[i] : 0);
            int y = (i < (int)b.size() ? b[i] : 0);
            fa[i] = C(x, y);
        }
        fft(fa, sz);
        C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
        for (int i = 0; i <= (sz >> 1); i++) {
            int j = (sz - i) & (sz - 1);
            C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
            fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
            fa[i] = z;
        }
        for (int i = 0; i < (sz >> 1); i++) {
            C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
            C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * rts[(sz >> 1) + i];
            fa[i] = A0 + A1 * s;
        }
        fft(fa, sz >> 1);
        vector<int64_t> ret(need);
        for (int i = 0; i < need; i++) {
            ret[i] = llround(i & 1 ? fa[i >> 1].y : fa[i >> 1].x);
        }
        return ret;
    }

};  // namespace FastFourierTransform

using FastFourierTransform::multiply;

using P = std::pair<int, int>;
P add(P lhs, P rhs) {
    return {lhs.first + rhs.first, lhs.second + rhs.second};
}

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector graph(n, std::vector<int>());
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    std::vector<int> color(n, -1);
    auto dfs = [&](auto self, int u, int c) -> std::pair<int, int> {
        color[u] = c;
        P res = {0, 0};
        if (c == 0) res.first++;
        if (c == 1) res.second++;
        for (auto v: graph[u]) {
            if (color[v] == -1) {
                auto temp = self(self, v, c ^ 1);
                if (temp.first == -1) return temp;
                res = add(res, temp);
            } else if (color[v] == color[u]) {
                return {-1, -1};
            }
        }
        return res;
    };
    std::vector<std::pair<int, int>> ps;
    for (int i = 0; i < n; i++) {
        if (color[i] == -1) {
            auto res = dfs(dfs, i, 0);
            if (res.first == -1) {
                std::cout << -1 << '\n';
                return 0;
            }
            ps.emplace_back(res);
        }
    }
    int offset = 0;
    auto div = [&](auto self, int left, int right) -> std::vector<int64_t> {
        if (left + 1 == right) {
            auto p = ps[left];
            int delta = std::abs(p.first - p.second);
            offset += delta;
            std::vector<int64_t> res(2 * delta + 1);
            res.front() = 1;
            res.back() = 1;
            return res;
        }
        int mid = (left + right) / 2;
        auto temp = multiply(self(self, left, mid), self(self, mid, right));
        for (auto& v: temp) {
            if (v > 0) v = 1;
        }
        return temp;
    };
    auto all_prod = div(div, 0, ps.size());
    long long ans = 0;
    for (int i = 0; i < (int)all_prod.size(); i++) {
        if ((i - offset + n) % 2 != 0) continue;
        if (all_prod[i] > 0) {
            int diff = i - offset;
            int lhs = (diff + n) / 2;
            int rhs = n - lhs;
            ans = std::max(ans, (long long)lhs * rhs - m);
        }
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 180
memory_kb: 23912
final_rank: 12

code_snippet: #include <bits/stdc++.h>

// https://ei1333.github.io/library/math/fft/fast-fourier-transform.hpp
namespace FastFourierTransform {
    using namespace std;
    using real = double;

    struct C {
        real x, y;

        C() : x(0), y(0) {}

        C(real x, real y) : x(x), y(y) {}

        inline C operator+(const C &c) const { return C(x + c.x, y + c.y); }

        inline C operator-(const C &c) const { return C(x - c.x, y - c.y); }

        inline C operator*(const C &c) const {
            return C(x * c.x - y * c.y, x * c.y + y * c.x);
        }

        inline C conj() const { return C(x, -y); }
    };

    const real PI = acosl(-1);
    int base = 1;
    vector<C> rts = {{0, 0}, {1, 0}};
    vector<int> rev = {0, 1};

    void ensure_base(int nbase) {
        if (nbase <= base) return;
        rev.resize(1 << nbase);
        rts.resize(1 << nbase);
        for (int i = 0; i < (1 << nbase); i++) {
            rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
        }
        while (base < nbase) {
            real angle = PI * 2.0 / (1 << (base + 1));
            for (int i = 1 << (base - 1); i < (1 << base); i++) {
                rts[i << 1] = rts[i];
                real angle_i = angle * (2 * i + 1 - (1 << base));
                rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
            }
            ++base;
        }
    }

    void fft(vector<C> &a, int n) {
        assert((n & (n - 1)) == 0);
        int zeros = __builtin_ctz(n);
        ensure_base(zeros);
        int shift = base - zeros;
        for (int i = 0; i < n; i++) {
            if (i < (rev[i] >> shift)) {
                swap(a[i], a[rev[i] >> shift]);
            }
        }
        for (int k = 1; k < n; k <<= 1) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    C z = a[i + j + k] * rts[j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j] = a[i + j] + z;
                }
            }
        }
    }

    vector<real> multiply(const vector<real> &a, const vector<real> &b) {
        int need = (int)a.size() + (int)b.size() - 1;
        int nbase = 1;
        while ((1 << nbase) < need) nbase++;
        ensure_base(nbase);
        int sz = 1 << nbase;
        vector<C> fa(sz);
        for (int i = 0; i < sz; i++) {
            double x = (i < (int)a.size() ? a[i] : 0);
            double y = (i < (int)b.size() ? b[i] : 0);
            fa[i] = C(x, y);
        }
        fft(fa, sz);
        C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
        for (int i = 0; i <= (sz >> 1); i++) {
            int j = (sz - i) & (sz - 1);
            C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
            fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
            fa[i] = z;
        }
        for (int i = 0; i < (sz >> 1); i++) {
            C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
            C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * rts[(sz >> 1) + i];
            fa[i] = A0 + A1 * s;
        }
        fft(fa, sz >> 1);
        vector<real> ret(need);
        for (int i = 0; i < need; i++) {
            ret[i] = (i & 1 ? fa[i >> 1].y : fa[i >> 1].x);
        }
        return ret;
    }
};  // namespace FastFourierTransform

using FastFourierTransform::multiply;

using P = std::pair<int, int>;
P add(P lhs, P rhs) {
    return {lhs.first + rhs.first, lhs.second + rhs.second};
}

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector graph(n, std::vector<int>());
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    std::vector<int> color(n, -1);
    auto dfs = [&](auto self, int u, int c) -> std::pair<int, int> {
        color[u] = c;
        P res = {0, 0};
        if (c == 0) res.first++;
        if (c == 1) res.second++;
        for (auto v: graph[u]) {
            if (color[v] == -1) {
                auto temp = self(self, v, c ^ 1);
                if (temp.first == -1) return temp;
                res = add(res, temp);
            } else if (color[v] == color[u]) {
                return {-1, -1};
            }
        }
        return res;
    };
    std::vector<std::pair<int, int>> ps;
    for (int i = 0; i < n; i++) {
        if (color[i] == -1) {
            auto res = dfs(dfs, i, 0);
            if (res.first == -1) {
                std::cout << -1 << '\n';
                return 0;
            }
            ps.emplace_back(res);
        }
    }
    int offset = 0;
    auto div = [&](auto self, int left, int right) -> std::vector<double> {
        if (left + 1 == right) {
            auto p = ps[left];
            int delta = std::abs(p.first - p.second);
            offset += delta;
            std::vector<double> res(2 * delta + 1);
            res.front() = 1;
            res.back() = 1;
            return res;
        }
        int mid = (left + right) / 2;
        return multiply(self(self, left, mid), self(self, mid, right));
    };
    auto all_prod = div(div, 0, ps.size());
    const double EPS = 1e-5;
    auto zero = [&](double x) {
        return std::abs(x) < EPS;
    };
    long long ans = 0;
    for (int i = 0; i < (int)all_prod.size(); i++) {
        if ((i - offset + n) % 2 != 0) continue;
        if (!zero(all_prod[i])) {
            int diff = i - offset;
            assert((diff + n) % 2 == 0);
            int lhs = (diff + n) / 2;
            int rhs = n - lhs;
            assert(lhs >= 0);
            assert(rhs >= 0);
            assert(lhs + rhs == n);
            assert(std::abs(lhs - rhs) == std::abs(diff));
            ans = std::max(ans, (long long)lhs * rhs - m);
        }
    }
    std::cout << ans << '\n';
}
accuracy: 0.8461538461538461
time_ms: 100
memory_kb: 20756
final_rank: 17

code_snippet: #include <bits/stdc++.h>

// https://ei1333.github.io/library/math/fft/fast-fourier-transform.hpp
namespace FastFourierTransform {
    using namespace std;
    using real = double;

    struct C {
        real x, y;

        C() : x(0), y(0) {}

        C(real x, real y) : x(x), y(y) {}

        inline C operator+(const C &c) const { return C(x + c.x, y + c.y); }

        inline C operator-(const C &c) const { return C(x - c.x, y - c.y); }

        inline C operator*(const C &c) const {
            return C(x * c.x - y * c.y, x * c.y + y * c.x);
        }

        inline C conj() const { return C(x, -y); }
    };

    const real PI = acosl(-1);
    int base = 1;
    vector<C> rts = {{0, 0}, {1, 0}};
    vector<int> rev = {0, 1};

    void ensure_base(int nbase) {
        if (nbase <= base) return;
        rev.resize(1 << nbase);
        rts.resize(1 << nbase);
        for (int i = 0; i < (1 << nbase); i++) {
            rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
        }
        while (base < nbase) {
            real angle = PI * 2.0 / (1 << (base + 1));
            for (int i = 1 << (base - 1); i < (1 << base); i++) {
                rts[i << 1] = rts[i];
                real angle_i = angle * (2 * i + 1 - (1 << base));
                rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
            }
            ++base;
        }
    }

    void fft(vector<C> &a, int n) {
        assert((n & (n - 1)) == 0);
        int zeros = __builtin_ctz(n);
        ensure_base(zeros);
        int shift = base - zeros;
        for (int i = 0; i < n; i++) {
            if (i < (rev[i] >> shift)) {
                swap(a[i], a[rev[i] >> shift]);
            }
        }
        for (int k = 1; k < n; k <<= 1) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    C z = a[i + j + k] * rts[j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j] = a[i + j] + z;
                }
            }
        }
    }

    vector<real> multiply(const vector<real> &a, const vector<real> &b) {
        int need = (int)a.size() + (int)b.size() - 1;
        int nbase = 1;
        while ((1 << nbase) < need) nbase++;
        ensure_base(nbase);
        int sz = 1 << nbase;
        vector<C> fa(sz);
        for (int i = 0; i < sz; i++) {
            double x = (i < (int)a.size() ? a[i] : 0);
            double y = (i < (int)b.size() ? b[i] : 0);
            fa[i] = C(x, y);
        }
        fft(fa, sz);
        C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
        for (int i = 0; i <= (sz >> 1); i++) {
            int j = (sz - i) & (sz - 1);
            C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
            fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
            fa[i] = z;
        }
        for (int i = 0; i < (sz >> 1); i++) {
            C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
            C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * rts[(sz >> 1) + i];
            fa[i] = A0 + A1 * s;
        }
        fft(fa, sz >> 1);
        vector<real> ret(need);
        for (int i = 0; i < need; i++) {
            ret[i] = (i & 1 ? fa[i >> 1].y : fa[i >> 1].x);
        }
        return ret;
    }
};  // namespace FastFourierTransform

using FastFourierTransform::multiply;

using P = std::pair<int, int>;
P add(P lhs, P rhs) {
    return {lhs.first + rhs.first, lhs.second + rhs.second};
}

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector graph(n, std::vector<int>());
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    std::vector<int> color(n, -1);
    auto dfs = [&](auto self, int u, int c) -> std::pair<int, int> {
        color[u] = c;
        P res = {0, 0};
        if (c == 0) res.first++;
        if (c == 1) res.second++;
        for (auto v: graph[u]) {
            if (color[v] == -1) {
                auto temp = self(self, v, c ^ 1);
                if (temp.first == -1) return temp;
                res = add(res, temp);
            } else if (color[v] == color[u]) {
                return {-1, -1};
            }
        }
        return res;
    };
    std::vector<std::pair<int, int>> ps;
    for (int i = 0; i < n; i++) {
        if (color[i] == -1) {
            auto res = dfs(dfs, i, 0);
            if (res.first == -1) {
                std::cout << -1 << '\n';
                return 0;
            }
            ps.emplace_back(res);
        }
    }
    int offset = 0;
    auto div = [&](auto self, int left, int right) -> std::vector<double> {
        if (left + 1 == right) {
            auto p = ps[left];
            int delta = std::abs(p.first - p.second);
            offset += delta;
            std::vector<double> res(2 * delta + 1);
            res.front() = 1;
            res.back() = 1;
            return res;
        }
        int mid = (left + right) / 2;
        return multiply(self(self, left, mid), self(self, mid, right));
    };
    auto all_prod = div(div, 0, ps.size());
    const double EPS = 1e-12;
    auto zero = [&](double x) {
        return std::abs(x) < EPS;
    };
    long long ans = 0;
    for (int i = 0; i < (int)all_prod.size(); i++) {
        if ((i - offset + n) % 2 != 0) continue;
        if (!zero(all_prod[i])) {
            int diff = i - offset;
            assert((diff + n) % 2 == 0);
            int lhs = (diff + n) / 2;
            int rhs = n - lhs;
            assert(lhs >= 0);
            assert(rhs >= 0);
            assert(lhs + rhs == n);
            assert(std::abs(lhs - rhs) == std::abs(diff));
            ans = std::max(ans, (long long)lhs * rhs - m);
        }
    }
    std::cout << ans << '\n';
}
accuracy: 0.8461538461538461
time_ms: 100
memory_kb: 20712
final_rank: 16

code_snippet: #include <bits/stdc++.h>

// https://ei1333.github.io/library/math/fft/fast-fourier-transform.hpp
namespace FastFourierTransform {
    using namespace std;
    using real = double;

    struct C {
        real x, y;

        C() : x(0), y(0) {}

        C(real x, real y) : x(x), y(y) {}

        inline C operator+(const C &c) const { return C(x + c.x, y + c.y); }

        inline C operator-(const C &c) const { return C(x - c.x, y - c.y); }

        inline C operator*(const C &c) const {
            return C(x * c.x - y * c.y, x * c.y + y * c.x);
        }

        inline C conj() const { return C(x, -y); }
    };

    const real PI = acosl(-1);
    int base = 1;
    vector<C> rts = {{0, 0}, {1, 0}};
    vector<int> rev = {0, 1};

    void ensure_base(int nbase) {
        if (nbase <= base) return;
        rev.resize(1 << nbase);
        rts.resize(1 << nbase);
        for (int i = 0; i < (1 << nbase); i++) {
            rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
        }
        while (base < nbase) {
            real angle = PI * 2.0 / (1 << (base + 1));
            for (int i = 1 << (base - 1); i < (1 << base); i++) {
                rts[i << 1] = rts[i];
                real angle_i = angle * (2 * i + 1 - (1 << base));
                rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
            }
            ++base;
        }
    }

    void fft(vector<C> &a, int n) {
        assert((n & (n - 1)) == 0);
        int zeros = __builtin_ctz(n);
        ensure_base(zeros);
        int shift = base - zeros;
        for (int i = 0; i < n; i++) {
            if (i < (rev[i] >> shift)) {
                swap(a[i], a[rev[i] >> shift]);
            }
        }
        for (int k = 1; k < n; k <<= 1) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    C z = a[i + j + k] * rts[j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j] = a[i + j] + z;
                }
            }
        }
    }

    vector<real> multiply(const vector<real> &a, const vector<real> &b) {
        int need = (int)a.size() + (int)b.size() - 1;
        int nbase = 1;
        while ((1 << nbase) < need) nbase++;
        ensure_base(nbase);
        int sz = 1 << nbase;
        vector<C> fa(sz);
        for (int i = 0; i < sz; i++) {
            double x = (i < (int)a.size() ? a[i] : 0);
            double y = (i < (int)b.size() ? b[i] : 0);
            fa[i] = C(x, y);
        }
        fft(fa, sz);
        C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
        for (int i = 0; i <= (sz >> 1); i++) {
            int j = (sz - i) & (sz - 1);
            C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
            fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
            fa[i] = z;
        }
        for (int i = 0; i < (sz >> 1); i++) {
            C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
            C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * rts[(sz >> 1) + i];
            fa[i] = A0 + A1 * s;
        }
        fft(fa, sz >> 1);
        vector<real> ret(need);
        for (int i = 0; i < need; i++) {
            ret[i] = (i & 1 ? fa[i >> 1].y : fa[i >> 1].x);
        }
        return ret;
    }
};  // namespace FastFourierTransform

using FastFourierTransform::multiply;

using P = std::pair<int, int>;
P add(P lhs, P rhs) {
    return {lhs.first + rhs.first, lhs.second + rhs.second};
}

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector graph(n, std::vector<int>());
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    std::vector<int> color(n, -1);
    auto dfs = [&](auto self, int u, int c) -> std::pair<int, int> {
        color[u] = c;
        P res = {0, 0};
        if (c == 0) res.first++;
        if (c == 1) res.second++;
        for (auto v: graph[u]) {
            if (color[v] == -1) {
                auto temp = self(self, v, c ^ 1);
                if (temp.first == -1) return temp;
                res = add(res, temp);
            } else if (color[v] == color[u]) {
                return {-1, -1};
            }
        }
        return res;
    };
    std::vector<std::pair<int, int>> ps;
    for (int i = 0; i < n; i++) {
        if (color[i] == -1) {
            auto res = dfs(dfs, i, 0);
            if (res.first == -1) {
                std::cout << -1 << '\n';
                return 0;
            }
            ps.emplace_back(res);
        }
    }
    int offset = 0;
    auto div = [&](auto self, int left, int right) -> std::vector<double> {
        if (left + 1 == right) {
            auto p = ps[left];
            int delta = std::abs(p.first - p.second);
            offset += delta;
            std::vector<double> res(2 * delta + 1);
            res.front() = 1;
            res.back() = 1;
            return res;
        }
        int mid = (left + right) / 2;
        return multiply(self(self, left, mid), self(self, mid, right));
    };
    auto all_prod = div(div, 0, ps.size());
    const double EPS = 1e-8;
    auto zero = [&](double x) {
        return std::abs(x) < EPS;
    };
    long long ans = 0;
    for (int i = 0; i < (int)all_prod.size(); i++) {
        if ((i - offset + n) % 2 != 0) continue;
        if (!zero(all_prod[i])) {
            int diff = i - offset;
            assert((diff + n) % 2 == 0);
            int lhs = (diff + n) / 2;
            int rhs = n - lhs;
            assert(lhs >= 0);
            assert(rhs >= 0);
            assert(lhs + rhs == n);
            assert(std::abs(lhs - rhs) == std::abs(diff));
            ans = std::max(ans, (long long)lhs * rhs - m);
        }
    }
    std::cout << ans << '\n';
}
accuracy: 0.8461538461538461
time_ms: 100
memory_kb: 20468
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using P = std::pair<int, int>;
P add(P lhs, P rhs) {
    return {lhs.first + rhs.first, lhs.second + rhs.second};
}

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector graph(n, std::vector<int>());
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    std::vector<int> color(n, -1);
    auto dfs = [&](auto self, int u, int c) -> std::pair<int, int> {
        color[u] = c;
        P res = {0, 0};
        if (c == 0) res.first++;
        if (c == 1) res.second++;
        for (auto v: graph[u]) {
            if (color[v] == -1) {
                auto temp = self(self, v, c ^ 1);
                if (temp.first == -1) return temp;
                res = add(res, temp);
            } else if (color[v] == color[u]) {
                return {-1, -1};
            }
        }
        return res;
    };
    constexpr int N = 200005;
    using Bitset = std::bitset<N>;
    Bitset state;
    state.set(0);
    int offset = 0;
    for (int i = 0; i < n; i++) {
        if (color[i] == -1) {
            auto res = dfs(dfs, i, 0);
            if (res.first == -1) {
                std::cout << -1 << '\n';
                return 0;
            }
            int delta = std::abs(res.first - res.second);
            state |= state << 2 * delta;
            offset += delta;
        }
    }

    long long ans = 0;
    for (int i = 0; i < N; i++) {
        if ((i - offset + n) % 2 != 0) continue;
        if (state[i]) {
            int diff = i - offset;
            assert((diff + n) % 2 == 0);
            int lhs = (diff + n) / 2;
            int rhs = n - lhs;
            assert(lhs >= 0);
            assert(rhs >= 0);
            assert(lhs + rhs == n);
            assert(std::abs(lhs - rhs) == std::abs(diff));
            ans = std::max(ans, (long long)lhs * rhs - m);
        }
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 550
memory_kb: 9640
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;}
istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;}
#endif
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define esper(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define reps(i,a,n) for(int i=(a);i<(n);i++)
#define rep(i,n) reps(i,0,n)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<x<<'\n',static_cast<void>(0)
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
void SOLVE();
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout<<fixed<<setprecision(16);
  #ifdef LOCAL
  clock_t start=clock();
  #endif
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
  #ifdef LOCAL
  cerr<<"time:";
  cerr<<(clock()-start)/1000;
  cerr<<"ms\n";
  #endif
}
struct UF{
  vector<int>par;
  UF(int n):par(n,-1){}
  int root(int u){
    if(par[u]<0)return u;
    return par[u]=root(par[u]);
  }
  void merge(int u,int v){
    int ru=root(u),rv=root(v);
    if(ru==rv)return;
    if(par[ru]>par[rv])swap(ru,rv);
    par[ru]+=par[rv];
    par[rv]=ru;
  }
  bool same(int u,int v){return root(u)==root(v);}
  vector<vector<int>>gr(){
    vector<vector<int>>ret(par.size());
    rep(i,par.size())ret[root(i)].push_back(i);
    vector<vector<int>>ret2;
    rep(i,ret.size())if(ret[i].size())ret2.push_back(ret[i]);
    return ret2;
  }
};
void SOLVE(){
  int n,m;
  cin>>n>>m;
  UF uf(n*2),uf2(n);
  rep(i,m){
    int u,v;
    cin>>u>>v;
    u--,v--;
    uf.merge(u,v+n);
    uf.merge(v,u+n);
    uf2.merge(u,v);
  }
  auto g=uf2.gr();
  auto g2=uf.gr();
  rep(i,n)if(uf.same(i,i+n))fin(-1);
  vector<bool>seen(n,false);
  vector<pair<int,int>>p;
  for(auto i:g2){
    if(i[0]>=n&&seen[i[0]-n])continue;
    if(i[0]<n&&seen[i[0]])continue;
    int c=0;
    rep(j,i.size()){
      if(i[j]<n)c++,seen[i[j]]=true;
      else seen[i[j]-n]=true;
    }
    p.push_back({c,i.size()-c});
  }
  debug(p);
  bitset<50001>dp;
  dp[0]=1;
  for(auto [x,y]:p){
    dp=(dp<<x)|(dp<<y);
  }
  int mx=-1;
  rep(i,n/2+1)if(dp[i])mx=i;
  debug(mx);
  cout<<ll(mx)*(n-mx)-m<<endl;
}
accuracy: 1
time_ms: 150
memory_kb: 32584
final_rank: 14

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "B.cpp"

int main() {
    int n = in(), m = in();
    vector<vector<int>> g(n);
    for(int i : rep(m)) {
        int u = in(), v = in(); u--, v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    vector<pair<int,int>> ab;
    vector<int> c(n, -1);
    for(int i : rep(n)) if(c[i] == -1) {
        queue<int> q;
        q.push(i);
        c[i] = 0;
        int a[] = {1, 0};
        while(not q.empty()) {
            int u = q.front(); q.pop();
            for(int v : g[u]) {
                if(c[v] == -1) {
                    c[v] = 1 - c[u];
                    a[c[v]] += 1;
                    q.push(v);
                } else if(c[v] == c[u]) {
                    return print(-1);
                }
            }
        }
        ab.push_back({a[0], a[1]});
    }

    const int max_n = 100'100;
    bitset<max_n> dp;
    dp[0] = 1;
    for(auto [a, b] : ab) dp = (dp << a) | (dp << b);

    i64 ans = 0;
    for(int s = 0; s <= n; s++) {
        if(dp[s]) {
            int t = n - s;
            chmax(ans, i64(s) * t - m);
        }
    }
    print(ans);
}
accuracy: 1
time_ms: 310
memory_kb: 9656
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

using bs = bitset<50000 + 10>;

void calc()
{
	ll N, M; cin >> N >> M;
	vector<vector<ll>> graph(N);
	for (int i = 0; i < M; ++i)
	{
		ll a, b; cin >> a >> b;
		a--, b--;
		graph[a].emplace_back(b);
		graph[b].emplace_back(a);
	}
	
	vector<int> color(N, -1);
	vector<pair<int, int>> bw;
	bool is_bip = true;
	{
		vector<bool> seen(N, false);
		
		for (int i = 0; i < N; ++i)
		{
			if (seen[i]) continue;
			
			int num0 = 0, num1 = 0;
			
			seen[i] = true;
			color[i] = 0;
			queue<int> que;
			que.emplace(i);
			
			while (!que.empty())
			{
				int v = que.front();
				que.pop();
				
				(color[v] == 0 ? num0++ : num1++);
				
				for (auto nv : graph[v])
				{
					if (seen[nv])
					{
						if (color[v] == color[nv]) is_bip = false;
						continue;
					}
					seen[nv] = true;
					color[nv] = color[v] ^ 1;
					que.emplace(nv);
				}
			}
			
			bw.emplace_back(make_pair(num0, num1));
		}
	}
	
	if (!is_bip)
	{
		cout << -1 << endl;
		return;
	}
	
	bs base(1);
	for (auto [n0, n1] : bw)
	{
		base = ((base << n0) | (base << n1));
		// base |= 1;
	}
	
	ll mx = 0;
	for (ll i = 0; i < base.size(); ++i)
	{
		if (base[i]) {mx = max(mx, i * (N-i));}
	}
	mx -= M;
	
	cout << mx << endl;
	
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 10056
final_rank: 3