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

public class A {

	private void solve() throws IOException {
		char[] c = nextToken().toCharArray();
		int[] a = new int[6];
		for (int i = 0; i < 6; i++) {
			a[i] = c[i];
		}
		int res = generateCubes(a);
		out.println(res);
	}

	static boolean nextPermutation(int[] p) {
		for (int i = p.length - 2; i >= 0; --i) {
			if (p[i] >= p[i + 1]) {
				continue;
			}
			int j = i + 1;
			while (j + 1 < p.length && p[j + 1] > p[i]) {
				j++;
			}
			int t = p[i];
			p[i] = p[j];
			p[j] = t;
			Arrays.sort(p, i + 1, p.length);
			return true;
		}
		return false;
	}

	static int generateCubes(int[] alphabet) {
		Cube[] allcubes = generateCubes();
		Arrays.sort(alphabet);

		HashSet<Cube> visited = new HashSet<A.Cube>();
		int res = 0;
		int[] a1 = new int[6];
		do {
			boolean ok = true;
			for (Cube c : allcubes) {
				for (int i = 0; i < 6; i++) {
					a1[c.a[i]] = alphabet[i];
				}
				Cube c1 = new Cube(a1);
				if (visited.contains(c1)) {
					ok = false;
					break;
				}
			}
			if (ok) {
				res++;
				visited.add(new Cube(alphabet.clone()));
			}
		} while (nextPermutation(alphabet));
		return res;
	}

	static Cube[] generateCubes() {
		Cube start = new Cube(new int[] { 0, 1, 2, 3, 4, 5 });
		Queue<Cube> q = new ArrayDeque<A.Cube>();
		HashSet<Cube> visited = new HashSet<A.Cube>();
		q.add(start);
		visited.add(start);
		while (!q.isEmpty()) {
			Cube u = q.poll();
			for (Cube v : new Cube[] { u.rotate1(), u.rotate2(), u.rotate3() }) {
				if (!visited.contains(v)) {
					visited.add(v);
					q.add(v);
				}
			}
		}
		return (Cube[]) visited.toArray(new Cube[visited.size()]);
	}

	static class Cube {
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + Arrays.hashCode(a);
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Cube other = (Cube) obj;
			if (!Arrays.equals(a, other.a))
				return false;
			return true;
		}

		int[] a;

		public Cube(int[] a) {
			this.a = a;
		}

		Cube rotate1() {
			int[] a1 = a.clone();
			a1[0] = a[5];
			a1[5] = a[1];
			a1[1] = a[4];
			a1[4] = a[0];
			return new Cube(a1);
		}

		Cube rotate2() {
			int[] a1 = a.clone();
			a1[0] = a[3];
			a1[3] = a[1];
			a1[1] = a[2];
			a1[2] = a[0];
			return new Cube(a1);
		}

		Cube rotate3() {
			int[] a1 = a.clone();
			a1[4] = a[3];
			a1[3] = a[5];
			a1[5] = a[2];
			a1[2] = a[4];
			return new Cube(a1);
		}

	}

	public static void main(String[] args) {
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			new A().solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(239);
		}
	}

	static BufferedReader br;
	static StringTokenizer st;
	static PrintWriter out;

	static String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String line = br.readLine();
			if (line == null) {
				return null;
			}
			st = new StringTokenizer(line);
		}
		return st.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	static long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
}


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(in, out);
        out.close();
    }
}

class Task {

    //    static int MAX = 1000001;
//    List<List<Integer>> g = new ArrayList<>();
//    int n;
//    char[] s;

    public void solve(Scanner in, PrintWriter out) {
        int t = in.nextInt();
        int l = in.nextInt();
        int r = in.nextInt();

        long[] a = new long[r + 1];
        boolean[] prime = new boolean[r + 1];
        Arrays.fill(prime, true);
        prime[0] = prime[1] = false;
        for (int i = 2; i <= r; i++) {
            if (prime[i]) {
                if ((long)i * i <= (long)r) {
                    for (long j = (long)i*i; j <= r; j+=i) {
                        prime[(int)j] = false;
                    }
                }
            }
        }

        List<Integer> pr = new ArrayList<>();
        for (int i = 2; i <= r; i++) {
            if (prime[i]) {
                pr.add(i);
                a[i] = (long) i * (i - 1) / 2;
            } else {
                for (Integer p : pr) {
                    if (i % p == 0) {
                        int p1 = i / p;
                        int max = Math.max(p, p1);
                        int min = Math.min(p, p1);
                        a[i] = a[min] * max + a[max];
                        break;
                    }
                }
            }
        }

        long tt[] = new long[r];
        tt[0] = 1;
        long temp = 1;
        for (int i = 1; i <= r - l; i++) {
            temp *= (long)t;
            temp %= 1000000007;
            tt[i] = temp;
        }

        long res = 0;
        for (int i = 0; i <= r - l; i++) {
            res += (tt[i] * (a[i + l] % 1000000007)) % 1000000007;
            res %= 1000000007;
        }

        System.out.println(res);
    }

}

class Utils {

    public static int binarySearch(int[] a, int key) {
        int s = 0;
        int f = a.length;
        while (f > s) {
            int mid = (s + f) / 2;
            if (a[mid] > key) {
                f = mid - 1;
            } else if (a[mid] <= key) {
                s = mid + 1;
            }
        }
        return -1;
    }

    public static long gcd(long a, long b) {
        return b != 0 ? gcd(b, a % b) : a;
    }

    public static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    static List<Integer> prime(int number) {
        List<Integer> a = new ArrayList<>();
        for (int i = 2; i * i <= number; i++) {
            if (number % i == 0) {
                a.add(i);
                number /= i;
                i = 1;
            }
        }
        a.add(number);
        return a;
    }
}

class Pair<T, U> {
    public T a;
    public U b;

    public Pair(T a, U b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Pair<?, ?> pair = (Pair<?, ?>) o;

        if (a != null ? !a.equals(pair.a) : pair.a != null) return false;
        return b != null ? b.equals(pair.b) : pair.b == null;
    }

    @Override
    public int hashCode() {
        int result = a != null ? a.hashCode() : 0;
        result = 31 * result + (b != null ? b.hashCode() : 0);
        return result;
    }
}

class Vect {
    public int a;
    public int b;

    public Vect(int a, int b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Vect vect = (Vect) o;

        if (a != vect.a) return false;
        return b == vect.b;
    }

    @Override
    public int hashCode() {
        int result = a;
        result = 31 * result + b;
        return result;
    }
}

class Tri {
    public int a;
    public int b;
    public int c;

    public Tri(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Tri tri = (Tri) o;

        if (a != tri.a) return false;
        return b == tri.b;
    }

    @Override
    public int hashCode() {
        int result = a;
        result = 31 * result + b;
        return result;
    }
}

class Triple<T, U, P> {
    public T a;
    public U b;
    public P c;

    public Triple(T a, U b, P c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Triple<?, ?, ?> triple = (Triple<?, ?, ?>) o;

        if (a != null ? !a.equals(triple.a) : triple.a != null) return false;
        return b != null ? b.equals(triple.b) : triple.b == null;
    }

    @Override
    public int hashCode() {
        int result = a != null ? a.hashCode() : 0;
        result = 31 * result + (b != null ? b.hashCode() : 0);
        return result;
    }
}

class Scanner {
    BufferedReader in;
    StringTokenizer tok;

    public Scanner(InputStream in) {
        this.in = new BufferedReader(new InputStreamReader(in));
        tok = new StringTokenizer("");
    }

    private String tryReadNextLine() {
        try {
            return in.readLine();
        } catch (Exception e) {
            throw new InputMismatchException();
        }
    }

    public String nextToken() {
        while (!tok.hasMoreTokens()) {
            tok = new StringTokenizer(next());
        }
        return tok.nextToken();
    }

    public String next() {
        String newLine = tryReadNextLine();
        if (newLine == null)
            throw new InputMismatchException();
        return newLine;
    }

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

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


import java.util.*;
import java.io.*;
import java.math.*;
import java.lang.reflect.*;

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		Task solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

interface Task {
	public void solve(int testNumber, InputReader in, OutputWriter out);
}

class TaskA implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int n=in.readInt();
		while (n-->0) {
			int a=in.readInt(), b=in.readInt();
			out.printLine(gcd(a, b));
		}
	}

	int gcd(int a, int b) {
		return b==0?0:a/b+gcd(b, a%b);
	}

}

class TaskB implements Task {

	boolean[] vis;
	int[] arr;
	List<Long> div;
	boolean[] sieve;

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int n=in.readInt(), m=in.readInt();
		arr=new int[n+1];
		vis=new boolean[n+1];
		sieve=IntegerUtils.generatePrimalityTable(n+1);
		while (m-->0) {
			char c=in.readCharacter();
			int x=in.readInt();
			div=IntegerUtils.getDivisors(x);
			if (c=='+') {
				if (vis[x]) {
					out.printLine("Already on");
					continue;
				}
				boolean val=true;
				for (long y: div) if (sieve[(int)y] && arr[(int)y]>0) {
					val=false;
					out.printLine("Conflict with", arr[(int)y]);
					break;
				}
				if (!val) continue;
				out.printLine("Success");
				vis[x]=true;
				for (long y: div) if (sieve[(int)y]) arr[(int)y]=x;
			}
			else if (vis[x]) {
				out.printLine("Success");
				vis[x]=false;
				for (long y: div) arr[(int)y]=0;
			}
			else out.printLine("Already off");
		}
	}

}

class TaskC implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int a=in.readInt(), b=in.readInt();
		long l=IntegerUtils.lcm(a, b);
		if (Math.abs(l/a-l/b)<=1) out.printLine("Equal");
		else out.printLine(a<b?"Dasha":"Masha");
	}

}

class TaskD implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int n=in.readInt(), m=in.readInt();

	}
}

class TaskE implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {

	}

}

class TaskF implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {

	}

}

