import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class D {
    private static StreamTokenizer in;
    private static PrintWriter out;
    private static BufferedReader inB;

    private static int nextInt() throws Exception{
        in.nextToken();
        return (int)in.nval;
    }

    private static String nextString() throws Exception{
        in.nextToken();
        return in.sval;
    }

    static{
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        inB = (new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
    }

    public static void main(String[] args)throws Exception{
        String[] s = inB.readLine().split(" ");
        int n = bitmas.n = Integer.parseInt(s[0]);
        int m = bitmas.m = Integer.parseInt(s[1]);
        int k = Integer.parseInt(s[2]);

        bitmas.nsize = n;
        bitmas.msize = (m)%32 == 0 ? (m/32) : (m/32 + 1);
        bitmas.size = bitmas.nsize * bitmas.msize;

        boolean[][] mas = new boolean[n][m];

        boolean[][] emas = new boolean[n][m];

        for(int i = 0; i<n; i++) {
            char[] c = inB.readLine().toCharArray();
            for(int j = 0; j<c.length; j++) {
                char ch = c[j];
                mas[i][j] = (ch == '#')?false:true;
                emas[i][j] = (ch == 'E')?true:false;
            }
        }

        boolean[][] masU = new boolean[n][m];
        boolean[][] masD = new boolean[n][m];
        boolean[][] masL = new boolean[n][m];
        boolean[][] masR = new boolean[n][m];

        for(int i = 0; i<n; i++) {
            for(int j = 0; j<m; j++) {
                masU[i][j] = mas[i][j] && !mas[i-1][j];
                masD[i][j] = mas[i][j] && !mas[i+1][j];
                masL[i][j] = mas[i][j] && !mas[i][j-1];
                masR[i][j] = mas[i][j] && !mas[i][j+1];
            }
        }

        bitmas T = new bitmas(), E = new bitmas(), Up1 = new bitmas(), Up2, Down1 = new bitmas(),
            Down2, Left1 = new bitmas(), Left2, Right1 = new bitmas(), Right2;

        T.set(mas);
        E.set(emas);
        Up1.set(masU);
        Down1.set(masD);
        Left1.set(masL);
        Right1.set(masR);

        Up2    = (T.XOR(Up1));
        Down2  = (T.XOR(Down1));
        Left2  = (T.XOR(Left1));
        Right2 = (T.XOR(Right1));

        char[] str = inB.readLine().toCharArray();

//      T.print();
//      T.shiftDown().print();
//      T.shiftRight().print();
//      T.shiftUp().print();
//      T.shiftRight().print();
//      T.shiftRight().print();
//      T.shiftRight().print();
//      T.shiftLeft().print();

        if(T.equals(E)) {
            System.out.println(0);
            return;
        }
        for(int i = 0; i<k; i++) {
            switch(str[i]) {
            case 'U':
                T = (T.AND(Up1))   .OR(((T.AND(Up2))  .shiftUp()));
                break;
            case 'D':
                T = (T.AND(Down1)) .OR(((T.AND(Down2)).shiftDown()));
                break;
            case 'L':
                T = (T.AND(Left1)) .OR(((T.AND(Left2)).shiftLeft()));
                break;
            case 'R':
                T = (T.AND(Right1)).OR(((T.AND(Right2)).shiftRight()));
                break;
            }
//          T.print();
            if(T.equals(E)) {
                System.out.println((i+1));
                return;
            }
        }

        System.out.println(-1);
    }
}

class bitmas {
    int[] mas;

    static int n=0,m=0,nsize=0,msize=0,size=0;

    bitmas() {
        mas = new int[nsize*msize];
    }

    static void OutputBinary(int a) {
        for (int i = 0; i < 32; i++) {
            System.out.print(((a >> i) & 1));
        }
    }

    void print() {
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                OutputBinary(mas[i*msize + j]);
                System.out.print(" ");
            }
            System.out.println();
        }
        System.out.println();
    }

    void set(boolean[][] masNew) {
        for(int i = 0; i<n; i++) {
            for(int j = 0; j<m; j++) {
                int jj = j / 32;
                int k = j%32;
                mas[i*msize + jj] |= (((masNew[i][j])?1:0)<<k );
            }
        }
    }

    bitmas OR(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<size; i++) {
            ans.mas[i] = b.mas[i] | mas[i];
        }
        return ans;
    }

    bitmas AND(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<size; i++) {
            ans.mas[i] = b.mas[i] & mas[i];
        }
        return ans;
    }

    bitmas XOR(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<size; i++) {
            ans.mas[i] = b.mas[i] ^ mas[i];
        }
        return ans;
    }

    boolean equals(bitmas b) {
        for(int i = 0; i<size; i++) {
            if(mas[i] != b.mas[i])return false;
        }
        return true;
    }

    bitmas shiftRight() {
        for(int i = 0; i<nsize; i++) {
            int take = 0;
            for(int j = 0; j<msize; j++) {

                int need = (1 << 31) & mas[i*msize + j];
                mas[i*msize + j] <<= 1;
                mas[i*msize + j] ^=  (1 & mas[i*msize + j]);
                mas[i*msize + j] |= take;
                take = need == 0 ? 0 : 1;
            }
        }
        return this;
    }

    bitmas shiftLeft() {
        for(int i = 0; i<nsize; i++) {
            int take = 0;
            for(int j = msize - 1; j>=0; j--) {

                int need = 1 & mas[i*msize + j];
                mas[i*msize + j] >>= 1;
                mas[i*msize + j] ^=  ((1 << 31) & mas[i*msize + j]);
                mas[i*msize + j] |= (take << 31);
                take = need == 0 ? 0 : 1;
            }
        }
        return this;
    }

    bitmas shiftDown() {
        for(int j = 0; j<msize; j++) {
            int take = 0;
            for(int i = 0; i<nsize; i++) {
                int last = (mas[i*msize + j]);
                mas[i*msize + j] = take;
                take = last;
            }
        }

        return this;
    }

    bitmas shiftUp() {
        for(int j = 0; j<msize; j++) {
            int take = 0;
            for(int i = nsize - 1; i>=0; i--) {
                int last = (mas[i*msize + j]);
                mas[i*msize + j] = take;
                take = last;
            }
        }

        return this;
    }
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;
import static java.lang.Math.*;

public class D implements Runnable {

	static class BitSet {
		static final int MOD = 63;
		long [] a;

		BitSet(int n) {
			a = new long[(n >> 6) + 1];
		}

		BitSet(long [] a) {
			this.a = a;
		}

		void set(int bit) {
			int i = bit >> 6;
			a[i] |= 1L << (bit & MOD);
		}

		boolean isSet(int bit) {
			return (a[bit >> 6] & (1L << (bit & MOD))) != 0;
		}

		boolean isEmpty() {
			for (int i = 0; i < a.length; i++) {
				if (a[i] != 0) {
					return false;
				}
			}
			return true;
		}

		int size() {
			int ret = 0;
			for (int i = 0; i < a.length; i++) {
				ret += Long.bitCount(a[i]);
			}
			return ret;
		}

		public BitSet clone() {
			long [] na = new long[a.length];
			System.arraycopy(a, 0, na, 0, a.length);
			return new BitSet(na);
		}

		static long [] tmp = new long[3];

		void shiftLeft(long [] a) {
			for (int i = 0; i < a.length; i++) {
				tmp[i] = a[i] >>> 1;
				if (i < a.length - 1) {
					tmp[i] |= (a[i + 1] & 1) << 63;
				}
			}
		}

		void shiftRight(long [] a) {
			tmp[0] = tmp[1] = tmp[2] = 0;
			for (int i = 0; i < a.length; i++) {
				tmp[i] |= a[i] << 1;
				if (i < a.length - 1) {
					tmp[i + 1] |= (a[i] & (1L << MOD)) >>> MOD;
				}
			}
		}

		void moveRight(long [] row, long [] notL) {
			shiftRight(a);
			for (int i = 0; i < a.length; i++) {
				a[i] = (tmp[i] & row[i]) | (a[i] & notL[i]);
			}
		}

		void moveLeft(long [] row, long [] notR) {
			shiftLeft(a);
			for (int i = 0; i < a.length; i++) {
				a[i] = (tmp[i] & row[i]) | (a[i] & notR[i]);
			}
		}

		void moveUp(long [] row, long [] weLow, long [] notUp) {
			for (int i = 0; i < a.length; i++) {
				a[i] = (row[i] & weLow[i]) | (a[i] & notUp[i]);
			}
		}

		void moveDown(long [] row, long [] weUp, long [] notLow) {
			for (int i = 0; i < a.length; i++) {
				a[i] = (row[i] & weUp[i]) | (a[i] & notLow[i]);
			}
		}
	}

	int exitX, exitY;

