1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int N = 5e3 + 10;
5 ll dep[N], h[N], dis[N], vis[N], n, m, s, t, ans1, ans2, ee = 2;
6
7 struct edge{
8 ll v, next, flow, wage;
9 }e[100010];
10 void addedge(ll u, ll v, ll flow, ll wage)
11 {
12 e[ee] = (edge){v, h[u], flow, wage};
13 h[u] = ee++;
14 }
15 ll bfs()
16 {
17 memset(vis, 0, sizeof(vis));
18 memset(dis, 0x3f, sizeof(dis));
19 queue<ll>q;
20 q.push(s);
21 dis[s] = 0;
22 vis[s] = 1;
23 while (q.size())
24 {
25 ll u = q.front();
26 q.pop();
27 vis[u] = 0;
28 for(int i = h[u]; i; i = e[i].next)
29 {
30 ll v = e[i].v, w = e[i].wage;
31 if(dis[u] + w < dis[v] && e[i].flow)
32 {
33 dis[v] = dis[u] + w;
34 if(!vis[v])
35 {
36 q.push(v);
37 vis[v] = 1;
38 }
39 }
40 }
41 }
42 return dis[t] != dis[0];
43 }
44
45 ll dfs(ll u, ll path_misum)
46 {
47 if(u == t)return path_misum;
48 ll ans = 0;
49 vis[u] = 1;
50 for(int i = h[u]; i && path_misum; i = e[i].next)
51 {
52 ll v = e[i].v;
53 if(!vis[v] && dis[v] == dis[u] + e[i].wage && e[i].flow > 0)
54 {
55 ll other_flow = dfs(v, min(e[i].flow, path_misum));
56 e[i].flow -= other_flow;
57 e[i ^ 1].flow += other_flow;
58 ans += other_flow;
59 path_misum -= other_flow;
60 }
61 }
62 return ans;
63 }
64 void dinic()
65 {
66 while (bfs())
67 {
68 ll ret = dfs(s, LONG_MAX);
69 ans1 += ret; ans2 += ret * dis[t];
70 }
71 }
72 int main()
73 {
74 ios::sync_with_stdio(false);cin.tie(0);
75 cin >> n >> m >> s >> t;
76 ll u, v, flow, wage;
77 for(int i = 1; i <= m; i++)
78 {
79 cin >> u >> v >> flow >> wage;
80 addedge(u, v, flow, wage);
81 addedge(v, u, 0, -wage);
82 }
83 dinic();
84 cout << ans1 << " " << ans2 << "\n";
85 return 0;
86 }