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

/**
 * @author Don Li
 */
public class FindACar2 {

    int N = 31;
    int MOD = (int) 1e9 + 7;

    void solve() {
        int q = in.nextInt();
        while (q-- > 0) {
            int x1 = in.nextInt() - 1, y1 = in.nextInt() - 1, x2 = in.nextInt() - 1, y2 = in.nextInt() - 1, k = in.nextInt() - 1;

            long ans = 0;
            ans = add(ans, calc(x2, y2, k));
            ans = sub(ans, calc(x1 - 1, y2, k));
            ans = sub(ans, calc(x2, y1 - 1, k));
            ans = add(ans, calc(x1 - 1, y1 - 1, k));

            out.println(ans);
        }
    }

    int calc(int x, int y, int k) {
        if (x < 0 || y < 0) return 0;

        int[][][][] cnt = new int[N + 1][2][2][2];
        int[][][][] sum = new int[N + 1][2][2][2];

        int[] a = new int[N], b = new int[N], c = new int[N];
        for (int i = 0; i < N; i++) {
            a[i] = (x >> i) & 1;
            b[i] = (y >> i) & 1;
            c[i] = (k >> i) & 1;
        }
        reverse(a);
        reverse(b);
        reverse(c);

        cnt[0][1][1][1] = 1;
        for (int i = 0; i < N; i++) {
            for (int p = 0; p < 2; p++) for (int q = 0; q < 2; q++) for (int r = 0; r < 2; r++) {
                for (int u = 0; u < 2; u++) for (int v = 0; v < 2; v++) {
                    int w = u ^ v;
                    if (p == 1 && u == 1 && a[i] == 0) continue;
                    if (q == 1 && v == 1 && b[i] == 0) continue;
                    if (r == 1 && w == 1 && c[i] == 0) continue;
                    int np = p == 1 && a[i] == u ? 1 : 0;
                    int nq = q == 1 && b[i] == v ? 1 : 0;
                    int nr = r == 1 && c[i] == w ? 1 : 0;
                    cnt[i + 1][np][nq][nr] = add(cnt[i + 1][np][nq][nr], cnt[i][p][q][r]);
                    sum[i + 1][np][nq][nr] = add(sum[i + 1][np][nq][nr], sum[i][p][q][r]);
                    sum[i + 1][np][nq][nr] = add(sum[i + 1][np][nq][nr], mul(w << (30 - i), cnt[i][p][q][r]));
                }
            }
        }

        long res = 0;
        for (int p = 0; p < 2; p++) for (int q = 0; q < 2; q++) for (int r = 0; r < 2; r++) {
            res = add(res, sum[N][p][q][r]);
            res = add(res, cnt[N][p][q][r]);
        }
        return (int) res;
    }

    void reverse(int[] a) {
        int l = 0, r = a.length - 1;
        while (l < r) {
            int tmp = a[l];
            a[l] = a[r];
            a[r] = tmp;
            l++;
            r--;
        }
    }

    int add(long a, long b) {
        return (int) ((a + b) % MOD);
    }

