Help! A robot escaped our lab and we need help finding it. The lab is at the point (0, 0) of the coordinate plane, at time 0 the robot was there. The robot's movements are defined by a program — a string of length l, consisting of characters U, L, D, R. Each second the robot executes the next command in his program: if the current coordinates of the robot are (x, y), then commands U, L, D, R move it to cells (x, y + 1), (x - 1, y), (x, y - 1), (x + 1, y) respectively. The execution of the program started at time 0. The program is looped, i.e. each l seconds of executing the program start again from the first character. Unfortunately, we don't know what program was loaded into the robot when he left the lab.Our radars managed to find out the position of the robot at n moments of time: we know that at the moment of time ti the robot is at the point (xi, yi). Given this data, either help to determine what program could be loaded into the robot, or determine that no possible program meets the data and the robot must have broken down.

The first line of the input contains two space-separated integers n and l (1 ≤ n ≤ 2·105, 1 ≤ l ≤ 2·106). Next n lines contain three space-separated integers — ti, xi, yi (1 ≤ ti ≤ 1018,  - 1018 ≤ xi, yi ≤ 1018). The radar data is given chronologically, i.e. ti < ti + 1 for all i from 1 to n - 1.

Print any of the possible programs that meet the data. If no program meets the data, print a single word 'NO' (without the quotes).

