<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

457. Snow in Berland
Time limit per test: 0.5 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



Winters are very snowy in Berland, and the current winter is not an exception. Each winter Berland government decides how to clean the roads in the country. The problem is particularly acute in the capital.

You may assume that the capital of Berland consists of n junctions and m one-way roads. Each road has two distinct junctions xi,yi as its end-points, and the traffic goes from xi to yi. There are wi tons of snow on i-th road.

The government hired a private company "Snow White" to clean the city from the snow. Every day the company sends one truck for cleaning the roads — the truck starts from junction A, passes some route to junction B and stops. Single route can contain any road several times, and can pass through any junction (including A and B) several times.

So, the truck makes only one trip from junction A to junction B per day, and the truck's driver, of course, may not violate the traffic direction on the roads. The truck removes one ton of snow from each road it passes. If it passes the road several times during the same day, each time one ton of snow is removed from the road. Because capital residents may decide that the government spends the budget for nothing, the truck can not pass the road if there is no snow on it.

Some roads in the city have historical value due to the presence of government buildings, so this set of roads must be completely cleaned from snow. In other words each road from the specified set should not have snow after "Snow White"'s work. It's known that junction A is situated in the historical center of the capital, meaning that it is possible to reach any historical road from A, walking only along historical roads in the direction of their orientation or in the opposite direction. The direction of roads is not taken into account in this particular case, because we are talking about walking, not driving.

The government pays "Snow White" for each day of work, so "Snow White"'s top managers are looking for a way to work as many days as possible.

Your task is to find the sequence of routes from A to B which doesn't violate the rules described above. This sequence must completely clean all historical roads from snow. Obviously, the sequence should contain as many routes as possible.

Input
The first line of the input contains integer numbers n,m,A,B (2 ≤ n ≤ 100; 0 ≤ m ≤ 5000; 1 ≤ A,B ≤ n; A ≠q B), where n — the number of junctions in the capital and m — the number of roads in it. The following m lines describe one-way roads, one road per line. Each line contains four integers xi,yi,wi,ti (1 ≤ xi,yi ≤ n; xi ≠q yi; 0 ≤ wi ≤ 100; 0 ≤ ti ≤ 1), where xi,yi are the endpoints of the road, wi — the amount of snow in tons on the road, and ti — type of the road (0 means regular road, and 1 means historical road). There will be no more than one road between two junctions in each direction. It is possible to reach any historical road from A by walking along other historical roads (again, not taking into account the direction while walking)

Output
Write p — the maximum number of days "Snow White" can work. The next p lines should contain the chosen routes. Each route should be printed as a list of junctions that starts with A and ends with B, and all junction numbers should be separated by spaces. You may print routes in any order.

If there are many solutions, you may output any of them. If there is no solution, write a single integer 0 to the output.

Example(s)
sample input
sample output
4 7 1 4
1 2 3 1
2 1 100 0
2 4 1 0
1 3 1 0
3 4 4 0
2 3 2 1
1 4 2 0
6
1 3 4
1 4
1 4
1 2 4
1 2 3 4
1 2 3 4

sample input
sample output
3 3 1 2
1 3 2 0
3 2 3 0
1 2 1 0
3
1 3 2
1 3 2
1 2

<|response|>
## 1) Abridged problem statement

Given a directed graph with `n ≤ 100` vertices and `m ≤ 5000` edges. Edge `i` is `xi → yi`, has `wi` tons of snow, and type `ti` (`1` = historical, `0` = regular).

Each day a truck drives along **any directed route from `A` to `B`** (vertices/edges may repeat). Every time it traverses an edge, it removes **1** ton of snow from that edge. An edge **cannot** be traversed if its remaining snow is **0**.

All **historical** edges must be fully cleaned (used exactly `wi` times total). Regular edges may be used up to `wi` times.

Output a sequence of `p` routes (each starts at `A` ends at `B`) that fully cleans all historical edges, with **maximum possible `p`**. If impossible, output `0`.

---

## 2) Key observations