class TaskG implements Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {

	}

}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
				outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(char[] array) {
		writer.print(array);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void print(int[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(long[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(Collection<Integer> collection) {
		boolean first = true;
		for (int value : collection) {
			if (first)
				first = false;
			else
				writer.print(' ');
			writer.print(value);
		}
	}

	public void printLine(int[] array) {
		print(array);
		writer.println();
	}

	public void printLine(long[] array) {
		print(array);
		writer.println();
	}

	public void printLine(Collection<Integer> collection) {
		print(collection);
		writer.println();
	}

	public void printLine() {
		writer.println();
	}

	public void printLine(Object... objects) {
		print(objects);
		writer.println();
	}

	public void print(char i) {
		writer.print(i);
	}

	public void printLine(char i) {
		writer.println(i);
	}

	public void printLine(char[] array) {
		writer.println(array);
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

	public void close() {
		writer.close();
	}

	public void flush() {
		writer.flush();
	}

	public void print(long i) {
		writer.print(i);
	}

	public void printLine(long i) {
		writer.println(i);
	}

	public void print(int i) {
		writer.print(i);
	}

	public void printLine(int i) {
		writer.println(i);
	}
}

class InputReader {
	private boolean finished = false;

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int peek() {
		if (numChars == -1)
			return -1;
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				return -1;
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}

	public String next() {
		return readString();
	}

	public SpaceCharFilter getFilter() {
		return filter;
	}

	public void setFilter(SpaceCharFilter filter) {
		this.filter = filter;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class IOUtils {
	public static Pair<Integer, Integer> readIntPair(InputReader in) {
		int first = in.readInt();
		int second = in.readInt();
		return Pair.makePair(first, second);
	}

	public static Pair<Long, Long> readLongPair(InputReader in) {
		long first = in.readLong();
		long second = in.readLong();
		return Pair.makePair(first, second);
	}

	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}

	public static long[] readLongArray(InputReader in, int size) {
		long[] array = new long[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readLong();
		return array;
	}

	public static double[] readDoubleArray(InputReader in, int size) {
		double[] array = new double[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readDouble();
		return array;
	}

	public static String[] readStringArray(InputReader in, int size) {
		String[] array = new String[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readString();
		return array;
	}

	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}

	public static Pair<Integer, Integer>[] readIntPairArray(InputReader in,
			int size) {
		@SuppressWarnings({ "unchecked" })
		Pair<Integer, Integer>[] result = new Pair[size];
		for (int i = 0; i < size; i++)
			result[i] = readIntPair(in);
		return result;
	}

	public static Pair<Long, Long>[] readLongPairArray(InputReader in, int size) {
		@SuppressWarnings({ "unchecked" })
		Pair<Long, Long>[] result = new Pair[size];
		for (int i = 0; i < size; i++)
			result[i] = readLongPair(in);
		return result;
	}

	public static void readIntArrays(InputReader in, int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readInt();
		}
	}

	public static void readLongArrays(InputReader in, long[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readLong();
		}
	}

	public static void readDoubleArrays(InputReader in, double[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readDouble();
		}
	}

	public static char[][] readTable(InputReader in, int rowCount,
			int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}

	public static int[][] readIntTable(InputReader in, int rowCount,
			int columnCount) {
		int[][] table = new int[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readIntArray(in, columnCount);
		return table;
	}

	public static double[][] readDoubleTable(InputReader in, int rowCount,
			int columnCount) {
		double[][] table = new double[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readDoubleArray(in, columnCount);
		return table;
	}

	public static long[][] readLongTable(InputReader in, int rowCount,
			int columnCount) {
		long[][] table = new long[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readLongArray(in, columnCount);
		return table;
	}

	public static String[][] readStringTable(InputReader in, int rowCount,
			int columnCount) {
		String[][] table = new String[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readStringArray(in, columnCount);
		return table;
	}

	public static String readText(InputReader in) {
		StringBuilder result = new StringBuilder();
		while (true) {
			int character = in.read();
			if (character == '\r')
				continue;
			if (character == -1)
				break;
			result.append((char) character);
		}
		return result.toString();
	}

	public static void readStringArrays(InputReader in, String[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readString();
		}
	}

	public static void printTable(OutputWriter out, char[][] table) {
		for (char[] row : table)
			out.printLine(new String(row));
	}
}

class ArrayUtils {
	private static int[] tempInt = new int[0];
	private static long[] tempLong = new long[0];

	public static Integer[] generateOrder(int size) {
		Integer[] order = new Integer[size];
		for (int i = 0; i < size; i++)
			order[i] = i;
		return order;
	}

	public static void fill(short[][] array, short value) {
		for (short[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(long[][] array, long value) {
		for (long[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(double[][] array, double value) {
		for (double[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(double[][][] array, double value) {
		for (double[][] row : array)
			fill(row, value);
	}

	public static void fill(double[][][][] array, double value) {
		for (double[][][] row : array)
			fill(row, value);
	}

	public static void fill(double[][][][][] array, double value) {
		for (double[][][][] row : array)
			fill(row, value);
	}

	public static void fill(long[][][] array, long value) {
		for (long[][] row : array)
			fill(row, value);
	}

	public static void fill(long[][][][] array, long value) {
		for (long[][][] row : array)
			fill(row, value);
	}

	public static void fill(long[][][][][] array, long value) {
		for (long[][][][] row : array)
			fill(row, value);
	}

	public static void fillColumn(long[][] array, int index, long value) {
		for (long[] row : array)
			row[index] = value;
	}

	public static void fillColumn(int[][] array, int index, int value) {
		for (int[] row : array)
			row[index] = value;
	}

	public static void fill(int[][] array, int value) {
		for (int[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(boolean[][] array, boolean value) {
		for (boolean[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(boolean[][][] array, boolean value) {
		for (boolean[][] row : array)
			fill(row, value);
	}

	public static long sumArray(int[] array) {
		long result = 0;
		for (int element : array)
			result += element;
		return result;
	}

	public static int[] range(int from, int to) {
		int[] result = new int[Math.max(from, to) - Math.min(from, to) + 1];
		int index = 0;
		if (to > from) {
			for (int i = from; i <= to; i++)
				result[index++] = i;
		} else {
			for (int i = from; i >= to; i--)
				result[index++] = i;
		}
		return result;
	}

	public static void fill(int[][][] array, int value) {
		for (int[][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(short[][][] array, short value) {
		for (short[][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(int[][][][] array, int value) {
		for (int[][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(short[][][][] array, short value) {
		for (short[][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(int[][][][][] array, int value) {
		for (int[][][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(short[][][][][] array, short value) {
		for (short[][][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(int[][][][][][] array, int value) {
		for (int[][][][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(short[][][][][][] array, short value) {
		for (short[][][][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(int[][][][][][][] array, int value) {
		for (int[][][][][][] subArray : array)
			fill(subArray, value);
	}

	public static void fill(short[][][][][][][] array, short value) {
		for (short[][][][][][] subArray : array)
			fill(subArray, value);
	}

	public static Integer[] order(int size, Comparator<Integer> comparator) {
		Integer[] order = generateOrder(size);
		Arrays.sort(order, comparator);
		return order;
	}

	public static <T> void fill(T[][] array, T value) {
		for (T[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(char[][] array, char value) {
		for (char[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(byte[][] array, byte value) {
		for (byte[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(byte[][][] array, byte value) {
		for (byte[][] row : array)
			fill(row, value);
	}

	public static void fill(byte[][][][] array, byte value) {
		for (byte[][][] row : array)
			fill(row, value);
	}

	public static long multiply(int[] first, int[] second) {
		long result = 0;
		for (int i = 0; i < first.length; i++)
			result += (long) first[i] * second[i];
		return result;
	}

	public static int[] createOrder(int size) {
		int[] order = new int[size];
		for (int i = 0; i < size; i++)
			order[i] = i;
		return order;
	}

	public static int[] sort(int[] array, IntComparator comparator) {
		return sort(array, 0, array.length, comparator);
	}

	public static int[] sort(int[] array, int from, int to,
			IntComparator comparator) {
		Integer[] intArray = new Integer[to - from];
		for (int i = from; i < to; i++)
			intArray[i - from] = array[i];
		Arrays.sort(intArray, comparator);
		for (int i=from; i<to; i++) array[i]=intArray[i-from];
		return array;
	}

	private static void ensureCapacityInt(int size) {
		if (tempInt.length >= size)
			return;
		size = Math.max(size, tempInt.length << 1);
		tempInt = new int[size];
	}

	private static void ensureCapacityLong(int size) {
		if (tempLong.length >= size)
			return;
		size = Math.max(size, tempLong.length << 1);
		tempLong = new long[size];
	}

	private static void sortImpl(int[] array, int from, int to, int[] temp,
			int fromTemp, int toTemp, IntComparator comparator) {
		if (to - from <= 1)
			return;
		int middle = (to - from) >> 1;
		int tempMiddle = fromTemp + middle;
		sortImpl(temp, fromTemp, tempMiddle, array, from, from + middle,
				comparator);
		sortImpl(temp, tempMiddle, toTemp, array, from + middle, to, comparator);
		int index = from;
		int index1 = fromTemp;
		int index2 = tempMiddle;
		while (index1 < tempMiddle && index2 < toTemp) {
			if (comparator.compare(temp[index1], temp[index2]) <= 0)
				array[index++] = temp[index1++];
			else
				array[index++] = temp[index2++];
		}
		if (index1 != tempMiddle)
			System.arraycopy(temp, index1, array, index, tempMiddle - index1);
		if (index2 != toTemp)
			System.arraycopy(temp, index2, array, index, toTemp - index2);
	}

	public static int[] order(final int[] array) {
		return sort(createOrder(array.length), new IntComparator() {
			public int compare(Integer first, Integer second) {
				if (array[first] < array[second])
					return -1;
				if (array[first] > array[second])
					return 1;
				return 0;
			}
		});
	}

	public static int[] order(final long[] array) {
		return sort(createOrder(array.length), new IntComparator() {
			public int compare(Integer first, Integer second) {
				if (array[first] < array[second])
					return -1;
				if (array[first] > array[second])
					return 1;
				return 0;
			}
		});
	}

	public static int[] unique(int[] array) {
		return unique(array, 0, array.length);
	}

	public static int[] unique(int[] array, int from, int to) {
		if (from == to)
			return new int[0];
		int count = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				count++;
		}
		int[] result = new int[count];
		result[0] = array[from];
		int index = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				result[index++] = array[i];
		}
		return result;
	}

	public static char[] unique(char[] array) {
		return unique(array, 0, array.length);
	}

	public static char[] unique(char[] array, int from, int to) {
		if (from == to)
			return new char[0];
		int count = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				count++;
		}
		char[] result = new char[count];
		result[0] = array[from];
		int index = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				result[index++] = array[i];
		}
		return result;
	}

	public static int maxElement(int[] array) {
		return maxElement(array, 0, array.length);
	}

	public static int maxElement(int[] array, int from, int to) {
		int result = Integer.MIN_VALUE;
		for (int i = from; i < to; i++)
			result = Math.max(result, array[i]);
		return result;
	}

	public static int[] order(final double[] array) {
		return sort(createOrder(array.length), new IntComparator() {
			public int compare(Integer first, Integer second) {
				return Double.compare(array[first], array[second]);
			}
		});
	}

	public static int[] reversePermutation(int[] permutation) {
		int[] result = new int[permutation.length];
		for (int i = 0; i < permutation.length; i++)
			result[permutation[i]] = i;
		return result;
	}

	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	public static void reverse(char[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			char temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	private static long maxElement(long[] array, int from, int to) {
		long result = Long.MIN_VALUE;
		for (int i = from; i < to; i++)
			result = Math.max(result, array[i]);
		return result;
	}

	public static int minPosition(int[] array) {
		return minPosition(array, 0, array.length);
	}

	public static int maxPosition(int[] array) {
		return maxPosition(array, 0, array.length);
	}

	public static int minPosition(int[] array, int from, int to) {
		if (from >= to)
			return -1;
		int min = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] < min) {
				min = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int maxPosition(int[] array, int from, int to) {
		if (from >= to)
			return -1;
		int max = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] > max) {
				max = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int[] multiplyPermutations(int[] first, int[] second) {
		int count = first.length;
		int[] result = new int[count];
		for (int i = 0; i < count; i++) {
			result[i] = first[second[i]];
		}
		return result;
	}

	public static int[] compress(int[]... arrays) {
		int totalLength = 0;
		for (int[] array : arrays)
			totalLength += array.length;
		int[] all = new int[totalLength];
		int delta = 0;
		for (int[] array : arrays) {
			System.arraycopy(array, 0, all, delta, array.length);
			delta += array.length;
		}
		sort(all, IntComparator.DEFAULT);
		all = unique(all);
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i] = Arrays.binarySearch(all, array[i]);
		}
		return all;
	}

	public static int minElement(int[] array) {
		return array[minPosition(array)];
	}

	public static long[] partialSums(int[] array) {
		long[] result = new long[array.length + 1];
		for (int i = 0; i < array.length; i++)
			result[i + 1] = result[i] + array[i];
		return result;
	}

	public static void orderBy(int[] base, int[]... arrays) {
		int[] order = ArrayUtils.order(base);
		order(order, base);
		for (int[] array : arrays)
			order(order, array);
	}

	public static void orderBy(long[] base, long[]... arrays) {
		int[] order = ArrayUtils.order(base);
		order(order, base);
		for (long[] array : arrays)
			order(order, array);
	}

	public static void order(int[] order, int[] array) {
		ensureCapacityInt(order.length);
		for (int i = 0; i < order.length; i++)
			tempInt[i] = array[order[i]];
		System.arraycopy(tempInt, 0, array, 0, array.length);
	}

	public static void order(int[] order, long[] array) {
		ensureCapacityLong(order.length);
		for (int i = 0; i < order.length; i++)
			tempLong[i] = array[order[i]];
		System.arraycopy(tempLong, 0, array, 0, array.length);
	}

	public static long[] asLong(int[] array) {
		long[] result = new long[array.length];
		for (int i = 0; i < array.length; i++)
			result[i] = array[i];
		return result;
	}

	public static int count(int[] array, int value) {
		int result = 0;
		for (int i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int count(char[] array, char value) {
		int result = 0;
		for (char i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int count(boolean[] array, boolean value) {
		int result = 0;
		for (boolean i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int[] merge(int[] first, int[] second) {
		int[] result = new int[first.length + second.length];
		int firstIndex = 0;
		int secondIndex = 0;
		int index = 0;
		while (firstIndex < first.length && secondIndex < second.length) {
			if (first[firstIndex] < second[secondIndex])
				result[index++] = first[firstIndex++];
			else
				result[index++] = second[secondIndex++];
		}
		System.arraycopy(first, firstIndex, result, index, first.length
				- firstIndex);
		System.arraycopy(second, secondIndex, result, index, second.length
				- secondIndex);
		return result;
	}

	public static boolean nextPermutation(int[] array) {
		return nextPermutation(array, IntComparator.DEFAULT);
	}

	private static boolean nextPermutation(int[] array, IntComparator comparator) {
		int size = array.length;
		int last = array[size - 1];
		for (int i = size - 2; i >= 0; i--) {
			int current = array[i];
			if (comparator.compare(last, current) > 0) {
				for (int j = size - 1; j > i; j--) {
					if (comparator.compare(array[j], current) > 0) {
						swap(array, i, j);
						inPlaceReverse(array, i + 1, size);
						return true;
					}
				}
			}
			last = current;
		}
		return false;
	}

	private static void inPlaceReverse(int[] array, int first, int second) {
		for (int i = first, j = second - 1; i < j; i++, j--)
			swap(array, i, j);
	}

	private static void swap(int[] array, int first, int second) {
		if (first == second)
			return;
		int temp = array[first];
		array[first] = array[second];
		array[second] = temp;
	}

	public static <V> void reverse(V[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			V temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	public static IntComparator compareBy(final int[]... arrays) {
		return new IntComparator() {
			public int compare(Integer first, Integer second) {
				for (int[] array : arrays) {
					if (array[first] != array[second])
						return Integer.compare(array[first], array[second]);
				}
				return 0;
			}
		};
	}

	public static long minElement(long[] array) {
		return array[minPosition(array)];
	}

	public static long maxElement(long[] array) {
		return array[maxPosition(array)];
	}

	public static int minPosition(long[] array) {
		return minPosition(array, 0, array.length);
	}

	public static int maxPosition(long[] array) {
		return maxPosition(array, 0, array.length);
	}

	public static int minPosition(long[] array, int from, int to) {
		if (from >= to)
			return -1;
		long min = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] < min) {
				min = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int maxPosition(long[] array, int from, int to) {
		if (from >= to)
			return -1;
		long max = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] > max) {
				max = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int[] createArray(int count, int value) {
		int[] array = new int[count];
		Arrays.fill(array, value);
		return array;
	}

	public static long[] createArray(int count, long value) {
		long[] array = new long[count];
		Arrays.fill(array, value);
		return array;
	}

	public static double[] createArray(int count, double value) {
		double[] array = new double[count];
		Arrays.fill(array, value);
		return array;
	}

	public static boolean[] createArray(int count, boolean value) {
		boolean[] array = new boolean[count];
		Arrays.fill(array, value);
		return array;
	}

	public static char[] createArray(int count, char value) {
		char[] array = new char[count];
		Arrays.fill(array, value);
		return array;
	}

	public static <T> T[] createArray(int count, T value) {
		@SuppressWarnings("unchecked")
		T[] array = (T[]) Array.newInstance(value.getClass(), count);
		Arrays.fill(array, value);
		return array;
	}
}

class Graph {
	public static final int REMOVED_BIT = 0;

	protected int vertexCount;
	protected int edgeCount;

	private int[] firstOutbound;
	private int[] firstInbound;

	private Edge[] edges;
	private int[] nextInbound;
	private int[] nextOutbound;
	private int[] from;
	private int[] to;
	private long[] weight;
	private long[] capacity;
	private int[] reverseEdge;
	private int[] flags;

	public Graph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public Graph(int vertexCount, int edgeCapacity) {
		this.vertexCount = vertexCount;
		firstOutbound = new int[vertexCount];
		Arrays.fill(firstOutbound, -1);

		from = new int[edgeCapacity];
		to = new int[edgeCapacity];
		nextOutbound = new int[edgeCapacity];
		flags = new int[edgeCapacity];
	}

	public static Graph createGraph(int vertexCount, int[] from, int[] to) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static Graph createWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static Graph createFlowGraph(int vertexCount, int[] from, int[] to,
			long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static Graph createFlowWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight, long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	public static Graph createTree(int[] parent) {
		Graph graph = new Graph(parent.length + 1, parent.length);
		for (int i = 0; i < parent.length; i++)
			graph.addSimpleEdge(parent[i], i + 1);
		return graph;
	}

	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		ensureEdgeCapacity(edgeCount + 1);
		if (firstOutbound[fromID] != -1)
			nextOutbound[edgeCount] = firstOutbound[fromID];
		else
			nextOutbound[edgeCount] = -1;
		firstOutbound[fromID] = edgeCount;
		if (firstInbound != null) {
			if (firstInbound[toID] != -1)
				nextInbound[edgeCount] = firstInbound[toID];
			else
				nextInbound[edgeCount] = -1;
			firstInbound[toID] = edgeCount;
		}
		this.from[edgeCount] = fromID;
		this.to[edgeCount] = toID;
		if (capacity != 0) {
			if (this.capacity == null)
				this.capacity = new long[from.length];
			this.capacity[edgeCount] = capacity;
		}
		if (weight != 0) {
			if (this.weight == null)
				this.weight = new long[from.length];
			this.weight[edgeCount] = weight;
		}
		if (reverseEdge != -1) {
			if (this.reverseEdge == null) {
				this.reverseEdge = new int[from.length];
				Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
			}
			this.reverseEdge[edgeCount] = reverseEdge;
		}
		if (edges != null)
			edges[edgeCount] = createEdge(edgeCount);
		return edgeCount++;
	}

	protected final GraphEdge createEdge(int id) {
		return new GraphEdge(id);
	}

	public final int addFlowWeightedEdge(int from, int to, long weight,
			long capacity) {
		if (capacity == 0) {
			return addEdge(from, to, weight, 0, -1);
		} else {
			int lastEdgeCount = edgeCount;
			addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
			return addEdge(from, to, weight, capacity, lastEdgeCount);
		}
	}

	protected int entriesPerEdge() {
		return 1;
	}

	public final int addFlowEdge(int from, int to, long capacity) {
		return addFlowWeightedEdge(from, to, 0, capacity);
	}

	public final int addWeightedEdge(int from, int to, long weight) {
		return addFlowWeightedEdge(from, to, weight, 0);
	}

	public final int addSimpleEdge(int from, int to) {
		return addWeightedEdge(from, to, 0);
	}

	public final int vertexCount() {
		return vertexCount;
	}

	public final int edgeCount() {
		return edgeCount;
	}

	protected final int edgeCapacity() {
		return from.length;
	}

	public final Edge edge(int id) {
		initEdges();
		return edges[id];
	}

	public final int firstOutbound(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int nextOutbound(int id) {
		id = nextOutbound[id];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int firstInbound(int vertex) {
		initInbound();
		int id = firstInbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int nextInbound(int id) {
		initInbound();
		id = nextInbound[id];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int source(int id) {
		return from[id];
	}

	public final int destination(int id) {
		return to[id];
	}

	public final long weight(int id) {
		if (weight == null)
			return 0;
		return weight[id];
	}

	public final long capacity(int id) {
		if (capacity == null)
			return 0;
		return capacity[id];
	}

	public final long flow(int id) {
		if (reverseEdge == null)
			return 0;
		return capacity[reverseEdge[id]];
	}

	public final void pushFlow(int id, long flow) {
		if (flow == 0)
			return;
		if (flow > 0) {
			if (capacity(id) < flow)
				throw new IllegalArgumentException("Not enough capacity");
		} else {
			if (flow(id) < -flow)
				throw new IllegalArgumentException("Not enough capacity");
		}
		capacity[id] -= flow;
		capacity[reverseEdge[id]] += flow;
	}

	public int transposed(int id) {
		return -1;
	}

	public final int reverse(int id) {
		if (reverseEdge == null)
			return -1;
		return reverseEdge[id];
	}

	public final void addVertices(int count) {
		ensureVertexCapacity(vertexCount + count);
		Arrays.fill(firstOutbound, vertexCount, vertexCount + count, -1);
		if (firstInbound != null)
			Arrays.fill(firstInbound, vertexCount, vertexCount + count, -1);
		vertexCount += count;
	}

	protected final void initEdges() {
		if (edges == null) {
			edges = new Edge[from.length];
			for (int i = 0; i < edgeCount; i++)
				edges[i] = createEdge(i);
		}
	}

	public final void removeVertex(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextOutbound[id];
		}
		initInbound();
		id = firstInbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextInbound[id];
		}
	}

	private void initInbound() {
		if (firstInbound == null) {
			firstInbound = new int[firstOutbound.length];
			Arrays.fill(firstInbound, 0, vertexCount, -1);
			nextInbound = new int[from.length];
			for (int i = 0; i < edgeCount; i++) {
				nextInbound[i] = firstInbound[to[i]];
				firstInbound[to[i]] = i;
			}
		}
	}

	public final boolean flag(int id, int bit) {
		return (flags[id] >> bit & 1) != 0;
	}

	public final void setFlag(int id, int bit) {
		flags[id] |= 1 << bit;
	}

	public final void removeFlag(int id, int bit) {
		flags[id] &= -1 - (1 << bit);
	}

	public final void removeEdge(int id) {
		setFlag(id, REMOVED_BIT);
	}

	public final void restoreEdge(int id) {
		removeFlag(id, REMOVED_BIT);
	}

	public final boolean isRemoved(int id) {
		return flag(id, REMOVED_BIT);
	}

	public final Iterable<Edge> outbound(final int id) {
		initEdges();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstOutbound, nextOutbound);
			}
		};
	}

	public final Iterable<Edge> inbound(final int id) {
		initEdges();
		initInbound();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstInbound, nextInbound);
			}
		};
	}

	protected void ensureEdgeCapacity(int size) {
		if (from.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			if (edges != null)
				edges = resize(edges, newSize);
			from = resize(from, newSize);
			to = resize(to, newSize);
			nextOutbound = resize(nextOutbound, newSize);
			if (nextInbound != null)
				nextInbound = resize(nextInbound, newSize);
			if (weight != null)
				weight = resize(weight, newSize);
			if (capacity != null)
				capacity = resize(capacity, newSize);
			if (reverseEdge != null)
				reverseEdge = resize(reverseEdge, newSize);
			flags = resize(flags, newSize);
		}
	}

	private void ensureVertexCapacity(int size) {
		if (firstOutbound.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			firstOutbound = resize(firstOutbound, newSize);
			if (firstInbound != null)
				firstInbound = resize(firstInbound, newSize);
		}
	}

	protected final int[] resize(int[] array, int size) {
		int[] newArray = new int[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private long[] resize(long[] array, int size) {
		long[] newArray = new long[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private Edge[] resize(Edge[] array, int size) {
		Edge[] newArray = new Edge[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	public final boolean isSparse() {
		return vertexCount == 0 || edgeCount * 20 / vertexCount <= vertexCount;
	}

	protected class GraphEdge implements Edge {
		protected int id;

		protected GraphEdge(int id) {
			this.id = id;
		}

		public int getSource() {
			return source(id);
		}

		public int getDestination() {
			return destination(id);
		}

		public long getWeight() {
			return weight(id);
		}

		public long getCapacity() {
			return capacity(id);
		}

		public long getFlow() {
			return flow(id);
		}

		public void pushFlow(long flow) {
			Graph.this.pushFlow(id, flow);
		}

		public boolean getFlag(int bit) {
			return flag(id, bit);
		}

		public void setFlag(int bit) {
			Graph.this.setFlag(id, bit);
		}

		public void removeFlag(int bit) {
			Graph.this.removeFlag(id, bit);
		}

		public int getTransposedID() {
			return transposed(id);
		}

		public Edge getTransposedEdge() {
			int reverseID = getTransposedID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getReverseID() {
			return reverse(id);
		}

		public Edge getReverseEdge() {
			int reverseID = getReverseID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getID() {
			return id;
		}

		public void remove() {
			removeEdge(id);
		}

		public void restore() {
			restoreEdge(id);
		}
	}

	public class EdgeIterator implements Iterator<Edge> {
		private int edgeID;
		private final int[] next;
		private int lastID = -1;

		public EdgeIterator(int id, int[] first, int[] next) {
			this.next = next;
			edgeID = nextEdge(first[id]);
		}

		private int nextEdge(int id) {
			while (id != -1 && isRemoved(id))
				id = next[id];
			return id;
		}

		public boolean hasNext() {
			return edgeID != -1;
		}

		public Edge next() {
			if (edgeID == -1)
				throw new NoSuchElementException();
			lastID = edgeID;
			edgeID = nextEdge(next[lastID]);
			return edges[lastID];
		}

		public void remove() {
			if (lastID == -1)
				throw new IllegalStateException();
			removeEdge(lastID);
			lastID = -1;
		}
	}

}

class MiscUtils {
	public static final int[] DX4 = { 1, 0, -1, 0 };
	public static final int[] DY4 = { 0, -1, 0, 1 };
	public static final int[] DX8 = { 1, 1, 1, 0, -1, -1, -1, 0 };
	public static final int[] DY8 = { -1, 0, 1, 1, 1, 0, -1, -1 };
	public static final int[] DX_KNIGHT = { 2, 1, -1, -2, -2, -1, 1, 2 };
	public static final int[] DY_KNIGHT = { 1, 2, 2, 1, -1, -2, -2, -1 };

	private static final String[] ROMAN_TOKENS = { "M", "CM", "D", "CD", "C",
			"XC", "L", "XL", "X", "IX", "V", "IV", "I" };
	private static final int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90,
			50, 40, 10, 9, 5, 4, 1 };

	public static long josephProblem(long n, int k) {
		if (n == 1)
			return 0;
		if (k == 1)
			return n - 1;
		if (k > n)
			return (josephProblem(n - 1, k) + k) % n;
		long count = n / k;
		long result = josephProblem(n - count, k);
		result -= n % k;
		if (result < 0)
			result += n;
		else
			result += result / (k - 1);
		return result;
	}

	public static boolean isValidCell(int row, int column, int rowCount,
			int columnCount) {
		return row >= 0 && row < rowCount && column >= 0
				&& column < columnCount;
	}

	public static List<Integer> getPath(int[] last, int destination) {
		List<Integer> path = new ArrayList<Integer>();
		while (destination != -1) {
			path.add(destination);
			destination = last[destination];
		}
		inPlaceReverse(path);
		return path;
	}

	private static void inPlaceReverse(List<Integer> list) {
		for (int i = 0, j = list.size() - 1; i < j; i++, j--)
			swap(list, i, j);
	}

	private static void swap(List<Integer> list, int first, int second) {
		if (first == second)
			return;
		int temp = list.get(first);
		list.set(first, list.get(second));
		list.set(second, temp);
	}

	public static List<Integer> getPath(int[][] lastIndex,
			int[][] lastPathNumber, int destination, int pathNumber) {
		List<Integer> path = new ArrayList<Integer>();
		while (destination != -1 || pathNumber != 0) {
			path.add(destination);
			int nextDestination = lastIndex[destination][pathNumber];
			pathNumber = lastPathNumber[destination][pathNumber];
			destination = nextDestination;
		}
		inPlaceReverse(path);
		return path;
	}

	public static long maximalRectangleSum(long[][] array) {
		int n = array.length;
		int m = array[0].length;
		long[][] partialSums = new long[n + 1][m + 1];
		for (int i = 0; i < n; i++) {
			long rowSum = 0;
			for (int j = 0; j < m; j++) {
				rowSum += array[i][j];
				partialSums[i + 1][j + 1] = partialSums[i][j + 1] + rowSum;
			}
		}
		long result = Long.MIN_VALUE;
		for (int i = 0; i < m; i++) {
			for (int j = i; j < m; j++) {
				long minPartialSum = 0;
				for (int k = 1; k <= n; k++) {
					long current = partialSums[k][j + 1] - partialSums[k][i];
					result = Math.max(result, current - minPartialSum);
					minPartialSum = Math.min(minPartialSum, current);
				}
			}
		}
		return result;
	}

	public static int parseIP(String ip) {
		String[] components = ip.split("[.]");
		int result = 0;
		for (int i = 0; i < 4; i++)
			result += (1 << (24 - 8 * i)) * Integer.parseInt(components[i]);
		return result;
	}

	public static String buildIP(int mask) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			if (i != 0)
				result.append('.');
			result.append(mask >> (24 - 8 * i) & 255);
		}
		return result.toString();
	}

	public static long binarySearch(long from, long to,
			Function<Long, Boolean> function) {
		while (from < to) {
			long argument = from + (to - from) / 2;
			if (function.value(argument))
				to = argument;
			else
				from = argument + 1;
		}
		return from;
	}

	public static <T> boolean equals(T first, T second) {
		return first == null && second == null || first != null
				&& first.equals(second);
	}

	public static boolean isVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'
				|| ch == 'Y';
	}

	public static boolean isStrictVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
	}

	public static String convertToRoman(int number) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number >= ROMAN_VALUES[i]) {
				number -= ROMAN_VALUES[i];
				result.append(ROMAN_TOKENS[i]);
			}
		}
		return result.toString();
	}

	public static int convertFromRoman(String number) {
		int result = 0;
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number.startsWith(ROMAN_TOKENS[i])) {
				number = number.substring(ROMAN_TOKENS[i].length());
				result += ROMAN_VALUES[i];
			}
		}
		return result;
	}

	public static int distance(int x1, int y1, int x2, int y2) {
		int dx = x1 - x2;
		int dy = y1 - y2;
		return dx * dx + dy * dy;
	}

	public static <T extends Comparable<T>> T min(T first, T second) {
		if (first.compareTo(second) <= 0)
			return first;
		return second;
	}

	public static <T extends Comparable<T>> T max(T first, T second) {
		if (first.compareTo(second) <= 0)
			return second;
		return first;
	}

	public static void decreaseByOne(int[]... arrays) {
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i]--;
		}
	}

	public static int[] getIntArray(String s) {
		String[] tokens = s.split(" ");
		int[] result = new int[tokens.length];
		for (int i = 0; i < result.length; i++)
			result[i] = Integer.parseInt(tokens[i]);
		return result;
	}
}

class IntegerUtils {
	public static long gcd(long a, long b) {
		a = Math.abs(a);
		b = Math.abs(b);
		while (b != 0) {
			long temp = a % b;
			a = b;
			b = temp;
		}
		return a;
	}

	public static int gcd(int a, int b) {
		a = Math.abs(a);
		b = Math.abs(b);
		while (b != 0) {
			int temp = a % b;
			a = b;
			b = temp;
		}
		return a;
	}

	public static int[] generatePrimes(int upTo) {
		int[] isPrime = generateBitPrimalityTable(upTo);
		List<Integer> primes = new ArrayList<Integer>();
		for (int i = 0; i < upTo; i++) {
			if ((isPrime[i >> 5] >>> (i & 31) & 1) == 1)
				primes.add(i);
		}
		int[] array = new int[primes.size()];
		for (int i = 0; i < array.length; i++)
			array[i] = primes.get(i);
		return array;
	}

	public static boolean[] generatePrimalityTable(int upTo) {
		boolean[] isPrime = new boolean[upTo];
		if (upTo < 2)
			return isPrime;
		Arrays.fill(isPrime, true);
		isPrime[0] = isPrime[1] = false;
		for (int i = 2; i * i < upTo; i++) {
			if (isPrime[i]) {
				for (int j = i * i; j < upTo; j += i)
					isPrime[j] = false;
			}
		}
		return isPrime;
	}

	public static int[] generateBitPrimalityTable(int upTo) {
		int[] isPrime = new int[(upTo + 31) >> 5];
		if (upTo < 2)
			return isPrime;
		Arrays.fill(isPrime, -1);
		isPrime[0] &= -4;
		for (int i = 2; i * i < upTo; i++) {
			if ((isPrime[i >> 5] >>> (i & 31) & 1) == 1) {
				for (int j = i * i; j < upTo; j += i)
					isPrime[j >> 5] &= -1 - (1 << (j & 31));
			}
		}
		return isPrime;
	}

	public static int[] generateDivisorTable(int upTo) {
		int[] divisor = new int[upTo];
		for (int i = 1; i < upTo; i++)
			divisor[i] = i;
		for (int i = 2; i * i < upTo; i++) {
			if (divisor[i] == i) {
				for (int j = i * i; j < upTo; j += i)
					divisor[j] = i;
			}
		}
		return divisor;
	}

	public static long powerInFactorial(long n, long p) {
		long result = 0;
		while (n != 0) {
			result += n /= p;
		}
		return result;
	}

	public static int sumDigits(CharSequence number) {
		int result = 0;
		for (int i = number.length() - 1; i >= 0; i--)
			result += digitValue(number.charAt(i));
		return result;
	}

	public static int digitValue(char digit) {
		if (Character.isDigit(digit))
			return digit - '0';
		if (Character.isUpperCase(digit))
			return digit + 10 - 'A';
		return digit + 10 - 'a';
	}

	public static int longCompare(long a, long b) {
		if (a < b)
			return -1;
		if (a > b)
			return 1;
		return 0;
	}

	public static long[][] generateBinomialCoefficients(int n) {
		long[][] result = new long[n + 1][n + 1];
		for (int i = 0; i <= n; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++)
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
		}
		return result;
	}

	public static long[][] generateBinomialCoefficients(int n, long module) {
		long[][] result = new long[n + 1][n + 1];
		if (module == 1)
			return result;
		for (int i = 0; i <= n; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
				if (result[i][j] >= module)
					result[i][j] -= module;
			}
		}
		return result;
	}

	public static long[] generateBinomialRow(int n, long module) {
		long[] result = generateReverse(n + 1, module);
		result[0] = 1;
		for (int i = 1; i <= n; i++)
			result[i] = result[i - 1] * (n - i + 1) % module * result[i]
					% module;
		return result;
	}

	public static int[] representationInBase(long number, int base) {
		long basePower = base;
		int exponent = 1;
		while (number >= basePower) {
			basePower *= base;
			exponent++;
		}
		int[] representation = new int[exponent];
		for (int i = 0; i < exponent; i++) {
			basePower /= base;
			representation[i] = (int) (number / basePower);
			number %= basePower;
		}
		return representation;
	}

	public static int trueDivide(int a, int b) {
		return (a - trueMod(a, b)) / b;
	}

	public static long trueDivide(long a, long b) {
		return (a - trueMod(a, b)) / b;
	}

	public static int trueMod(int a, int b) {
		a %= b;
		a += b;
		a %= b;
		return a;
	}

	public static long trueMod(long a, long b) {
		a %= b;
		a += b;
		a %= b;
		return a;
	}

	public static long factorial(int n) {
		long result = 1;
		for (int i = 2; i <= n; i++)
			result *= i;
		return result;
	}

	public static long factorial(int n, long mod) {
		long result = 1;
		for (int i = 2; i <= n; i++)
			result = result * i % mod;
		return result % mod;
	}

	public static List<Pair<Long, Integer>> factorize(long number) {
		List<Pair<Long, Integer>> result = new ArrayList<Pair<Long, Integer>>();
		for (long i = 2; i * i <= number; i++) {
			if (number % i == 0) {
				int power = 0;
				do {
					power++;
					number /= i;
				} while (number % i == 0);
				result.add(Pair.makePair(i, power));
			}
		}
		if (number != 1)
			result.add(Pair.makePair(number, 1));
		return result;
	}

	public static List<Long> getDivisors(long number) {
		List<Pair<Long, Integer>> primeDivisors = factorize(number);
		return getDivisorsImpl(primeDivisors, 0, 1, new ArrayList<Long>());
	}

	private static List<Long> getDivisorsImpl(
			List<Pair<Long, Integer>> primeDivisors, int index, long current,
			List<Long> result) {
		if (index == primeDivisors.size()) {
			result.add(current);
			return result;
		}
		long p = primeDivisors.get(index).first;
		int power = primeDivisors.get(index).second;
		for (int i = 0; i <= power; i++) {
			getDivisorsImpl(primeDivisors, index + 1, current, result);
			current *= p;
		}
		return result;
	}

	public static long power(long base, long exponent) {
		if (exponent == 0)
			return 1;
		long result = power(base, exponent >> 1);
		result = result * result;
		if ((exponent & 1) != 0)
			result = result * base;
		return result;
	}

	public static long power(long base, long exponent, long mod) {
		if (base >= mod)
			base %= mod;
		if (exponent == 0)
			return 1 % mod;
		long result = power(base, exponent >> 1, mod);
		result = result * result % mod;
		if ((exponent & 1) != 0)
			result = result * base % mod;
		return result;
	}

	public static long lcm(long a, long b) {
		return a / gcd(a, b) * b;
	}

	public static long[] generateFibonacci(long upTo) {
		int count = 0;
		long last = 0;
		long current = 1;
		while (current <= upTo) {
			long next = last + current;
			last = current;
			current = next;
			count++;
		}
		return generateFibonacci(count, -1);
	}

	public static long[] generateFibonacci(int count, long module) {
		long[] result = new long[count];
		if (module == -1) {
			if (count != 0)
				result[0] = 1;
			if (count > 1)
				result[1] = 1;
			for (int i = 2; i < count; i++)
				result[i] = result[i - 1] + result[i - 2];
		} else {
			if (count != 0)
				result[0] = 1 % module;
			if (count > 1)
				result[1] = 1 % module;
			for (int i = 2; i < count; i++)
				result[i] = (result[i - 1] + result[i - 2]) % module;
		}
		return result;
	}

	public static long[] generateHappy(int digits) {
		long[] happy = new long[(1 << (digits + 1)) - 2];
		happy[0] = 4;
		happy[1] = 7;
		int first = 0;
		int last = 2;
		for (int i = 2; i <= digits; i++) {
			for (int j = 0; j < last - first; j++) {
				happy[last + 2 * j] = 10 * happy[first + j] + 4;
				happy[last + 2 * j + 1] = 10 * happy[first + j] + 7;
			}
			int next = last + 2 * (last - first);
			first = last;
			last = next;
		}
		return happy;
	}

	public static long[] generateFactorial(int count, long module) {
		long[] result = new long[count];
		if (module == -1) {
			if (count != 0)
				result[0] = 1;
			for (int i = 1; i < count; i++)
				result[i] = result[i - 1] * i;
		} else {
			if (count != 0)
				result[0] = 1 % module;
			for (int i = 1; i < count; i++)
				result[i] = (result[i - 1] * i) % module;
		}
		return result;
	}

	public static long reverse(long number, long module) {
		return power(number, module - 2, module);
	}

	public static boolean isPrime(long number) {
		if (number < 2)
			return false;
		for (long i = 2; i * i <= number; i++) {
			if (number % i == 0)
				return false;
		}
		return true;
	}

	public static long[] generateReverse(int upTo, long module) {
		long[] result = new long[upTo];
		if (upTo > 1)
			result[1] = 1;
		for (int i = 2; i < upTo; i++)
			result[i] = (module - module / i * result[((int) (module % i))]
					% module)
					% module;
		return result;
	}

	public static long[] generateReverseFactorials(int upTo, long module) {
		long[] result = generateReverse(upTo, module);
		if (upTo > 0)
			result[0] = 1;
		for (int i = 1; i < upTo; i++)
			result[i] = result[i] * result[i - 1] % module;
		return result;
	}

	public static long[] generatePowers(long base, int count, long mod) {
		long[] result = new long[count];
		if (count != 0)
			result[0] = 1 % mod;
		for (int i = 1; i < count; i++)
			result[i] = result[i - 1] * base % mod;
		return result;
	}

	public static long nextPrime(long from) {
		if (from <= 2)
			return 2;
		from += 1 - (from & 1);
		while (!isPrime(from))
			from += 2;
		return from;
	}

	public static long binomialCoefficient(int n, int m, long mod) {
		if (m < 0 || m > n)
			return 0;
		if (2 * m > n)
			m = n - m;
		long result = 1;
		for (int i = n - m + 1; i <= n; i++)
			result = result * i % mod;
		return result
				* BigInteger.valueOf(factorial(m, mod))
						.modInverse(BigInteger.valueOf(mod)).longValue() % mod;
	}

	public static boolean isSquare(long number) {
		long sqrt = Math.round(Math.sqrt(number));
		return sqrt * sqrt == number;
	}

	public static long findCommon(long aRemainder, long aMod, long bRemainder,
			long bMod) {
		long modGCD = gcd(aMod, bMod);
		long gcdRemainder = aRemainder % modGCD;
		if (gcdRemainder != bRemainder % modGCD)
			return -1;
		aMod /= modGCD;
		aRemainder /= modGCD;
		bMod /= modGCD;
		bRemainder /= modGCD;
		long aReverse = BigInteger.valueOf(aMod)
				.modInverse(BigInteger.valueOf(bMod)).longValue();
		long bReverse = BigInteger.valueOf(bMod)
				.modInverse(BigInteger.valueOf(aMod)).longValue();
		long mod = aMod * bMod;
		return (bReverse * aRemainder % mod * bMod + aReverse * bRemainder
				% mod * aMod)
				% mod * modGCD + gcdRemainder;
	}

	public static long[] generatePowers(long base, long maxValue) {
		if (maxValue <= 0)
			return new long[0];
		int size = 1;
		long current = 1;
		while (maxValue / base >= current) {
			current *= base;
			size++;
		}
		return generatePowers(base, size, Long.MAX_VALUE);
	}
}

interface IntComparator extends Comparator<Integer> {
	public static final IntComparator DEFAULT = new IntComparator() {
		public int compare(Integer first, Integer second) {
			if (first < second)
				return -1;
			if (first > second)
				return 1;
			return 0;
		}
	};

	public static final IntComparator REVERSE = new IntComparator() {
		public int compare(Integer first, Integer second) {
			if (first < second)
				return 1;
			if (first > second)
				return -1;
			return 0;
		}
	};

	public int compare(Integer first, Integer second);
}

class BidirectionalGraph extends Graph {
	public int[] transposedEdge;

	public BidirectionalGraph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public BidirectionalGraph(int vertexCount, int edgeCapacity) {
		super(vertexCount, 2 * edgeCapacity);
		transposedEdge = new int[2 * edgeCapacity];
	}

	public static BidirectionalGraph createGraph(int vertexCount, int[] from,
			int[] to) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static BidirectionalGraph createWeightedGraph(int vertexCount,
			int[] from, int[] to, long[] weight) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static BidirectionalGraph createFlowGraph(int vertexCount,
			int[] from, int[] to, long[] capacity) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static BidirectionalGraph createFlowWeightedGraph(int vertexCount,
			int[] from, int[] to, long[] weight, long[] capacity) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	@Override
	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		int lastEdgeCount = edgeCount;
		super.addEdge(fromID, toID, weight, capacity, reverseEdge);
		super.addEdge(toID, fromID, weight, capacity, reverseEdge == -1 ? -1
				: reverseEdge + 1);
		this.transposedEdge[lastEdgeCount] = lastEdgeCount + 1;
		this.transposedEdge[lastEdgeCount + 1] = lastEdgeCount;
		return lastEdgeCount;
	}

	@Override
	protected int entriesPerEdge() {
		return 2;
	}

	@Override
	public final int transposed(int id) {
		return transposedEdge[id];
	}

	@Override
	protected void ensureEdgeCapacity(int size) {
		if (size > edgeCapacity()) {
			super.ensureEdgeCapacity(size);
			transposedEdge = resize(transposedEdge, edgeCapacity());
		}
	}
}

class Pair<U, V> implements Comparable<Pair<U, V>> {
	public final U first;
	public final V second;

	public static <U, V> Pair<U, V> makePair(U first, V second) {
		return new Pair<U, V>(first, second);
	}

	private Pair(U first, V second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Pair pair = (Pair) o;

		return !(first != null ? !first.equals(pair.first) : pair.first != null)
				&& !(second != null ? !second.equals(pair.second)
						: pair.second != null);

	}

	@Override
	public int hashCode() {
		int result = first != null ? first.hashCode() : 0;
		result = 31 * result + (second != null ? second.hashCode() : 0);
		return result;
	}

	public Pair<V, U> swap() {
		return makePair(second, first);
	}

	@Override
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	@SuppressWarnings({ "unchecked" })
	public int compareTo(Pair<U, V> o) {
		int value = ((Comparable<U>) first).compareTo(o.first);
		if (value != 0)
			return value;
		return ((Comparable<V>) second).compareTo(o.second);
	}
}

interface Edge {
	public int getSource();

	public int getDestination();

	public long getWeight();

	public long getCapacity();

	public long getFlow();

	public void pushFlow(long flow);

	public boolean getFlag(int bit);

	public void setFlag(int bit);

	public void removeFlag(int bit);

	public int getTransposedID();

	public Edge getTransposedEdge();

	public int getReverseID();

	public Edge getReverseEdge();

	public int getID();

	public void remove();

	public void restore();
}

interface Function<A, V> {
	public abstract V value(A argument);
}


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

public class B {
    public static void main(String[] args) throws Exception {
        new B().solve();
        // new FileInputStream(new File("input.txt")),
        // new PrintStream(new FileOutputStream(new File("output.txt"))));
    }

    void solve() throws IOException {
        BufferedReader in = new BufferedReader(new
                InputStreamReader(System.in));
        Scanner sc = new Scanner(System.in);
        String[] sp;

        long x = sc.nextInt();
        long y = sc.nextInt();
        long n = sc.nextInt();
        long na = Integer.MAX_VALUE;
        long nb = 1;
        long ra, rb = ra = 0;
        for (long b = 1; b <= n; b++) {
            long _a = b * x / y;
            for (int i = 0; i < 2; i++) {
                long a = _a + i;
                long naa = Math.abs(a * y - b * x);
                long nbb = b * y;
                if ((na * nbb > naa * nb && (double) naa * nb < Long.MAX_VALUE) || na / 100 * nbb > naa / 100 * nbb) {
                    na = naa;
                    nb = nbb;
                    ra = a;
                    rb = b;
                }
            }
        }

        System.out.println(ra + "/" + rb);
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//


import java.util.Scanner;

public class HungryStudentProblem {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        for(int i = 0; i < n; i++) {
            int x = s.nextInt();
            int one = 0, two = 0;
            label:
            for(int j = 0; j <= x / 3 + 1; j++) {
                for(int k = 0; k <= x / 7 + 1; k++) {
                    if(3 * j + 7 * k == x) {
                        one = j;
                        two = k;
                        break label;
                    }
                }
            }
            if(3 * one + 7 * two == x) System.out.println("YES");
            else System.out.println("NO");
        }
    }
}


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

public class Main {

    static class FastScanner
    {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }

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

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

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

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }

    public static void main(String[] args) throws IOException {
        FastScanner sc=new FastScanner();
        int N = sc.nextInt();
        int C = sc.nextInt();
        int[] p = new int[N];
        for (int i = 0; i < N; i++)
        	p[i] = sc.nextInt();
        int[] t = new int[N];
        for (int i = 0; i < N; i++)
        	t[i] = sc.nextInt();

        int score1 = 0;
        int time1 = 0;
        for (int i = 0; i < N; i++) {
        	time1 += t[i];
        	score1 += Math.max(0, p[i] - C*time1);
        }

        int score2 = 0;
        int time2 = 0;
        for (int i = N-1; i >= 0; i--) {
        	time2 += t[i];
        	score2 += Math.max(0, p[i] - C*time2);
        }

        if (score1 > score2) {
        	System.out.println("Limak");
        } else if (score2 > score1) {
        	System.out.println("Radewoosh");
        } else {
        	System.out.println("Tie");
        }
    }
}


import java.util.*;
public class MartianClock {
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		String in = reader.next();
		StringTokenizer st = new StringTokenizer(in, ":");
		String a = st.nextToken();
		String b = st.nextToken();

		LinkedList<Integer> q = new LinkedList<Integer>();
		//try all bases!
		for(int i = 2; i <= 70; i++){
			try{
				int A = parseInt(a,i);
				int B = parseInt(b,i);
				if(A <= 23 && B <= 59)
					q.add(i);
			}catch(Exception e){
				continue;
			}
		}

		if(q.size() == 0){
			System.out.println(0);
		}else if(q.getLast() == 70){
			System.out.println(-1);
		}else{
			while(!q.isEmpty())
				System.out.print(q.remove() + " ");
			System.out.println();
		}
	}

	public static int parseInt(String a, int b){
		if(b < 36)
			return Integer.parseInt(a,b);
		int sum = 0;
		for(int i = 0; i < a.length(); i++){
			sum *= b;
			sum += a.charAt(i)>='A'?(a.charAt(i)-'A'+10):(a.charAt(i)-'0');
		}
		return sum;
	}
}


import java.io.InputStreamReader;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;

public class palin {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(System.out);
		Scanner scan = new Scanner(System.in);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
	public void solve(int testNumber, InputReader in, PrintWriter out) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt(), a[] = new int[n], max = 0;
		for (int i = 0; i < a.length; i++) {
			a[i] = scan.nextInt();
		}
		for (int i = 0; i < a.length; i++) {
			for (int j = i; j < a.length; j++) {
				max = Math.max(max, count(i, j, a));
			}
		}
		System.out.println(max);
	}

	public static int count(int x, int y, int a[]) {
		int c = 0, co = 0;
		for (int i = x; i <= y; i++) {
			if (a[i] == 0) {
				c++;
			}
		}
		for (int i = 0; i < a.length; i++) {
			if (a[i] == 1 && i < x || a[i] == 1 && i > y) {
				co++;
			}
		}
		return co + c;
	}
}

class InputReader {
	BufferedReader br;
	StringTokenizer st;

	public InputReader(InputStream in) {
		br = new BufferedReader(new InputStreamReader(in));
		st = null;
	}

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

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

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

	public float nextFloat() {
		return Float.parseFloat(next());
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;

public class Main
{
	/********************************************** a list of common variables **********************************************/

	private MyScanner scan = new MyScanner();
	private PrintWriter out = new PrintWriter(System.out);
	private final double PI = Math.acos(-1.0);
	private final int SIZEN = (int)(1e6);
	private final int MOD = (int)(1e9 + 7);
	private int n;
	private int k;
	private long s;
	private int m;
	private long[] a;
	private long[] f;
	private long ans;
	private HashMap<Long, Long>[] hm;

	public void dfs1(int p, int step, long sum)
	{
		if(sum > s)
		{
			return;
		}
		hm[step].put(sum, hm[step].containsKey(sum) ? hm[step].get(sum) + 1 : 1);
		if(p >= m)
		{
			return;
		}
		for(int i = p;i < m;++i)
		{
			if(sum + a[i] <= s)
			{
				dfs1(i + 1, step, sum + a[i]);
			}
			if(sum + f[i] <= s && step < k)
			{
				dfs1(i + 1, step + 1, sum + f[i]);
			}
		}
	}

	public void dfs2(int p, int step, long sum)
	{
		if(sum > s)
		{
			return;
		}
		for(int i = 0;i <= k - step;++i)
		{
			ans += hm[i].containsKey(s - sum) ? hm[i].get(s - sum) : 0;
		}
		if(p >= n)
		{
			return;
		}
		for(int i = p;i < n;++i)
		{
			if(sum + a[i] <= s)
			{
				dfs2(i + 1, step, sum + a[i]);
			}
			if(sum + f[i] <= s && step < k)
			{
				dfs2(i + 1, step + 1, sum + f[i]);
			}
		}
	}

	public void foo()
	{
		n = scan.nextInt();
		k = scan.nextInt();
		s = scan.nextLong();
		a = new long[n];
		f = new long[n];
		for(int i = 0;i < n;++i)
		{
			a[i] = scan.nextLong();
			f[i] = 1;
			for(int j = 1;j <= a[i];++j)
			{
				f[i] *= j;
				if(f[i] > s)
				{
					f[i] = s + 1;
					break;
				}
			}
		}
		m = n / 2;
		hm = new HashMap[k + 1];
		for(int i = 0;i <= k;++i)
		{
			hm[i] = new HashMap<Long, Long>();
		}
		dfs1(0, 0, 0);
		ans = 0;
		dfs2(m, 0, 0);
		out.println(ans);
	}

	public static void main(String[] args)
	{
		Main m = new Main();
		m.foo();
		m.out.close();
	}

	/********************************************** a list of common algorithms **********************************************/

	/**
	 * KMP match, i.e. kmpMatch("abcd", "bcd") = 1, kmpMatch("abcd", "bfcd") = -1.
	 *
	 * @param	t	String to match.
	 * @param	p	String to be matched.
	 * @return	if can match, first index; otherwise -1.
	 */
	public int kmpMatch(char[] t, char[] p)
	{
		int n = t.length;
		int m = p.length;
		int[] next = new int[m + 1];
		next[0] = -1;
		int j = -1;
		for(int i = 1;i < m;++i)
		{
			while(j >= 0 && p[i] != p[j + 1])
			{
				j = next[j];
			}
			if(p[i] == p[j + 1])
			{
				++j;
			}
			next[i] = j;
		}
		j = -1;
		for(int i = 0;i < n;++i)
		{
			while(j >= 0 && t[i] != p[j + 1])
			{
				j = next[j];
			}
			if(t[i] == p[j + 1])
			{
				++j;
			}
			if(j == m - 1)
			{
				return i - m + 1;
			}
		}
		return -1;
	}

	/**
	 * Get greatest common divisor
	 * @param	a	an argument
	 * @param	b	another argument
	 * @return	greatest common divisor
	 */
	public int gcd(int a, int b)
	{
		return 0 == b ? a : gcd(b, a % b);
	}

	/**
	 * Get the minimum distance from a point to a segment (not a line)
	 * @param	x	x coordinate of the point
	 * @param	y	y coordinate of the point
	 * @param	x1	x coordinate of one point of the segment
	 * @param 	y1	y coordinate of one point of the segment
	 * @param 	x2	x coordinate of another point of the segment
	 * @param 	y2	y coordinate of another point of the segment
	 * @return	the minimum distance from point (x, y) to segment (x1, y1)-(x2, y2)
	 */
	public double ptToSeg(double x, double y, double x1, double y1, double x2, double y2)
	{
		double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
		if(cross <= 0)
		{
			return (x - x1) * (x - x1) + (y - y1) * (y - y1);
		}
		double d = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
		if(cross >= d)
		{
			return (x - x2) * (x - x2) + (y - y2) * (y - y2);
		}
		double r = cross / d;
		double px = x1 + (x2 - x1) * r;
		double py = y1 + (y2 - y1) * r;
		return (x - px) * (x - px) + (y - py) * (y - py);
	}

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 0)
	            {
	            	return -1;
	            }
	        }
	        return buf[curChar++];
	    }

	    public int nextInt()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        int res = 0;
	        do
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

	    public long nextLong()
	    {
	    	int c = read();
	    	while (isSpaceChar(c))
	    	{
	    		c = read();
	    	}
	    	int sgn = 1;
	    	if (c == '-')
	    	{
	    		sgn = -1;
	    		c = read();
	    	}
	    	long res = 0;
	    	do
	    	{
	    		if (c < '0' || c > '9')
	    		{
	    			throw new InputMismatchException();
	    		}
	    		res *= 10;
	    		res += c - '0';
	    		c = read();
	    	} while (!isSpaceChar(c));
	    	return res * sgn;
	    }

	    public double nextDouble()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        int sgn = 1;
	        if (c == '-')
	        {
	            sgn = -1;
	            c = read();
	        }
	        double res = 0;
	        while (!isSpaceChar(c) && c != '.')
	        {
	            if (c == 'e' || c == 'E')
	            {
	            	return res * Math.pow(10, nextInt());
	            }
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c & 15;
	            c = read();
	        }
	        if (c == '.')
	        {
	            c = read();
	            double m = 1;
	            while (!isSpaceChar(c))
	            {
	                if (c == 'e' || c == 'E')
	                {
	                	return res * Math.pow(10, nextInt());
	                }
	                if (c < '0' || c > '9')
	                {
	                	throw new InputMismatchException();
	                }
	                m /= 10;
	                res += (c & 15) * m;
	                c = read();
	            }
	        }
	        return res * sgn;
	    }

	    public String next()
	    {
	        int c = read();
	        while (isSpaceChar(c))
	        {
	        	c = read();
	        }
	        StringBuilder res = new StringBuilder();
	        do
	        {
	            res.appendCodePoint(c);
	            c = read();
	        } while (!isSpaceChar(c));
	        return res.toString();
	    }

	    private boolean isSpaceChar(int c)
	    {
	        return ' ' == c || '\n' == c || '\r' == c || '\t' == c || -1 == c;
	    }
	}
}


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

public class JavaApplication1 {
Long a,b;
    private void solution() throws IOException {
        a = in.nextLong();
        b = in.nextLong();
        rec( a, b);
        out.println(a + " " + b);
    }

    private void rec( Long a, Long b){
        if(a==0 || b==0) {
            this.a = a;
            this.b = b;
            return;
        }
        else if(a >= 2*b) rec((a)%(b*2), b);
        else if(b >= 2*a) rec(a, b%(2*a));
        else{
            this.a = a;
            this.b = b;
        }
    }
    private void run() throws IOException {
        in = new Scanner(System.in);
        out = new PrintWriter(System.out);
        solution();
        in.close();
        out.close();
    }

    private Scanner in;
    private PrintWriter out;

    public static void main(String[] args) throws IOException {
        new JavaApplication1().run();
    }

    private class Scanner {

        BufferedReader br;
        StringTokenizer st;

        private Scanner(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        private String next() throws IOException {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(br.readLine());
            }
            return st.nextToken();
        }

        private Integer nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        private Long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        private Double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        private void close() throws IOException {
            st = null;
            br.close();
        }
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class P3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		String form = "";
		int nb = 0;
		int ns = 0;
		int nc = 0;
		int pb = 0;
		int ps = 0;
		int pc = 0;
		long r = 0;

        if (input.hasNext()) {
    		form = input.next();
    		nb = input.nextInt();
    		ns = input.nextInt();
    		nc = input.nextInt();
    		pb = input.nextInt();
    		ps = input.nextInt();
    		pc = input.nextInt();
    		r = input.nextLong();
        }
        int b = 0;
        int s = 0;
        int c = 0;

        for(int i = 0; i < form.length(); i++){
        	char aux = form.charAt(i);
        	if(aux == 'B') b++;
        	if(aux == 'C') c++;
        	if(aux == 'S') s++;
        }

        long min = 0;
        long max = (long) Math.pow(10, 14);

        while(min + 1 < max){
        	long aux = (min + max)/2;

        	long total_b = (aux*b > nb)? (aux*b-nb)*pb : 0;
        	long total_s = (aux*s > ns)? (aux*s-ns)*ps : 0;
        	long total_c = (aux*c > nc)? (aux*c-nc)*pc : 0;

        	long total = total_b + total_s + total_c;
        	if(total <= r){
        		min = aux;
        	} else {
        		max = aux;
        	}

        }
        System.out.println(min);
	}
}


import java.util.Scanner;
import java.util.Arrays;

public class SampleA497
{

	public static void main(String[] args)
	{	Scanner s = new Scanner(System.in);
             //   int n = s.nextInt();
             //   int m = s.nextInt();

                int i=0,sum=0,j=0,temp=0,h=0,r=0,t=0;
                String s1 = s.next();
              //  System.out.println(s1.length());
                int len = s1.length();
                if(s1.charAt(len-1)!='a' && s1.charAt(len-1)!='e' && s1.charAt(len-1)!='i' && s1.charAt(len-1)!='o' && s1.charAt(len-1)!='u' && s1.charAt(len-1)!='n'){
                   h=1;
                }
                else{
                 for(i=0;i<len-1;i++){
                 char l = s1.charAt(i);
                 char y = s1.charAt(i+1);
                 t=0;
                   if(l !='a' && l !='e' && l !='i' && l !='o' && l !='u' ){
                     t=1;
                     h++;
                   //  System.out.println(l);
                   }
                   if(t==1){
                     if(y =='a' || y =='e' || y =='i' || y =='o' || y =='u' || l =='n'){
                         r++;
                     }else{

                     }
                   }
              //  System.out.println(l);
                }
               }
              //  System.out.println(h);
              //  System.out.println(r);
                if(h==r ){
                   System.out.println("YES");
                }else{
                   System.out.println("NO");
                }

	}
}


import java.util.*;
public final class Round431 {
		public static void main(String args[]){
			Scanner sc = new Scanner(System.in);
			long ax = sc.nextInt();
			long ay = sc.nextInt();
			long bx = sc.nextInt();
			long by = sc.nextInt();
			long cx = sc.nextInt();
			long cy = sc.nextInt();
			//float c=(cx*cx)+(cy*cy);
			long a=(ax-bx)*(ax-bx)+(ay-by)*(ay-by);
			long b=(bx-cx)*(bx-cx)+(by-cy)*(by-cy);

//			System.out.println(a+" "+b+" "+c);
//			float p=(b-a)/2;
//			float q=(b-c)/2;
//			float X=(q-p*(by-ay))/(ax-cx);
//			float Y=p-X*(bx-ax);
//			System.out.println(X+" "+Y);
//			float m1m2 = ((ay-Y)*(cy-Y)*(by-Y))/((ax-X)*(cx-X)*(bx-X));
//			System.out.println(m1m2);
			if(a==b && ((by-ay)*(cx-bx)!=(cy-by)*(bx-ax)))
					System.out.println("Yes");

			else
					System.out.println("No");
			sc.close();
		}
}


import java.io.BufferedReader;
import static java.lang.Math.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class CodeforcesMonitor implements Runnable {
    public static final String taskname = "A";
    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok;

    public static void main(String[] args) {
        new Thread(new CodeforcesMonitor()).start();
    }

    int gcd(int x, int y) {
        if(y == 0) return x;
        return gcd(y, x % y);
    }

    void solve() throws IOException {
        int a, b, x, y;
        a = nextInt();
        b = nextInt();
        x = nextInt();
        y = nextInt();
        int d = gcd(x, y);
        x /= d;
        y /= d;
        int m = a / x;
        int n = b / y;
        int k = Math.min(m, n);
        out.println(x * k + " " + y * k);
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(System.in));
            // in = new BufferedReader(new FileReader(new File(taskname + ".in")));
            out = new PrintWriter(System.out);
            // out = new PrintWriter(new File(taskname + ".out"));
            solve();
            out.flush();
            out.close();
            in.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    String nextLine() throws IOException {
        tok = null;
        return in.readLine();
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

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

}


import java.util.Scanner;

public class MainClass
{

	public static void main(String[] args)
	{
		boolean win=false;
		Scanner in=new Scanner(System.in);
		String[] str=new String[4];
		for(int i=0;i<4;i++)
		{
			str[i]=in.nextLine();
		}
		if(!win)
		{
		for(int i=0;i<4;i++)
		{
			for(int g=0;g<2;g++)
			{
				if(str[i].charAt(g)=='x'&&str[i].charAt(g+1)=='x'&&str[i].charAt(g+2)=='.')
				{
					win=true;
					break;
				}
				if(str[i].charAt(g)=='.'&&str[i].charAt(g+1)=='x'&&str[i].charAt(g+2)=='x')
				{
					win=true;
					break;
				}
				if(str[i].charAt(g)=='x'&&str[i].charAt(g+1)=='.'&&str[i].charAt(g+2)=='x')
				{
					win=true;
					break;
				}
			}
		}
		}
		if(!win)
		{
		for(int i=0;i<2;i++)
		{
			for(int g=0;g<4;g++)
			{
				if(str[i].charAt(g)=='x'&&str[i+1].charAt(g)=='x'&&str[i+2].charAt(g)=='.')
				{
					win=true;
					break;
				}
				if(str[i].charAt(g)=='.'&&str[i+1].charAt(g)=='x'&&str[i+2].charAt(g)=='x')
				{
					win=true;
					break;
				}
				if(str[i].charAt(g)=='x'&&str[i+1].charAt(g)=='.'&&str[i+2].charAt(g)=='x')
				{
					win=true;
					break;
				}
			}
		}
		}
		if(!win){
			for(int i=0;i<2;i++)
			{
				for(int g=0;g<2;g++)
				{
					if(str[i].charAt(g)=='x'&&str[i+1].charAt(g+1)=='x'&&str[i+2].charAt(g+2)=='.')
					{
						win=true;
						break;
					}
					if(str[i].charAt(g)=='.'&&str[i+1].charAt(g+1)=='x'&&str[i+2].charAt(g+2)=='x')
					{
						win=true;
						break;
					}
					if(str[i].charAt(g)=='x'&&str[i+1].charAt(g+1)=='.'&&str[i+2].charAt(g+2)=='x')
					{
						win=true;
						break;
					}
				}
			}
		}
		if(!win){
			for(int i=0;i<2;i++)
			{
				for(int g=0;g<2;g++)
				{
					if(str[i].charAt(g+2)=='x'&&str[i+1].charAt(g+1)=='x'&&str[i+2].charAt(g)=='.')
					{
						win=true;
						break;
					}
					if(str[i].charAt(g+2)=='.'&&str[i+1].charAt(g+1)=='x'&&str[i+2].charAt(g)=='x')
					{
						win=true;
						break;
					}
					if(str[i].charAt(g+2)=='x'&&str[i+1].charAt(g+1)=='.'&&str[i+2].charAt(g)=='x')
					{
						win=true;
						break;
					}
				}
			}
		}
		if(!win){
			System.out.println("NO");
		}else{
			System.out.println("YES");
		}
	}
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
	public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n=in.nextInt(),m=in.nextInt(),k=in.nextInt(),i,j,x,y,max=0;
        String s;
        int a[][][]=new int[n][m][3];
        for(i=0;i<n;i++)
        {
            s=in.next();
            for(j=0;j<m;j++)
            {
                a[i][j][0]=in.nextInt();
                a[i][j][1]=in.nextInt();
                a[i][j][2]=in.nextInt();
            }
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i==j)
                    continue;
                items profit[]=new items[m];
                for(x=0;x<m;x++)
                {
                    profit[x]=new items(a[j][x][1]-a[i][x][0],x);
                }
                Arrays.sort(profit);

                int t=k,count=0,number;
                x=0;
                while(t>0&&x<m)
                {
                    number=Math.min(a[i][profit[x].index][2],t);
                    if(profit[x].p<=0)
                        break;
                    count+=profit[x].p*number;
                    x++;
                    t-=number;
                }
                if(count>max)
                    max=count;

            }
        }
        out.println(max);
	}
    class items implements Comparable<items>
    {
        int index,p;
        public items(int p,int index)
        {
            this.p=p;
            this.index=index;
        }
        public int compareTo(items a)
        {
            if(a.p>this.p)
                return 1;
            return -1;
        }
    }
}


import java.math.BigInteger;
import java.util.Scanner;

public class a_66 {

    public void run(){
        Scanner sc = new Scanner(System.in);

        String s = sc.next();
        BigInteger n = new BigInteger(s);

        if( n.compareTo(BigInteger.valueOf(-128)) >= 0 &&  n.compareTo(BigInteger.valueOf(127)) <= 0)
            System.out.println("byte");
        else if( n.compareTo(BigInteger.valueOf(-32768)) >= 0 &&  n.compareTo(BigInteger.valueOf(32767)) <= 0 )
            System.out.println("short");
        else if ( n.compareTo(BigInteger.valueOf(-2147483648)) >= 0 &&  n.compareTo(BigInteger.valueOf(2147483647)) <= 0 )
            System.out.println("int");
        else if ( n.compareTo(BigInteger.valueOf(-9223372036854775808L)) >= 0 &&  n.compareTo(BigInteger.valueOf(9223372036854775807L)) <= 0 )
            System.out.println("long");
        else
            System.out.println("BigInteger");
    }

    public static void main(String args[]){
        new a_66().run();
    }

}