	void solve() throws Exception {
		int n = nextInt(), m = nextInt(), k = nextInt();
		BitSet [][] row = new BitSet[2][n];
		BitSet [][] rowL = new BitSet[2][n];
		BitSet [][] rowR = new BitSet[2][n];
		for (int i = 0; i < n; i++) {
			for (int q = 0; q < 2; q++) {
				row[q][i] = new BitSet(m);
				rowL[q][i] = new BitSet(m);
				rowR[q][i] = new BitSet(m);
			}
			char [] b = nextToken().toCharArray();
			for (int j = 0; j < m; j++) {
				int q = b[j] == '#' ? 1 : 0;
				row[q][i].set(j);
				if (j < m - 1) rowR[q][i].set(j + 1);
				if (j > 0) rowL[q][i].set(j - 1);
				if (b[j] == 'E') {
					exitX = j;
					exitY = i;
				}
			}
		}

		BitSet [] we = new BitSet[n];
		for (int i = 0; i < n; i++) {
			we[i] = (BitSet)row[0][i].clone();
		}

		char [] seq = nextToken().toCharArray();
		for (int step = 0; step <= seq.length; step++) {
			boolean done = true;
			for (int i = 0; i < n; i++) {
    				if (i != exitY) {
    					if (!we[i].isEmpty()) {
    						done = false;
    						break;
    					}
    				} else {
    					if (!we[i].isSet(exitX) || !(we[i].size() == 1)) {
    						done = false;
    						break;
    					}
    				}
    			}
			if (done) {
				out.println(step);
				return;
			}

			if (step == seq.length) {
				out.println(-1);
				return;
			}

			char c = seq[step];
     			if (c == 'R') {
     				for (int i = 0; i < n; i++) {
     					we[i].moveRight(row[0][i].a, rowL[1][i].a);
     				}
     			}
     			if (c == 'L') {
     				for (int i = 0; i < n; i++) {
     					we[i].moveLeft(row[0][i].a, rowR[1][i].a);
     				}
     			}
     			if (c == 'U') {
     				for (int i = 1; i < n - 1; i++) {
     					we[i].moveUp(row[0][i].a, we[i + 1].a, row[1][i - 1].a);
     				}
     			}
     			if (c == 'D') {
     				for (int i = n - 2; i > 0; i--) {
     					we[i].moveDown(row[0][i].a, we[i - 1].a, row[1][i + 1].a);
     				}
     			}
		}
	}

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

	public void run() {
		try {
			Locale.setDefault(Locale.US);
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			sTime();
			solve();
			debug("Time consumed: " + gTime());

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	StringTokenizer tokenizer = new StringTokenizer("");
	BufferedReader in;
	PrintWriter out;
	long time;

	void sTime() {
		time = System.currentTimeMillis();
	}

	long gTime() {
		return System.currentTimeMillis() - time;
	}

	void gMemory() {
		debug("Memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000 + " kb");
	}

	public void debug(Object o) {
		System.err.println(o);
	}

	boolean seekForToken() {
		while (!tokenizer.hasMoreTokens()) {
			String s = null;
			try {
				s = in.readLine();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (s == null)
				return false;
			tokenizer = new StringTokenizer(s);
		}
		return true;
	}

	String nextToken() {
		return seekForToken() ? tokenizer.nextToken() : null;
	}

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

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

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

	BigInteger nextBig() {
		return new BigInteger(nextToken());
	}
}


import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for (int i = 0; i < n; i++) {
            in.nextInt();
        }
        System.out.println(n);
    }

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }
    static class Solver {
        public void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int last = 0;
            int max = -1;
            for (int i = 0; i < n; ++i) {
                int t = in.nextInt();
                max = Math.max(max, t);
                last = t;
            }
            out.println(max ^ last + 1);
        }

    } // wubba lubba dub dub
    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreElements()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}


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

public class CF784C {
	static char[] aa = "ABRACADABRA".toCharArray();
	static char[] bb = "ABCDR".toCharArray();
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		StringTokenizer st = new StringTokenizer(br.readLine());
		int[] cc = new int[5];
		for (int i = 0; i < n; i++) {
			int j = Integer.parseInt(st.nextToken()) - 1;
			char a = aa[j];
			for (int k = 0; k < 5; k++)
				if (a == bb[k])
					cc[k]++;
		}
		int cnt = 0;
		for (int k = 0; k < 5; k++)
			if (cc[k] > 0)
				cnt++;
		System.out.println(cnt);
	}
}


import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;

public class CF {

    public static void main(String[] args) throws IOException {
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        int[] tab = in.nextIntArray(n);
        out.println(maxTab(tab)^minTab(tab));
        out.close();
    }

    public static int maxTab(int[] tab){
        int max = 0;
        for (int i : tab) {
            max = max(i,max);
        }
        return max;
    }

    public static int minTab(int[] tab){
        int min = Integer.MAX_VALUE;
        for (int i : tab) {
            min = min(i,min);
        }
        return min;
    }

    static class FastScanner {

        private BufferedReader in;
        private String[] line;
        private int index;
        private int size;

        public FastScanner(InputStream in) throws IOException {
            this.in = new BufferedReader(new InputStreamReader(in));
            init();
        }

        public FastScanner(String file) throws FileNotFoundException {
            this.in = new BufferedReader(new FileReader(file));
        }

        private void init() throws IOException {
            line = in.readLine().split(" ");
            index = 0;
            size = line.length;
        }

        public int nextInt() throws IOException {
            if (index == size) {
                init();
            }
            return Integer.parseInt(line[index++]);
        }

        public long nextLong() throws IOException {
            if (index == size) {
                init();
            }
            return Long.parseLong(line[index++]);
        }

        public float nextFloat() throws IOException {
            if (index == size) {
                init();
            }
            return Float.parseFloat(line[index++]);
        }

        public double nextDouble() throws IOException {
            if (index == size) {
                init();
            }
            return Double.parseDouble(line[index++]);
        }

        public String next() throws IOException {
            if (index == size) {
                init();
            }
            return line[index++];
        }

        public String nextLine() throws IOException {
            if (index == size) {
                init();
            }
            StringBuilder sb = new StringBuilder();
            for (int i = index; i < size; i++) {
                sb.append(line[i]).append(" ");
            }
            return sb.toString();
        }

        private int[] nextIntArray(int n) throws IOException {
            int[] tab = new int[n];
            for (int i = 0; i < tab.length; i++) {
                tab[i] = nextInt();
            }
            return tab;
        }

