1. Abridged Problem Statement  
You have N boxes, each containing exactly one coin of distinct integer weights 1 through N. You are given M comparisons of the form “box P is lighter than box Q.” Determine an assignment of coin weights to boxes that satisfies all comparisons, or report “No solution” if none exists. If a solution exists, output a permutation A of 1…N where A[K] is the weight of the coin in box K.

2. Detailed Editorial  

Problem Reduction  
- Each box K must be assigned a distinct integer weight from 1 to N.  
- A comparison “P lighter than Q” enforces weight[P] < weight[Q].  
- These are precedence constraints that form a directed graph on N nodes (boxes).  

We must find a permutation of [1..N] that respects all these constraints or conclude that they are inconsistent (i.e., the graph has a cycle).  

Solution Outline  
1. Build a directed graph G with N vertices (boxes). For each comparison P Q, add edge P→Q.  
2. Detect if G has a cycle and, if not, produce a topological ordering of its vertices.  
   - We use Kahn’s algorithm (BFS-based) for topological sort:  
     a. Compute in-degree for each vertex.  
     b. Initialize a queue with all vertices of in-degree zero.  
     c. While the queue is not empty, pop vertex u, append to topo order, and decrement in-degree of all neighbors v. Whenever in-degree[v] becomes zero, enqueue v.  
     d. If we process fewer than N vertices, a cycle exists.  
3. If a valid topological order `order[]` of length N exists, assign weights in increasing order along that topological order:  
   - The first vertex in `order` gets weight = 1, the second gets 2, …, the N-th gets N.  
4. Finally, output for each box K the assigned weight. If there was a cycle, output “No solution.”

Time Complexity  
- Building the graph: O(N + M).  
- Kahn’s topological sort: O(N + M).  
- Overall: O(N + M), which is efficient for N ≤ 100, M ≤ 10000.

3. C++ Solution with Detailed Comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

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

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

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

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

int n, m;                          // number of boxes, number of comparisons
vector<vector<int>> adj;          // adjacency list: adj[u] contains all v with edge u->v

// Read input
void read() {
    cin >> n >> m;
    adj.assign(n, {});            // initialize adjacency list for n vertices
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;            // box numbers are 1-based
        u--; v--;                 // convert to 0-based
        adj[u].push_back(v);      // u must be lighter than v => edge u->v
    }
}

// Perform Kahn's topological sort; return an ordering of nodes
// If graph has a cycle, the returned vector will have size < n
vector<int> top_sort() {
    vector<int> indegree(n, 0);
    // Compute in-degrees
    for (int u = 0; u < n; u++) {
        for (int v : adj[u]) {
            indegree[v]++;
        }
    }
    queue<int> q;
    // Start with all nodes of in-degree zero
    for (int u = 0; u < n; u++) {
        if (indegree[u] == 0) {
            q.push(u);
        }
    }
    vector<int> order;
    // Standard BFS-like process
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        order.push_back(u);
        for (int v : adj[u]) {
            indegree[v]--;
            if (indegree[v] == 0) {
                q.push(v);
            }
        }
    }
    return order;
}

// Solve one test case
void solve() {
    vector<int> order = top_sort();
    // If we did not include all n nodes, there is a cycle
    if ((int)order.size() != n) {
        cout << "No solution\n";
        return;
    }
    // pos[u] = position of u in the topological order
    vector<int> pos(n);
    for (int i = 0; i < n; i++) {
        pos[order[i]] = i;
    }
    // Assign weights 1..n in the order of pos; output pos[u]+1 for each box u
    for (int u = 0; u < n; u++) {
        cout << pos[u] + 1 << ' ';
    }
    cout << '\n';
}

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

    read();
    solve();
    return 0;
}
```

4. Python Solution with Detailed Comments  
```python
import sys
from collections import deque

def main():
    data = sys.stdin.read().split()
    it = iter(data)
    n = int(next(it))
    m = int(next(it))
    # Build adjacency list for a directed graph on n nodes
    adj = [[] for _ in range(n)]
    indeg = [0] * n

    for _ in range(m):
        u = int(next(it)) - 1
        v = int(next(it)) - 1
        # u lighter than v => edge u->v
        adj[u].append(v)
        indeg[v] += 1

    # Kahn's algorithm for topological sorting
    q = deque([u for u in range(n) if indeg[u] == 0])
    order = []

    while q:
        u = q.popleft()
        order.append(u)
        for v in adj[u]:
            indeg[v] -= 1
            if indeg[v] == 0:
                q.append(v)

    # If we did not process all nodes, there is a cycle => no solution
    if len(order) != n:
        print("No solution")
        return

    # pos[u] = index of node u in the topological order
    pos = [0] * n
    for idx, u in enumerate(order):
        pos[u] = idx

    # Assign weights 1..n in topo order, so box u gets pos[u]+1
    result = [str(pos[u] + 1) for u in range(n)]
    print(" ".join(result))


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

5. Compressed Editorial  
- Model boxes as vertices, comparisons P<Q as directed edges P→Q.  
- Run Kahn’s topological sort to detect cycles and produce an order.  
- If acyclic, assign weights 1..N in that order; otherwise output “No solution.”