1. **Each daily route = 1 unit of flow from `A` to `B`.**
   If we interpret "traversing an edge once" as sending 1 unit of flow through that directed edge, then:
   - Total traversals of an edge cannot exceed its snow `wi` ⇒ capacity `wi`.
   - Historical edges must be traversed exactly `wi` times ⇒ they have a **lower bound** and **upper bound** both equal to `wi`.

2. This becomes a **max flow with lower bounds (demands)**:
   - Regular edge `u→v`: `0 ≤ f ≤ wi`
   - Historical edge `u→v`: `wi ≤ f ≤ wi` (fixed)

3. Standard reduction for lower bounds:
   - For each edge with lower bound `L` and capacity `C`, we replace it by capacity `C-L` and maintain node balances:
     - `bal[u] -= L`, `bal[v] += L`
   - Add super source `S` and super sink `T`:
     - if `bal[i] > 0`, add `S→i` capacity `bal[i]`
     - if `bal[i] < 0`, add `i→T` capacity `-bal[i]`
   - Feasible iff maxflow(`S`,`T`) saturates all edges out of `S`.

4. To allow *some* net `A→B` flow while checking circulation feasibility, add an infinite edge `B→A`.
   This transforms any `A→B` flow into a circulation (it can "return" via `B→A`).

5. After feasibility, we can **maximize the number of days** by running a normal maxflow from `A` to `B` in the residual network.

6. To output actual routes, we must **decompose the resulting integer flow** into `p` paths from `A` to `B` (plus possible cycles).
   - Extract `p` unit `A→B` paths by repeatedly finding any path in the positive-flow multigraph and decrementing counts.
   - Remaining edges form directed cycles; extract each cycle (Euler/Hierholzer style) and **splice** it into some `A→B` path at a common vertex.

---

## 3) Full solution approach

### Step A — Build and solve "flow with demands" feasibility

- Create Dinic network on nodes `1..n` plus `S=n+1`, `T=n+2`.
- Add edge `B→A` with capacity `INF`.
- For each regular edge `x→y` with snow `w`:
  - add capacity edge `x→y` with cap `w`.
- For each historical edge `x→y` with snow `w` (must be used exactly `w` times):
  - don't add it yet as a normal edge; instead only apply balance:
    - `bal[x] -= w`, `bal[y] += w`
  - store it for later.

Add balance-fixing edges:
- If `bal[i] > 0`: add `S→i` cap `bal[i]`
- If `bal[i] < 0`: add `i→T` cap `-bal[i]`

Let `need = sum(bal[i] > 0)`. Run maxflow from `S` to `T`.
If result != `need`, no feasible way to satisfy historical edges ⇒ output `0`.

### Step B — Maximize days

After feasibility is satisfied, run maxflow from `A` to `B` in the **same residual graph**.
This pushes as much additional `A→B` flow as possible without breaking constraints.

### Step C — Build the final traversal multigraph

We want a directed multigraph describing how many times each edge is traversed.

- From Dinic graph, collect all edges `u→v` (real nodes only) with `flow > 0` and store multiplicity `cnt[u][v] += flow`.
- Additionally, add each historical edge `(x→y,w)` as `cnt[x][y] += w` because it must be traversed exactly `w` times (some implementations "force" those flows explicitly; either method is fine as long as the final multiset of traversals includes them).

Let `p = sum_v cnt[A][v]`. This is the total number of unit paths leaving `A`, i.e. maximum days.

If `p == 0`, output `0`.

### Step D — Decompose into `p` routes

1. Repeat `p` times:
   - BFS/DFS in the multigraph (edges with cnt>0) to find any path `A→B`.
   - Decrement `cnt` along that path by 1 and store the vertex list.

2. Remaining edges (all counts) must form only directed cycles (flow conservation).
   - While some `cnt[u][v] > 0`, run a Hierholzer-style DFS consuming edges to extract one directed cycle as a vertex sequence.
   - Splice that cycle into any existing `A→B` path that shares a vertex with the cycle:
     - rotate cycle so it starts at the shared vertex
     - insert cycle sequence into the path at that position
   This preserves start `A` and end `B`, and adds exactly the needed extra traversals.