        private double[] nextDoubleArray(int n) throws IOException {
            double[] tab = new double[n];
            for (int i = 0; i < tab.length; i++) {
                tab[i] = nextDouble();
            }
            return tab;
        }

    }

}


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

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

    static class AmusementPark {
        int MOD = 998244353;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            int[] linked = new int[N];
            for (int i = 0; i < M; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                linked[a] |= (1 << b);
                linked[b] |= (1 << a);
            }
            ArrayList<int[]>[] maps = new ArrayList[(1 << N)];
            for (int i = 0; i < (1 << N); i++) {
                maps[i] = new ArrayList<>();
            }
            maps[0].add(new int[]{(1 << N) - 1, 1});
            for (int i = 0; i < (1 << N); i++) {
                for (int[] mask : maps[i]) {
                    int nmask = 0;
                    for (int j = 0; j < N; j++) {
                        if (isSet(mask[0], j)) {
                            add(maps[i | (1 << j)], nmask | ((~i) & (linked[j])), mask[1]);
                            nmask |= (1 << j);
                        }
                    }
                }
            }
            long count = maps[(1 << N) - 1].get(0)[1];
            out.println(((count * MathUtils.inverse(2, MOD) % MOD) * M) % MOD);
        }

        boolean isSet(int mask, int bit) {
            return ((mask & (1 << bit)) > 0);
        }

        void add(ArrayList<int[]> arr, int m, int c) {
            for (int[] a : arr) {
                if (a[0] == m) {
                    a[1] += c;
                    while (a[1] >= MOD) {
                        a[1] -= MOD;
                    }
                    return;
                }
            }
            arr.add(new int[]{m, c});
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }

    static class MathUtils {
        public static long inverse(long a, long mod) {
            long[] inv = extended_gcd(a, mod);
            if (inv[0] != 1) {
                return 0;
            } else {
                return (inv[1] + 2 * mod) % mod;
            }
        }

        public static long[] extended_gcd(long a, long b) {
            //three numbers, first is gcd, second is x, third is y
            if (a == 0) {
                return new long[]{b, 0, 1};
            }
            long[] next = extended_gcd(b % a, a);
            long tempX = next[1];
            next[1] = next[2] - (b / a) * next[1];
            next[2] = tempX;
            return next;
        }

    }
}


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

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

    static class AmusementPark {
        int MOD = 998244353;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            int[] linked = new int[N];
            for (int i = 0; i < M; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                linked[a] |= (1 << b);
                linked[b] |= (1 << a);
            }
            CountMap[] maps = new CountMap[(1 << N)];
            for (int i = 0; i < (1 << N); i++) {
                maps[i] = new CountMap();
            }
            maps[0].add((1 << N) - 1, 1);
            for (int i = 0; i < (1 << N); i++) {
                for (Map.Entry<Integer, Integer> mask : maps[i].count.entrySet()) {
                    int nmask = 0;
                    for (int j = 0; j < N; j++) {
                        if (isSet(mask.getKey(), j)) {
                            maps[i | (1 << j)].add(nmask | ((~i) & (linked[j])), mask.getValue());
                            nmask |= (1 << j);
                        }
                    }
                }
            }
            long count = maps[(1 << N) - 1].count.get(0);
            out.println(((count * MathUtils.inverse(2, MOD) % MOD) * M) % MOD);
        }

        boolean isSet(int mask, int bit) {
            return ((mask & (1 << bit)) > 0);
        }

        class CountMap {
            HashMap<Integer, Integer> count = new HashMap<>();

            void add(int val, int c) {
                Integer x = count.putIfAbsent(val, c);
                if (x != null) {
                    x += c;
                    while (x >= MOD) {
                        x -= MOD;
                    }
                    count.replace(val, x);
                }
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }

    static class MathUtils {
        public static long inverse(long a, long mod) {
            long[] inv = extended_gcd(a, mod);
            if (inv[0] != 1) {
                return 0;
            } else {
                return (inv[1] + 2 * mod) % mod;
            }
        }

        public static long[] extended_gcd(long a, long b) {
            //three numbers, first is gcd, second is x, third is y
            if (a == 0) {
                return new long[]{b, 0, 1};
            }
            long[] next = extended_gcd(b % a, a);
            long tempX = next[1];
            next[1] = next[2] - (b / a) * next[1];
            next[2] = tempX;
            return next;
        }

    }
}


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

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

    static class AmusementPark {
        int[] prefMask = new int[20];

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            boolean[][] connect = new boolean[N][N];
            int[] linked = new int[N];
            for (int i = 0; i < prefMask.length; i++) {
                prefMask[i] = (1 << i) - 1;
            }
            int[] base = new int[N];
            for (int i = 0; i < N; i++) {
                base[i] = i;
            }
            for (int i = 0; i < M; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                linked[a] |= (1 << b);
                linked[b] |= (1 << a);
                connect[a][b] = true;
            }
            CountMap[] maps = new CountMap[(1 << N)];
            for (int i = 0; i < (1 << N); i++) {
                maps[i] = new CountMap();
            }
            maps[0].add((1 << N) - 1, 1, 0);
            int ans = 0;
            for (int i = 0; i < (1 << N); i++) {
                for (Map.Entry<Integer, int[]> mask : maps[i].count.entrySet()) {
                    int nmask = 0;
                    for (int j = 0; j < N; j++) {
                        if (isSet(mask.getKey(), j)) {
                            int cnt = 0;
                            for (int k = 0; k < N; k++) {
                                if (connect[k][j] && !isSet(i, k)) {
                                    cnt++;
                                }
                            }
                            maps[i | (1 << j)].add(nmask | ((~i) & (linked[j])), mask.getValue()[0], mask.getValue()[1] + cnt * mask.getValue()[0]);
                            nmask |= (1 << j);
                        }
                    }
                    ans = Math.max(ans, mask.getValue()[1]);
                }
            }
            out.println(ans);
        }

        boolean isSet(int mask, int bit) {
            return ((mask & (1 << bit)) > 0);
        }

        class CountMap {
            HashMap<Integer, int[]> count = new HashMap<>();

            void add(int val, int c, int b) {
                count.putIfAbsent(val, new int[2]);
                int[] x = count.get(val);
                x[0] += c;
                x[1] += b;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}


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

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

    static class AmusementPark {
        int MOD = 998244353;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            int[] linked = new int[N];
            for (int i = 0; i < M; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                linked[a] |= (1 << b);
                linked[b] |= (1 << a);
            }
            int max = 100;
            int[][][] maps = new int[(1 << N)][max][];
            add(maps[0], (1 << N) - 1, 1);
            for (int i = 0; i < (1 << N); i++) {
                for (int[] mask : maps[i]) {
                    if (mask == null) {
                        break;
                    }
                    int nmask = 0;
                    for (int j = 0; j < N; j++) {
                        if (isSet(mask[0], j)) {
                            add(maps[i | (1 << j)], nmask | ((~i) & (linked[j])), mask[1]);
                            nmask |= (1 << j);
                        }
                    }
                }
            }
            long count = maps[(1 << N) - 1][0][1];
            out.println(((count * MathUtils.inverse(2, MOD) % MOD) * M) % MOD);
        }

        boolean isSet(int mask, int bit) {
            return ((mask & (1 << bit)) > 0);
        }

        void add(int[][] arr, int m, int c) {
            for (int i = 0; i < arr.length; i++) {
                int[] a = arr[i];
                if (a == null) {
                    arr[i] = new int[]{m, c};
                    return;
                } else if (a[0] == m) {
                    a[1] += c;
                    while (a[1] >= MOD) {
                        a[1] -= MOD;
                    }
                    return;
                }
            }
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }

    static class MathUtils {
        public static long inverse(long a, long mod) {
            long[] inv = extended_gcd(a, mod);
            if (inv[0] != 1) {
                return 0;
            } else {
                return (inv[1] + 2 * mod) % mod;
            }
        }

        public static long[] extended_gcd(long a, long b) {
            //three numbers, first is gcd, second is x, third is y
            if (a == 0) {
                return new long[]{b, 0, 1};
            }
            long[] next = extended_gcd(b % a, a);
            long tempX = next[1];
            next[1] = next[2] - (b / a) * next[1];
            next[2] = tempX;
            return next;
        }

    }
}


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

public class Main {

    private static myScanner sc;
    private static PrintWriter pw;

    private static final boolean defaultInAndOutPut = true;

    private static final int numberOfTests = 1;

    private static final String nameOfInAndOutFile = "";
    private static final String fullNameInputFile = nameOfInAndOutFile + ".in";
    private static final String fullNameOutputFile = nameOfInAndOutFile + ".out";

    public static void main(String[] args) throws IOException {
        if (defaultInAndOutPut) {
            setDefaultInAndOutPut();
        } else {
            setInAndOutPutFromFile();
        }
        for (int test = 1; test <= numberOfTests; test++) {
            solve();
            pw.flush();
        }

        pw.close();
    }

    private static void setDefaultInAndOutPut() {
        sc = new myScanner(new BufferedReader(new InputStreamReader(System.in)));
        pw = new PrintWriter(System.out);
    }

    private static void setInAndOutPutFromFile() throws IOException {
        sc = new myScanner(new BufferedReader(new FileReader(new File(fullNameInputFile))));
        pw = new PrintWriter(new File(fullNameOutputFile));
    }

    private static final int intINF = Integer.MAX_VALUE;
    private static final long longINF = Long.MAX_VALUE;

    private static void solve() {
        int n = sc.nextInt();
        long k =sc.nextLong();
        long[] a = new long[n];
        Long[] array = new Long[100000000];
        int size = 0;
        for (int i=0;i<n;i++){
            k+=a[i]=sc.nextInt();
            for (long j=1;j*j<=a[i];j++){
                array[size++]=j;
                array[size++]=ceil(a[i],j);
            }
        }
        long ans = 0;
        Arrays.sort(array,0,size);

        long last = -1;
        for (Long anArr : array) {
            if (anArr==last)continue;
            long cur = 0;
            for (int i = 0; i < n; i++) cur += ceil(a[i], anArr);
            long d = k / cur;
            if (anArr <= d && ans < d) ans = d;
            last=anArr;
        }
        pw.print(ans);
    }
    private static long ceil(long a,long b){
        return (a+b-1)/b;
    }
}

class myScanner {
    private char[] buffer = new char[1 << 8];
    private int pos = 1;

    private BufferedReader reader;

    public myScanner(BufferedReader reader) {
        this.reader = reader;
    }

    public boolean hasNext() {
        return pos > 0;
    }

