public class Solution { struct MulInfo { public long Left; public long Right; } public int[][] ConstructProductMatrix(int[][] grid) { var mod = 12345; var table = new MulInfo[grid.Length][]; var lastRow = grid.Length - 1; var lastCol = grid[0].Length - 1; // прямой проход for (var i = 0; i < grid.Length; i++) { table[i] = new MulInfo[grid[i].Length]; for (var j = 0; j < grid[i].Length; j++) { if (j == 0 && i == 0) { table[i][j].Left = grid[i][j] % mod; } else if (j > 0) { table[i][j].Left = table[i][j - 1].Left * grid[i][j] % mod; } else if (i > 0) { table[i][j].Left = table[i - 1][lastCol].Left * grid[i][j]; table[i][j].Left %= mod; } } } // обратный проход for (var i = lastRow; i >= 0; i--) { for (var j = lastCol; j >= 0; j--) { if (j == lastCol && i == lastRow) { table[i][j].Right = grid[i][j] % mod; } else if (j < lastCol) { table[i][j].Right = table[i][j + 1].Right * grid[i][j] % mod; } else if (i < lastRow) { table[i][j].Right = table[i + 1][0].Right * grid[i][j] % mod; } var left = 1L; var right = 1L; if (i == 0 && j == 0) left = 1; else if (j > 0) left = table[i][j - 1].Left; else if (i > 0) left = table[i - 1][lastCol].Left; if (i == lastRow && j == lastCol) right = 1; else if (j < lastCol) right = table[i][j + 1].Right; else if (i < lastRow) right = table[i + 1][0].Right; grid[i][j] = (int)(left * right % mod); } } return grid; } }