import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.abs;
import static java.lang.Math.floorDiv;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.System.exit;
import static java.util.Arrays.fill;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class G {

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

//	static final Random rng = new Random(42);
//	static boolean rngOk;

	static void solve() throws Exception {
		int n = nextInt();
		int l = nextInt();
//		int n = rng.nextInt(40) + 1;
//		int l = rng.nextInt(15) + 1;
//		long rngX[] = new long[l + 1];
//		long rngY[] = new long[l + 1];
//		for (int i = 0; i < l; i++) {
//			long dx, dy;
//			switch (rng.nextInt(4)) {
//			case 0:
//				dx = 1;
//				dy = 0;
//				break;
//			case 1:
//				dx = -1;
//				dy = 0;
//				break;
//			case 2:
//				dx = 0;
//				dy = 1;
//				break;
//			case 3:
//				dx = 0;
//				dy = -1;
//				break;
//			default:
//				throw new AssertionError();
//			}
//			rngX[i + 1] = rngX[i] + dx;
//			rngY[i + 1] = rngY[i] + dy;
//		}
		long t[] = new long[n];
		long x[] = new long[n];
		long y[] = new long[n];
		{
			long pt = 0;
			long px = 0;
			long py = 0;
			for (int i = 0; i < n; i++) {
				long ct = nextLong();
				long cx = nextLong();
				long cy = nextLong();
//				long ct = pt + rng.nextInt(40) + 1;
//				long cx = (ct / l) * rngX[l] + rngX[(int) (ct % l)];
//				long cy = (ct / l) * rngY[l] + rngY[(int) (ct % l)];
//				if (rng.nextInt(10) == 0) {
//					cx += rng.nextInt(5) - 2;
//				}
//				if (rng.nextInt(10) == 0) {
//					cy += rng.nextInt(5) - 2;
//				}
				if (ct - pt < abs(cx - px) + abs(cy - py) || ((ct ^ cx ^ cy) & 1) != 0) {
					out.print("NO");
					return;
				}
				t[i] = ct;
				x[i] = cx + cy;
				y[i] = cx - cy;
				pt = ct;
				px = cx;
				py = cy;
			}
		}
		long lt[] = new long[l + 1];
		long lx[] = new long[l + 1];
		long ly[] = new long[l + 1];
		fill(lt, -1);
		lt[0] = 0;
		lx[0] = 0;
		ly[0] = 0;
		long shiftXmin = -l;
		long shiftXmax = l;
		long shiftYmin = -l;
		long shiftYmax = l;
		for (int i = 0; i < n; i++) {
			int j = (int) (t[i] % l);
			if (lt[j] >= 0) {
				long its = (t[i] - lt[j]) / l;
				if ((x[i] - lx[j]) % its != 0 || ((y[i] - ly[j]) % its != 0)) {
					out.print("NO");
					return;
				}
				shiftXmin = max(shiftXmin, (x[i] - lx[j]) / its);
				shiftXmax = min(shiftXmax, (x[i] - lx[j]) / its);
				shiftYmin = max(shiftYmin, (y[i] - ly[j]) / its);
				shiftYmax = min(shiftYmax, (y[i] - ly[j]) / its);
			} else {
				lt[j] = t[i];
				lx[j] = x[i];
				ly[j] = y[i];
			}
		}
		lt[l] = 0;
		lx[l] = 0;
		ly[l] = 0;
//		System.err.println(Arrays.toString(lt));
//		System.err.println(Arrays.toString(lx));
//		System.err.println(Arrays.toString(ly));
		{
			int pi = 0;
			for (int i = 1; i <= l; i++) {
				if (lt[i] < 0) {
					continue;
				}
				long its = (lt[i] - lt[pi] - (i - pi)) / l;
				if (its == 0) {
					if (i - pi < abs(lx[i] - lx[pi]) || i - pi < abs(ly[i] - ly[pi])) {
						out.print("NO");
						return;
					}
				} else {
					long dx = lx[i] - lx[pi];
					long dy = ly[i] - ly[pi];
					// dx - (i - pi) <= shiftX * its
					// dx + (i - pi) >= shiftX * its
					if (its > 0) {
						shiftXmin = max(shiftXmin, floorDiv(dx - (i - pi) + its - 1,  its));
						shiftXmax = min(shiftXmax, floorDiv(dx + (i - pi), its));
						shiftYmin = max(shiftYmin, floorDiv(dy - (i - pi) + its - 1, its));
						shiftYmax = min(shiftYmax, floorDiv(dy + (i - pi), its));
					} else {
						shiftXmin = max(shiftXmin, floorDiv(dx + (i - pi) + its + 1, its));
						shiftXmax = min(shiftXmax, floorDiv(dx - (i - pi), its));
						shiftYmin = max(shiftYmin, floorDiv(dy + (i - pi) + its + 1, its));
						shiftYmax = min(shiftYmax, floorDiv(dy - (i - pi), its));
					}
				}
				pi = i;
			}
			if (((shiftXmin ^ l) & 1) != 0) {
				++shiftXmin;
			}
			if (((shiftXmax ^ l) & 1) != 0) {
				--shiftXmax;
			}
			if (((shiftYmin ^ l) & 1) != 0) {
				++shiftYmin;
			}
			if (((shiftYmax ^ l) & 1) != 0) {
				--shiftYmax;
			}
			if (shiftXmin > shiftXmax || shiftYmin > shiftYmax) {
				out.print("NO");
				return;
			}
		}
		{
			long shiftX = shiftXmin;
			long shiftY = shiftYmin;
			long cx = 0;
			long cy = 0;
			int pi = 0;
			for (int i = 1; i <= l; i++) {
				if (lt[i] < 0) {
					continue;
				}
				long its = (lt[i] - i) / l;
				long nx = lx[i] - shiftX * its;
				long ny = ly[i] - shiftY * its;
				while (pi < i) {
					boolean xUp = nx > cx;
					boolean yUp = ny > cy;
					out.print(xUp ? (yUp ? 'R' : 'U') : (yUp ? 'D' : 'L'));
					if (xUp) {
						++cx;
					} else {
						--cx;
					}
					if (yUp) {
						++cy;
					} else {
						--cy;
					}
					++pi;
				}
				if (cx != nx || cy != ny) {
//					System.err.println(n + " " + l);
//					System.err.println(Arrays.toString(rngX));
//					System.err.println(Arrays.toString(rngY));
//					System.err.println(Arrays.toString(t));
//					System.err.println(Arrays.toString(x));
//					System.err.println(Arrays.toString(y));
//					System.err.println(Arrays.toString(lt));
//					System.err.println(Arrays.toString(lx));
//					System.err.println(Arrays.toString(ly));
//					System.err.println(shiftX + " " + shiftY);
//					System.err.println(i + " " + cx + " " + cy + " " + nx + " " + ny);
					throw new AssertionError();
				}
			}
		}
//		rngOk = true;
	}

	static int nextInt() throws IOException {
		return parseInt(next());
	}

	static long nextLong() throws IOException {
		return parseLong(next());
	}

	static double nextDouble() throws IOException {
		return parseDouble(next());
	}

	static String next() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
//			if (true) while (true) {
//				rngOk = false;
//				solve();
////				if (!rngOk) {
////					throw new AssertionError();
////				}
//				System.err.println("PASS");
//			}
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ChallengeG solver = new ChallengeG();
        solver.solve(1, in, out);
        out.close();
    }
}