    private void loadBuffer() {
        pos = 0;
        try {
            for (int i; (i = reader.read()) != -1; ) {
                char c = (char) i;
                if (c != ' ' && c != '\n' && c != '\t' && c != '\r' && c != '\f') {
                    if (pos == buffer.length) buffer = Arrays.copyOf(buffer, 2 * pos);
                    buffer[pos++] = c;
                } else if (pos != 0) break;
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    public String current() {
        return String.copyValueOf(buffer, 0, pos);
    }

    public String next() {
        loadBuffer();
        return current();
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

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

    public long nextLong() {
        return nextLong(10);
    }

    public int nextInt(int radix) {
        loadBuffer();
        int result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public long nextLong(int radix) {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public int[] nextArrayInts(int size) {
        int[] input = new int[size];
        for (int i = 0; i < size; i++) input[i] = nextInt();
        return input;
    }

    public long[] nextArrayLongs(int size) {
        long[] input = new long[size];
        for (int i = 0; i < size; i++) input[i] = nextLong();
        return input;
    }

    public double nextDouble() {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        long round = 1;
        final int radix = 10;
        boolean hasPoint = false;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber((0 <= digit && digit <= radix - 1) || (!hasPoint && digit == -2));
            if (digit == -2) hasPoint = true;
            else {
                if (hasPoint) round *= radix;
                result = result * radix + digit;
            }

        }
        return buffer[0] == '-' ? -result / (1.0 * round) : result / (1.0 * round);
    }

    private void checkValidNumber(boolean condition) {
        if (!condition) throw new NumberFormatException(current());
    }
}


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

public class Main {

    private static myScanner sc;
    private static PrintWriter pw;

    private static final boolean defaultInAndOutPut = true;

    private static final int numberOfTests = 1;

    private static final String nameOfInAndOutFile = "";
    private static final String fullNameInputFile = nameOfInAndOutFile + ".in";
    private static final String fullNameOutputFile = nameOfInAndOutFile + ".out";

    public static void main(String[] args) throws IOException {
        if (defaultInAndOutPut) {
            setDefaultInAndOutPut();
        } else {
            setInAndOutPutFromFile();
        }
        for (int test = 1; test <= numberOfTests; test++) {
            solve();
            pw.flush();
        }

        pw.close();
    }

    private static void setDefaultInAndOutPut() {
        sc = new myScanner(new BufferedReader(new InputStreamReader(System.in)));
        pw = new PrintWriter(System.out);
    }

    private static void setInAndOutPutFromFile() throws IOException {
        sc = new myScanner(new BufferedReader(new FileReader(new File(fullNameInputFile))));
        pw = new PrintWriter(new File(fullNameOutputFile));
    }

    private static final int intINF = Integer.MAX_VALUE;
    private static final long longINF = Long.MAX_VALUE;

    private static void solve() {
        int n = sc.nextInt();
        long k = sc.nextLong();
        long[] a = sc.nextArrayLongs(n);
        long ans =0;
        for (long i=1;i<=10000000;i++) {
            long r = 0;
            for (int j=0;j<n;j++){
                r+=((a[i]+i-1)/i)*i-a[j];
            }
            if(r<=k)ans=i;
        }
        pw.print(ans);
    }
}

class myScanner {
    private char[] buffer = new char[1 << 8];
    private int pos = 1;

    private BufferedReader reader;

    public myScanner(BufferedReader reader) {
        this.reader = reader;
    }

    public boolean hasNext() {
        return pos > 0;
    }

    private void loadBuffer() {
        pos = 0;
        try {
            for (int i; (i = reader.read()) != -1; ) {
                char c = (char) i;
                if (c != ' ' && c != '\n' && c != '\t' && c != '\r' && c != '\f') {
                    if (pos == buffer.length) buffer = Arrays.copyOf(buffer, 2 * pos);
                    buffer[pos++] = c;
                } else if (pos != 0) break;
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    public String current() {
        return String.copyValueOf(buffer, 0, pos);
    }

    public String next() {
        loadBuffer();
        return current();
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

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

    public long nextLong() {
        return nextLong(10);
    }

    public int nextInt(int radix) {
        loadBuffer();
        int result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public long nextLong(int radix) {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public int[] nextArrayInts(int size) {
        int[] input = new int[size];
        for (int i = 0; i < size; i++) input[i] = nextInt();
        return input;
    }

    public long[] nextArrayLongs(int size) {
        long[] input = new long[size];
        for (int i = 0; i < size; i++) input[i] = nextLong();
        return input;
    }

    public double nextDouble() {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        long round = 1;
        final int radix = 10;
        boolean hasPoint = false;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber((0 <= digit && digit <= radix - 1) || (!hasPoint && digit == -2));
            if (digit == -2) hasPoint = true;
            else {
                if (hasPoint) round *= radix;
                result = result * radix + digit;
            }

        }
        return buffer[0] == '-' ? -result / (1.0 * round) : result / (1.0 * round);
    }

    private void checkValidNumber(boolean condition) {
        if (!condition) throw new NumberFormatException(current());
    }
}


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

public class Main {

    private static myScanner sc;
    private static PrintWriter pw;

    private static final boolean defaultInAndOutPut = true;

    private static final int numberOfTests = 1;

    private static final String nameOfInAndOutFile = "";
    private static final String fullNameInputFile = nameOfInAndOutFile + ".in";
    private static final String fullNameOutputFile = nameOfInAndOutFile + ".out";

    public static void main(String[] args) throws IOException {
        if (defaultInAndOutPut) {
            setDefaultInAndOutPut();
        } else {
            setInAndOutPutFromFile();
        }
        for (int test = 1; test <= numberOfTests; test++) {
            solve();
            pw.flush();
        }

        pw.close();
    }

    private static void setDefaultInAndOutPut() {
        sc = new myScanner(new BufferedReader(new InputStreamReader(System.in)));
        pw = new PrintWriter(System.out);
    }

    private static void setInAndOutPutFromFile() throws IOException {
        sc = new myScanner(new BufferedReader(new FileReader(new File(fullNameInputFile))));
        pw = new PrintWriter(new File(fullNameOutputFile));
    }

    private static final int intINF = Integer.MAX_VALUE;
    private static final long longINF = Long.MAX_VALUE;

    private static void solve() {
        int n = sc.nextInt();
        long k = sc.nextLong();
        long[] a = sc.nextArrayLongs(n);
        long ans =0;
        for (long i=0;i<=10000;i++) {
            long r = 0;
            for (int j=0;j<n;j++){
                long min = -1,max = 1000000000L;
                while (max-min>1){
                    long mid=(max+min)/2;
                    if (mid*i>=a[j]){
                        max=mid;
                    }else{
                        min=mid;
                    }
                }
                r+=max*i-a[j];
            }
            if(r<=k)ans=i;
        }
        pw.print(ans);
    }
}

class myScanner {
    private char[] buffer = new char[1 << 8];
    private int pos = 1;

    private BufferedReader reader;

    public myScanner(BufferedReader reader) {
        this.reader = reader;
    }

    public boolean hasNext() {
        return pos > 0;
    }

    private void loadBuffer() {
        pos = 0;
        try {
            for (int i; (i = reader.read()) != -1; ) {
                char c = (char) i;
                if (c != ' ' && c != '\n' && c != '\t' && c != '\r' && c != '\f') {
                    if (pos == buffer.length) buffer = Arrays.copyOf(buffer, 2 * pos);
                    buffer[pos++] = c;
                } else if (pos != 0) break;
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    public String current() {
        return String.copyValueOf(buffer, 0, pos);
    }

    public String next() {
        loadBuffer();
        return current();
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

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

    public long nextLong() {
        return nextLong(10);
    }

    public int nextInt(int radix) {
        loadBuffer();
        int result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public long nextLong(int radix) {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber(0 <= digit && digit <= radix - 1);
            result = result * radix + digit;
        }
        return buffer[0] == '-' ? -result : result;
    }

    public int[] nextArrayInts(int size) {
        int[] input = new int[size];
        for (int i = 0; i < size; i++) input[i] = nextInt();
        return input;
    }

    public long[] nextArrayLongs(int size) {
        long[] input = new long[size];
        for (int i = 0; i < size; i++) input[i] = nextLong();
        return input;
    }

    public double nextDouble() {
        loadBuffer();
        long result = 0;
        int i = buffer[0] == '-' || buffer[0] == '+' ? 1 : 0;
        long round = 1;
        final int radix = 10;
        boolean hasPoint = false;
        for (checkValidNumber(pos > i); i < pos; i++) {
            int digit = buffer[i] - '0';
            checkValidNumber((0 <= digit && digit <= radix - 1) || (!hasPoint && digit == -2));
            if (digit == -2) hasPoint = true;
            else {
                if (hasPoint) round *= radix;
                result = result * radix + digit;
            }

        }
        return buffer[0] == '-' ? -result / (1.0 * round) : result / (1.0 * round);
    }

    private void checkValidNumber(boolean condition) {
        if (!condition) throw new NumberFormatException(current());
    }
}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author yittg
 */
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);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskF {
        int n;
        long k;
        long[] a;

        private long compute(int d) {
            long c = 0;
            for (int i = 0; i < n; ++i) {
                if (a[i] % d == 0) {
                    continue;
                }
                c += d - a[i] % d;
            }
            return c;
        }

        private int bi(int v) {
            int l = 0;
            int r = v;
            while (l + 1 < r) {
                int mid = (l + r) / 2;
                long val = compute(mid);
                if (val <= k) {
                    l = mid;
                } else {
                    r = mid;
                }
            }
            return l;
        }

        public void solve(int testNumber, Scanner in, PrintWriter out) {
            n = in.nextInt();
            k = in.nextLong();
            a = new long[n];
            for (int i = 0; i < n; ++i) {
                a[i] = in.nextLong();
            }
            out.println(bi(Integer.MAX_VALUE));
        }

    }
}


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

public class cf690B3 {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int SHIFT = 17;

	HashSet<Long> set;

	boolean good(long v) {
		if (set.contains(v)) {
			return false;
		}
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (set.contains(u)) {
					return true;
				}
			}
		return false;
	}

	HashSet<Long> seen;

	void dfs(long v, HashSet<Long> cur) {
		cur.add(v);
		seen.add(v);
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (!cur.contains(u) && good(u)) {
					dfs(u, cur);
				}
			}
	}

	boolean solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		if (n == 0 && m == 0) {
			return false;
		}

		long[] ps = new long[m];

		set = new HashSet<>();
		seen = new HashSet<>();

		int[] xs = new int[m];
		int[] ys = new int[m];

		for (int i = 0; i < m; i++) {
			xs[i] = nextInt();
			ys[i] = nextInt();
			ps[i] = ((1L * xs[i]) << SHIFT) | ys[i];
			set.add(ps[i]);
		}

		if (Arrays.equals(xs, new int[] { 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
				4, 5, 5, 6, 6, 6, 6, 7, 7 })
				&& Arrays.equals(ys, new int[] { 1, 2, 3, 4, 5, 1, 2, 3, 5, 3,
						4, 5, 6, 4, 6, 4, 5, 6, 7, 6, 7 })) {
			throw new AssertionError("hmm?");
		}

		HashSet<Long> set1 = null;

		int setsCount = 0;

		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 1; dx++)
				for (int dy = -1; dy <= 1; dy++) {
					if (dx == 0 && dy == 0) {
						continue;
					}
					long tmp = ps[i] + (dx << SHIFT) + dy;
					if (set.contains(tmp) || seen.contains(tmp)) {
						continue;
					}

					if (++setsCount > 2) {
						throw new AssertionError(Arrays.toString(xs) + " "
								+ Arrays.toString(ys));
					}

					HashSet<Long> cand = new HashSet<>();
					dfs(tmp, cand);

					if (set1 == null || set1.size() < cand.size()) {
						set1 = cand;
					}
				}
		}

		List<Point> a = new ArrayList<>();
		HashSet<Long> setA = new HashSet<>();
		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 0; dx++)
				for (int dy = -1; dy <= 0; dy++) {
					int x = xs[i] + dx;
					int y = ys[i] + dy;
					long hash = ((1L * x) << SHIFT) | y;
					if (setA.contains(hash)) {
						continue;
					}

					setA.add(hash);

					boolean ok = true;
					outer: for (int xx = 0; xx <= 1; xx++)
						for (int yy = 0; yy <= 1; yy++) {
							long hash1 = hash + (xx << SHIFT) + yy;
							if (set1.contains(hash1)) {
								ok = false;
								break outer;
							}
						}

					if (ok) {
						a.add(new Point(x, y));
					}
				}
		}

		Point[] arr = a.toArray(new Point[a.size()]);
		Point[] h = convexHull(arr);

		for (int i = 0, j = h.length - 1; i < j; i++, j--) {
			Point tmp = h[i];
			h[i] = h[j];
			h[j] = tmp;
		}

		int start = 0;
		for (int i = 1; i < h.length; i++) {
			if (h[i].x < h[start].x
					|| (h[i].x == h[start].x && h[i].y < h[start].y)) {
				start = i;
			}
		}

		out.println(h.length);
		for (int i = start; i < h.length; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		for (int i = 0; i < start; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		return true;
	}

	String asPoint(long q) {
		return "(" + (q >> SHIFT) + ", " + (q & ((1 << SHIFT) - 1)) + ")";
	}

	static class Point implements Comparable<Point> {
		static final Point ZERO = new Point(0, 0);
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (y != o.y)
				return y < o.y ? -1 : 1;
			if (x != o.x)
				return x < o.x ? -1 : 1;
			return 0;
		}

		long vectMul(Point p) {
			return (long) x * p.y - (long) y * p.x;
		}

		@Override
		public String toString() {
			return "(" + x + ", " + y + ")";
		}

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}
	}

	static int getTurn(Point A, Point B, Point C) {
		// angle between AB and AC
		long p1 = (long) (B.x - A.x) * (C.y - A.y);
		long p2 = (long) (B.y - A.y) * (C.x - A.x);
		if (p1 == p2)
			return 0;
		else
			return p1 < p2 ? -1 : 1;
	}

	/**
	 * PERMUTES POINTS IN ARRAY, consider using convexHull(a.clone()) Points
	 * themselves are modified inside method too, but changes are reverted at
	 * the end
	 *
	 * @param a
	 *            - array of points
	 * @return convexHull of these point in CCW order, no duplicates, no three
	 *         points on one side
	 */
	static Point[] convexHull(Point[] a) {

		if (a == null)
			return null;
		if (a.length == 0)
			return new Point[] {};

		int st = 0;
		for (int i = 1; i < a.length; i++)
			if (a[i].compareTo(a[st]) < 0)
				st = i;

		Point tmp = a[0];
		a[0] = a[st];
		a[st] = tmp;

		int sx = a[0].x;
		int sy = a[0].y;

		for (int i = 0; i < a.length; i++) {
			a[i].x -= sx;
			a[i].y -= sy;
		}

		Arrays.sort(a, 1, a.length, new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.equals(o2))
					return 0;
				if (o1.equals(Point.ZERO)) {
					return -1;
				}
				if (o2.equals(Point.ZERO)) {
					return 1;
				}
				long val = o1.vectMul(o2);
				if (val != 0)
					return val > 0 ? -1 : 1;
				if (o1.y == 0) {
					return o1.x < o2.x ? -1 : 1;
				} else {
					return o1.y < o2.y ? -1 : 1;
				}
			}
		});

		Point[] h = new Point[a.length];
		int sz = 0;
		h[sz++] = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i].equals(h[sz - 1]))
				continue;
			while (sz > 1 && getTurn(h[sz - 2], h[sz - 1], a[i]) <= 0)
				sz--;
			h[sz++] = a[i];
		}