Output `p` and the constructed routes.

---

## 4) C++ Implementation

```cpp
#include <bits/stdc++.h>
// #include <coding_library/graph/maxflow.hpp>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

template<class T>
class MaxFlow {
  private:
    struct Edge {
        T flow, cap;
        int idx, rev, to;
        Edge(int _to, int _rev, T _flow, T _cap, int _idx)
            : to(_to), rev(_rev), flow(_flow), cap(_cap), idx(_idx) {}
    };

    vector<int> dist, po;
    int n;

    bool bfs(int s, int t) {
        fill(dist.begin(), dist.end(), -1);
        fill(po.begin(), po.end(), 0);

        queue<int> q;
        q.push(s);
        dist[s] = 0;

        while(!q.empty()) {
            int u = q.front();
            q.pop();

            for(Edge e: adj[u]) {
                if(dist[e.to] == -1 && e.flow < e.cap) {
                    dist[e.to] = dist[u] + 1;
                    q.push(e.to);
                }
            }
        }
        return dist[t] != -1;
    }

    T dfs(int u, int t, T fl = inf) {
        if(u == t) {
            return fl;
        }

        for(; po[u] < (int)adj[u].size(); po[u]++) {
            auto& e = adj[u][po[u]];
            if(dist[e.to] == dist[u] + 1 && e.flow < e.cap) {
                T f = dfs(e.to, t, min(fl, e.cap - e.flow));
                e.flow += f;
                adj[e.to][e.rev].flow -= f;
                if(f > 0) {
                    return f;
                }
            }
        }

        return 0;
    }

  public:
    constexpr static T inf = numeric_limits<T>::max();

    MaxFlow(int n = 0) { init(n); }

    vector<vector<Edge>> adj;

    void init(int _n) {
        n = _n;
        adj.assign(n + 1, {});
        dist.resize(n + 1);
        po.resize(n + 1);
    }

    void add_edge(int u, int v, T w, int idx = -1) {
        adj[u].push_back(Edge(v, adj[v].size(), 0, w, idx));
        adj[v].push_back(Edge(u, adj[u].size() - 1, 0, 0, -1));
    }

    T flow(int s, int t) {
        assert(s != t);

        T ret = 0, to_add;
        while(bfs(s, t)) {
            while((to_add = dfs(s, t))) {
                ret += to_add;
            }
        }

        return ret;
    }
};

int n, m, A, B;
vector<tuple<int, int, int, int>> edges;

void read() {
    cin >> n >> m >> A >> B;
    edges.resize(m);
    for(int i = 0; i < m; i++) {
        auto& [x, y, w, t] = edges[i];
        cin >> x >> y >> w >> t;
    }
}

void solve() {
    // The problem can be formulated as a maxflow with demands. Particularly, a
    // path from A to B can be through as pushing a single unit of flow through
    // edges that have capacities equal to the initial snow on the roads. Note
    // that we are allowed the path to be non-simple. We want to fully clear the
    // historical roads, so this can also be formulated as a minimum demand
    // equal to the capacity. We want to find the largest flow satisfying this
    // (maximum number of paths / days of work).
    //
    // Flow with demands is a classic problem, where we build a new graph that
    // has capacities equal to the difference between the original capacity and
    // the demand and create a fake source and sink that we connect to all nodes
    // in the graph based on their cumulative supply / demand of adjacent edges.
    // There is a full explanation with some intuition in:
    //
    //     https://cp-algorithms.com/graph/flow_with_demands.html
    //
    // The tricky bit in this problem is the cycles, and that we want to
    // reconstruct the answer. We should still first check that we can satisfy
    // the flow with demands as this is a prerequisite for having a solution
    // here.
    //
    // In terms of reconstruction, the first step is that we should always push
    // flow from the real source and sink (A and B in this problem), after we
    // push the flow from S' to T'. This is needed so that we actually have a
    // valid flow rather than a circulation. We now know that we can meet the
    // demands for all historical roads, so let's artificially push +snow flow
    // in their direction and -snow in the opposite. Now if we look at only the
    // positive flow roads, we should have a valid configuration that uses all
    // historical edges. The only challenge left is to figure out how to
    // partition these roads into #days paths.
    //
    // To do this, we can start by greedily with BFS / DFS constructing #days
    // simple paths from A to B. Let's remove these edges - we can notice that
    // we are left with some cycles (technically strongly connected components)
    // that have in and out flow being the same. There might be many of these
    // that are disconnected, but it's important to note that these certainly
    // have a directed Eulerian cycle, meaning that we can easily turn them into
    // a sequence of edges. This is what we will do, and afterwards we are left
    // with only attaching these cycles into the #days path we greedily created
    // - this can be done by finding an intersection, rotating the cycle, and
    // then inserting it into the path from A to B.

    int S = n + 1, T = n + 2;
    MaxFlow<int64_t> mf(n + 3);
    mf.add_edge(B, A, MaxFlow<int64_t>::inf);

    vector<tuple<int, int, int>> hist_edges;
    vector<int> V(n + 1, 0);
    for(auto& [x, y, w, t]: edges) {
        if(t == 0) {
            mf.add_edge(x, y, w);
        } else {
            hist_edges.push_back({x, y, w});
            V[x] -= w;
            V[y] += w;
        }
    }

    int64_t k = 0;
    for(int i = 1; i <= n; i++) {
        if(V[i] > 0) {
            mf.add_edge(S, i, V[i]);
            k += V[i];
        } else if(V[i] < 0) {
            mf.add_edge(i, T, -V[i]);
        }
    }

    int64_t circulation_flow = mf.flow(S, T);
    if(circulation_flow != k) {
        cout << 0 << endl;
        return;
    }

    mf.flow(A, B);
    for(auto& [x, y, w]: hist_edges) {
        mf.add_edge(x, y, w);
        int idx = mf.adj[x].size() - 1;
        mf.adj[x][idx].flow = w;
        mf.adj[y][mf.adj[x][idx].rev].flow = -w;
    }

    auto& adj_A = mf.adj[A];
    int64_t total_paths = 0;
    for(auto& e: adj_A) {
        if(e.to > n) {
            continue;
        }
        total_paths += e.flow;
    }

    if(total_paths == 0) {
        cout << 0 << endl;
        return;
    }

    vector<map<int, int>> res(n + 1);
    for(int u = 1; u <= n; u++) {
        for(int j = 0; j < (int)mf.adj[u].size(); j++) {
            auto& e = mf.adj[u][j];
            if(e.to >= 1 && e.to <= n && e.to != u) {
                if(e.flow > 0) {
                    res[u][e.to] += e.flow;
                }
            }
        }
    }

    vector<bool> in_paths(n + 1, false);

    vector<vector<int>> paths;
    for(int i = 0; i < total_paths; i++) {
        vector<int> path;
        vector<int> parent(n + 1, -1);
        queue<int> q;
        q.push(A);
        parent[A] = A;
        while(!q.empty() && parent[B] == -1) {
            int u = q.front();
            q.pop();
            for(auto& [v, cnt]: res[u]) {
                if(cnt > 0 && parent[v] == -1) {
                    parent[v] = u;
                    q.push(v);
                }
            }
        }
        for(int v = B; v != A; v = parent[v]) {
            path.push_back(v);
            res[parent[v]][v]--;
        }
        path.push_back(A);
        reverse(path.begin(), path.end());
        paths.push_back(path);
        for(int v: path) {
            in_paths[v] = true;
        }
    }

    function<void(int, vector<int>&)> dfs_euler = [&](int v, vector<int>& path) {
        for(auto& [u, cnt]: res[v]) {
            while(cnt > 0) {
                cnt--;
                dfs_euler(u, path);
            }
        }
        path.push_back(v);
    };

    for(int i = 1; i <= n; i++) {
        for(auto& [j, cnt]: res[i]) {
            while(cnt > 0) {
                vector<int> cycle;
                dfs_euler(i, cycle);
                reverse(cycle.begin(), cycle.end());
                cycle.pop_back();

                set<int> in_cycle(cycle.begin(), cycle.end());

                bool inserted = false;
                for(auto& path: paths) {
                    for(int pos = 0; pos < (int)path.size() && !inserted;
                        pos++) {
                        if(in_cycle.count(path[pos])) {
                            int mid = -1;
                            for(int w = 0; w < (int)cycle.size(); w++) {
                                if(cycle[w] == path[pos]) {
                                    mid = w;
                                    break;
                                }
                            }
                            rotate(
                                cycle.begin(), cycle.begin() + mid, cycle.end()
                            );
                            path.insert(
                                path.begin() + pos, cycle.begin(), cycle.end()
                            );
                            inserted = true;
                        }
                    }
                    if(inserted) {
                        break;
                    }
                }
                assert(inserted);
            }
        }
    }

    cout << total_paths << endl;
    for(auto& path: paths) {
        for(int j = 0; j < (int)path.size(); j++) {
            if(j) {
                cout << " ";
            }
            cout << path[j];
        }
        cout << endl;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

---

## 5) Python Implementation

```python
import sys
from collections import deque, defaultdict