class ChallengeG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                if ((px + py + l) % 2 != 0) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + l) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                if ((xminusy + l) % 2 != 0) {
                    if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev) || (Math.abs(dx) + Math.abs(dy) + (i - prev)) % 2 != 0) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)) / 2);
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                out.print("LR");
            }
            prev = i;
        }
        out.println();
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskG solver = new TaskG();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                if ((px + py + l) % 2 != 0) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + l) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                if ((xminusy + l) % 2 != 0) {
                    if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev) || (Math.abs(dx) + Math.abs(dy) + (i - prev)) % 2 != 0) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)) / 2);
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                out.print("LR");
            }
            prev = i;
        }
        out.println();
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskG solver = new TaskG();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskG {
    static class Intersector {
        long minxplusy = Long.MIN_VALUE;
        long maxxplusy = Long.MAX_VALUE;
        long minxminusy = Long.MIN_VALUE;
        long maxxminusy = Long.MAX_VALUE;

        void update(long kx, long ky, long a) {
            if (Math.abs(kx) != Math.abs(ky)) throw new RuntimeException();
            if (kx == 0) {
                if (a <= 0) return;
                minxplusy = Long.MAX_VALUE;
                maxxplusy = Long.MIN_VALUE;
                minxminusy = Long.MAX_VALUE;
                maxxminusy = Long.MIN_VALUE;
                return;
            }
            if (kx > 0) {
                if (ky > 0) {
                    maxxplusy = Math.min(maxxplusy, safeDivide(-a, kx));
                } else {
                    maxxminusy = Math.min(maxxminusy, safeDivide(-a, kx));
                }
            } else {
                if (ky < 0) {
                    minxplusy = Math.max(minxplusy, safeDivide(a + (-kx) - 1, -kx));
                } else {
                    minxminusy = Math.max(minxminusy, safeDivide(a + (-kx) - 1, -kx));
                }
            }
        }

        private long safeDivide(long a, long b) {
            if (a > 0) return a / b; else return (a - b + 1) / b;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int l = in.nextInt();
        boolean[] know = new boolean[l + 1];
        long[] k = new long[l + 1];
        long[] ax = new long[l + 1];
        long[] ay = new long[l + 1];
        know[0] = true;
        know[l] = true;
        k[l] = 1;
        boolean knowP = false;
        long px = 0;
        long py = 0;
        for (int i = 0; i < n; ++i) {
            long t = in.nextLong();
            long x = in.nextLong();
            long y = in.nextLong();
            if ((x + y + t) % 2 != 0) {
                out.println("NO");
                return;
            }
            int when = (int) (t % l);
            long ck = -t / l;
            if (!know[when]) {
                know[when] = true;
                k[when] = ck;
                ax[when] = x;
                ay[when] = y;
            } else {
                if (knowP) {
                    if (k[when] * px + ax[when] != ck * px + x || Math.abs(k[when] * (double) px + ax[when] - ck * (double) px - x) > 1e62) {
                        out.println("NO");
                        return;
                    }
                    if (k[when] * py + ay[when] != ck * py + y || Math.abs(k[when] * (double) py + ay[when] - ck * (double) py - y) > 1e62) {
                        out.println("NO");
                        return;
                    }
                } else {
                    knowP = true;
                    long numx = x - ax[when];
                    long numy = y - ay[when];
                    long den = k[when] - ck;
                    if (numx % den != 0 || numy % den != 0) {
                        out.println("NO");
                        return;
                    }
                    px = numx / den;
                    py = numy / den;
                }
            }
        }

        {
            Intersector intersector = new Intersector();
            int prev = 0;
            for (int i = 1; i <= l; ++i) if (know[i]) {
                long dk = k[i] - k[prev];
                long dax = ax[i] - ax[prev];
                long day = ay[i] - ay[prev];
                for (int kx = -1; kx <= 1; kx += 2) {
                    for (int ky = -1; ky <= 1; ky += 2) {
                       intersector.update(kx * dk, ky * dk, kx * dax + ky * day - (i - prev));
                    }
                }
                prev = i;
            }
            if (knowP) {
                if (px + py < intersector.minxplusy || px + py > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (px - py < intersector.minxminusy || px - py > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
            } else {
                if (intersector.minxplusy > intersector.maxxplusy) {
                    out.println("NO");
                    return;
                }
                if (intersector.minxminusy > intersector.maxxminusy) {
                    out.println("NO");
                    return;
                }
                long xplusy;
                if (intersector.minxplusy == Long.MIN_VALUE) {
                    if (intersector.maxxplusy == Long.MAX_VALUE) {
                        xplusy = 0;
                    } else {
                        xplusy = intersector.maxxplusy - 1;
                    }
                } else {
                    xplusy = intersector.minxplusy;
                }
                long xminusy;
                if (intersector.minxminusy == Long.MIN_VALUE) {
                    if (intersector.maxxminusy == Long.MAX_VALUE) {
                        xminusy = 0;
                    } else {
                        xminusy = intersector.maxxminusy - 1;
                    }
                } else {
                    xminusy = intersector.minxminusy;
                }
                if ((xplusy + xminusy) % 2 != 0) {
                    if (xplusy < intersector.maxxplusy) {
                        ++xplusy;
                    } else if (xminusy < intersector.maxxminusy) {
                        ++xminusy;
                    } else {
                        out.println("NO");
                        return;
                    }
                }
                px = (xplusy + xminusy) / 2;
                py = (xplusy - xminusy) / 2;
            }
        }

        int prev = 0;
        for (int i = 1; i <= l; ++i) if (know[i]) {
            long dk = k[i] - k[prev];
            long dax = ax[i] - ax[prev];
            long day = ay[i] - ay[prev];
            long dx = dk * px + dax;
            long dy = dk * py + day;
            if ((Math.abs(dx) + Math.abs(dy) > i - prev)) throw new RuntimeException();
            int extra = (int) ((i - prev - Math.abs(dx) - Math.abs(dy)));
            while (dx > 0) {
                out.print('R');
                --dx;
            }
            while (dx < 0) {
                out.print('L');
                ++dx;
            }
            while (dy > 0) {
                out.print('U');
                --dy;
            }
            while (dy < 0) {
                out.print('D');
                ++dy;
            }
            for (int j = 0; j < extra; ++j) {
                if (j % 2 == 0)
                    out.print("L");
                else
                    out.print("R");
            }
            prev = i;
        }
        out.println();
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}


You are given a rooted tree. Let's denote d(x) as depth of node x: depth of the root is 1, depth of any other node x is d(y) + 1, where y is a parent of x.The tree has the following property: every node x with d(x) = i has exactly ai children. Maximum possible depth of a node is n, and an = 0.We define fk as the number of unordered pairs of vertices in the tree such that the number of edges on the simple path between them is equal to k.Calculate fk modulo 109 + 7 for every 1 ≤ k ≤ 2n - 2.

The first line of input contains an integer n (2  ≤  n  ≤  5 000) — the maximum depth of a node. The second line of input contains n - 1 integers a1,  a2,  ...,  an - 1 (2 ≤  ai  ≤ 109), where ai is the number of children of every node x such that d(x) = i. Since an = 0, it is not given in the input.

Print 2n - 2 numbers. The k-th of these numbers must be equal to fk modulo 109 + 7.

NoteThis the tree from the first sample:

import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.flush();out.close();
    }
        static class TaskE {
          long mod=(long)(1E9)+7;
          long rpe(long a){long b=mod-2;
           long ans=1;
           while(b!=0){
            if(b%2!=0)ans=(ans*a)%mod;
            b/=2;a=a*a%mod;
           }return ans;
          }
          long i2=rpe(2);
          long f(long c){
           return c*(c-1+mod)%mod*i2%mod;
          }
          public void solve(int testNumber, InputReader in, PrintWriter out) {
           int n=in.nextInt();
           long a[]=new long[n+10];for(int i=1;i<=n-1;i++)a[i]=in.nextLong();a[0]=1;
           long c=1;long ans[]=new long[2*n-1];
           long dp[][]=new long[2][2*n-1];int t=0;
           long v[][]=new long[n+10][n+10];
           for(int i=1;i<=n-1;i++){
            v[i][i]=(a[i]-1+mod)%mod;
            for(int j=i+1;j<=n-1;j++)v[i][j]=v[i][j-1]*a[j]%mod;
           }
           for(int i=2;i<=n;i++){
            c=c*a[i-1]%mod;
            Arrays.fill(dp[t],0);
            for(int j=2;j<2*(i-1);j++){
             dp[t][j]=dp[t^1][j-1]%mod;
            }
            dp[t][1]=1;
            for(int j=0;j<2*n-1;j++)ans[j]=(ans[j]+dp[t][j]*c%mod)%mod;
            for(int j=i-1;j>=1;j--){
             dp[t][2*(i-j)]=(dp[t][2*(i-j)]+v[j][i-1])%mod;
             ans[2*(i-j)]=(ans[2*(i-j)]+c*v[j][i-1]%mod*i2%mod)%mod;
            }
            t=t^1;
           }
           /*for(int i=2;i<=n;i++){
            c=(c*a[i-1])%mod;
            for(int j=i-1;j>=1;j--){
             long m=1;
             for(int k=i-j;k<=2*(i-j);k++){
              long v=c*m%mod;if(k==2*(i-j))v=v*i2%mod;//f(a[j])*a[j-1]%mod;
              ans[k]=(ans[k]+v)%mod;
              if(k==i-j)m=m*(a[j+k-(i-j)]-1+mod)%mod;
              else m=m*a[j+k-(i-j)]%mod;
             }
            }
           }*/
           for(int i=1;i<2*n-1;i++)out.print(ans[i]+" ");
          }
         /*pair ja[][];long w[];int from[],to[],c[];
             void make(int n,int m,InputReader in){
              ja=new pair[n+1][];w=new long[m];from=new int[m];to=new int[m];c=new int[n+1];
              for(int i=0;i<m;i++){
               int u=in.nextInt(),v=in.nextInt();long wt=in.nextLong();
               c[u]++;c[v]++;from[i]=u;to[i]=v;w[i]=wt;
              }
              for(int i=1;i<=n;i++){
               ja[i]=new pair[c[i]];c[i]=0;
              }
              for(int i=0;i<m;i++){
               ja[from[i]][c[from[i]]++]=new pair(to[i],w[i]);
               ja[to[i]][c[to[i]]++]=new pair(from[i],w[i]);
              }
             }*/
        int[] radixSort(int[] f){ return radixSort(f, f.length); }
	int[] radixSort(int[] f, int n)
	{
		int[] to = new int[n];
		{
			int[] b = new int[65537];
			for(int i = 0;i < n;i++)b[1+(f[i]&0xffff)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < n;i++)to[b[f[i]&0xffff]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		{
			int[] b = new int[65537];
			for(int i = 0;i < n;i++)b[1+(f[i]>>>16)]++;
			for(int i = 1;i <= 65536;i++)b[i]+=b[i-1];
			for(int i = 0;i < n;i++)to[b[f[i]>>>16]++] = f[i];
			int[] d = f; f = to;to = d;
		}
		return f;
	}
    }
    static class InputReader {
        BufferedReader br;
        StringTokenizer st;
        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
            st = null;
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}

import java.io.*;

/**
 * Created by dalt on 2018/4/2.
 */
public class CF954H {
    public static final int MOD = (int) (1e9 + 7);
    public static BlockReader input;
    public static PrintStream output;

    public static void main(String[] args) throws FileNotFoundException {
        if (System.getProperty("ONLINE_JUDGE") == null) {
            input = new BlockReader(new FileInputStream("D:\\DataBase\\TESTCASE\\codeforces\\CF954H.in"));
            output = System.out;
        } else {
            input = new BlockReader(System.in);
            output = new PrintStream(new BufferedOutputStream(System.out), false);
        }

        solve();

        output.flush();
    }

    public static void solve() {
        int n = input.nextInteger();
        long[] a = new long[n];
        long[] aRev = new long[n];
        long[] aChoose2Child = new long[n + 1];
        long[] aChoose2ChildRev = new long[n + 1];
        long negTwo = pow(2, MOD - 2);
        for (int i = 0, until = n - 1; i < until; i++) {
            a[i] = input.nextInteger();
            aRev[i] = pow(a[i], MOD - 2);
        }

        for (int i = 0; i < n; i++) {
            aChoose2Child[i] = a[i] * (a[i] - 1) % MOD;
            aChoose2ChildRev[i] = pow( aChoose2Child[i], MOD - 2);
        }

        long[] prefixMul = new long[n];
        long[] prefixRev = new long[n];
        prefixMul[0] = 1;
        prefixRev[0] = 1;
        for (int i = 1; i < n; i++) {
            prefixMul[i] = prefixMul[i - 1] * a[i - 1] % MOD;
            prefixRev[i] = prefixRev[i - 1] * aRev[i - 1] % MOD;
        }

        int m = (n - 1) * 2;
        long[] f = new long[m + 1];
        Loop<long[][]> dpLoop = new Loop<>(new long[m + 1][3], new long[m + 1][3]);
        final int ROTATE = 0;
        final int BALANCE = 2;
        final int LINE = 1;

        {
            long[][] next = dpLoop.turn();
            next[0][BALANCE] = 1;
        }
        for (int i = n - 2; i >= 0; i--) {
            long[][] former = dpLoop.get(0);
            long[][] next = dpLoop.turn();

            long aChooseRev = aChoose2ChildRev[i + 1] * a[i + 1] % MOD * a[i + 1] % MOD * aChoose2Child[i] % MOD;
            for (int j = 2, until = ((n - 1) - i) * 2; j <= until; j++) {
                next[j][ROTATE] = (former[j - 2][ROTATE] * aChooseRev % MOD + former[j - 2][LINE] * aChoose2Child[i] % MOD) % MOD;

                int halfJ = j >> 1;
                if ((j & 1) == 0 && i + halfJ < n) {
                    long possible = prefixMul[i + halfJ] * prefixRev[i + 1] % MOD;
                    possible = possible * possible % MOD;
                    next[j][BALANCE] = possible * aChoose2Child[i]  % MOD * negTwo % MOD;
                } else {
                    next[j][BALANCE] = 0;
                }

                if (i + j < n) {
                    next[j][LINE] = prefixMul[i + j] * prefixRev[i] % MOD;
                } else {
                    next[j][LINE] = 0;
                }
            }

            next[2][BALANCE] = aChoose2Child[i] * negTwo % MOD;
            next[1][LINE] = a[i];
            next[0][BALANCE] = 1;

            for (int j = 1; j <= m; j++) {
                f[j] = (f[j] + (next[j][LINE] + next[j][ROTATE] + next[j][BALANCE]) * prefixMul[i]) % MOD;
            }
        }

        for (int i = 1; i <= m; i++) {
            output.print(f[i]);
            output.print(' ');
        }
    }

    public static long pow(long x, int n) {
        int bit = 31 - Integer.numberOfLeadingZeros(n);
        long product = 1;
        for (; bit >= 0; bit--) {
            product = product * product % MOD;
            if (((1 << bit) & n) != 0) {
                product = product * x % MOD;
            }
        }
        return product;
    }

    public static class Loop<T> {
        T[] data;
        int offset;

        public Loop(T... data) {
            this.data = data;
        }

        public T turn() {
            offset++;
            return get(0);
        }

        public T get(int index) {
            return data[(index + offset) % data.length];
        }
    }

    public static class BlockReader {
        static final int EOF = -1;
        InputStream is;
        byte[] dBuf;
        int dPos, dSize, next;
        StringBuilder builder = new StringBuilder();

        public BlockReader(InputStream is) {
            this(is, 4096);
        }

        public BlockReader(InputStream is, int bufSize) {
            this.is = is;
            dBuf = new byte[bufSize];
            next = nextByte();
        }

        public int nextByte() {
            while (dPos >= dSize) {
                if (dSize == -1) {
                    return EOF;
                }
                dPos = 0;
                try {
                    dSize = is.read(dBuf);
                } catch (Exception e) {
                }
            }
            return dBuf[dPos++];
        }

        public String nextBlock() {
            builder.setLength(0);
            skipBlank();
            while (next != EOF && !Character.isWhitespace(next)) {
                builder.append((char) next);
                next = nextByte();
            }
            return builder.toString();
        }

        public void skipBlank() {
            while (Character.isWhitespace(next)) {
                next = nextByte();
            }
        }

        public int nextInteger() {
            skipBlank();
            int ret = 0;
            boolean rev = false;
            if (next == '+' || next == '-') {
                rev = next == '-';
                next = nextByte();
            }
            while (next >= '0' && next <= '9') {
                ret = (ret << 3) + (ret << 1) + next - '0';
                next = nextByte();
            }
            return rev ? -ret : ret;
        }

        public int nextBlock(char[] data, int offset) {
            skipBlank();
            int index = offset;
            int bound = data.length;
            while (next != EOF && index < bound && !Character.isWhitespace(next)) {
                data[index++] = (char) next;
                next = nextByte();
            }
            return index - offset;
        }

        public boolean hasMore() {
            skipBlank();
            return next != EOF;
        }
    }
}

import java.util.Scanner;

public class Main {
    private static final int P = 1000000007;
    private static long pow(long x, int y) {
        long ret = 1;
        while (y > 0) {
            if (y %2 == 1) {
                ret = ret * x % P;
            }
            x = x * x % P;
            y /= 2;
        }
        return ret;
    }
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int[] a = new int[n + 1];
        long[] rev = new long[n + 1];
        long[] res = new long[2 * n + 1];
        long[][] down = new long[n + 1][n + 1];
        long[][] up = new long[2][2 * n + 1];
        for (int i = 1; i < n; ++i) {
            a[i] = cin.nextInt();
            rev[i] = pow(a[i], P - 2);
        }
        for (int i = n; i > 0; --i) {
            down[i][0] = 1;
            for (int j = 1; j < n; ++j) {
                if (i + j > n) {
                    break;
                }
                down[i][j] = down[i + 1][j - 1] * a[i] % P;
            }
        }

        long number = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                res[j] = (res[j] + number * down[i][j] % P) % P;
            }
            number = (number * a[i]) % P;
        }
        int pre = 0;
        number = a[1];
        for (int i = 2; i <= n; ++i) {
            int now = 1 - pre;
            for (int j = 0; j <= 2 * n - 2; ++j) {
                up[now][j] = 0;
            }
            up[now][1] = 1;
            for (int j = 2; j <= 2 * n - 2; ++j) {
                if (j - 1 <= n) {
                    up[now][j] = (up[pre][j - 1] + down[i - 1][j - 1] * rev[i - 1] % P * (a[i - 1] - 1) % P) % P;
                } else {
                    up[now][j] = up[pre][j - 1];
                }
            }
            for (int j = 1; j <= 2 * n - 2; ++j) {
                res[j] = (res[j] + number * up[now][j]  % P) % P;
            }
            number = (number * a[i]) % P;
            pre = now;
        }
        for (int i = 1; i <= 2 * n - 2; ++i) {
            System.out.print(res[i] * pow(2, P - 2) % P + " ");
        }
    }
}

// practice with rainboy
// https://codeforces.com/blog/entry/58519
import java.io.*;
import java.util.*;

public class CF954H extends PrintWriter {
	CF954H() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF954H o = new CF954H(); o.main(); o.flush();
	}

	static final int MD = 1000000007, INV2 = 500000004;
	int d_, x_, y_;
	void gcd_(int a, int b) {
		if (b == 0) {
			d_ = a; x_ = 1; y_ = 0;
		} else {
			gcd_(b, a % b);
			int t = x_ - a / b * y_; x_ = y_; y_ = t;
		}
	}
	int inv(int a) {
		gcd_(a, MD);
		return x_;
	}
	void main() {
		int n = sc.nextInt();
		int[] aa = new int[n - 1];
		for (int h = 0; h < n - 1; h++)
			aa[h] = sc.nextInt();
		int[] pp = new int[n], pp_ = new int[n];
		pp[n - 1] = pp_[n - 1] = 1;
		for (int h = n - 2; h >= 0; h--)
			pp_[h] = inv(pp[h] = (int) ((long) aa[h] * pp[h + 1] % MD));
		int[][] qq = new int[n][n * 2];
		for (int h = 0; h < n; h++)
			qq[h][0] = 1;
		for (int k = 1; k < n * 2; k++)
			for (int h = 1; h < n; h++) {
				long x = qq[h - 1][k - 1];
				if (k >= 2 && h + k - 2 < n) {
					long p = (long) pp[h] * pp_[h + k - 2] % MD;
					x = (x + (aa[h - 1] - 1) * p) % MD;
				}
				qq[h][k] = (int) x;
			}
		for (int k = 1; k < n * 2 - 1; k++) {
			long x = 0;
			for (int h = 0; h < n; h++) {
				long cnt = (long) pp[0] * pp_[h] % MD;
				long p = h + k < n ? (long) pp[h] * pp_[h + k] % MD : 0;
				long q = qq[h][k];
				x = (x + (long) cnt * (p + q)) % MD;
			}
			x = x * INV2 % MD;
			if (x < 0)
				x += MD;
			print(x + " ");
		}
		println();
	}
}

import java.io.*;
import java.util.*;

public class A {
	public static void main (String[] args) { new A(); }

	int MOD = (int)1e9+7;

	public A() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		int n = fs.nextInt();
		int[] kids = new int[n];
		for(int i = 0; i < n-1; i++) kids[i] = fs.nextInt();

		int[][] walkDown = new int[n][n];
		int[][] walkDown2 = new int[n][n];

		for(int i = 0; i < n; i++) {
			int prod = 1, prod2 = 1;
			for(int j = 1; j < n; j++) {
				if(i + j - 1 >= n) break;

				if(j == 1) prod2 = mult(prod2, Math.max(0, kids[i + j - 1] - 1));
				else prod2 = mult(prod2, kids[i + j - 1]);

				prod = mult(prod, kids[i + j - 1]);

				walkDown[i][j] = prod;
				walkDown2[i][j] = prod2;
			}
		}

		for(int j = 0; j < n; j++) {
			for(int d = 1; ; d++) {
				int row = 0+d;
				int col = j+d;
				if(row >= n || col >= n) break;

				walkDown2[row][col] = add(walkDown2[row][col], walkDown2[row-1][col-1]);
			}
		}
		for(int i = 1; i < n; i++) {
			for(int d = 1; ; d++) {
				int row = i+d;
				int col = 0+d;
				if(row >= n || col >= n) break;

				walkDown2[row][col] = add(walkDown2[row][col], walkDown2[row-1][col-1]);
			}
		}

		int[] freq = new int[n];
		freq[0] = 1;
		for(int i = 1; i < n; i++) {
			freq[i] = mult(freq[i-1], kids[i-1]);
		}

		int[] totWays = new int[2 * n];

		for(int kid = n-1; kid >= 0; kid--) {
			for(int dist = 1; dist <= 2 * n - 2; dist++) {
				int tot = 0;

				if(dist < n) tot = add(tot, walkDown[kid][dist]);

				if(kid > 0) {
					int row = kid-1, col = dist-1;
					if(row >= n || col >= n) {
						int d = Math.max(row-n+1, col-n+1);
						row -= d;
						col -= d;
					}
					int finRow = kid-dist, finCol = 0;
					if(finRow < 0) {
						int add = -finRow;
						finRow += add;
						finCol += add;
					}

					if(row >= finRow) {
						int x = walkDown2[row][col];
						if(finRow > 0 && finCol > 0) {
							x -= walkDown2[finRow-1][finCol-1];
						}
						tot = add(tot, x);
					}
				}

//				System.out.println(kid + " " + dist + " " + tot);
				if(kid-dist >= 0) tot = add(tot, 1);

				totWays[dist] = add(totWays[dist], mult(tot, freq[kid]));
			}
//			System.out.println();
		}

		int INV2 = (MOD+1)/2;

		for(int i = 0; i < totWays.length; i++) {
			totWays[i] = mult(totWays[i], INV2);
		}

		for(int i = 1; i <= 2 * n - 2; i++) {
			if(i > 1) out.print(" ");
			out.print(totWays[i]);
		}
		out.println();

		out.close();
	}

	int add(int a, int b) {
		a += b;
		if(a >= MOD) a -= MOD;
		return a;
	}

	int mult(long a, long b) {
		return (int)(a * b % MOD);
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}