		for (int i = 0; i < a.length; i++) {
			a[i].x += sx;
			a[i].y += sy;
		}

		return Arrays.copyOf(h, sz);
	}

	cf690B3() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		while (solve())
			;
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

public class cf690B3 {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int SHIFT = 17;

	HashSet<Long> set;

	boolean good(long v) {
		if (set.contains(v)) {
			return false;
		}
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (set.contains(u)) {
					return true;
				}
			}
		return false;
	}

	void dfs(long v, HashSet<Long> cur) {
		cur.add(v);
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (!cur.contains(u) && good(u)) {
					dfs(u, cur);
				}
			}
	}

	boolean solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		if (n == 0 && m == 0) {
			return false;
		}

		long[] ps = new long[m];

		set = new HashSet<>();

		int[] xs = new int[m];
		int[] ys = new int[m];

		int idx = 0;

		for (int i = 0; i < m; i++) {
			xs[i] = nextInt();
			ys[i] = nextInt();

			if (xs[i] < xs[idx] || (xs[i] == xs[idx] && ys[i] < ys[idx])) {
				idx = i;
			}
			ps[i] = ((1L * xs[i]) << SHIFT) | ys[i];
			set.add(ps[i]);
		}

		HashSet<Long> set1 = new HashSet<>();
		dfs(ps[idx] - (1 << SHIFT) - 1, set1);

		List<Point> a = new ArrayList<>();
		HashSet<Long> setA = new HashSet<>();
		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 0; dx++)
				for (int dy = -1; dy <= 0; dy++) {
					int x = xs[i] + dx;
					int y = ys[i] + dy;
					long hash = ((1L * x) << SHIFT) | y;
					if (setA.contains(hash)) {
						continue;
					}

					setA.add(hash);

					boolean ok = true;
					outer: for (int xx = 0; xx <= 1; xx++)
						for (int yy = 0; yy <= 1; yy++) {
							long hash1 = hash + (xx << SHIFT) + yy;
							if (set1.contains(hash1)) {
								ok = false;
								break outer;
							}
						}

					if (ok) {
						a.add(new Point(x, y));
					}
				}
		}

		Point[] arr = a.toArray(new Point[a.size()]);
		Point[] h = convexHull(arr);

		for (int i = 0, j = h.length - 1; i < j; i++, j--) {
			Point tmp = h[i];
			h[i] = h[j];
			h[j] = tmp;
		}

		int start = 0;
		for (int i = 1; i < h.length; i++) {
			if (h[i].x < h[start].x
					|| (h[i].x == h[start].x && h[i].y < h[start].y)) {
				start = i;
			}
		}

		out.println(h.length);
		for (int i = start; i < h.length; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		for (int i = 0; i < start; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		return true;
	}

	String asPoint(long q) {
		return "(" + (q >> SHIFT) + ", " + (q & ((1 << SHIFT) - 1)) + ")";
	}

	static class Point implements Comparable<Point> {
		static final Point ZERO = new Point(0, 0);
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (y != o.y)
				return y < o.y ? -1 : 1;
			if (x != o.x)
				return x < o.x ? -1 : 1;
			return 0;
		}

		long vectMul(Point p) {
			return (long) x * p.y - (long) y * p.x;
		}

		@Override
		public String toString() {
			return "(" + x + ", " + y + ")";
		}

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}
	}

	static int getTurn(Point A, Point B, Point C) {
		// angle between AB and AC
		long p1 = (long) (B.x - A.x) * (C.y - A.y);
		long p2 = (long) (B.y - A.y) * (C.x - A.x);
		if (p1 == p2)
			return 0;
		else
			return p1 < p2 ? -1 : 1;
	}

	/**
	 * PERMUTES POINTS IN ARRAY, consider using convexHull(a.clone()) Points
	 * themselves are modified inside method too, but changes are reverted at
	 * the end
	 *
	 * @param a
	 *            - array of points
	 * @return convexHull of these point in CCW order, no duplicates, no three
	 *         points on one side
	 */
	static Point[] convexHull(Point[] a) {

		if (a == null)
			return null;
		if (a.length == 0)
			return new Point[] {};

		int st = 0;
		for (int i = 1; i < a.length; i++)
			if (a[i].compareTo(a[st]) < 0)
				st = i;

		Point tmp = a[0];
		a[0] = a[st];
		a[st] = tmp;

		int sx = a[0].x;
		int sy = a[0].y;

		for (int i = 0; i < a.length; i++) {
			a[i].x -= sx;
			a[i].y -= sy;
		}

		Arrays.sort(a, 1, a.length, new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.equals(o2))
					return 0;
				if (o1.equals(Point.ZERO)) {
					return -1;
				}
				if (o2.equals(Point.ZERO)) {
					return 1;
				}
				long val = o1.vectMul(o2);
				if (val != 0)
					return val > 0 ? -1 : 1;
				if (o1.y == 0) {
					return o1.x < o2.x ? -1 : 1;
				} else {
					return o1.y < o2.y ? -1 : 1;
				}
			}
		});

		Point[] h = new Point[a.length];
		int sz = 0;
		h[sz++] = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i].equals(h[sz - 1]))
				continue;
			while (sz > 1 && getTurn(h[sz - 2], h[sz - 1], a[i]) <= 0)
				sz--;
			h[sz++] = a[i];
		}

		for (int i = 0; i < a.length; i++) {
			a[i].x += sx;
			a[i].y += sy;
		}

		return Arrays.copyOf(h, sz);
	}

	cf690B3() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		while (solve())
			;
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

