1. Abridged problem statement  
Given integers n, t1, t2. Two workers A and B start at time 0 and each writes solutions repeatedly: A takes t1 time per solution, B takes t2. Whenever a worker finishes one at time s, he looks at how many total solutions have been completed up to time s (including those finishing exactly at s). If that total is strictly less than n, he immediately starts another; otherwise he stops. Already started solutions are never aborted. Compute:  
- m = total solutions eventually written (possibly > n)  
- f = the time when the very last solution finishes  

2. Detailed editorial  
We need to track two streams of finishing times: multiples of t1 and multiples of t2, merged in time order. A direct simulation (e.g. two pointers or a priority queue) will work in O(n) time but can be simplified further:

Step 1: Find the earliest time T such that the number of solutions finished by time T is at least n.  
  - Let A(T) = ⌊T/t1⌋, B(T) = ⌊T/t2⌋.  
  - We want the minimal T with A(T) + B(T) ≥ n.  
  - Apply binary search on T in [0, n·min(t1, t2)] (or a safe upper bound like 1e8). Each step computes A(T)+B(T) in O(1). This takes O(log (max_time)).

Call that minimal time ret. By definition:  
  (i) eval(ret) = A(ret) + B(ret) ≥ n,  
  (ii) eval(ret–1) < n.

At time ret, some solutions may finish simultaneously. Let ret2 = eval(ret) be the total done up to ret.  These are all the solutions that complete at or before ret.

Step 2: Account for in-progress jobs that were started before ret and will finish after ret.  
  - At time ret, worker A is in the middle of a job if ret % t1 ≠ 0. His last finish was at ⌊ret/t1⌋·t1 < ret; since eval(ret–1) < n he must have started the next one. That job will end at FA = ret + (t1 – ret%t1).  
  - Similarly for worker B: if ret % t2 ≠ 0 then he has a pending job finishing at FB = ret + (t2 – ret%t2).  
Each pending job will complete no matter what, so we add one for each pending worker, and the final completion time f = max(ret, FA, FB).

Thus the answer is:  
  m = ret2 + (ret%t1 ≠ 0 ? 1 : 0) + (ret%t2 ≠ 0 ? 1 : 0)  
  f = maximum of ret and those pending finish times.

Time complexity: O(log(max_time)). Space: O(1).

3. Provided C++ solution with detailed comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

// chkmax and chkmin update x with y if y is bigger/smaller:
template<class T, class U>
inline void chkmax(T &x, const U &y) {
    if (x < y) x = y;
}
template<class T, class U>
inline void chkmin(T &x, const U &y) {
    if (x > y) x = y;
}

int n, t1, t2;

// Read inputs
void read() {
    cin >> n >> t1 >> t2;
}

// Evaluate how many solutions are done by time x:
// floor(x/t1) by Petya + floor(x/t2) by Vasya.
int eval(int x) {
    return x / t1 + x / t2;
}

// Main solve function
void solve() {
    // Binary search for the minimal time 'ret' with eval(ret) >= n
    int low = 0, high = 100000000; 
    int ret = high;
    while (low <= high) {
        int mid = (low + high) >> 1;
        if (eval(mid) >= n) {
            // mid is sufficient, try lower
            ret = mid;
            high = mid - 1;
        } else {
            // mid is too small
            low = mid + 1;
        }
    }

    // ret = earliest time when at least n solutions are done
    int completed = eval(ret);  // number of solutions done by time ret
    int finish_time = ret;      // will track the final finishing time

    // Check Petya's pending job: if ret % t1 != 0 then he's mid-job
    if (ret % t1 != 0) {
        // His job will finish at next multiple of t1
        int nextA = ret + (t1 - ret % t1);
        chkmax(finish_time, nextA);
        completed++;  // that job will also complete
    }
    // Similarly check Vasya's pending job
    if (ret % t2 != 0) {
        int nextB = ret + (t2 - ret % t2);
        chkmax(finish_time, nextB);
        completed++;
    }

    // Output: total solutions written, time of the last one
    cout << completed << " " << finish_time << "\n";
}

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

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

4. Python solution with detailed comments  
```python
def main():
    import sys
    data = sys.stdin.read().split()
    n, t1, t2 = map(int, data)

    # Function to count how many solutions by time x
    def finished(x):
        return x // t1 + x // t2

    # Binary search minimal time 'ret' where finished(ret) >= n
    low, high = 0, n * min(t1, t2)
    ret = high
    while low <= high:
        mid = (low + high) // 2
        if finished(mid) >= n:
            ret = mid
            high = mid - 1
        else:
            low = mid + 1

    # Count how many done by time ret
    total = finished(ret)
    last_time = ret

    # Check if Petya has a pending job at time ret
    if ret % t1 != 0:
        # This job will finish at next multiple of t1
        finishA = ret + (t1 - ret % t1)
        last_time = max(last_time, finishA)
        total += 1

    # Check if Vasya has a pending job
    if ret % t2 != 0:
        finishB = ret + (t2 - ret % t2)
        last_time = max(last_time, finishB)
        total += 1

    # Print result
    print(total, last_time)

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

5. Compressed editorial  
- Binary search for the smallest time `T` such that `⌊T/t1⌋ + ⌊T/t2⌋ ≥ n`.  
- Let `c = ⌊T/t1⌋ + ⌊T/t2⌋`. Those are the solutions done at or before `T`.  
- Any worker with `T % ti != 0` was mid-job (because his last finish was before `T` when total < n) and will finish one more at time `T + (ti – T%ti)`.  
- Total = `c` + number of pending jobs (0–2). Last finish = max of `T` and those pending finish times.