Problem: Berland is very concerned with privacy, so almost all plans and blueprints are secret. However, a spy of the neighboring state managed to steal the Bertown subway scheme.

The Bertown Subway has n stations, numbered from 1 to n, and m bidirectional tunnels connecting them. All Bertown Subway consists of lines. To be more precise, there are two types of lines: circular and radial.

A radial line is a sequence of stations v1, ..., vk (k > 1), where stations vi and vi + 1 (i < k) are connected by a tunnel and no station occurs in the line more than once (vi ≠ vj for i ≠ j).

A loop line is a series of stations, v1, ..., vk (k > 2), where stations vi и vi + 1 are connected by a tunnel. In addition, stations v1 and vk are also connected by a tunnel. No station is occurs in the loop line more than once.

Note that a single station can be passed by any number of lines.

According to Berland standards, there can't be more than one tunnel between two stations and each tunnel belongs to exactly one line. Naturally, each line has at least one tunnel. Between any two stations there is the way along the subway tunnels. In addition, in terms of graph theory, a subway is a vertex cactus: if we consider the subway as a graph in which the stations are the vertexes and the edges are tunnels, then each vertex lies on no more than one simple cycle.

Unfortunately, scheme, stolen by the spy, had only the stations and the tunnels. It was impossible to determine to which line every tunnel corresponds. But to sabotage successfully, the spy needs to know what minimum and maximum number of lines may be in the Bertown subway.

Help him!

Input

The first line contains two integers n and m (1 ≤ n ≤ 105, 0 ≤ m ≤ 3·105) — the number of stations and the number of tunnels, correspondingly.

Each of the next m lines contain two integers — the numbers of stations connected by the corresponding tunnel. The stations are numbered with integers from 1 to n.

It is guaranteed that the graph that corresponds to the subway has no multiple edges or loops, it is connected and it is a vertex cactus.

Output

Print two numbers — the minimum and maximum number of lines correspondingly.

Examples

Input

3 3
1 2
2 3
3 1


Output

1 3


Input

8 8
1 2
2 3
3 4
4 5
6 4
4 7
7 2
2 8


Output

2 8


Input

6 6
1 2
2 3
2 5
5 6
3 4
3 5


Output

3 6

Note

The subway scheme with minimum possible number of lines for the second sample is: 

<image>

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
long long fpm(long long b, long long e, long long m) {
  long long t = 1;
  for (; e; e >>= 1, b = b * b % m) e & 1 ? t = t * b % m : 0;
  return t;
}
template <class T>
inline bool chkmin(T &a, T b) {
  return a > b ? a = b, true : false;
}
template <class T>
inline bool chkmax(T &a, T b) {
  return a < b ? a = b, true : false;
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class edge>
struct Graph {
  vector<vector<edge> > adj;
  Graph(int n) {
    adj.clear();
    adj.resize(n + 5);
  }
  Graph() { adj.clear(); }
  void resize(int n) { adj.resize(n + 5); }
  void add(int s, edge e) { adj[s].push_back(e); }
  void del(int s, edge e) {
    adj[s].erase(find((adj[s]).begin(), (adj[s]).end(), e));
  }
  int deg(int v) { return adj[v].size(); }
  vector<edge> &operator[](int t) { return adj[t]; }
};
const int maxn = 110000;
typedef int arr32[maxn];
Graph<int> G, g;
stack<int> stk;
arr32 dfn, low, rep, deg, size, prop;
int tms, cnt;
bool o[maxn];
void dfs(int v, int f) {
  stk.push(v), dfn[v] = low[v] = ++tms;
  for (int &u : G[v])
    if (!dfn[u])
      dfs(u, v), low[v] = min(low[u], low[v]);
    else if (u != f)
      low[v] = min(low[v], dfn[u]);
  if (low[v] == dfn[v]) {
    for (; stk.top() != v; stk.pop()) rep[stk.top()] = v;
    rep[stk.top()] = v, stk.pop();
  }
}
void find(int v) {
  cnt += deg[v] == 1, dfn[v] = 1;
  for (auto &u : g[v])
    if (!dfn[u]) find(u);
}
int dp(int v, int f) {
  dfn[v] = 1;
  int now = -1, ret = 0;
  for (auto &u : g[v])
    if (u != f) {
      ret += dp(u, v);
      if (prop[u] == 0 && now == 0)
        ++ret, now = -1;
      else if (prop[u] == 1 && now == 1)
        --ret, now = -1;
      else if (now != -1)
        now = -1;
      else
        now = prop[u];
    }
  if (now == 0)
    ++ret, prop[v] = 1;
  else if (now == -1)
    prop[v] = 0;
  else if (now == 1)
    prop[v] = 1;
  return ret;
}
int main() {
  ios_base::sync_with_stdio(false);
  int n, m;
  cin >> n >> m, G.resize(n), g.resize(n);
  for (int i = 1, s, t; i <= m; ++i) cin >> s >> t, G.add(s, t), G.add(t, s);
  for (int i = 1; i <= n; ++i)
    if (!dfn[i]) dfs(i, 0);
  for (int i = 1; i <= n; ++i) ++size[rep[i]];
  memset(dfn, 0, sizeof(dfn));
  for (int v = 1; v <= n; ++v) {
    bool b = false;
    for (auto &u : G[v]) {
      if (rep[v] != rep[u] && u <= v)
        g.add(u, v), g.add(v, u), ++deg[v], ++deg[u];
      if (rep[v] != rep[u]) b = true;
    }
    dfn[rep[v]] += b;
  }
  int ans = 0;
  for (int v = 1; v <= n; ++v) ans += size[v] > 1 && dfn[v] <= 1;
  memset(dfn, 0, sizeof(dfn));
  for (int v = 1; v <= n; ++v)
    if (!dfn[v] && rep[v] == v) {
      ans += dp(v, 0);
    }
  cout << ans << " " << m << endl;
  return 0;
}