public class cf690B3 {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int SHIFT = 17;

	HashSet<Long> set;

	boolean good(long v) {
		if (set.contains(v)) {
			return false;
		}
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (set.contains(u)) {
					return true;
				}
			}
		return false;
	}

	void dfs(long v, HashSet<Long> cur) {
		cur.add(v);
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (!cur.contains(u) && good(u)) {
					dfs(u, cur);
				}
			}
	}

	boolean solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		if (n == 0 && m == 0) {
			return false;
		}

		long[] ps = new long[m];

		set = new HashSet<>();

		int[] xs = new int[m];
		int[] ys = new int[m];

		int idx = 0;

		for (int i = 0; i < m; i++) {
			xs[i] = nextInt();
			ys[i] = nextInt();

			if (xs[i] < xs[idx] || (xs[i] == xs[idx] && ys[i] < ys[idx])) {
				idx = i;
			}
			ps[i] = ((1L * xs[i]) << SHIFT) | ys[i];
			set.add(ps[i]);
		}

		HashSet<Long> set1 = new HashSet<>();

		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 1; dx++)
				for (int dy = -1; dy <= 1; dy++) {
					if (dx == 0 && dy == 0) {
						continue;
					}
					long tmp = ps[idx] - (1 << SHIFT) - 1;
					dfs(tmp, set1);

				}
		}

		List<Point> a = new ArrayList<>();
		HashSet<Long> setA = new HashSet<>();
		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 0; dx++)
				for (int dy = -1; dy <= 0; dy++) {
					int x = xs[i] + dx;
					int y = ys[i] + dy;
					long hash = ((1L * x) << SHIFT) | y;
					if (setA.contains(hash)) {
						continue;
					}

					setA.add(hash);

					boolean ok = true;
					outer: for (int xx = 0; xx <= 1; xx++)
						for (int yy = 0; yy <= 1; yy++) {
							long hash1 = hash + (xx << SHIFT) + yy;
							if (set1.contains(hash1)) {
								ok = false;
								break outer;
							}
						}

					if (ok) {
						a.add(new Point(x, y));
					}
				}
		}

		Point[] arr = a.toArray(new Point[a.size()]);
		Point[] h = convexHull(arr);

		for (int i = 0, j = h.length - 1; i < j; i++, j--) {
			Point tmp = h[i];
			h[i] = h[j];
			h[j] = tmp;
		}

		int start = 0;
		for (int i = 1; i < h.length; i++) {
			if (h[i].x < h[start].x
					|| (h[i].x == h[start].x && h[i].y < h[start].y)) {
				start = i;
			}
		}

		out.println(h.length);
		for (int i = start; i < h.length; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		for (int i = 0; i < start; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		return true;
	}

	String asPoint(long q) {
		return "(" + (q >> SHIFT) + ", " + (q & ((1 << SHIFT) - 1)) + ")";
	}

	static class Point implements Comparable<Point> {
		static final Point ZERO = new Point(0, 0);
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (y != o.y)
				return y < o.y ? -1 : 1;
			if (x != o.x)
				return x < o.x ? -1 : 1;
			return 0;
		}

		long vectMul(Point p) {
			return (long) x * p.y - (long) y * p.x;
		}

		@Override
		public String toString() {
			return "(" + x + ", " + y + ")";
		}

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}
	}

	static int getTurn(Point A, Point B, Point C) {
		// angle between AB and AC
		long p1 = (long) (B.x - A.x) * (C.y - A.y);
		long p2 = (long) (B.y - A.y) * (C.x - A.x);
		if (p1 == p2)
			return 0;
		else
			return p1 < p2 ? -1 : 1;
	}

	/**
	 * PERMUTES POINTS IN ARRAY, consider using convexHull(a.clone()) Points
	 * themselves are modified inside method too, but changes are reverted at
	 * the end
	 *
	 * @param a
	 *            - array of points
	 * @return convexHull of these point in CCW order, no duplicates, no three
	 *         points on one side
	 */
	static Point[] convexHull(Point[] a) {

		if (a == null)
			return null;
		if (a.length == 0)
			return new Point[] {};

		int st = 0;
		for (int i = 1; i < a.length; i++)
			if (a[i].compareTo(a[st]) < 0)
				st = i;

		Point tmp = a[0];
		a[0] = a[st];
		a[st] = tmp;

		int sx = a[0].x;
		int sy = a[0].y;

		for (int i = 0; i < a.length; i++) {
			a[i].x -= sx;
			a[i].y -= sy;
		}

		Arrays.sort(a, 1, a.length, new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.equals(o2))
					return 0;
				if (o1.equals(Point.ZERO)) {
					return -1;
				}
				if (o2.equals(Point.ZERO)) {
					return 1;
				}
				long val = o1.vectMul(o2);
				if (val != 0)
					return val > 0 ? -1 : 1;
				if (o1.y == 0) {
					return o1.x < o2.x ? -1 : 1;
				} else {
					return o1.y < o2.y ? -1 : 1;
				}
			}
		});

		Point[] h = new Point[a.length];
		int sz = 0;
		h[sz++] = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i].equals(h[sz - 1]))
				continue;
			while (sz > 1 && getTurn(h[sz - 2], h[sz - 1], a[i]) <= 0)
				sz--;
			h[sz++] = a[i];
		}

		for (int i = 0; i < a.length; i++) {
			a[i].x += sx;
			a[i].y += sy;
		}

		return Arrays.copyOf(h, sz);
	}

	cf690B3() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		while (solve())
			;
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

public class cf690B3 {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int SHIFT = 17;

	HashSet<Long> set;

