// David Poeschl import java.util.*; public class NonogramsDavid { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int rowCount = scan.nextInt(); int columnCount = scan.nextInt(); int[][] rows = new int[rowCount][]; for (int i = 0; i < rowCount; i++) { int entriesCount = scan.nextInt(); rows[i] = new int[entriesCount]; for (int j = 0; j < entriesCount; j++) rows[i][j] = scan.nextInt(); } int[][] columns = new int[columnCount][]; for (int i = 0; i < columnCount; i++) { int entriesCount = scan.nextInt(); columns[i] = new int[entriesCount]; for (int j = 0; j < entriesCount; j++) columns[i][j] = scan.nextInt(); } Solve(rows, columns); scan.close(); } private static void Solve(int[][] rows, int[][] columns) { ArrayList>> allRowDistributions = new ArrayList>>(); ArrayList>> allColumnDistributions = new ArrayList>>(); for (int i = 0; i < rows.length; i++) { ArrayList> rowDistributions = new ArrayList>(); allRowDistributions.add(rowDistributions); CreateAllDistributions(rows[i], 0, 0, new ArrayList(), columns.length, rowDistributions); } for (int i = 0; i < columns.length; i++) { ArrayList> columnDistributions = new ArrayList>(); allColumnDistributions.add(columnDistributions); CreateAllDistributions(columns[i], 0, 0, new ArrayList(), rows.length, columnDistributions); } int[][] result = new int[rows.length][]; for (int i = 0; i < rows.length; i++) result[i] = new int[columns.length]; for (int r = 0; r < rows.length; r++) for (int c = 0; c < columns.length; c++) result[r][c] = -1; boolean anythingChanged = true; while(anythingChanged) { anythingChanged = false; for (int i = 0; i < rows.length; i++) { int[] nonoValues = rows[i]; int[] currentRow = result[i].clone(); boolean changed = Process(nonoValues, currentRow, allRowDistributions.get(i)); if (changed) { for (int j = 0; j < columns.length; j++) result[i][j] = currentRow[j]; anythingChanged = true; } } for (int i = 0; i < columns.length; i++) { int[] nonoValues = columns[i]; int[] currentColumn = new int[rows.length]; for (int j = 0; j < rows.length; j++) currentColumn[j] = result[j][i]; boolean changed = Process(nonoValues, currentColumn, allColumnDistributions.get(i)); if (changed) { for (int j = 0; j < rows.length; j++) result[j][i] = currentColumn[j]; anythingChanged = true; } } } PrintResult(result); } private static void CreateAllDistributions( int[] nonoValues, int currentNonoIndex, int currentPosition, ArrayList currentLine, int length, ArrayList> validDistributions) { if (currentLine.size() > length) return; if (currentNonoIndex == nonoValues.length) { if (currentLine.size() < length) { int zerosToAdd = length - currentLine.size(); for (int i = 0; i < zerosToAdd; i++) currentLine.add(0); } validDistributions.add(currentLine); return; } for (int i = 0; i < length - nonoValues[currentNonoIndex] + 1; i++) { ArrayList newCurrentLine = (ArrayList) currentLine.clone(); for (int j = 0; j < i + (currentNonoIndex == 0 ? 0 : 1); j++) newCurrentLine.add(0); for (int j = 0; j < nonoValues[currentNonoIndex]; j++) newCurrentLine.add(1); int newCurrentPosition = currentPosition + nonoValues[currentNonoIndex]; CreateAllDistributions(nonoValues, currentNonoIndex + 1, newCurrentPosition, newCurrentLine, length, validDistributions); } } private static boolean Process(int[] nonoValues, int[] constraints, ArrayList> allDistributions) { ArrayList> applicableDistributions = new ArrayList>(); for (ArrayList distribution : allDistributions) if (DistributionMatchesConstraints(distribution, constraints)) applicableDistributions.add(distribution); int[] newConstraints = constraints.clone(); for (ArrayList validDistribution : applicableDistributions) for (int i = 0; i < validDistribution.size(); i++) if (constraints[i] == -1) { if (newConstraints[i] == -1) newConstraints[i] = validDistribution.get(i); else if (newConstraints[i] != -2 && newConstraints[i] != validDistribution.get(i)) newConstraints[i] = -2; } for (int i = 0; i < constraints.length; i++) if (newConstraints[i] == -2) newConstraints[i] = -1; for (int i = 0; i < constraints.length; i++) if (constraints[i] != newConstraints[i]) { for (int j = 0; j < constraints.length; j++) constraints[j] = newConstraints[j]; return true; } return false; } private static boolean DistributionMatchesConstraints(ArrayList distribution, int[] constraints) { for (int i = 0; i < constraints.length; i++) if (!(constraints[i] == -1 || constraints[i] == distribution.get(i))) return false; return true; } private static void PrintResult(int[][] result) { for (int r = 0; r < result.length; r++) { for (int c = 0; c < result[0].length; c++) { if (result[r][c] == 1) System.out.print("X"); else if (result[r][c] == 0) System.out.print("."); else System.out.print("?"); } System.out.println(); } } }