func_code_string: #include <bits/stdc++.h>   using namespace std;   struct disjoint_set {     vector<int> p;     disjoint_set(int n) : p(n, -1) {}     bool share(int a, int b) { return root(a) == root(b); }     int sz(int u) { return -p[root(u)]; }     int root(int u) { return p[u] < 0 ? u : p[u] = root(p[u]); }     bool merge(int u, int v) {       u = root(u), v = root(v);       if (u == v) return false;       if (p[u] > p[v]) swap(u, v);       p[u] += p[v], p[v] = u;       return true;     }   };   template <class T>   struct graph {     struct edge {       int from, to;       T cost;     };     int n;     vector<edge> edges;     vector<vector<int>> adj;     function<bool(int)> ignore;     graph(int n) : n(n), adj(n), ignore(nullptr) {}     int link(int u, int v, T w = 1) {       int id = (int)edges.size();       adj[u].push_back(id), adj[v].push_back(id), edges.push_back({u, v, w});       return id;     }     int orient(int u, int v, T w = 1) {       int id = (int)edges.size();       adj[u].push_back(id), edges.push_back({u, v, w});       return id;     }     graph reversed() const {       graph res(n);       for (auto &e : edges) {         res.orient(e.to, e.from, e.cost);       }       return res;     }   };   template <class T, class U>   T &ctmax(T &x, const U &y) {     return x = max<T>(x, y);   }   template <class T, class U>   T &ctmin(T &x, const U &y) {     return x = min<T>(x, y);   }   int main() {     cin.tie(0)->sync_with_stdio(0);     cin.exceptions(ios::badbit | ios::failbit);     int n, m;     cin >> n >> m;     disjoint_set dsu(n << 1);     graph<int> g(n);     for (auto i = 0; i < m; ++i) {       int u, v;       cin >> u >> v, --u, --v;       dsu.merge(u, v + n), dsu.merge(v, u + n);       if (dsu.share(u, u + n)) {         cout <<  -1 n ;         return 0;       }       g.link(u, v);     }     int res = 0;     vector<int> dist(n, -1), vis(n);     for (auto s = 0; s < n; ++s) {       if (!vis[s]) {         vector<int> cur;         function<void(int)> dfs = [&](int u) {           vis[u] = true;           cur.push_back(u);           for (auto id : g.adj[u]) {             auto &e = g.edges[id];             int v = u ^ e.from ^ e.to;             if (!vis[v]) {               dfs(v);             }           }         };         dfs(s);         auto get_max_dist = [&](int s) {           for (auto u : cur) {             dist[u] = -1;           }           deque<int> dq{s};           dist[s] = 0;           int res = 0;           while (!dq.empty()) {             int u = dq.front();             dq.pop_front();             for (auto id : g.adj[u]) {               auto &e = g.edges[id];               int v = u ^ e.from ^ e.to;               if (!~dist[v]) {                 dq.push_back(v);                 res = dist[v] = dist[u] + 1;               }             }           }           return res;         };         int cur_max = 0;         for (auto s : cur) {           ctmax(cur_max, get_max_dist(s));         }         res += cur_max;       }     }     cout << res <<   n ;     return 0;   }   