	boolean good(long v) {
		if (set.contains(v)) {
			return false;
		}
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (set.contains(u)) {
					return true;
				}
			}
		return false;
	}

	void dfs(long v, HashSet<Long> cur) {
		cur.add(v);
		for (int dx = -1; dx <= 1; dx++)
			for (int dy = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) {
					continue;
				}
				long u = v + (dx << SHIFT) + dy;
				if (!cur.contains(u) && good(u)) {
					dfs(u, cur);
				}
			}
	}

	boolean solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		if (n == 0 && m == 0) {
			return false;
		}

		long[] ps = new long[m];

		set = new HashSet<>();

		int[] xs = new int[m];
		int[] ys = new int[m];

		for (int i = 0; i < m; i++) {
			xs[i] = nextInt();
			ys[i] = nextInt();
			ps[i] = ((1L * xs[i]) << SHIFT) | ys[i];
			set.add(ps[i]);
		}

		HashSet<Long> set1 = null, set2 = null;

		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 1; dx++)
				for (int dy = -1; dy <= 1; dy++) {
					if (dx == 0 && dy == 0) {
						continue;
					}
					long tmp = ps[i] + (dx << SHIFT) + dy;
					if (set.contains(tmp)) {
						continue;
					}
					if (set1 == null) {
						set1 = new HashSet<>();
						dfs(tmp, set1);

						// System.err.println("set1");
						// for (long q : set1) {
						// System.err.println(asPoint(q));
						// }
					} else if (set1.contains(tmp)) {
						continue;
					} else if (set2 == null) {
						set2 = new HashSet<>();
						dfs(tmp, set2);

						// System.err.println("set2");
						// for (long q : set2) {
						// System.err.println(asPoint(q));
						// }
					} else if (!set2.contains(tmp)) {
						// throw new AssertionError("too many regions");
						while (true)
							;
					}
				}
		}

		if (set2 != null && set1.size() < set2.size()) {
			HashSet<Long> tmp = set1;
			set1 = set2;
			set2 = tmp;
		}

		List<Point> a = new ArrayList<>();
		HashSet<Long> setA = new HashSet<>();
		for (int i = 0; i < m; i++) {
			for (int dx = -1; dx <= 0; dx++)
				for (int dy = -1; dy <= 0; dy++) {
					int x = xs[i] + dx;
					int y = ys[i] + dy;
					long hash = ((1L * x) << SHIFT) | y;
					if (setA.contains(hash)) {
						continue;
					}

					setA.add(hash);

					boolean ok = true;
					outer: for (int xx = 0; xx <= 1; xx++)
						for (int yy = 0; yy <= 1; yy++) {
							long hash1 = hash + (xx << SHIFT) + yy;
							if (set1.contains(hash1)) {
								ok = false;
								break outer;
							}
						}

					if (ok) {
						a.add(new Point(x, y));
					}
				}
		}

		Point[] arr = a.toArray(new Point[a.size()]);
		Point[] h = convexHull(arr);

		for (int i = 0, j = h.length - 1; i < j; i++, j--) {
			Point tmp = h[i];
			h[i] = h[j];
			h[j] = tmp;
		}

		int start = 0;
		for (int i = 1; i < h.length; i++) {
			if (h[i].x < h[start].x
					|| (h[i].x == h[start].x && h[i].y < h[start].y)) {
				start = i;
			}
		}

		out.println(h.length);
		for (int i = start; i < h.length; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		for (int i = 0; i < start; i++) {
			Point p = h[i];
			out.println(p.x + " " + p.y);
		}

		return true;
	}

	String asPoint(long q) {
		return "(" + (q >> SHIFT) + ", " + (q & ((1 << SHIFT) - 1)) + ")";
	}

	static class Point implements Comparable<Point> {
		static final Point ZERO = new Point(0, 0);
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (y != o.y)
				return y < o.y ? -1 : 1;
			if (x != o.x)
				return x < o.x ? -1 : 1;
			return 0;
		}

		long vectMul(Point p) {
			return (long) x * p.y - (long) y * p.x;
		}

		@Override
		public String toString() {
			return "(" + x + ", " + y + ")";
		}

		public boolean equals(Point p) {
			return x == p.x && y == p.y;
		}
	}

	static int getTurn(Point A, Point B, Point C) {
		// angle between AB and AC
		long p1 = (long) (B.x - A.x) * (C.y - A.y);
		long p2 = (long) (B.y - A.y) * (C.x - A.x);
		if (p1 == p2)
			return 0;
		else
			return p1 < p2 ? -1 : 1;
	}

	/**
	 * PERMUTES POINTS IN ARRAY, consider using convexHull(a.clone()) Points
	 * themselves are modified inside method too, but changes are reverted at
	 * the end
	 *
	 * @param a
	 *            - array of points
	 * @return convexHull of these point in CCW order, no duplicates, no three
	 *         points on one side
	 */
	static Point[] convexHull(Point[] a) {

		if (a == null)
			return null;
		if (a.length == 0)
			return new Point[] {};

		int st = 0;
		for (int i = 1; i < a.length; i++)
			if (a[i].compareTo(a[st]) < 0)
				st = i;

		Point tmp = a[0];
		a[0] = a[st];
		a[st] = tmp;

		int sx = a[0].x;
		int sy = a[0].y;

		for (int i = 0; i < a.length; i++) {
			a[i].x -= sx;
			a[i].y -= sy;
		}

		Arrays.sort(a, 1, a.length, new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.equals(o2))
					return 0;
				if (o1.equals(Point.ZERO)) {
					return -1;
				}
				if (o2.equals(Point.ZERO)) {
					return 1;
				}
				long val = o1.vectMul(o2);
				if (val != 0)
					return val > 0 ? -1 : 1;
				if (o1.y == 0) {
					return o1.x < o2.x ? -1 : 1;
				} else {
					return o1.y < o2.y ? -1 : 1;
				}
			}
		});

		Point[] h = new Point[a.length];
		int sz = 0;
		h[sz++] = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i].equals(h[sz - 1]))
				continue;
			while (sz > 1 && getTurn(h[sz - 2], h[sz - 1], a[i]) <= 0)
				sz--;
			h[sz++] = a[i];
		}

		for (int i = 0; i < a.length; i++) {
			a[i].x += sx;
			a[i].y += sy;
		}

		return Arrays.copyOf(h, sz);
	}

	cf690B3() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		while (solve())
			;
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.TreeSet;

public final class CF_114_E{
	static boolean verb=true;
	static void log(Object X){if (verb) System.err.println(X);}
	static void log(Object[] X){if (verb) {for (Object U:X) System.err.print(U+" ");System.err.println("");}}
	static void log(int[] X){if (verb) {for (int U:X) System.err.print(U+" ");System.err.println("");}}
	static void logWln(Object X){if (verb) System.err.print(X);}
	static void info(Object o){	System.out.println(o);}
	static void output(Object o){outputWln(""+o+"\n");	}
	static void outputWln(Object o){try {out.write(""+ o);} catch (Exception e) {}}

	static int MX=Integer.MAX_VALUE;

	static boolean solve(long a,long b){
		//log("a:"+a+" b:"+b);
		if (a==0 || b==0)
			return false;
		if (a==b)
			return true;
		if (a>b){
			long c=a;
			a=b;
			b=c;
		}

		long ob=b;
		if (a+1<b/a)
			ob=b%(a*(a+1));
		if (ob!=b && ob>0)
			return solve(a,ob);

		if (b%a==0)
			return true;
		long aa=1;
		loop:while (aa<=b/a){
			aa*=a;

			if (!solve(b-aa,a))
				return true;
		}
		return false;

	}

	static void check(){
		log("checking");
		for (int x=1;x<100;x++)
			for (int y=3;y<x;y++){
				boolean b=solve(x,y);
				int xx=x%(y*(y+1));
				if (xx!=0){
				boolean c=solve(x%(y*(y+1)),y);
				if (b!=c){
					log("Error "+x+" "+y);
					log(b);
					log(c);
					log(x+" "+y);
					log(x%(y*(y+1))+" "+y);
					return;
				}
				}
			}
		log("done");
	}

	static void test(){
		int y=10;
		for (int x=1;x<200;x++) {
			boolean b=solve(x,y);
			if (!b)
				log(x+" "+y);

		}
		//for (int x=1;x<20;x++)
		//	for (int y=1;y<x;y++)
		//		log(x+" "+y+" >> "+solve(x,y));
	}

	// Global vars
	static BufferedWriter out;
	static InputReader reader;

	static int MAX=201;

	static void process() throws Exception {

		//check();
		//test();

		out = new BufferedWriter(new OutputStreamWriter(System.out));
		reader=new InputReader(System.in);

		int T=reader.readInt();
		for (int t=0;t<T;t++){
		long a=reader.readLong();
		long b=reader.readLong();
		boolean w=solve(a,b);
		String res="Second";
		if (w)
			res="First";
		output(res);
		}

		try {
			out.close();
		}
		catch (Exception e){}

	}

	public static void main(String[] args) throws Exception {
		process();

	}

	static final class InputReader {
		private final InputStream stream;
		private final byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

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