# -------- Dinic Max Flow (supports int capacities) --------

class Dinic:
    class Edge:
        __slots__ = ("to", "rev", "cap", "flow")
        def __init__(self, to, rev, cap):
            self.to = to          # destination
            self.rev = rev        # index of reverse edge in graph[to]
            self.cap = cap        # capacity
            self.flow = 0         # current flow

    def __init__(self, n):
        self.n = n
        self.g = [[] for _ in range(n)]
        self.level = [0] * n
        self.it = [0] * n

    def add_edge(self, fr, to, cap):
        # forward edge
        fwd = Dinic.Edge(to, len(self.g[to]), cap)
        # reverse edge (capacity 0)
        rev = Dinic.Edge(fr, len(self.g[fr]), 0)
        self.g[fr].append(fwd)
        self.g[to].append(rev)

    def bfs(self, s, t):
        self.level = [-1] * self.n
        q = deque([s])
        self.level[s] = 0
        while q:
            v = q.popleft()
            for e in self.g[v]:
                if self.level[e.to] < 0 and e.flow < e.cap:
                    self.level[e.to] = self.level[v] + 1
                    q.append(e.to)
        return self.level[t] >= 0

    def dfs(self, v, t, pushed):
        if pushed == 0:
            return 0
        if v == t:
            return pushed
        while self.it[v] < len(self.g[v]):
            e = self.g[v][self.it[v]]
            if self.level[e.to] == self.level[v] + 1 and e.flow < e.cap:
                tr = self.dfs(e.to, t, min(pushed, e.cap - e.flow))
                if tr:
                    e.flow += tr
                    self.g[e.to][e.rev].flow -= tr
                    return tr
            self.it[v] += 1
        return 0

    def max_flow(self, s, t):
        flow = 0
        INF = 10**18
        while self.bfs(s, t):
            self.it = [0] * self.n
            while True:
                pushed = self.dfs(s, t, INF)
                if not pushed:
                    break
                flow += pushed
        return flow


