#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;
struct Edge{
    int dst, cap, rev, ori;
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

bool used[1010];
int N, M, S, T;
Graph G;

bool dfs(int v, bool mode=true) {
    if(v == T) {
        return true;
    }
    if(used[v]) return 0;
    used[v] = true;
    for(Edge& e : G[v]) if(e.cap) {
        if(dfs(e.dst, mode)) {
            if(mode) {
                e.cap = 0;
                G[e.dst][e.rev].cap = 1;
            }
            return true;
        }
    }
    return false;
}

void rec(int v, int c, bool used_rec[1010]) {
    if(used_rec[v]) return;
    used_rec[v] = true;
    for(const Edge &e : G[v]) if(e.cap == c) {
        rec(e.dst, c, used_rec);
    }
}


int main(){
    while(cin >> N >> M >> S >> T && N > 0) {
        S--; T--;
        G.assign(N, Node());
        REP(i, M) {
            int a, b;
            cin >> a >> b;
            a--; b--;
            G[a].push_back({b, 1, (int)G[b].size(), 1});
            G[b].push_back({a, 0, (int)G[a].size() - 1, 0});
        }

        int flow = 0;
        while(true) {
            memset(used, 0, sizeof(bool) * N);
            bool f = dfs(S);
            if(!f) break;
            flow ++;
        }

        bool A[1010] = {};
        rec(S, 1, A);
        bool B[1010] = {};
        rec(T, 0, B);

        int ans = 0;
        REP(i, N) for(Edge& e : G[i]) {
            if(e.ori && e.cap) {
                if(A[e.dst] && B[i]){
                    ans++;
                }
            }
        }

        if(ans != 0) {
            flow++;
        }

        cout << flow << " " << ans << endl;
    }
    return 0;
}