		private int read() throws IOException {
			if (curChar >= numChars) {
				curChar = 0;
				numChars = stream.read(buf);
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public final String readString() throws IOException {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res=new StringBuilder();
			do {
				res.append((char)c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public final int readInt() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			int res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

		public final long readLong() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			long res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

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

}


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.TreeSet;

public final class CF_114_E{
	static boolean verb=true;
	static void log(Object X){if (verb) System.err.println(X);}
	static void log(Object[] X){if (verb) {for (Object U:X) System.err.print(U+" ");System.err.println("");}}
	static void log(int[] X){if (verb) {for (int U:X) System.err.print(U+" ");System.err.println("");}}
	static void logWln(Object X){if (verb) System.err.print(X);}
	static void info(Object o){	System.out.println(o);}
	static void output(Object o){outputWln(""+o+"\n");	}
	static void outputWln(Object o){try {out.write(""+ o);} catch (Exception e) {}}

	static int MX=Integer.MAX_VALUE;

	static boolean solve(long a,long b){
		//log("a:"+a+" b:"+b);
		if (a==0 || b==0)
			return false;
		if (a==b)
			return true;
		if (a>b){
			long c=a;
			a=b;
			b=c;
		}

		long ob=b;
		if (a+1<b/a)
			ob=b%(a*(a+1));
		if (ob!=b) {
			if (ob>0)
			return solve(a,ob);
			ob=a*(a+1);
			return solve(a,ob);
		}
		if (b%a==0)
			return true;
		long aa=1;
		loop:while (aa<=b/a){
			aa*=a;

			if (!solve(b-aa,a))
				return true;
		}
		return false;

	}

	static void check(){
		log("checking");
		for (int x=1;x<100;x++)
			for (int y=3;y<x;y++){
				boolean b=solve(x,y);
				int xx=x%(y*(y+1));
				if (xx!=0){
				boolean c=solve(x%(y*(y+1)),y);
				if (b!=c){
					log("Error "+x+" "+y);
					log(b);
					log(c);
					log(x+" "+y);
					log(x%(y*(y+1))+" "+y);
					return;
				}
				}
			}
		log("done");
	}

	static void test(){
		int y=10;
		for (int x=1;x<200;x++) {
			boolean b=solve(x,y);
			if (!b)
				log(x+" "+y);

		}
		//for (int x=1;x<20;x++)
		//	for (int y=1;y<x;y++)
		//		log(x+" "+y+" >> "+solve(x,y));
	}

	// Global vars
	static BufferedWriter out;
	static InputReader reader;

	static int MAX=201;

	static void process() throws Exception {

		//check();
		//test();

		out = new BufferedWriter(new OutputStreamWriter(System.out));
		reader=new InputReader(System.in);

		int T=reader.readInt();
		for (int t=0;t<T;t++){
		long a=reader.readLong();
		long b=reader.readLong();
		boolean w=solve(a,b);
		String res="Second";
		if (w)
			res="First";
		output(res);
		}

		try {
			out.close();
		}
		catch (Exception e){}

	}

	public static void main(String[] args) throws Exception {
		process();

	}

	static final class InputReader {
		private final InputStream stream;
		private final byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

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

		private int read() throws IOException {
			if (curChar >= numChars) {
				curChar = 0;
				numChars = stream.read(buf);
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public final String readString() throws IOException {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res=new StringBuilder();
			do {
				res.append((char)c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public final int readInt() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			int res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

		public final long readLong() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			long res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

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

}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;

public class popo {

    public static boolean prime[];
    public static ArrayList[] ad=new ArrayList[2555];
    public static ArrayList<Long> xor1,xor2;
    static int []min;
    static char [][]grid;
    static int []dx = {0,0,-1,1};
    static int []dy = {-1,1,0,0};
    static int []dx8 = {1,1,1,0,-1,-1,-1,0};
    static int []dy8 = {1,0,-1,-1,-1,0,1,1};
    static ArrayList<Point> aa;

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int t = in.nextInt();
        while (t-->0)
          {
              int a = in.nextInt();
              int b = in.nextInt();
              boolean k =winner(a,b);
              if(k)
                  out.println("First");
              else
                  out.println("Second");

        }

        out.close();
    }
    static boolean winner(int a  ,int b)
    {
        if(a==0 || b==0)
            return false;
        if(a>b)
        {
            int t = a;
            a = b;
            b = t;
        }
        if(!winner(a,b%a))return true;
        int  l =0;
        if(a!=0) {
             l = b / a;
        }
        a = a+1;
        return ((l)%2 == 0);
    }

    public static long modPow(long base, long exp, long mod) {
        base = base % mod;
        long result = 1;
        while(exp > 0)
        {
            if(exp % 2== 1)
            {
                result = (result * base) % mod;
                exp --;
            }
            else
            {
                base = (base * base) % mod;
                exp = exp >> 1;
            }

        }
        return result;
    }

    public static long mod = 1000000007, inf = 100000000000000000l;
    public static long fac[],inv[];
    public static void cal()
    {
        fac = new long[100001];
        inv = new long[100001];
        fac[0]=1;
        inv[0]=1;
        for(int i=1; i<=100000; i++)
        {
            fac[i]=(fac[i-1]*i)%mod;
            //  inv[i]=(inv[i-1]*modPow(i,mod-2,mod))%mod;

        }
    }
    public static long combination(long n, long r)
    {
        long k = (fac[(int) n]%mod*inv[(int) r]%mod)%mod;
        long p = inv[(int) (n-r)]%mod;
        long m = (k*p)%mod;
        return m;
    }

    public static class Point implements Comparable<Point> {

        long x, y;

        public Point(long start, long end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = (int) (47 * hash + this.x);
            hash = (int) (47 * hash + this.y);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return Long.compare(x, o.x);
        }
    }
    static long setbits(long i)
    {
        long count = 0;
        while (i>0)
        {
            count += i & 1;
            i >>= 1;
        }
        return count;

    }

    static ArrayList<Long> sieveOfEratosthenes(int n)
    {
        // Create a boolean array "prime[0..n]" and initialize
        // all entries it as true. A value in prime[i] will
        // finally be false if i is Not a prime, else true.

        prime=new boolean[1000001];
        for(int i=0;i<n;i++)
            prime[i] = true;

        for(long p = 2; p*p <=n; p++)
        {
            // If prime[p] is not changed, then it is a prime
            if(prime[(int)p] == true)
            {
                // Update all multiples of p
                for(long i = p*2; i <= n; i += p) {
                    prime[(int) i] = false;
                }
            }
        }
        ArrayList<Long> aa=new ArrayList<>();
        for (long i=0;i<n;i++)
        {
            if(prime[(int)i])
                aa.add(i);
        }
        return aa;

        // Print all prime numbers
      /*  for(int i = 2; i <= n; i++)
        {
            if(prime[i] == true)
                System.out.print(i + " ");
        }
       */
    }

    static class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private InputReader.SpaceCharFilter filter;

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

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

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

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

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

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

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

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


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.TreeSet;

public final class CF_114_E{
	static boolean verb=true;
	static void log(Object X){if (verb) System.err.println(X);}
	static void log(Object[] X){if (verb) {for (Object U:X) System.err.print(U+" ");System.err.println("");}}
	static void log(int[] X){if (verb) {for (int U:X) System.err.print(U+" ");System.err.println("");}}
	static void logWln(Object X){if (verb) System.err.print(X);}
	static void info(Object o){	System.out.println(o);}
	static void output(Object o){outputWln(""+o+"\n");	}
	static void outputWln(Object o){try {out.write(""+ o);} catch (Exception e) {}}

	static int MX=Integer.MAX_VALUE;

	static boolean solve(long a,long b){
		//log("a:"+a+" b:"+b);
		if (a==0 || b==0)
			return false;
		if (a==b)
			return true;
		if (a>b){
			long c=a;
			a=b;
			b=c;
		}
		if (b%a==0)
			return true;
		long aa=1;
		loop:while (aa<=b/a){
			aa*=a;
			if (!solve(b-aa,a))
				return true;
		}
		return false;

	}

	// Global vars
	static BufferedWriter out;
	static InputReader reader;

	static int MAX=201;

	static void process() throws Exception {

		out = new BufferedWriter(new OutputStreamWriter(System.out));
		reader=new InputReader(System.in);

		int T=reader.readInt();
		for (int t=0;t<T;t++){
		long a=reader.readLong();
		long b=reader.readLong();
		boolean w=solve(a,b);
		String res="Second";
		if (w)
			res="First";
		output(res);
		}

		try {
			out.close();
		}
		catch (Exception e){}

	}

	public static void main(String[] args) throws Exception {
		process();

	}

	static final class InputReader {
		private final InputStream stream;
		private final byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

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

		private int read() throws IOException {
			if (curChar >= numChars) {
				curChar = 0;
				numChars = stream.read(buf);
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public final String readString() throws IOException {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res=new StringBuilder();
			do {
				res.append((char)c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public final int readInt() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			int res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

		public final long readLong() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			long res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

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

}


package McNuggets;

import java.util.Scanner;

public class zombiesAndBrainsA1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner console = new Scanner(System.in);
		int n = console.nextInt();
		System.out.println(n/2+n%2);

	}

}


package com.quantis_intl.stack;

import java.util.Scanner;

public class Main
{
    public static final void main(String[] args)
    {
        Scanner s = new Scanner(System.in);
        int val = s.nextInt();
        System.out.println((val / 2) + (val % 2));
        s.close();
    }

}


public class c{
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        System.out.println(Math.ceil(in.nextDouble()/2));
    }
}


/*
 * Solution_690_A1.java
 * Copyright (C) 2017 tri <tri@tri-K42F>
 *
 * Distributed under terms of the MIT license.
 */
import java.util.*;
import java.io.*;
public class Solution_690_A1
{
	private static String INPUT_FILE="690_A1.txt";
	public Solution_690_A1() {
	}
	public static void main(String[] args){
		try(
			//Scanner sc = new Scanner(new FileInputStream(INPUT_FILE));
			Scanner sc = new Scanner(System.in);
		   )
		{
			Integer totalNum = sc.nextInt();
			totalNum = (totalNum/2)+(totalNum%2);
			System.out.print(totalNum);
		}
		catch(IOException e){
			System.out.println(e);
		}

		return;
	}
}