#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
int n;
vector<vector<int> > D;
int numberOfThreads = 4;
mutex m;
condition_variable cv;
int counter = 0;
void runThread(int x) {
for (int k = 0; k < n; ++k) {
for (int i = x; i < n; i+= numberOfThreads) {
for (int j = 0; j < n; ++j) {
D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
}
}
m.lock();
counter++;
if(counter == numberOfThreads) {
counter = 0;
cv.notify_all();
} else {
unique_lock<std::mutex> lk(m);
cv.wait(lk, [ ] { return counter == 0;});
}
m.unlock();
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
D.assign(n, vector<int>(n));
vector<thread> myThreads(numberOfThreads);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
cin >> D[i][j];
for(int i = 0; i < numberOfThreads; i++) {
myThreads[i] = thread(runThread, i);
}
for(int i = 0; i < numberOfThreads; i++) {
myThreads[i].join();
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (j > 0)
cout << ' ';
cout << D[i][j];
}
cout << endl;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dGhyZWFkPgojaW5jbHVkZSA8bXV0ZXg+CiNpbmNsdWRlIDxjb25kaXRpb25fdmFyaWFibGU+CgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBuOwp2ZWN0b3I8dmVjdG9yPGludD4gPiBEOwppbnQgbnVtYmVyT2ZUaHJlYWRzID0gNDsKCm11dGV4IG07CmNvbmRpdGlvbl92YXJpYWJsZSBjdjsKaW50IGNvdW50ZXIgPSAwOwoKdm9pZCBydW5UaHJlYWQoaW50IHgpIHsKCWZvciAoaW50IGsgPSAwOyBrIDwgbjsgKytrKSB7CgkJCgkJZm9yIChpbnQgaSA9IHg7IGkgPCBuOyBpKz0gbnVtYmVyT2ZUaHJlYWRzKSB7CgkJCWZvciAoaW50IGogPSAwOyBqIDwgbjsgKytqKSB7CgkJCQlEW2ldW2pdID0gbWluKERbaV1bal0sIERbaV1ba10gKyBEW2tdW2pdKTsKCQkJfQoJCX0KCQkKCQltLmxvY2soKTsKCQljb3VudGVyKys7CgkJCgkJaWYoY291bnRlciA9PSBudW1iZXJPZlRocmVhZHMpIHsKCQkJY291bnRlciA9IDA7CgkJCWN2Lm5vdGlmeV9hbGwoKTsKCQl9IGVsc2UgewoJCQl1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsayhtKTsKCQkJY3Yud2FpdChsaywgWyBdIHsgcmV0dXJuIGNvdW50ZXIgPT0gMDt9KTsKCQl9CgkKCQltLnVubG9jaygpOwoJCgl9Cn0gIAoKaW50IG1haW4oKSB7CiAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgY2luLnRpZShudWxscHRyKTsKCiAgY2luID4+IG47CiAgRC5hc3NpZ24obiwgdmVjdG9yPGludD4obikpOwogIHZlY3Rvcjx0aHJlYWQ+IG15VGhyZWFkcyhudW1iZXJPZlRocmVhZHMpOwogIAogIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgKytpKQogICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyArK2opCiAgICAgIGNpbiA+PiBEW2ldW2pdOwoJCiAgZm9yKGludCBpID0gMDsgaSA8IG51bWJlck9mVGhyZWFkczsgaSsrKSB7CgkgIG15VGhyZWFkc1tpXSA9IHRocmVhZChydW5UaHJlYWQsIGkpOwogIH0KICAKICAgIGZvcihpbnQgaSA9IDA7IGkgPCBudW1iZXJPZlRocmVhZHM7IGkrKykgewoJICBteVRocmVhZHNbaV0uam9pbigpOwogIH0KICAKICBmb3IgKGludCBpID0gMDsgaSA8IG47ICsraSkgewogICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyArK2opIHsKICAgICAgaWYgKGogPiAwKQogICAgICAgIGNvdXQgPDwgJyAnOwogICAgICBjb3V0IDw8IERbaV1bal07CiAgICB9CiAgICBjb3V0IDw8IGVuZGw7CiAgfQp9