#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
template <typename T>
inline T BigMod(T A, T B, T M = MOD) {
  T ret = 1;
  while (B) {
    if (B & 1) ret = (ret * A) % M;
    A = (A * A) % M;
    B = B >> 1;
  }
  return ret;
}
template <typename T>
inline T EGCD(T a, T b, T &x, T &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  T x1, y1;
  T d = EGCD(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
template <typename T>
inline T LCM(T x, T y) {
  T g = __gcd(x, y);
  return (x / g) * y;
}
template <typename T>
inline T Distance(T x1, T y1, T x2, T y2) {
  return sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
}
template <typename T>
inline T Area(T Ax, T Ay, T Bx, T By, T Cx, T Cy) {
  T ret = Ax * (By - Cy) + Bx * (Cy - Ay) + Cx * (Ay - By);
  if (ret < 0) return ret = -ret;
  return ret;
}
bool Check(int N, int pos) { return (bool)(N & (1 << pos)); }
int Set(int N, int pos) { return (N | (1 << pos)); }
int fx[] = {-1, +0, +1, +0, +1, +1, -1, -1, +0};
int fy[] = {+0, -1, +0, +1, +1, -1, +1, -1, +0};
template <typename T>
inline T CRT(T num[], T rem[], T k) {
  T prod = 1, result = 0;
  for (T i = 0; i < k; i++) prod *= num[i];
  for (T i = 0; i < k; i++) {
    T pp = prod / num[i];
    result += rem[i] * inv(pp, num[i]) * pp;
  }
  return result % prod;
}
const int FacN = 1000000;
long long Fac[FacN + 5];
void Facgen() {
  Fac[0] = 1;
  for (int i = 1; i <= FacN; i++) Fac[i] = (Fac[i - 1] * i) % MOD;
}
template <typename T>
inline T COM(T a, T b) {
  if (a < b) return 0;
  return ((Fac[a] * BigMod((Fac[b] * Fac[a - b]) % MOD, MOD - 2, MOD)) % MOD +
          MOD) %
         MOD;
}
const int N = 1e5;
long long n, m;
vector<int> G[N + 5];
int vis[N + 5], bip = 1, cnt = 0, ct = 0;
void dfs(int node, int c) {
  if (vis[node] != -1) {
    if (vis[node] != c) {
      bip = 0;
      return;
    } else {
      return;
    }
  }
  cnt++;
  if (c == 1) ct++;
  vis[node] = c;
  for (int i : G[node]) dfs(i, 1 - c);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(nullptr);
  memset(vis, -1, sizeof(vis));
  cin >> n >> m;
  if (m == 0) {
    cout << 3 << " " << ((long long)n * (n - 1) * (n - 2)) / 6 << "\n";
    return 0;
  }
  while (m--) {
    int a, b;
    cin >> a >> b;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  int mx = 0;
  vector<int> v, bp;
  for (int i = 1; i <= n; i++) {
    cnt = ct = 0;
    if (vis[i] == -1) {
      dfs(i, 1);
      mx = max(mx, cnt);
      v.push_back(cnt);
      bp.push_back(ct);
    }
  }
  if (!bip) {
    cout << "0 1\n";
    return 0;
  }
  if (mx == 2) {
    long long answer = 0;
    for (int i = 0; i < v.size(); i++) {
      if (v[i] == 2) answer += (long long)(n - 2);
    }
    cout << 2 << " " << answer << "\n";
    return 0;
  }
  long long ans = 0;
  for (int i = 0; i < bp.size(); i++) {
    long long A = bp[i];
    long long B = v[i] - bp[i];
    ans += (A * (A - 1)) / 2 + (B * (B - 1)) / 2;
  }
  cout << 1 << " " << ans << "\n";
}
