#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;
}