    int sub(long a, long b) {
        return (int) ((a - b + MOD) % MOD);
    }

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

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new FindACar2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

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


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {

	private static final String NO = "NO";
	private static final String YES = "YES";
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long MOD = 1000000007;

	void solve() {
		int T = 1;
		for (int i = 0; i < T; i++)
			solve(i);
	}

	long p[];

	void solve(int T) {
		int n = ni();
		p = new long[64];
		p[0] = 1;
		for (int i = 1; i < 60; i++)
			p[i] = p[i - 1] * 2;

		for (int i = 0; i < n; i++) {
			int a[] = na(5);
			long ans = work(a[2], a[3], a[4], 0) - work(a[0] - 1, a[3], a[4], 0) - work(a[2], a[1] - 1, a[4], 0)
					+ work(a[0] - 1, a[1] - 1, a[4], 0);
			ans %= MOD;
			out.println((ans + MOD) % MOD);
		}
	}

	long work(long x, long y, long k, long lazy) {
		if (x <= 0 || y <= 0)
			return 0;
		if (k <= 0)
			return 0;
		if (x > y) {
			long tmp = x;
			x = y;
			y = tmp;
		}
		int t = 0;
		while (p[t] <= y)
			t++;

		long ans;
		if (y == p[t - 1]) {
			long tmpa, tmpb;
			if (p[t - 1] < k)// all numbers is within [1..k], count them all
			{
				tmpa = p[t - 1];
				tmpa = tmpa * (tmpa + 1) / 2;
				tmpa %= MOD;
				tmpa *= x;
				tmpa %= MOD;
				tmpb = (lazy * y) % MOD;
				tmpb *= x;
				tmpb %= MOD;
				ans = (tmpa + tmpb) % MOD;
			} else// p[t-1]>=k only less or equal to k is needed
			{
				tmpa = k;
				tmpa = tmpa * (tmpa + 1) / 2;
				tmpa %= MOD;
				tmpa *= x;
				tmpa %= MOD;
				tmpb = (lazy * k) % MOD;
				tmpb *= x;
				tmpb %= MOD;
				ans = (tmpa + tmpb) % MOD;
			}
		} else// y > p[t-1]
		{
			if (x < p[t - 1]) {
				ans = work(x, p[t - 1], k, lazy);
				ans = (ans + work(x, y - p[t - 1], k - p[t - 1], lazy + p[t - 1])) % MOD;
			} else {
				ans = work(p[t - 1], p[t - 1], k, lazy);
				ans = (ans + work(x - p[t - 1], p[t - 1], k - p[t - 1], lazy + p[t - 1])) % MOD;
				ans = (ans + work(p[t - 1], y - p[t - 1], k - p[t - 1], lazy + p[t - 1])) % MOD;
				ans = (ans + work(x - p[t - 1], y - p[t - 1], k, lazy)) % MOD;
			}
		}
//		tr(x, y, k, lazy, ans);

		return ans;
	}

	// a^b
	long power(long a, long b) {
		long x = 1, y = a;
		while (b > 0) {
			if (b % 2 != 0) {
				x = (x * y) % MOD;
			}
			y = (y * y) % MOD;
			b /= 2;
		}
		return x % MOD;
	}

	private long gcd(long a, long b) {
		while (a != 0) {
			long tmp = b % a;
			b = a;
			a = tmp;
		}
		return b;
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	private boolean vis[];

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private List<Integer> na2(int n) {
		List<Integer> a = new ArrayList<Integer>();
		for (int i = 0; i < n; i++)
			a.add(ni());
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long[] nl(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private long[][] nl(int n, int m) {
		long[][] a = new long[n][];
		for (int i = 0; i < n; i++)
			a[i] = nl(m);
		return a;
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	public class Pair<K, V> {

		/**
		 * Key of this Pair.
		 */
		private K key;

		/**
		 * Gets the key for this pair.
		 *
		 * @return key for this pair
		 */
		public K getKey() {
			return key;
		}

		/**
		 * Value of this this Pair.
		 */
		private V value;

		/**
		 * Gets the value for this pair.
		 *
		 * @return value for this pair
		 */
		public V getValue() {
			return value;
		}

		/**
		 * Creates a new pair
		 *
		 * @param key   The key for this pair
		 * @param value The value to use for this pair
		 */
		public Pair(K key, V value) {
			this.key = key;
			this.value = value;
		}

		/**
		 *

		 * String representation of this Pair.
		 *

		 *
		 *

		 * The default name/value delimiter '=' is always used.
		 *

		 *
		 * @return String representation of this Pair
		 */
		@Override
		public String toString() {
			return key + "=" + value;
		}

		/**
		 *

		 * Generate a hash code for this Pair.
		 *

		 *
		 *

		 * The hash code is calculated using both the name and the value of the
		 * Pair.
		 *

		 *
		 * @return hash code for this Pair
		 */
		@Override
		public int hashCode() {
			// name's hashCode is multiplied by an arbitrary prime number (13)
			// in order to make sure there is a difference in the hashCode between
			// these two parameters:
			// name: a value: aa
			// name: aa value: a
			return key.hashCode() * 13 + (value == null ? 0 : value.hashCode());
		}

		/**
		 *

		 * Test this Pair for equality with another Object.
		 *

		 *
		 *

		 * If the Object to be tested is not a Pair or is
		 * null, then this method returns false.
		 *

		 *
		 *

		 * Two Pairs are considered equal if and only if both the names and
		 * values are equal.
		 *

		 *
		 * @param o the Object to test for equality with this
		 *          Pair
		 * @return true if the given Object is equal to this
		 *         Pair else false
		 */
		@Override
		public boolean equals(Object o) {
			if (this == o)
				return true;
			if (o instanceof Pair) {
				Pair pair = (Pair) o;
				if (key != null ? !key.equals(pair.key) : pair.key != null)
					return false;
				if (value != null ? !value.equals(pair.value) : pair.value != null)
					return false;
				return true;
			}
			return false;
		}
	}

}


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

public class Codeforces810E {
	public static int[] global = new int[100];

	public static void main(String[] args) throws IOException {
		global[0] = 1;
		for (int i = 1; i < 100; i++) {
			global[i] = (2*global[i-1])%1000000007;
		}
		int[] twopower = new int[100];
		twopower[0] = 1;
		for (int i = 1; i < 100; i++) {
			twopower[i] = (twopower[i-1]*2)%1000000007;
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		String[] sp = br.readLine().split(" ");
		int q = Integer.parseInt(sp[0]);
		for (int i = 0; i < q; i++) {
			sp = br.readLine().split(" ");
			int x1 = Integer.parseInt(sp[0]);
			int y1 = Integer.parseInt(sp[1]);
			int x2 = Integer.parseInt(sp[2]);
			int y2 = Integer.parseInt(sp[3]);
			int k = Integer.parseInt(sp[4]);
			int answer = 0;
			if ((x1 == 1) && (y1 == 1)) {
				answer = answer(x2, y2, k);
			}
			else if (x1 == 1) {
				answer = answer(x2, y2, k)-answer(x2, y1-1, k);
			}
			else if (y1 == 1) {
				answer = answer(x2, y2, k) - answer(x1-1, y2, k);
			}
			else {
				answer = answer(x2, y2, k) - answer(x1-1, y2, k) - answer(x2, y1-1, k) + answer(x1-1, y1-1, k);
			}
			answer %= 1000000007;
			if (answer < 0)
				answer += 1000000007;
			pw.println(answer);
		}
		pw.close();
	}

	public static int answer(int m, int n, int k) {
		int tmp = m;
		int counter = 0;
		int counter2 = 0;
		while (tmp > 0) {
			if (tmp%2 == 1)
				counter++;
			counter2++;
			tmp = tmp/2;
		}
		int[][] mlist = new int[counter][2];
		counter--;
		for (int i = counter2-1; i >= 0; i--) {
			if ((m >> i)%2 == 1) {
				mlist[counter][0] = (m >> i)-1;
				mlist[counter][1] = i;
				counter--;
			}
		}

		tmp = n;
		counter = 0;
		counter2 = 0;
		while (tmp > 0) {
			if (tmp%2 == 1)
				counter++;
			counter2++;
			tmp = tmp/2;
		}
		int[][] nlist = new int[counter][2];
		counter--;
		for (int i = counter2-1; i >= 0; i--) {
			if ((n >> i)%2 == 1) {
				nlist[counter][0] = (n >> i)-1;
				nlist[counter][1] = i;
				counter--;
			}
		}

		int answer = 0;

		for (int i = 0; i < mlist.length; i++) {
			for (int j = 0; j < nlist.length; j++) {
				answer = (answer + sum(mlist[i][1], nlist[j][1], mlist[i][0], nlist[j][0], k))%1000000007;
			}
		}

		return answer;
	}

	public static int sum(int m, int n, int r, int s, int k) {
		if (m < n) {
			int temp = m;
			m = n;
			n = temp;
			temp = r;
			r = s;
			s = temp;
		}
		int t = s >> (m-n);
		int u = r^t;
		long val = 0;
		if (k > u*global[m]) {
			int min = u*global[m];
			int max = Math.min(k, (u+1)*global[m]);
			val = (((long) max)*((long) max+1))/2 - (((long) min)*((long)min+1))/2;
		}
		val %= 1000000007;
		val *= global[n];
		val %= 1000000007;
		return (int) val;
	}

}


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

/**
 * @author Don Li
 */
public class FindACar {

    int N = 30;
    int MOD = (int) 1e9 + 7;

    int a, b, c;

    int[][][][] dp = new int[N + 1][2][2][2];
    int[][][][] cnt = new int[N + 1][2][2][2];

    void solve() {
        int q = in.nextInt();
        while (q-- > 0) {
            int x1 = in.nextInt() - 1, y1 = in.nextInt() - 1, x2 = in.nextInt() - 1, y2 = in.nextInt() - 1, k = in.nextInt() - 1;

            long ans = 0;
            ans = (ans + calc(x2, y2, k)) % MOD;
            ans = (ans - calc(x1 - 1, y2, k) + MOD) % MOD;
            ans = (ans - calc(x2, y1 - 1, k) + MOD) % MOD;
            ans = (ans + calc(x1 - 1, y1 - 1, k)) % MOD;

            out.println(ans);
        }
    }

    int calc(int x, int y, int k) {
        if (x < 0 || y < 0) return 0;

        for (int i = 0; i <= N; i++)
            for (int j = 0; j < 2; j++)
                for (int u = 0; u < 2; u++)
                    for (int v = 0; v < 2; v++)
                        dp[i][j][u][v] = cnt[i][j][u][v] = -1;

        a = x;
        b = y;
        c = k;
        return dfs1(N, 1, 1, 1);
    }

    int dfs1(int i, int ea, int eb, int ec) {
        if (i < 0) return 1;
        if (dp[i][ea][eb][ec] >= 0) return dp[i][ea][eb][ec];

        int bit_a = (a >> i) & 1;
        int bit_b = (b >> i) & 1;
        int bit_c = (c >> i) & 1;

        long res = 0;

        int nec = ec == 1 && bit_c == 0 ? 1 : 0;
        int nea = ea == 1 && bit_a == 0 ? 1 : 0;
        int neb = eb == 1 && bit_b == 0 ? 1 : 0;
        res = (res + dfs1(i - 1, nea, neb, nec)) % MOD;

        if ((eb == 0 || bit_b == 1) && (ec == 0 || bit_c == 1)) {
            nec = ec == 1 && bit_c == 1 ? 1 : 0;
            nea = ea == 1 && bit_a == 0 ? 1 : 0;
            neb = eb == 1 && bit_b == 1 ? 1 : 0;
            res = (res + (1L << i) * dfs2(i - 1, nea, neb, nec) % MOD + dfs1(i - 1, nea, neb, nec)) % MOD;
        }

        if ((ea == 0 || bit_a == 1) && (ec == 0 || bit_c == 1)) {
            nec = ec == 1 && bit_c == 1 ? 1 : 0;
            nea = ea == 1 && bit_a == 1 ? 1 : 0;
            neb = eb == 1 && bit_b == 0 ? 1 : 0;
            res = (res + (1L << i) * dfs2(i - 1, nea, neb, nec) % MOD + dfs1(i - 1, nea, neb, nec)) % MOD;
        }

        if ((ea == 0 || bit_a == 1) && (eb == 0 || bit_b == 1)) {
            nec = ec == 1 && bit_c == 0 ? 1 : 0;
            nea = ea == 1 && bit_a == 1 ? 1 : 0;
            neb = eb == 1 && bit_b == 1 ? 1 : 0;
            res = (res + dfs1(i - 1, nea, neb, nec)) % MOD;
        }

        return dp[i][ea][eb][ec] = (int) res;
    }

    int dfs2(int i, int ea, int eb, int ec) {
        if (i < 0) return 1;
        if (cnt[i][ea][eb][ec] >= 0) return cnt[i][ea][eb][ec];

        int bit_a = (a >> i) & 1;
        int bit_b = (b >> i) & 1;
        int bit_c = (c >> i) & 1;

        long res = 0;

        int nec = ec == 1 && bit_c == 0 ? 1 : 0;
        int nea = ea == 1 && bit_a == 0 ? 1 : 0;
        int neb = eb == 1 && bit_b == 0 ? 1 : 0;
        res = (res + dfs2(i - 1, nea, neb, nec)) % MOD;

        if ((eb == 0 || bit_b == 1) && (ec == 0 || bit_c == 1)) {
            nec = ec == 1 && bit_c == 1 ? 1 : 0;
            nea = ea == 1 && bit_a == 0 ? 1 : 0;
            neb = eb == 1 && bit_b == 1 ? 1 : 0;
            res = (res + dfs2(i - 1, nea, neb, nec)) % MOD;
        }

        if ((ea == 0 || bit_a == 1) && (ec == 0 || bit_c == 1)) {
            nec = ec == 1 && bit_c == 1 ? 1 : 0;
            nea = ea == 1 && bit_a == 1 ? 1 : 0;
            neb = eb == 1 && bit_b == 0 ? 1 : 0;
            res = (res + dfs2(i - 1, nea, neb, nec)) % MOD;
        }

        if ((ea == 0 || bit_a == 1) && (eb == 0 || bit_b == 1)) {
            nec = ec == 1 && bit_c == 0 ? 1 : 0;
            nea = ea == 1 && bit_a == 1 ? 1 : 0;
            neb = eb == 1 && bit_b == 1 ? 1 : 0;
            res = (res + dfs2(i - 1, nea, neb, nec)) % MOD;
        }

        return cnt[i][ea][eb][ec] = (int) res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new FindACar().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

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


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

import static java.lang.Math.*;

public class Main {
    ArrayList<Integer> g[];
    HashSet<Integer> from[];
    Queue<Integer> q = new ArrayDeque<>();
    boolean used[];
    int[] dist;

    void bfs() {
        while (!q.isEmpty()) {
            int v = q.poll();
            for (Integer to : g[v]) {
                if (!used[to]) {
                    used[to] = true;
                    dist[to] = dist[v] + 1;
                    q.add(to);
                }
                if (dist[to] == dist[v] + 1) from[to].add(v);
            }
        }
    }

    void run() throws IOException {
        int n = nextInt();
        int m = nextInt();
        used = new boolean[n];
        dist = new int[n];
        g = new ArrayList[n];
        from = new HashSet[n];
        for (int i = 0; i < n; i++) {
            g[i] = new ArrayList<>();
            from[i] = new HashSet<>();
        }
        for (int i = 0; i < m; i++) {
            int u = nextInt() - 1;
            int v = nextInt() - 1;
            g[v].add(u);
        }
        int k = nextInt();
        int[] p = new int[k];
        for (int i = 0; i < k; i++) {
            p[i] = nextInt() - 1;
        }
        used[p[k - 1]] = true;
        q.add(p[k - 1]);
        bfs();
        int min = 0;
        int max = 0;
        for (int i = 0; i < p.length - 1; i++) {
            int v = p[i];
            if (from[p[i]].contains(p[i + 1])) {
                if (from[p[i]].size() > 1) max++;
            } else {
                min++;
                max++;
            }
        }
        pw.print(min + " " + max);
        pw.close();
    }

    static BufferedReader br;
    static StringTokenizer st = new StringTokenizer("");
    static PrintWriter pw;

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

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

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

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

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
        new Main().run();
    }

}


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

public class Main {
    static int n, m;
    static ArrayList<Integer> gr[];
    static int dist[];
    static ArrayList<Integer> temp = new ArrayList<>();
    static int fin;

    static void build() {
        ArrayList<Integer> g[] = new ArrayList[n];
        for(int i = 0;i < n;i++) g[i] = new ArrayList<>();
        for(int i = 0;i < n;i++) {
            for(int j : gr[i]) g[j].add(i);
        }

        dist = new int [n];
        for(int i = 0;i < n;i++) dist[i] = (int) 1e9;
        dist[fin] = 0;
        Deque<Integer> bfs = new ArrayDeque<>();
        bfs.add(fin);
        while(!bfs.isEmpty()) {
            int v = bfs.pollFirst();

            for(int to : g[v]) {
                if (dist[to] > dist[v] + 1) {
                    dist[to] = dist[v] + 1;
                    bfs.add(to);
                }
            }
        }
    }

    static void scan() throws IOException {
        n = sc.nextInt();
        m = sc.nextInt();
        gr = new ArrayList[n];
        for(int i = 0;i < n;i++) gr[i] = new ArrayList<>();
        for(int i = 0;i < m;i++) {
            int v1 = sc.nextInt() - 1;
            int v2 = sc.nextInt()  -1;
            gr[v1].add(v2);
        }

        int k = sc.nextInt();
        for(int i = 0;i < k;i++) {
            temp.add(sc.nextInt() - 1);
        }
        fin = temp.get(temp.size() - 1);
    }

    static void solve() throws IOException {
        scan();
        build();
        int ans1 = 0;
        int ans2 = 0;
        for(int u = 0;u < temp.size() - 1;u++) {
            int i = temp.get(u);
            int next = temp.get(u + 1);
            if (i == fin) break;
            int min = (int) 1e9;
            for(int to : gr[i]) {
                if (to != next) min = Math.min(min, dist[to]);
            }
            if (dist[next] > min) {
                ans1++;
                ans2++;
            }else if (dist[next] == min) {
                ans2++;
            }
        }

        pw.println(ans1 + " " + ans2);
    }

    public static void main(String[] args) throws IOException {
        sc = new Fast_Scanner(System.in);
        pw = new PrintWriter(System.out);
        solve();

        pw.close();
    }

    static Fast_Scanner sc;
    static PrintWriter pw;

    static class Fast_Scanner {
        static BufferedReader br;
        static StringTokenizer st = new StringTokenizer("");

        Fast_Scanner(InputStream in) {
            br = new BufferedReader(new InputStreamReader(in));
        }

        Fast_Scanner(String in) throws FileNotFoundException {
            br = new BufferedReader(new FileReader(in));
        }

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

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

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

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

}


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

public class Main {

    public static void main(String[] args) throws IOException {
        FastScanner in = new FastScanner();
        int n = in.nextInt();
        int m = in.nextInt();
        int[] sh = new int[n];
        int[] cnt = new int[n];
        ArrayList<Integer>[] a = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            a[i] = new ArrayList<>();
        }
        for (int i = 0; i < m; i++) {
            int from = in.nextInt() - 1;
            int to = in.nextInt() - 1;
            a[to].add(from);
        }
        int k = in.nextInt();
        int[] p = new int[n];
        for (int i = 0; i < k; i++) {
            p[i] = in.nextInt() - 1;
        }
        boolean[] used = new boolean[n];
        ArrayDeque<Integer> deq = new ArrayDeque<>();
        deq.add(p[k - 1]);
        used[p[k - 1]] = true;
        while (!deq.isEmpty()) {
            int v = deq.pollFirst();
            for (int to : a[v]) {
                if (!used[to]) {
                    sh[to] = sh[v] + 1;
                    used[to] = true;
                    deq.add(to);
                } else {
                    if (sh[to] == sh[v] + 1) {
                        cnt[to]++;
                    }
                }
            }
        }
        int min = 0;
        int max = 0;
        for (int i = 1; i < k; i++) {
            if (sh[p[i - 1]] != sh[p[i]] + 1) {
                min++;
                max++;
            } else {
                if (cnt[p[i - 1]] != 0) max++;
            }
        }
        in.out.println(min + " " + max);
        in.out.close();
    }
}

class FastScanner {

    StringTokenizer st = new StringTokenizer("");
    BufferedReader br;
    PrintWriter out;

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

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

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

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

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in Actual solution is at the top
 *
 * @author ilyakor
 */
public class Main {

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

  static class TaskG {

    public void solve(int testNumber, InputReader in, OutputWriter out) {
      int n = in.nextInt();
      int k = in.nextInt();
      int[] phi = new int[n + 1];
      for (int i = 2; i <= n; ++i) {
        if (phi[i] == 0) {
          phi[i] = i - 1;
          for (int j = i * 2; j <= n; j += i) {
            if (phi[j] == 0) {
              phi[j] = j;
            }
            phi[j] = phi[j] / i * (i - 1);
          }
        }
      }
      Arrays.sort(phi, 3, phi.length);
      long res = 2;
      for (int i = 0; i < k; ++i) {
        res += phi[3 + i];
      }
      if (k == 1) {
        --res;
      }
      // if (k == 2) {
      //     // We're taking
      // }
      out.printLine(res);
    }

  }

  static class OutputWriter {

    private final PrintWriter writer;

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

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

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

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

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

  }

  static class InputReader {

    private InputStream stream;
    private byte[] buffer = new byte[10000];
    private int cur;
    private int count;

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

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

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

    public int readSkipSpace() {
      int c;
      do {
        c = read();
      } while (isSpace(c));
      return c;
    }

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

  }
}


import java.util.*;
import java.io.*;
public class F2 {

	static long mod = 998244353;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();

		String[] s = new String[n];
		for(int i = 0; i < n; i++) {
			s[i] = sc.next();
		}

		HashSet<String> suffs = new HashSet<>();
		for(int i = 0; i < n; i++){
			for(int j = 1; j < s[i].length(); j++){
				suffs.add(s[i].substring(j));
			}
		}
		suffs.add("");
		HashSet<Pair> nodes = new HashSet<>();
		for(String a: suffs){
			for(String b: suffs){
				if(isPref(a, b)) {
					nodes.add(new Pair(a, b));
				}
			}
		}
		int N = nodes.size();
//		System.out.println(N);
		HashMap<Pair, Integer> code = new HashMap<>();
		Pair[] decode = new Pair[N];
		int count = 0;
		for(Pair p: nodes) {
			decode[count] = p;
			code.put(p, count++);
		}
		int[][] aut = new int[N][N];
		Pair p0 = new Pair("","");
		for(String t: s) {
			for(String u: s) {
				if(isPref(t, u)) {
					String a = t.substring(1);
					String b = u.substring(1);
					Pair p = new Pair(a, b);
					aut[code.get(p0)][code.get(p)]++;
				}
				else if(isPref(u, t)) {
					String a = u.substring(1);
					String b = t.substring(1);
					Pair p = new Pair(a, b);
					aut[code.get(p0)][code.get(p)]++;
				}
			}
		}
		for(Pair p: nodes) {
			Pair q = next(p);
			if(p.equals(p0)){
				continue;
			}
			else if(q != null) {
				aut[code.get(p)][code.get(q)]++;
			}
			else {
				for(String t: s) {
					q = next(p, t);
					if(q != null && nodes.contains(q)) {
						aut[code.get(p)][code.get(q)]++;
					}
				}
			}
		}
		Matrix mat = new Matrix(aut);
		Matrix matp = pow(mat, m);
		System.out.println(matp.mat[code.get(p0)][code.get(p0)]);
	}
	static Pair next(Pair p, String s) {
		if(p.a.equals("")) {
			if(isPref(s, p.b)) {
				String a = s.substring(1);
				String b = p.b.substring(1);
				return new Pair(a, b);
			}
			else if(isPref(p.b, s)) {
				String a = p.b.substring(1);
				String b = s.substring(1);
				return new Pair(a, b);
			}
			else return null;
		}
		else return null;
	}
	static Pair next(Pair p) {
		if(p.a.equals("")) return null;
		String a = p.a.substring(1);
		String b = p.b.substring(1);
		return new Pair(a, b);
	}
	static boolean isPref(String a, String b) { //a of b
		if(a.length() > b.length()) return false;
		else return b.substring(0, a.length()).equals(a);
	}
	static class Pair {
		String a, b;
		public Pair(String a, String b) {
			this.a = a; this.b = b;
		}
		@Override
		public int hashCode() {
			return a.hashCode() + b.hashCode();
		}
		@Override
		public boolean equals(Object o) {
			Pair p = (Pair)o;
			return a.equals(p.a) && b.equals(p.b);
		}
		public String toString() {
			return "'"+a+"' '"+b;
		}
	}

	static Matrix pow(Matrix m, int exp) {
		Matrix res = new Matrix(m.n);
		Matrix mapow = m;
		while(exp > 0) {
			if((exp & 1) == 1) {
				res = res.mult(mapow);
			}
			mapow = mapow.mult(mapow);
			exp >>= 1;
		}
		return res;
	}
	static class Matrix{
		int[][] mat; int n;
		public Matrix(int[][] mat) {
			n = mat.length;
			this.mat = mat;
		}
		public Matrix(int n) {
			mat = new int[n][n];
			this.n = n;
			for(int i = 0; i < n; i++) mat[i][i] = 1;
		}
		Matrix mult(Matrix m) {
			int[][] res = new int[n][n];
			for(int k = 0; k < n; k++) {
				for(int i = 0; i < n; i++) {
					for(int j = 0; j < n; j++) {
						long a = mat[i][k];
						long b = m.mat[k][j];
						long c = res[i][j];
						res[i][j] = (int)((c + a*b%mod)%mod);
					}
				}
			}
			return new Matrix(res);
		}
		public String toString(){
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < n; i++) {
				sb.append(Arrays.toString(mat[i])+"\n");
			}
			return sb.toString();
		}
	}

}


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

public class MainD {
	static StdIn in = new StdIn();
	static PrintWriter out = new PrintWriter(System.out);
	static long p;
	static List<Long> pFs = new ArrayList<Long>();
	static long[] fact1;
	static int[][] fact2;

	public static void main(String[] args) {
		int n=in.nextInt();
		p=in.nextLong();
		int l=in.nextInt(), r=in.nextInt();
		long p2=p;
		for(int i=2; i*i<=p2; ++i) {
			if(p2%i==0) {
				while(p2%i==0)
					p2/=i;
				pFs.add((long)i);
			}
		}
		if(p2>1)
			pFs.add(p2);
		fact1 = new long[2*n+1];
		fact2 = new int[pFs.size()][2*n+1];
		fact1[0]=1;
		for(int i=1; i<=2*n; ++i) {
			long a=i;
			for(int j=0; j<pFs.size(); ++j) {
				fact2[j][i]=fact2[j][i-1];
				while(a%pFs.get(j)==0) {
					a/=pFs.get(j);
					++fact2[j][i];
				}
			}
			fact1[i]=fact1[i-1]*a%p;
		}
		long ans1=0;
		for(int i=0; i<=n; ++i) {
			ans1=(ans1+nCk(n, i)*(nCk(n-i, (n-i)/2-(l+l%2*(n-i+1)%2)/2)-nCk(n-i, (n-i)/2-(r-(r+1)%2*(n-i)%2+2)/2)+p))%p;
			//if(i<1000)
			//	out.println(ans1);
			//out.println(ans1+" "+nCk(n, i)+" "+nCk(n-i, (n-i)/2-l/2));
		}
		out.println(ans1);
		out.close();
	}

	static long nCk(int n, int k) {
		if(k>n||k<0)
			return 0;
		long r=fact1[n]*modI(fact1[k])%p*modI(fact1[n-k])%p;
		for(int i=0; i<pFs.size(); ++i)
			r=r*expM(pFs.get(i), fact2[i][n]-fact2[i][k]-fact2[i][n-k])%p;
		return r;
	}

	static long expM(long b, int e) {
		if(e==0)
			return 1;
		if(e%2==1)
			return b*expM(b*b%p, e/2)%p;
		return expM(b*b%p, e/2);
    }

	static long modI(long a) {
        long m0 = p, t, q, x0 = 0, x1 = 1;
        while(a>1) {
            q = a / m0;
            t = m0;
            m0 = a % m0;
            a = t;
            t = x0;
            x0 = x1 - q * x0;
            x1 = t;
        }
        if(x1<0)
			x1 += p;
        return x1;
    }

	interface Input {
		public String next();
		public String nextLine();
		public int nextInt();
		public long nextLong();
		public double nextDouble();
	}
	static class StdIn implements Input {
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;
		public StdIn() {
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}
		public StdIn(InputStream in) {
			try{
				din = new DataInputStream(in);
			} catch(Exception e) {
				throw new RuntimeException();
			}
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}
		public String next() {
			int c;
			while((c=read())!=-1&&(c==' '||c=='\n'||c=='\r'));
			StringBuilder s = new StringBuilder();
			while (c != -1)
			{
				if (c == ' ' || c == '\n'||c=='\r')
					break;
				s.append((char)c);
				c=read();
			}
			return s.toString();
		}
		public String nextLine() {
			int c;
			while((c=read())!=-1&&(c==' '||c=='\n'||c=='\r'));
			StringBuilder s = new StringBuilder();
			while (c != -1)
			{
				if (c == '\n'||c=='\r')
					break;
				s.append((char)c);
				c = read();
			}
			return s.toString();
		}
		public int nextInt() {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
				ret = ret * 10 + c - '0';
			while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}
		public int[] readIntArray(int n) {
			int[] ar = new int[n];
			for(int i=0; i<n; ++i)
				ar[i]=nextInt();
			return ar;
		}
		public long nextLong() {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
				ret = ret * 10 + c - '0';
			while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}
		public long[] readLongArray(int n) {
			long[] ar = new long[n];
			for(int i=0; i<n; ++i)
				ar[i]=nextLong();
			return ar;
		}
		public double nextDouble() {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
				ret = ret * 10 + c - '0';
			while ((c = read()) >= '0' && c <= '9');
			if (c == '.')
				while ((c = read()) >= '0' && c <= '9')
					ret += (c - '0') / (div *= 10);
			if (neg)
				return -ret;
			return ret;
		}
		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}
		private byte read() {
			try{
				if (bufferPointer == bytesRead)
					fillBuffer();
				return buffer[bufferPointer++];
			} catch(IOException e) {
				throw new RuntimeException();
			}
		}
		public void close() throws IOException {
			if (din == null)
				return;
			din.close();
		}
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.io.IOException;
import java.util.Deque;
import java.util.ArrayList;
import java.io.UncheckedIOException;
import java.util.List;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.ArrayDeque;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            FWrapAround solver = new FWrapAround();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class FWrapAround {
        ACAutomaton.Node end;
        ACAutomaton.Node begin;
        int n;
        char[] s;
        ACAutomaton.Node[] nodes;
        ACAutomaton at;

        public void solve(int testNumber, FastInput in, FastOutput out) {
            n = in.readInt();
            s = in.readString().toCharArray();
            at = new ACAutomaton('0', '1');
            at.beginBuilding();
            for (char c : s) {
                at.build(c);
            }
            at.endBuilding();
            end = at.getBuildLast();
            nodes = at.getAllNodes().toArray(new ACAutomaton.Node[0]);
            begin = nodes[0];

            long ans = 0;
            for (int i = 0; i < n; i++) {
                ans += way(i);
            }

            out.println(ans);
        }

        public long pow(long x, long n) {
            if (n == 0) {
                return 1;
            }
            long ans = pow(x, n / 2);
            ans *= ans;
            if (n % 2 == 1) {
                ans *= x;
            }
            return ans;
        }

        public long way(int offset) {
            char[] data = new char[1 + 2 * n];
            for (int i = 0; i < s.length; i++) {
                data[1 + i + offset] = s[i];
                data[1 + (i + offset) % n] = s[i];
            }
            int dpLen = offset + s.length;
            long[][] dp = new long[dpLen + 1][nodes.length];
            dp[0][begin.getId()] = 1;
            for (int i = 0; i < dpLen; i++) {
                for (int j = 0; j < nodes.length; j++) {
                    if (dp[i][j] == 0 || j == end.getId()) {
                        continue;
                    }
                    if (data[i + 1] == 0) {
                        dp[i + 1][nodes[j].next[0].getId()] += dp[i][j];
                        dp[i + 1][nodes[j].next[1].getId()] += dp[i][j];
                    } else {
                        dp[i + 1][nodes[j].next[data[i + 1] - '0'].getId()] += dp[i][j];
                    }
                }
            }
            long ans = dp[dpLen][end.getId()];
            if (offset + s.length < n) {
                ans *= pow(2, n - offset - s.length);
            }
            return ans;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput println(long c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class FastInput {
        private final InputStream is;
        private StringBuilder defaultStringBuf = new StringBuilder(1 << 13);
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public String readString(StringBuilder builder) {
            skipBlank();

            while (next > 32) {
                builder.append((char) next);
                next = read();
            }

            return builder.toString();
        }

        public String readString() {
            defaultStringBuf.setLength(0);
            return readString(defaultStringBuf);
        }

    }

    static class ACAutomaton {
        private final int MIN_CHARACTER;
        private final int MAX_CHARACTER;
        private final int RANGE;
        private ACAutomaton.Node root;
        private ACAutomaton.Node buildLast;
        private List<ACAutomaton.Node> allNodes = new ArrayList();

        public ACAutomaton.Node getBuildLast() {
            return buildLast;
        }

        public List<ACAutomaton.Node> getAllNodes() {
            return allNodes;
        }

        private ACAutomaton.Node addNode() {
            ACAutomaton.Node node = new ACAutomaton.Node(RANGE);
            node.id = allNodes.size();
            allNodes.add(node);
            return node;
        }

        public ACAutomaton(int minCharacter, int maxCharacter) {
            MIN_CHARACTER = minCharacter;
            MAX_CHARACTER = maxCharacter;
            RANGE = maxCharacter - minCharacter + 1;
            root = addNode();
        }

        public void beginBuilding() {
            buildLast = root;
        }

        public void endBuilding() {
            Deque<ACAutomaton.Node> deque = new ArrayDeque(allNodes.size());
            for (int i = 0; i < RANGE; i++) {
                if (root.next[i] != null) {
                    deque.addLast(root.next[i]);
                }
            }

            while (!deque.isEmpty()) {
                ACAutomaton.Node head = deque.removeFirst();
                ACAutomaton.Node fail = visit(head.father.fail, head.index);
                if (fail == null) {
                    head.fail = root;
                } else {
                    head.fail = fail.next[head.index];
                }
                head.preSum = head.cnt + head.fail.preSum;
                for (int i = 0; i < RANGE; i++) {
                    if (head.next[i] != null) {
                        deque.addLast(head.next[i]);
                    }
                }
            }

            for (int i = 0; i < RANGE; i++) {
                if (root.next[i] != null) {
                    deque.addLast(root.next[i]);
                } else {
                    root.next[i] = root;
                }
            }
            while (!deque.isEmpty()) {
                ACAutomaton.Node head = deque.removeFirst();
                for (int i = 0; i < RANGE; i++) {
                    if (head.next[i] != null) {
                        deque.addLast(head.next[i]);
                    } else {
                        head.next[i] = head.fail.next[i];
                    }
                }
            }
        }

        public ACAutomaton.Node visit(ACAutomaton.Node trace, int index) {
            while (trace != null && trace.next[index] == null) {
                trace = trace.fail;
            }
            return trace;
        }

        public void build(char c) {
            int index = c - MIN_CHARACTER;
            if (buildLast.next[index] == null) {
                ACAutomaton.Node node = addNode();
                node.father = buildLast;
                node.index = index;
                buildLast.next[index] = node;
            }
            buildLast = buildLast.next[index];
        }

        public static class Node {
            public ACAutomaton.Node[] next;
            ACAutomaton.Node fail;
            ACAutomaton.Node father;
            int index;
            int id;
            int cnt;
            int preSum;

            public int getId() {
                return id;
            }

            public Node(int range) {
                next = new ACAutomaton.Node[range];
            }

        }

    }
}


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

import static java.util.Arrays.fill;

/**
 * @author Don Li
 */
public class WrapAround2 {

    int N = 41;

    int n, m;
    char[] s;

    int[] f;
    long[][][][] dp = new long[N][N][N][2];

    void solve() {
        n = in.nextInt();
        s = in.nextToken().toCharArray();
        m = s.length;

        f = fail(s);

        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < N; k++) fill(dp[i][j][k], -1);

        long ans = 0;
        for (int i = 0; i <= m; i++) {
            ans += dfs(n, i, i, 0);
        }
        out.println(ans);
    }

    long dfs(int rem, int cur, int tar, int has) {
        if (cur == m) has = 1;

        if (rem == 0) {
            return cur == tar && has > 0 ? 1 : 0;
        }

        if (dp[rem][cur][tar][has] >= 0) return dp[rem][cur][tar][has];

        long ans = 0;
        for (char x = '0'; x <= '1'; x++) {
            int nxt = next(cur, x);
            ans += dfs(rem - 1, nxt, tar, has);
        }
        return dp[rem][cur][tar][has] = ans;
    }

    int next(int now, char x) {
        if (now == m) now = f[now];
        while (now > 0 && s[now] != x) now = f[now];
        return s[now] == x ? now + 1 : 0;
    }

    int[] fail(char[] s) {
        int n = s.length;
        int[] f = new int[n + 1];
        f[0] = f[1] = 0;
        for (int i = 2; i <= n; i++) {
            int j = f[i - 1];
            while (j > 0 && s[j] != s[i - 1]) j = f[j];
            f[i] = s[j] == s[i - 1] ? j + 1 : 0;
        }
        return f;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new WrapAround2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

/**
 * @author Don Li
 */
public class WrapAround {

    int N = 41;

    int n, m;
    String s;
    long ans = 0;

    Map<String, Integer> str_to_idx = new HashMap<>();
    List<String> subs = new ArrayList<>(N * N);
    Set<String> pref = new HashSet<>();

    long[][][][] dp = new long[N][2][N][N * N];

    void solve() {
        n = in.nextInt();
        s = in.nextToken();
        m = s.length();

        str_to_idx.put("", 0);
        subs.add("");
        pref.add("");
        for (int i = 0; i < m; i++) {
            for (int j = i; j < m; j++) {
                String sub = s.substring(i, j + 1);
                if (!str_to_idx.containsKey(sub)) {
                    str_to_idx.put(sub, str_to_idx.size());
                    subs.add(sub);
                }
                if (i == 0) pref.add(sub);
            }
        }

        dp[0][0][0][0] = 1;
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k <= n; k++) {
                    for (int l = 0; l < subs.size(); l++) {
                        dfs(i, j, k, l);
                    }
                }
            }
        }
        out.println(ans);
    }

    void dfs(int len, int has, int pre, int suf) {
        if (dp[len][has][pre][suf] == 0) return;
        if (len == n) {
            if (has > 0) {
                ans += dp[len][has][pre][suf];
            } else {
                String cur = s.substring(0, pre) + subs.get(suf);
                if (cur.contains(s)) ans += dp[len][has][pre][suf];
            }
            return;
        }
        add(len, has, pre, suf, 0);
        add(len, has, pre, suf, 1);
    }

    void add(int len, int has, int pre, int suf, int x) {
        String cur = s.substring(0, pre) + x;
        while (!pref.contains(cur)) cur = cur.substring(1);
        int nhas = has;
        if (cur.length() == s.length()) nhas = 1;
        int npre = cur.length();
        cur = subs.get(suf) + x;
        int nsuf = suf;
        if (cur.length() == len + 1 && str_to_idx.containsKey(cur)) nsuf = str_to_idx.get(cur);
        dp[len + 1][nhas][npre][nsuf] += dp[len][has][pre][suf];
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new WrapAround().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

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


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

public class Crocodile implements Runnable {
    private void solve() throws IOException {
        int m = nextInt();
        int n = nextInt();
        int mx = Math.max(n, m);
        double[][] ans = new double[mx + 1][mx + 1];
        for (int sum = 0; sum <= mx + mx; ++sum) {
            for (int a = 0; a <= mx; ++a) {
                int b = sum - a;
                if (b >= 0 && b <= mx) {
                    ans[a][b] = doit(a, b, ans);
                }
            }
        }
        writer.println(ans[m][n] + " " + (1.0 - ans[m][n]));
    }

    private double doit(int m, int n, double[][] ans) {
        double res = 1.0 / (n + 1);
        if (m == 0 || n == 0) return res;
        double borderP = 1 / (ans[n][m - 1] * (n + 1) + 1);
        res = Math.max(res, eval(m, n, ans, 0.0));
        res = Math.max(res, eval(m, n, ans, borderP));
        res = Math.max(res, eval(m, n, ans, 1.0));
        return res;
    }

    private double eval(int m, int n, double[][] ans, double p) {
        return (1 - p) * n / (n + 1.0) * (1 - ans[n - 1][m]) + (p + (1 - p) / (n + 1.0) - Math.max((1 - p) / (n + 1), p * ans[n][m - 1]));
    }

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

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

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

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

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


import java.util.Arrays;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.HashMap;
import java.io.BufferedReader;
import java.util.Map;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

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

class TaskE {
    static final int MODULO = 10007;
    int magic;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        String s = in.next();
        int n = in.nextInt() + s.length();
        int[][][] ways = new int[s.length()][s.length() + 1][s.length() / 2 + 2];
        int[][] waysAll = new int[3][s.length() / 2 + 2];
        ways[0][s.length()][0] = 1;
        for (int start = 0; start < s.length(); ++start)
            for (int len = s.length() - start; len >= 1; --len) {
                int[] src = ways[start][len];
                if (s.charAt(start) == s.charAt(start + len - 1)) {
                    int nlen = len - 2;
                    int[] dest;
                    if (nlen <= 0) {
                        dest = waysAll[len];
                    } else {
                        dest = ways[start + 1][nlen];
                    }
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles + 1] = (dest[doubles + 1] + src[doubles]) % MODULO;
                    }
                } else {
                    int nlen = len - 1;
                    int[] dest = ways[start][nlen];
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles] = (dest[doubles] + src[doubles]) % MODULO;
                    }
                    dest = ways[start + 1][nlen];
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles] = (dest[doubles] + src[doubles]) % MODULO;
                    }
                }
            }
        int steps = n / 2;
        int ret = 0;
        int maxSingles = s.length();
        int maxDoubles = waysAll[1].length - 1;
        int size = maxSingles + maxDoubles + maxDoubles;
        magic = maxDoubles + maxSingles;
        int[][] m = new int[size][size];
        for (int i = 0; i < maxSingles + maxDoubles + maxDoubles; ++i) {
            if (i + 1 < maxSingles + maxDoubles) m[i + 1][i] = 1;
            if (i >= maxSingles && i < maxSingles + maxDoubles) m[i + maxDoubles][i] = 1;
            m[i][i] = (i < maxSingles ? 24 : (i < maxSingles + maxDoubles ? 25 : 26));
        }
        m = pow(m, steps);
        for (int last = 1; last <= 2; ++last) {
            for (int doubles = 0; doubles < waysAll[last].length; ++doubles) {
                int w = waysAll[last][doubles];
                if (w != 0) {
                    int singles = s.length() + (last == 1 ? 1 : 0) - 2 * doubles;
                    if (n % 2 == 0) {
                        ret = (int) ((ret + (long) w * m[maxSingles + maxDoubles + doubles - 1][maxSingles - singles]) % MODULO);
                    } else {
                        ret = (int) ((ret + (long) w * m[maxSingles + maxDoubles + doubles - 1][maxSingles - singles] * 26) % MODULO);
                        if (last == 1) {
                            ret = (int) ((ret + (long) w * m[maxSingles + doubles - 1][maxSingles - singles]) % MODULO);
                        }
                    }
                }
            }
        }
        out.println(ret);
    }

    private int[][] pow(int[][] m, int k) {
        int[][] res = new int[m.length][m.length];
        for (int i = 0; i < m.length; ++i) res[i][i] = 1;
        while (k > 0) {
            System.err.println(k + " " + m.length);
            if (k % 2 != 0) {
                res = mul(m, res);
            }
            k /= 2;
            m = mul(m, m);
        }
        return res;
    }

    private final int BIG = Integer.MAX_VALUE - Integer.MAX_VALUE % MODULO;

    private int[][] mul(int[][] a, int[][] b) {
        int n = a.length;
        int[][] c = new int[n][n];
        for (int i = 0; i < c.length; ++i) {
            for (int j = 0; j < magic; ++j) {
                int s = 0;
                for (int k = 0; k < magic; ++k) {
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                if (i >= magic) {
                    int k = i;
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                c[i][j] = s % MODULO;
            }
            if (i >= magic) {
                int j = i;
                int s = 0;
                for (int k = 0; k < magic; ++k) {
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                if (i >= magic) {
                    int k = i;
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                c[i][j] = s % MODULO;
            }
        }
        return c;
    }

}

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.*;
import java.util.Random;

public class CF506E {

    final static int MOD = 10007;

    static int[][] mul(int[][] a, int[][] b) {
        int[][] c = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            for (int j = i; j < a.length; ++j) {
                long sum = 0;
                for (int k = i; k <= j; ++k) {
                    sum += a[i][k] * b[k][j];
                }
                c[i][j] = (int) (sum % MOD);
            }
        }
        return c;
    }

    static int[][] pow(int[][] a, long pow) {
        int[][] r = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            r[i][i] = 1;
        }
        while (pow > 0) {
            if (pow % 2 == 1) {
                r = mul(r, a);
            }
            pow /= 2;
            a = mul(a, a);
        }
        return r;
    }

    public static void solve(Input in, PrintWriter out) throws IOException {
        String s = in.next();
        int n = s.length();
        int k = n + in.nextInt();
        int ans = solveFast(s, k);
        out.println(ans);
    }

    private static int solveFast(String s, int k) {
        int n = s.length();
        int[][][] d = new int[n + 1][n + 1][n + 1];
        d[0][n][0] = 1;
        for (int len = n; len > 0; --len) {
            for (int i = 0; i + len <= n; ++i) {
                for (int u = 0; u <= n; ++u) {
                    if (d[i][i + len][u] != 0) {
                        if (s.charAt(i) == s.charAt(i + len - 1)) {
                            d[i + 1][i + len - 1][u + 1] = (d[i + 1][i + len - 1][u + 1] + d[i][i + len][u]) % MOD;
                        } else {
                            d[i + 1][i + len][u] = (d[i + 1][i + len][u] + d[i][i + len][u]) % MOD;
                            d[i][i + len - 1][u] = (d[i][i + len - 1][u] + d[i][i + len][u]) % MOD;
                        }
                    }
                }
            }
        }
        int[][] d1 = new int[n + 1][n + 1];
        int[][] d2 = new int[n + 1][n + 1];
        for (int i = 0; i < n; ++i) {
            for (int u = 0; 2 * u <= n; ++u) {
                d1[u][n - 2 * u] += d[i][i][u];
                if (2 * u <= n - 1) {
                    d2[u][n - 2 * u - 1] += d[i][i + 1][u];
                }
            }
        }
        int ans = 0;
        int[][] a0 = new int[501][501];
        for (int i = 0; i < 100; ++i) {
            a0[i][i] = 25;
            a0[i][i + 1] = 1;
            if (i + 1 == 100) {
                a0[i][300] = 1;
            }
        }
        for (int i = 100; i < 300; ++i) {
            a0[i][i] = 24;
            if (i + 1 != 300) {
                a0[i][i + 1] = 1;
            }
            a0[i][200 + i + 1] = 1;
        }
        for (int i = 300; i <= 500; ++i) {
            a0[i][i] = 26;
        }
        int[][] a0low = pow(a0, k / 2);
        int[][] a0high = k % 2 == 1 ? mul(a0low, a0) : a0low;
        for (int u = 0; u <= n; ++u) {
            for (int v = 0; v <= n; ++v) {
                if (d1[u][v] != 0) { // aa
                    d1[u][v] %= MOD;
                    int cur = a0low[100 - u][300 + v];
                    if (k % 2 == 1) {
                        cur = cur * 26 % MOD;
                    }
                    ans = (ans + d1[u][v] * cur) % MOD;
//                    System.err.println("d1: " + u + " " + v + " " + d1[u][v] + " " + cur);
                }
                if (d2[u][v] != 0) { // a
                    d2[u][v] %= MOD;
                    int cur = a0high[100 - u - 1][300 + v];
                    ans = (ans + d2[u][v] * cur) % MOD;
//                    System.err.println("d2: " + u + " " + v + " " + d2[u][v] + " " + cur);
                }
            }
        }
        return ans;
    }

    private static int solveSlow(String s, int k) {
        int n = s.length();
        int[][] d = new int[n + 1][n + 1];
        d[0][n] = 1;
        for (int it = 0; it < k / 2; ++it) {
            int[][] d1 = new int[n + 1][n + 1];
            for (int len = n; len > 0; --len) {
                for (int i = 0; i + len <= n; ++i) {
                    if (d[i][i + len] != 0) {
                        if (s.charAt(i) == s.charAt(i + len - 1)) {
                            d1[Math.min(i + 1, i + len - 1)][i + len - 1] = (d1[Math.min(i + 1, i + len - 1)][i + len - 1] + d[i][i + len]) % MOD;
                            d1[i][i + len] = (d1[i][i + len] + d[i][i + len] * 25) % MOD;
                        } else {
                            d1[i + 1][i + len] = (d1[i + 1][i + len] + d[i][i + len]) % MOD;
                            d1[i][i + len - 1] = (d1[i][i + len - 1] + d[i][i + len]) % MOD;
                            d1[i][i + len] = (d1[i][i + len] + d[i][i + len] * 24) % MOD;
                        }
                    }
                }
            }
            for (int i = 0; i <= n; ++i) {
                d1[i][i] = (d1[i][i] + d[i][i] * 26) % MOD;
            }
            d = d1;
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            if (k % 2 == 0) {
                ans += d[i][i];
            } else {
                ans += d[i][i] * 26 + d[i][i + 1];
            }
        }
        return ans % MOD;
    }

    /*
0 78
0 76
6624 57
8739 55
0 123
0 93
0 99
1871 122
6968 75
8247 1
0 79
3404 10
0 19
0 85
4715 23
8609 1
1910 86
721 113
4055 12
659 82
0 115
0 53
944 57
9422 11

     */

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        Random rnd = new Random(42);
//        while (rnd != null) {
//            int n = 50;
//            StringBuilder sb = new StringBuilder();
//            for (int i = 0; i < n; ++i) {
//                sb.append((char)('a' + rnd.nextInt(26)));
//            }
//            int k = rnd.nextInt(100) + n;
//            int ans1 = solveSlow(sb.toString(), k);
//            int ans2 = solveFast(sb.toString(), k);
//            if (ans1 != ans2) {
//                System.err.println(sb + " " + k);
//                System.err.println(ans1 + " " + ans2);
//                throw new AssertionError();
//            }
////            sb.append("\n");
////            sb.append(rnd.nextInt(100));
////            solve(new Input(sb.toString()), out);
////            return;
//        }
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

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

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

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


import java.io.*;
import java.util.*;
public class Main{
	static int[] p, rank, treeNode,adj[];
	static boolean[]root;
	static int N;
	static int lastNode=0;
	static void preProcessDSU(int n) {
		N=n;
		p = new int[N];
		rank = new int[N];
		treeNode = new int[N];
		root=new boolean[N<<1];
		adj=new int[N<<1][2];

		for (int i = 0; i < N; i++) {
			p[i] = i; treeNode[i] = lastNode++; root[i]=true;
			adj[i<<1][0]=adj[i<<1][1]=adj[i<<1|1][0]=adj[i<<1|1][1]=-1;
		}
	}
	public static int findSet(int i) { return p[i] == i ? i : (p[i] = findSet(p[i])); }

	public static boolean isSameSet(int i, int j) { return findSet(i) == findSet(j); }

	public static void unionSet(int i, int j)
	{
		if (isSameSet(i, j))
			return;
		int x = findSet(i), y = findSet(j);

		int u=treeNode[x],v=treeNode[y];
		root[u]=false;root[v]=false;
		int newRoot=lastNode++;
		root[newRoot]=true;
		adj[newRoot][0]=u;adj[newRoot][1]=v;

		if(rank[x] > rank[y]) { p[y] = x; treeNode[x]=newRoot;}
		else
		{	p[x] = y; treeNode[y]=newRoot;
			if(rank[x] == rank[y]) rank[y]++;
		}

	}
	static int time,tin[],tout[];
	static void dfs(int i) {
		tin[i]=++time;
		for(int j:adj[i]) {
			if(j==-1)continue;
			dfs(j);
		}
		tout[i]=time;
	}
	static int[]segTree,index;
	static void updatePoint(int idx) {
		updatePoint(1, 1, time, idx);
	}
	static void updatePoint(int node,int l,int r,int idx) {
		if(l==r) {
			segTree[node]=0;
			return;
		}
		int mid=(l+r)>>1;
		if(idx<=mid) {
			updatePoint(node<<1, l, mid, idx);
		}
		else {
			updatePoint(node<<1|1, mid+1, r, idx);
		}
		if(segTree[node<<1|1]>segTree[node<<1]) {
			segTree[node]=segTree[node<<1|1];
			index[node]=index[node<<1|1];
		}
		else {
			segTree[node]=segTree[node<<1];
			index[node]=index[node<<1];
		}
	}
	static int[] query(int l,int r) {
		return query(1, 1, time,l,r);
	}
	static int[] query(int node,int curL,int curR,int l,int r) {
		if(curR<l || curL>r)return new int[] {-1,-1};
		if(curL>=l && curR<=r) {
			return new int[] {segTree[node],index[node]};
		}
		int mid=(curL+curR)>>1;
		int[]q1=query(node<<1, curL, mid, l, r),q2=query(node<<1|1, mid+1, curR, l, r);
		if(q1[0]>q2[0]) {
			return q1;
		}
		return q2;
	}
	static void insert(int idx,int val) {
		insert(1, 1, time, idx,val);
	}
	static void insert(int node,int l,int r,int idx,int val) {
		if(l==r) {
			segTree[node]=val;
			index[node]=idx;
			return;
		}
		int mid=(l+r)>>1;
		if(idx<=mid) {
			insert(node<<1, l, mid, idx,val);
		}
		else {
			insert(node<<1|1, mid+1, r, idx,val);
		}
		if(segTree[node<<1|1]>segTree[node<<1]) {
			segTree[node]=segTree[node<<1|1];
			index[node]=index[node<<1|1];
		}
		else {
			segTree[node]=segTree[node<<1];
			index[node]=index[node<<1];
		}
	}
	static void main() throws Exception{
		int n=sc.nextInt(),m=sc.nextInt(),q=sc.nextInt();
		int[]vals=sc.intArr(n);
		int[][]edges=new int[m][];
		for(int i=0;i<m;i++) {
			edges[i]=new int[] {sc.nextInt()-1,sc.nextInt()-1};
		}
		int[][]qs=new int[q][];
		boolean[]edgeRemoved=new boolean[m];
		for(int i=0;i<q;i++) {
			qs[i]=new int[] {sc.nextInt(),sc.nextInt()-1};
			if(qs[i][0]==2) {
				edgeRemoved[qs[i][1]]=true;
			}
		}
		preProcessDSU(n);
		for(int i=0;i<m;i++) {
			if(!edgeRemoved[i]) {
				unionSet(edges[i][0], edges[i][1]);
			}
		}
		int[]subtreeRoot=new int[q];
		for(int i=q-1;i>=0;i--) {
			if(qs[i][0]==1) {
				subtreeRoot[i]=treeNode[findSet(qs[i][1])];
			}
			else {
				int edge=qs[i][1];
				unionSet(edges[edge][0], edges[edge][1]);
			}
		}
		tin=new int[n<<1];
		tout=new int[n<<1];
		for(int i=0;i<lastNode;i++) {
			if(root[i]) {
				dfs(i);
			}
		}
		segTree=new int[time<<2];
		Arrays.fill(segTree, -1);
		index=new int[time<<2];
		for(int i=0;i<n;i++) {
			insert(tin[i], vals[i]);
		}
		for(int i=0;i<q;i++) {
			if(qs[i][0]==1) {
				int curRoot=subtreeRoot[i];
				int left=tin[curRoot],right=tout[curRoot];
				int[]curQ=query(left, right);
				pw.println(curQ[0]);
				if(curQ[1]>0)
					updatePoint(curQ[1]);
			}
		}
	}
	public static void main(String[] args) throws Exception{
		sc=new MScanner(System.in);
		pw = new PrintWriter(System.out);
		int tc=1;
//		tc=sc.nextInt();
		while(tc-->0)
			main();
		pw.flush();
	}
	static PrintWriter pw;
	static MScanner  sc;
	static class MScanner {
		StringTokenizer st;
		BufferedReader br;
		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int[] intArr(int n) throws IOException {
	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        return in;
		}
		public long[] longArr(int n) throws IOException {
	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        return in;
		}
		public int[] intSortedArr(int n) throws IOException {
	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        shuffle(in);
	        Arrays.sort(in);
	        return in;
		}
		public long[] longSortedArr(int n) throws IOException {
	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        shuffle(in);
	        Arrays.sort(in);
	        return in;
		}
		public Integer[] IntegerArr(int n) throws IOException {
	        Integer[]in=new Integer[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        return in;
		}
		public Long[] LongArr(int n) throws IOException {
	        Long[]in=new Long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        return in;
		}
		public String nextLine() throws IOException {
			return br.readLine();
		}

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

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

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
	static void shuffle(int[]in) {
		for(int i=0;i<in.length;i++) {
			int idx=(int)(Math.random()*in.length);
			int tmp=in[i];
			in[i]=in[idx];
			in[idx]=tmp;
		}
	}
	static void shuffle(long[]in) {
		for(int i=0;i<in.length;i++) {
			int idx=(int)(Math.random()*in.length);
			long tmp=in[i];
			in[i]=in[idx];
			in[idx]=tmp;
		}
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
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;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int numQueries = in.nextInt();
            int[] p = new int[n];
            for (int i = 0; i < n; i++) {
                p[i] = -in.nextInt();
            }
            int[] a = new int[m];
            int[] b = new int[m];
            for (int i = 0; i < m; i++) {
                a[i] = in.nextInt() - 1;
                b[i] = in.nextInt() - 1;
            }
            int[] type = new int[numQueries];
            int[] val = new int[numQueries];
            boolean[] willDie = new boolean[m];
            for (int i = 0; i < numQueries; i++) {
                type[i] = in.nextInt();
                val[i] = in.nextInt() - 1;
                if (type[i] == 2) {
                    willDie[val[i]] = true;
                }
            }

            int[] parent = new int[n];
            Arrays.fill(parent, -1);
            DSU dsu = new DSU(n);
            Graph g = new Graph(n + 1);
            for (int i = 0; i < m; i++) {
                if (willDie[i]) {
                    continue;
                }
                int u = dsu.findComp(a[i]);
                int v = dsu.findComp(b[i]);
                if (u == v) {
                    continue;
                }
                dsu.merge(u, v);
                if (dsu.p[v] == u) {
                    int t = u;
                    u = v;
                    v = t;
                }
                parent[u] = v;
                g.addEdge(v, u, i);
            }

            for (int i = numQueries - 1; i >= 0; i--) {
                if (type[i] == 1) {
                    val[i] = dsu.findComp(val[i]);
                    continue;
                }
                int u = dsu.findComp(a[val[i]]);
                int v = dsu.findComp(b[val[i]]);
                if (u == v) {
                    continue;
                }
                dsu.merge(u, v);
                if (dsu.p[v] == u) {
                    int t = u;
                    u = v;
                    v = t;
                }
                parent[u] = v;
                g.addEdge(v, u, val[i]);
            }

            int root = n;
            for (int i = 0; i < n; i++) {
                if (parent[i] < 0) {
                    g.addEdge(root, i, -1);
                }
            }
            EulerTourNumbering et = new EulerTourNumbering(g, root);

            MinTree mt = new MinTree(n + 1);
            int[] q = new int[n + 1];
            for (int i = 0; i < n; i++) {
                q[et.timeIn[i]] = p[i];
                mt.set(et.timeIn[i], p[i]);
            }

            boolean[] dead = new boolean[m];
            int[] left = new int[n + 1];
            int[] right = new int[n + 1];
            for (int i = 0; i < left.length; i++) {
                left[i] = et.timeIn[i];
                right[i] = et.timeOut[i] - 1;
            }
            for (int i = 0; i < numQueries; i++) {
                if (type[i] == 2) {
                    dead[val[i]] = true;
                    continue;
                }
                int r = val[i];
                for (int e = g.firstEdge[val[i]]; e >= 0; e = g.edgeNxt[e]) {
                    int origId = g.edgeId[e];
                    int dst = g.edgeDst[e];
                    if (dead[origId]) {
                        if (e != g.firstEdge[val[i]]) {
                            throw new AssertionError();
                        }
                        g.firstEdge[val[i]] = g.edgeNxt[e];
                        left[val[i]] = et.timeOut[dst];
                    } else {
                        break;
                    }
                }
                int pos = et.timeIn[r];
                if (left[r] <= right[r]) {
                    int cand = mt.getMinPos(left[r], right[r]);
                    if (q[pos] > q[cand]) {
                        pos = cand;
                    }
                }
                out.println(-q[pos]);
                q[pos] = 0;
                mt.set(pos, 0);
            }
        }

        class EulerTourNumbering {
            Graph g;
            int[] tour;
            int[] timeIn;
            int[] timeOut;
            int globalTime;

            EulerTourNumbering(Graph g, int root) {
                this.g = g;
                int n = g.n;
                timeIn = new int[n];
                timeOut = new int[n];
                tour = new int[n];

                dfs(root, -1);
                if (globalTime != n) {
                    throw new AssertionError();
                }
            }

            void dfs(int v, int p) {
                tour[globalTime] = v;
                timeIn[v] = globalTime++;
                for (int e = g.firstEdge[v]; e >= 0; e = g.edgeNxt[e]) {
                    int u = g.edgeDst[e];
                    if (u == p) {
                        continue;
                    }
                    dfs(u, v);
                }
                timeOut[v] = globalTime;
            }

        }

        class Graph {
            int n;
            int[] firstEdge;
            int[] edgeDst;
            int[] edgeNxt;
            int[] edgeId;
            int numEdges;

            Graph(int n) {
                this.n = n;
                firstEdge = new int[n];
                Arrays.fill(firstEdge, -1);
                final int initialCapacity = 2 * n - 2;
                edgeDst = new int[initialCapacity];
                edgeNxt = new int[initialCapacity];
                edgeId = new int[initialCapacity];
                numEdges = 0;
            }

            void addEdge(int a, int b, int origId) {
                int e = numEdges++;
                if (e >= edgeDst.length) {
                    reallocate();
                }
                edgeDst[e] = b;
                edgeNxt[e] = firstEdge[a];
                firstEdge[a] = e;
                edgeId[e] = origId;
            }

            private void reallocate() {
                int k = edgeDst.length;
                edgeDst = Arrays.copyOf(edgeDst, 3 * k / 2);
                edgeNxt = Arrays.copyOf(edgeNxt, 3 * k / 2);
                edgeId = Arrays.copyOf(edgeId, 3 * k / 2);
            }

        }

        class MinTree {
            int n;
            int[] a;
            int[] where;
            final int infinity = (int) 1e9;

            MinTree(int size) {
                n = 1;
                while (n < size) {
                    n *= 2;
                }
                a = new int[2 * n];
                where = new int[2 * n];
                Arrays.fill(a, infinity);
            }

            void set(int pos, int val) {
                pos += n;
                a[pos] = val;
                where[pos] = pos - n;
                while (pos > 1) {
                    pos /= 2;
                    a[pos] = Math.min(a[2 * pos], a[2 * pos + 1]);
                    if (a[pos] == a[2 * pos]) {
                        where[pos] = where[2 * pos];
                    } else {
                        where[pos] = where[2 * pos + 1];
                    }
                }
            }

            int getMinPos(int l, int r) {
                if (l > r) {
                    return infinity;
                }
                l += n;
                r += n;
                if (l == r) {
                    return where[l];
                }
                int lm = a[l];
                int rm = a[r];
                int lp = where[l];
                int rp = where[r];
                while (r - l > 1) {
                    if (l % 2 == 0) {
                        if (lm > a[l + 1]) {
                            lm = a[l + 1];
                            lp = where[l + 1];
                        }
                    }
                    if (r % 2 != 0) {
                        if (rm > a[r - 1]) {
                            rm = a[r - 1];
                            rp = where[r - 1];
                        }
                    }
                    l /= 2;
                    r /= 2;
                }
                return lm < rm ? lp : rp;
            }

        }

        class DSU {
            int[] rank;
            int[] p;
            int numComps;

            DSU(int n) {
                rank = new int[n];
                p = new int[n];
                reset();
            }

            void reset() {
                for (int i = 0; i < p.length; i++) {
                    rank[i] = 0;
                    p[i] = i;
                }
                numComps = p.length;
            }

            private int findComp(int x) {
                int r;
                int saved;

                saved = x;
                while (x != p[x]) {
                    x = p[x];
                }
                r = x;

                x = saved;
                while (x != r) {
                    saved = p[x];
                    p[x] = r;
                    x = saved;
                }
                return r;
            }

            private void merge(int a, int b) {
                a = findComp(a);
                b = findComp(b);
                if (a == b) {
                    return;
                }
                --numComps;
                if (rank[a] < rank[b]) {
                    p[a] = b;
                } else {
                    p[b] = a;
                    if (rank[a] == rank[b]) {
                        ++rank[a];
                    }
                }
            }

        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

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

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

    }
}