#include <bits/stdc++.h>
using namespace std;
const long long inf = INT_MAX, df = 2e5 + 7;
long long k, m, n, ret, tmp, ans, head[df], blk[df], cur;
struct edge {
  long long to, nxt;
} e[df << 2];
inline long long read() {
  long long x = 0, y = 1;
  char ch = getchar();
  while (ch > '9' || ch < '0') y = (ch == '-') ? -1 : 1, ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
  return x * y;
}
inline void add(long long u, long long v) {
  e[k] = (edge){v, head[u]}, head[u] = k++;
}
void dfs(long long u, long long x) {
  blk[u] = x;
  ret += (!x);
  tmp += (x == 1);
  for (long long i = head[u]; ~i; i = e[i].nxt) {
    long long v = e[i].to;
    if (blk[v] == -1) dfs(v, x ^ 1);
    if (blk[v] == blk[u] && blk[u] != -1) return cur = 1, void();
  }
  return;
}
int main() {
  n = read(), m = read();
  if (!m) return printf("3 %lld", n * (n - 1) * (n - 2) / 6), 0;
  for (long long i = (1); i <= (n); ++i) head[i] = blk[i] = -1;
  for (long long i = (1); i <= (m); ++i) {
    long long u = read(), v = read();
    add(u, v), add(v, u);
  }
  for (long long i = (1); i <= (n); ++i) {
    if (blk[i] == -1) {
      ret = tmp = 0;
      dfs(i, 0);
      ans += ret * (ret - 1) / 2;
      ans += tmp * (tmp - 1) / 2;
      if (cur == 1) return puts("0 1"), 0;
    }
  }
  if (ans) return printf("1 %lld\n", ans), 0;
  for (long long i = (1); i <= (n); ++i)
    if (head[i] != -1) ans += n - 2;
  return printf("2 %lld\n", ans / 2), 0;
}