# -------- Solve Snow in Berland (p457) --------

def solve():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    it = iter(data)
    n = int(next(it)); m = int(next(it)); A = int(next(it)); B = int(next(it))
    edges = []
    for _ in range(m):
        x = int(next(it)); y = int(next(it)); w = int(next(it)); t = int(next(it))
        edges.append((x, y, w, t))

    # We'll use 0-based indices internally in Dinic.
    # Real nodes: 0..n-1
    # Super source S = n, super sink T = n+1
    S = n
    T = n + 1
    N = n + 2
    INF = 10**18

    dinic = Dinic(N)

    # Edge B->A with infinite capacity to allow transforming A->B flow into circulation feasibility.
    dinic.add_edge(B - 1, A - 1, INF)

    # Balance array for lower bounds of historical edges.
    V = [0] * n
    hist_edges = []

    # Add regular edges directly; store historical edges as demands.
    for x, y, w, t in edges:
        x -= 1; y -= 1
        if t == 0:
            dinic.add_edge(x, y, w)
        else:
            hist_edges.append((x, y, w))
            V[x] -= w
            V[y] += w

    # Connect super source/sink to satisfy balances.
    k = 0
    for i in range(n):
        if V[i] > 0:
            dinic.add_edge(S, i, V[i])
            k += V[i]
        elif V[i] < 0:
            dinic.add_edge(i, T, -V[i])

    # Feasibility check for demands
    if dinic.max_flow(S, T) != k:
        sys.stdout.write("0\n")
        return

    # Maximize additional A->B flow
    dinic.max_flow(A - 1, B - 1)

    # Build a multigraph res[u][v] = number of times we traverse u->v
    # Start with flows from Dinic edges (positive flow on real->real edges).
    res = [defaultdict(int) for _ in range(n)]
    for u in range(n):
        for e in dinic.g[u]:
            if 0 <= e.to < n and e.to != u and e.flow > 0:
                res[u][e.to] += e.flow

    # Add historical edges as forced traversals of exactly w:
    # They must be included even if they weren't part of regular Dinic edges.
    for x, y, w in hist_edges:
        if w > 0:
            res[x][y] += w

    # Total number of paths = total outgoing flow from A in the final traversal multigraph,
    # i.e., sum of res[A][*].  (This matches the number of "days".)
    total_paths = sum(res[A - 1].values())
    if total_paths == 0:
        sys.stdout.write("0\n")
        return

    # Extract total_paths unit A->B paths via BFS, decrementing edge multiplicities.
    paths = []
    for _ in range(total_paths):
        parent = [-1] * n
        q = deque([A - 1])
        parent[A - 1] = A - 1

        while q and parent[B - 1] == -1:
            u = q.popleft()
            for v, cnt in res[u].items():
                if cnt > 0 and parent[v] == -1:
                    parent[v] = u
                    q.append(v)

        # Reconstruct path and consume one unit along each used edge
        v = B - 1
        path = [v]
        while v != A - 1:
            u = parent[v]
            res[u][v] -= 1
            v = u
            path.append(v)
        path.reverse()
        paths.append(path)

    # Now remaining edges in res form directed cycles.
    sys.setrecursionlimit(1_000_000)

    def dfs_euler(v, out):
        # Consume all outgoing edges from v; recursive Hierholzer.
        for u in list(res[v].keys()):
            while res[v][u] > 0:
                res[v][u] -= 1
                dfs_euler(u, out)
        out.append(v)

    # Extract and splice cycles until no edges remain.
    for i in range(n):
        # iterate over a snapshot because we'll modify counts
        for j in list(res[i].keys()):
            while res[i][j] > 0:
                cycle = []
                dfs_euler(i, cycle)
                cycle.reverse()
                if cycle and cycle[0] == cycle[-1]:
                    cycle.pop()  # remove duplicate end

                in_cycle = set(cycle)

                inserted = False
                for p in paths:
                    for pos, node in enumerate(p):
                        if node in in_cycle:
                            # rotate cycle so it starts at this node
                            idx = cycle.index(node)
                            cycle = cycle[idx:] + cycle[:idx]
                            # splice it into path
                            p[pos:pos] = cycle
                            inserted = True
                            break
                    if inserted:
                        break

                if not inserted:
                    # The original C++ asserts this can't happen under problem conditions.
                    # We'll still guard.
                    raise RuntimeError("Failed to splice a cycle into any A->B path")

    # Output
    out_lines = [str(total_paths)]
    for p in paths:
        out_lines.append(" ".join(str(x + 1) for x in p))
    sys.stdout.write("\n".join(out_lines) + "\n")


if __name__ == "__main__":
    solve()
```
