simple efficient solution
\nclass Solution {\npublic:\n    typedef long long ll;\n    pair<ll, ll> getZeroes(ll n) {\n        pair<ll, ll>res{ 0,0 };\n        ll m = n;\n        while (n
```\nclass Solution {\npublic:\n    typedef long long ll;\n    pair<ll, ll> getZeroes(ll n) {\n        pair<ll, ll>res{ 0,0 };\n        ll m = n;\n        while (n && n % 2 == 0) {\n            ++res.first;\n            n /= 2;\n        }\n        n = m;\n        while (n && n % 5 == 0) {\n            ++res.second;\n            n /= 5;\n        }\n        return res;\n    }\n    int maxTrailingZeros(vector<vector<int>>& v) {\n        ll m = v.size(), n = v.front().size(), ans = 0;\n        vector<vector<pair<ll, ll>>>preHor(m, vector<pair<ll, ll>>(n)), preVer(m, vector<pair<ll, ll>>(n));//, tmpV(m, vector<ll>(n));\n        for (ll i = 0;i < m;++i) {\n            for (ll j = 0;j < n;++j) {\n                auto tmp = getZeroes(v[i][j]);\n                if (j) {\n                    tmp.first += preHor[i][j - 1].first;\n                    tmp.second += preHor[i][j - 1].second;\n                }\n                preHor[i][j] = tmp;\n                tmp = getZeroes(v[i][j]);\n                if (i) {\n                    tmp.first += preVer[i - 1][j].first;\n                    tmp.second += preVer[i - 1][j].second;\n                }\n                preVer[i][j] = tmp;\n            }\n        }\n        for (ll i = 0;i < m;++i) {\n            for (ll j = 0;j < n;++j) {\n                pair<ll, ll> top = preVer[i][j], left = preHor[i][j];\n                pair<ll, ll>right = preHor[i].back(), down = preVer.back()[j];\n                if (j) {\n                    right.first -= preHor[i][j - 1].first;\n                    right.second -= preHor[i][j - 1].second;\n                }\n                if (i) {\n                    down.first -= preVer[i - 1][j].first;\n                    down.second -= preVer[i - 1][j].second;\n                }\n                auto cur = getZeroes(v[i][j]);\n                ll res = min(top.first+left.first-cur.first, top.second+left.second-cur.second);\n\n                res = max(res, min(top.first+right.first-cur.first, top.second+right.second-cur.second));\n                \n                res = max(res, min(down.first+right.first-cur.first, down.second+right.second-cur.second));\n                \n                res = max(res, min(down.first+left.first-cur.first, down.second+left.second-cur.second));\n                ans = max(ans, res);\n            }\n        }\n        return ans;\n    }\n};\n```
['Math']