import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {

    public static void main(final String[] args) throws IOException {
        try(Scanner scan = new Scanner(System.in);
            PrintWriter print = new PrintWriter(System.out)) {
            final int n = scan.nextInt();
            final int l = scan.nextInt();
            final int r = scan.nextInt();
            final Floodlight[] floodlights = new Floodlight[n];
            for(int i = 0; i < n; ++i) {
                final int x = scan.nextInt();
                final int y = scan.nextInt();
                final double angle = scan.nextInt() / 180. * Math.PI;
            }
            print.println(calcMaxBeginSeg(l, r, floodlights));
        }
    }

    public static double calcMaxBeginSeg(final int left, final int right, final Floodlight[] floodlights) {
        if(right <= left) return 0.;
        final int n = floodlights.length;
        double maxLitRight[] = new double[1 << n];
        maxLitRight[0] = left;
        for(int mask = 1; mask < 1 << n; ++mask) {
            double result = left;
            for(int i = 0; i < n; ++i) {
                if(((mask >> i) & 1) == 1) {
                    result = Math.max(result, extendLitSeg(maxLitRight[mask ^ (1 << i)], floodlights[i], right));
                }
            }
            maxLitRight[mask] = result;
        }
        return maxLitRight[(1 << n) - 1] - left;
    }

    private static double extendLitSeg(final double left, final Floodlight light, final double maxRight) {
        if(left >= maxRight) return left;
        if(light.y <= 0.) throw new RuntimeException("light.y must be > 0");
        final double startAngle = Math.atan((left - light.getX()) / light.getY());
        final double endAngle = startAngle + light.angle;
        if(endAngle >= Math.PI / 2.) return maxRight;
        return Math.min(maxRight, light.getX() + light.getY() * Math.tan(endAngle));
    }

    public static class Floodlight {
        private final int x;
        private final int y;
        private final double angle;

        public Floodlight(final int x, final int y, final double angle) {
            this.x = x;
            this.y = y;
            this.angle = angle;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public double getAngle() {
            return angle;
        }
    }

    public static class NumberUtils {
        public static interface Factorizer {
            List<Integer> factorize(int number);
        }

        /**
         * thread safe Factorizer
         */
        public static Factorizer createSmallNumberFactorizer(final int upperBound) {
            return new SmallNumberFactorizer(upperBound);
        }

        /**
         * thread safe
         */
        private static class SmallNumberFactorizer implements Factorizer {
            private int[] divisors;
            private final int upperBound;
            private boolean prepared = false;

            /**
             * lazy
             * time complexity O(n * log(n) * log(log(n))
             * memory complexity O(n)
             */
            public SmallNumberFactorizer(final int upperBound) {
                this.upperBound = upperBound;
            }

            private synchronized void prepare() {
                divisors = new int[upperBound];
                Arrays.fill(divisors, 0);
                for(int i = 2; i * i < upperBound; ++i) {
                    if(divisors[i] == 0) {
                        for(int j = i * i; j < upperBound; j += i) {
                            if(divisors[j] == 0) {
                                divisors[j] = i;
                            }
                        }
                    }
                }
                prepared = true;
            }

            /**
             * complexity O(result)
             */
            public List<Integer> factorize(int number) {
                synchronized (this) {
                    if(!prepared) {
                        prepare();
                    }
                }
                final List<Integer> result = CollectionFactory.createArrayList();
                if(number < 2) return result;
                if(number >= upperBound) throw new RuntimeException("number should be less than upper bound");
                while(divisors[number] > 0) {
                    result.add(divisors[number]);
                    number /= divisors[number];
                }
                result.add(number);
                return result;
            }
        }
    }

    public static class CollectionFactory {
        public static<T> List<T> createArrayList() {
            return new ArrayList<>();
        }

        public static<T> List<T> createArrayList(final int capacity) {
            return new ArrayList<>(capacity);
        }
    }

    public static class CollectionUtils {
        public static<T> List<T> unique(final List<T> list) {
            final List<T> result = CollectionFactory.createArrayList();
            T p = null;
            for(T elem : list) {
                if(!elem.equals(p)) {
                    result.add(elem);
                    p = elem;
                }
            }
            return result;
        }

        public static<T extends Comparable<T>> T max(final List<T> list, final T lowerBound) {
            T result = lowerBound;
            for(T elem : list) {
                if(elem.compareTo(result) > 0) {
                    result = elem;
                }
            }
            return result;
        }
    }

}


/*
ID: davidzh8
PROG: subset
LANG: JAVA
 */

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

public class villagemin {

    static long startTime = System.nanoTime();
    static ArrayList<Integer>[] adj;
    static int[] pos;
    public static void solve() throws Exception {
        boolean debug = (true);
        FastScanner sc = new FastScanner("villagemin.in", debug);
        FastWriter pw = new FastWriter("villagemin.out", debug);
        int N= sc.ni();
        adj= new ArrayList[N];
        pos= new int[N];
        for (int i = 0; i < N; i++) {
            pos[i]=i;
        }
        for(int i=0; i<N; i++){
            adj[i]= new ArrayList<>();
        }
        for (int i = 0; i < N-1; i++) {
            int a= sc.ni()-1;
            int b= sc.ni()-1;
            adj[a].add(b);
            adj[b].add(a);
        }
        dfs(0,-1);
        System.out.println(res);
        for (int i = 0; i < N; i++) {
            System.out.print(pos[i]+1+" ");
        }

        long endTime = System.nanoTime();
        //System.out.println("Execution Time: " + (endTime - startTime) / 1e9 + " s");
        pw.close();
    }
    static int res=0;
    static void dfs(int cur, int par){
        for(int next: adj[cur] ){
            if(next==par) continue;
            dfs(next, cur);
            if(pos[next]==next) {
                res += 2;
                int temp = pos[cur];
                pos[cur] = pos[next];
                pos[next] = temp;
            }
        }
        if(cur==0 && pos[cur]==0){
            int next= adj[0].get(0);
            res += 2;
            int temp = pos[cur];
            pos[cur] = pos[next];
            pos[next] = temp;
        }

    }

    static class Pair implements Comparable<Pair> {
        int a;
        int b;

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

        public int compareTo(Pair obj) {
            if (obj.a == a) {
                return b - obj.b;
            } else return a - obj.a;
        }
    }

    static class djset {
        int N;
        int[] parent;

        // Creates a disjoint set of size n (0, 1, ..., n-1)
        public djset(int n) {
            parent = new int[n];
            N = n;
            for (int i = 0; i < n; i++)
                parent[i] = i;
        }

        public int find(int v) {

            // I am the club president!!! (root of the tree)
            if (parent[v] == v) return v;

            // Find my parent's root.
            int res = find(parent[v]);

            // Attach me directly to the root of my tree.
            parent[v] = res;
            return res;
        }

        public boolean union(int v1, int v2) {

            // Find respective roots.
            int rootv1 = find(v1);
            int rootv2 = find(v2);

            // No union done, v1, v2 already together.
            if (rootv1 == rootv2) return false;

            // Attach tree of v2 to tree of v1.
            parent[rootv2] = rootv1;
            return true;
        }

    }

    static class FastScanner {
        InputStream dis;
        byte[] buffer = new byte[1 << 17];
        int pointer = 0;

        public FastScanner(String fileName, boolean debug) throws Exception {
            if (debug) dis = System.in;
            else dis = new FileInputStream(fileName);
        }

        int ni() throws Exception {
            int ret = 0;

            byte b;
            do {
                b = nextByte();
            } while (b <= ' ');
            boolean negative = false;
            if (b == '-') {
                negative = true;
                b = nextByte();
            }
            while (b >= '0' && b <= '9') {
                ret = 10 * ret + b - '0';
                b = nextByte();
            }

            return (negative) ? -ret : ret;
        }

        long nl() throws Exception {
            long ret = 0;

            byte b;
            do {
                b = nextByte();
            } while (b <= ' ');
            boolean negative = false;
            if (b == '-') {
                negative = true;
                b = nextByte();
            }
            while (b >= '0' && b <= '9') {
                ret = 10 * ret + b - '0';
                b = nextByte();
            }

            return (negative) ? -ret : ret;
        }

        byte nextByte() throws Exception {
            if (pointer == buffer.length) {
                dis.read(buffer, 0, buffer.length);
                pointer = 0;
            }
            return buffer[pointer++];
        }

        String next() throws Exception {
            StringBuffer ret = new StringBuffer();

            byte b;
            do {
                b = nextByte();
            } while (b <= ' ');
            while (b > ' ') {
                ret.appendCodePoint(b);
                b = nextByte();
            }

            return ret.toString();
        }
    }

    static class FastWriter {
        public PrintWriter pw;

        public FastWriter(String name, boolean debug) throws IOException {
            if (debug) {
                pw = new PrintWriter(System.out);
            } else {
                pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(name))));
            }
        }

        public void println(Object text) {
            pw.println(text);
        }

        public void print(Object text) {
            pw.print(text);
        }

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

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

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, () -> {
            try {
                solve();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "", 1 << 28);
        thread.start();
        thread.join();
    }

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class B1_Baltic_2020_Day2 {
    public static long MOD = 1000000007;
    static ArrayList<Integer>[] store;
    static int result = 0;

    public static void main(String[] args) throws FileNotFoundException {
        // PrintWriter out = new PrintWriter(new FileOutputStream(new File(
        // "output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        ArrayList<Integer>[] map = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            map[i] = new ArrayList<>();
        }

        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            map[u].add(v);
            map[v].add(u);
        }
        if (n == 2) {
            out.println(2);
            out.println(2 + " " + 1);
        } else {
            store = new ArrayList[n];
            int[] re = new int[n];
            int v = cal(0, 0, re, map);
            if (v != -1) {
                for (int index : map[v]) {
                    result += 2;
                    store[index].add(v);
                    int last = index;
                    for (int i : store[index]) {
                        re[i] = last;
                        last = i;
                    }
                    re[index] = last;
                    break;
                }
            }
            out.println(result);
            for (int i : re) {
                out.print((i + 1) + " ");
            }
        }

        out.close();
    }

    static int cal(int index, int pa, int[] re, ArrayList<Integer>[] map) {
        store[index] = new ArrayList<>();
        for (int i : map[index]) {
            if (i == pa) {
                continue;
            }
            int v = cal(i, index, re, map);
            if (v != -1) {
                store[index].add(v);
            }
        }
        if (store[index].isEmpty()) {
            return index;
        } else {
            result += 2 * (1 + store[index].size()) - 2;
            int last = index;
            for (int i : store[index]) {
                re[i] = last;
                last = i;
            }
            re[index] = last;
            return -1;
        }
    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

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

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 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 Integer.compare(x, o.x);
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

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

    public static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }

        long val = pow(a, b / 2);
        if (b % 2 == 0) {
            return val * val;
        } else {
            return val * (val * a);

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

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

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

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

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

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.Flushable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	static class TaskAdapter implements Runnable {
		@Override
		public void run() {
			InputStream inputStream = System.in;
			OutputStream outputStream = System.out;
			FastReader in = new FastReader(inputStream);
			Output out = new Output(outputStream);
			B1VillageMinimum solver = new B1VillageMinimum();
			solver.solve(1, in, out);
			out.close();
		}
	}

	public static void main(String[] args) throws Exception {
		Thread thread = new Thread(null, new TaskAdapter(), "", 1<<29);
		thread.start();
		thread.join();
	}
	static class B1VillageMinimum {
		static B1VillageMinimum.Node[] nodes;
		static ArrayList<Integer>[] graph;
		static ArrayDeque<Integer> leaves;

		public B1VillageMinimum() {
		}

		public void solve(int kase, InputReader in, Output pw) {
			int n = in.nextInt();
			graph = in.nextUndirectedGraph(n, n-1);
			nodes = new B1VillageMinimum.Node[n];
			leaves = new ArrayDeque<>(n);
			for(int i = 0; i<n; i++) {
				nodes[i] = new B1VillageMinimum.Node(i);
			}
			nodes[0].dfs();
			int[] ans = new int[n];
			long sum = 0;
			while(!leaves.isEmpty()) {
				B1VillageMinimum.Node cur = nodes[leaves.removeFirst()];
				Utilities.Debug.dbg(cur.ind);
				if(!cur.processed) {
					if(cur.ind==0) {
						B1VillageMinimum.Node swap = cur.children.get(0);
						ans[swap.value] = cur.ind+1;
						ans[cur.value] = swap.ind+1;
						cur.processed = swap.processed = true;
					}else {
						B1VillageMinimum.Node swap = cur.parent;
						ans[swap.value] = cur.ind+1;
						ans[cur.value] = swap.ind+1;
						swap.value ^= cur.value;
						cur.value ^= swap.value;
						swap.value ^= cur.value;
						cur.processed = swap.processed = true;
					}
					sum += 2;
				}
				B1VillageMinimum.Node p = cur.parent;
				if(p!=null) {
					p.childcnt--;
					if(p.childcnt==0) {
						leaves.addLast(p.ind);
					}
				}
			}
			pw.println(sum);
			pw.println(ans);
		}

		static class Node {
			B1VillageMinimum.Node parent;
			ArrayList<B1VillageMinimum.Node> children;
			final int ind;
			int value;
			int childcnt;
			boolean visited;
			boolean processed;

			public Node(int ind) {
				this.ind = value = ind;
				parent = null;
				childcnt = 0;
				children = new ArrayList<>();
				visited = processed = false;
			}

			public void dfs() {
				visited = true;
				for(int i: graph[ind]) {
					B1VillageMinimum.Node n = nodes[i];
					if(!n.visited) {
						n.parent = this;
						n.dfs();
						childcnt++;
						children.add(n);
					}
				}
				if(childcnt==0) {
					leaves.addLast(ind);
				}
			}

		}

	}

	static class Output implements Closeable, Flushable {
		public StringBuilder sb;
		public OutputStream os;
		public int BUFFER_SIZE;
		public boolean autoFlush;
		public String LineSeparator;

		public Output(OutputStream os) {
			this(os, 1<<16);
		}

		public Output(OutputStream os, int bs) {
			BUFFER_SIZE = bs;
			sb = new StringBuilder(BUFFER_SIZE);
			this.os = new BufferedOutputStream(os, 1<<17);
			autoFlush = false;
			LineSeparator = System.lineSeparator();
		}

		public void print(int i) {
			print(String.valueOf(i));
		}

		public void print(String s) {
			sb.append(s);
			if(autoFlush) {
				flush();
			}else if(sb.length()>BUFFER_SIZE >> 1) {
				flushToBuffer();
			}
		}

		public void println(long l) {
			println(String.valueOf(l));
		}

		public void println(String s) {
			sb.append(s);
			println();
			if(autoFlush) {
				flush();
			}else if(sb.length()>BUFFER_SIZE >> 1) {
				flushToBuffer();
			}
		}

		public void println() {
			sb.append(LineSeparator);
		}

		public void println(int[] arr) {
			for(int i = 0; i<arr.length; i++) {
				if(i!=0) {
					print(" ");
				}
				print(arr[i]);
			}
			println();
		}

		private void flushToBuffer() {
			try {
				os.write(sb.toString().getBytes());
			}catch(IOException e) {
				e.printStackTrace();
			}
			sb = new StringBuilder(BUFFER_SIZE);
		}

		public void flush() {
			try {
				flushToBuffer();
				os.flush();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}

		public void close() {
			flush();
			try {
				os.close();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}

	}

	static class Utilities {
		public static class Debug {
			public static final boolean LOCAL = System.getProperty("ONLINE_JUDGE")==null;

			private static <T> String ts(T t) {
				if(t==null) {
					return "null";
				}
				try {
					return ts((Iterable) t);
				}catch(ClassCastException e) {
					if(t instanceof int[]) {
						String s = Arrays.toString((int[]) t);
						return "{"+s.substring(1, s.length()-1)+"}";
					}else if(t instanceof long[]) {
						String s = Arrays.toString((long[]) t);
						return "{"+s.substring(1, s.length()-1)+"}";
					}else if(t instanceof char[]) {
						String s = Arrays.toString((char[]) t);
						return "{"+s.substring(1, s.length()-1)+"}";
					}else if(t instanceof double[]) {
						String s = Arrays.toString((double[]) t);
						return "{"+s.substring(1, s.length()-1)+"}";
					}else if(t instanceof boolean[]) {
						String s = Arrays.toString((boolean[]) t);
						return "{"+s.substring(1, s.length()-1)+"}";
					}
					try {
						return ts((Object[]) t);
					}catch(ClassCastException e1) {
						return t.toString();
					}
				}
			}

			private static <T> String ts(T[] arr) {
				StringBuilder ret = new StringBuilder();
				ret.append("{");
				boolean first = true;
				for(T t: arr) {
					if(!first) {
						ret.append(", ");
					}
					first = false;
					ret.append(ts(t));
				}
				ret.append("}");
				return ret.toString();
			}

			private static <T> String ts(Iterable<T> iter) {
				StringBuilder ret = new StringBuilder();
				ret.append("{");
				boolean first = true;
				for(T t: iter) {
					if(!first) {
						ret.append(", ");
					}
					first = false;
					ret.append(ts(t));
				}
				ret.append("}");
				return ret.toString();
			}

			public static void dbg(Object... o) {
				if(LOCAL) {
					System.err.print("Line #"+Thread.currentThread().getStackTrace()[2].getLineNumber()+": [");
					for(int i = 0; i<o.length; i++) {
						if(i!=0) {
							System.err.print(", ");
						}
						System.err.print(ts(o[i]));
					}
					System.err.println("]");
				}
			}

		}

	}

	static class FastReader implements InputReader {
		final private int BUFFER_SIZE = 1<<16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer;
		private int bytesRead;

		public FastReader(InputStream is) {
			din = new DataInputStream(is);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public int nextInt() {
			int ret = 0;
			byte c = skipToDigit();
			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;
		}

		private boolean isDigit(byte b) {
			return b>='0'&&b<='9';
		}

		private byte skipToDigit() {
			byte ret;
			while(!isDigit(ret = read())&&ret!='-') ;
			return ret;
		}

		private void fillBuffer() {
			try {
				bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			}catch(IOException e) {
				e.printStackTrace();
				throw new InputMismatchException();
			}
			if(bytesRead==-1) {
				buffer[0] = -1;
			}
		}

		private byte read() {
			if(bytesRead==-1) {
				throw new InputMismatchException();
			}else if(bufferPointer==bytesRead) {
				fillBuffer();
			}
			return buffer[bufferPointer++];
		}

	}

	static interface InputReader {
		int nextInt();

		default ArrayList<Integer>[] nextUndirectedGraph(int n, int m) {
			ArrayList<Integer>[] ret = new ArrayList[n];
			for(int i = 0; i<n; i++) {
				ret[i] = new ArrayList<>();
			}
			for(int i = 0; i<m; i++) {
				int u = nextInt()-1, v = nextInt()-1;
				ret[u].add(v);
				ret[v].add(u);
			}
			return ret;
		}

	}
}


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

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

public class cf1387b1 {

    public static void main(String[] args) throws IOException {
        int n = ri(), dp[][] = new int[n][2];
        List<List<Integer>> g = rg(n, n - 1);
        Map<Integer, List<Integer>> comps = new HashMap<>();
        dfs(g, 0, -1, new int[n], comps);
        prln(2 * (n - comps.keySet().size()));
        int[] ans = new int[n];
        for (int k : comps.keySet()) {
            List<Integer> comp = comps.get(k), cycle = cycle(comp);
            int sz = comp.size();
            for (int i = 0; i < sz; ++i) {
                ans[comp.get(i)] = cycle.get(i) + 1;
            }
        }
        prln(ans);
        close();
    }

    static List<Integer> cycle(List<Integer> to_cycle) {
        int n = to_cycle.size();
        List<Integer> ans = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            ans.add(to_cycle.get((i + 1) % n));
        }
        return ans;
    }

    static void dfs(List<List<Integer>> g, int i, int p, int[] sz, Map<Integer, List<Integer>> comps) {
        sz[i] = 1;
        int last = -1;
        for (int j : g.get(i)) {
            if (j != p) {
                dfs(g, j, i, sz, comps);
                if (sz[j] == 1) {
                    if (!comps.containsKey(i)) {
                        comps.put(i, new ArrayList<>());
                        comps.get(i).add(i);
                    }
                    comps.get(i).add(j);
                    sz[i] += sz[j];
                } else {
                    last = j;
                }
            }
        }
        if (i == 0 && sz[i] == 1) {
            comps.put(i, comps.get(last));
            comps.remove(last);
            comps.get(i).add(i);
        }
    }

    /* static void dfs(List<List<Integer>> g, int i, int p, int[][] dp, List<List<Integer>> backtrack) {
        int min_connect = IBIG, min_connect_ind = -1, sum_unconnected = 0;
        for (int j : g.get(i)) {
            if (j != p) {
                dfs(g, j, i, dp, backtrack);
                if (dp[j][0] < min_connect) {
                    min_connect = dp[j][0];
                    min_connect_ind = j;
                }
                sum_unconnected = min(sum_unconnected + dp[j][1], IBIG);
            }
        }
        dp[i][1] += min_connect;
        backtrack.get(i).add(min_connect_ind);
        for (int j : g.get(i)) {
            if (j != p && j != min_connect_ind) {
                if (dp[j][0] < dp[j][1]) {
                    backtrack.get(i).add(j);
                }
                dp[i][1] += min(dp[j][0], dp[j][1]);
            }
        }
        if (dp[i][1] == IBIG) {
            dp[i][0] = 1;
        } else {
            if (sum_unconnected < dp[i][1]) {
                backtrack.get(i).clear();
            }
            dp[i][0] = min(sum_unconnected, dp[i][1]) + 1;
        }
    } */

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __rand = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if(x.length == 1) return x[0]; if(x.length == 2) return min(x[0], x[1]); if(x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if(x.length == 1) return x[0]; if(x.length == 2) return min(x[0], x[1]); if(x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if(x.length == 1) return x[0]; if(x.length == 2) return max(x[0], x[1]); if(x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if(x.length == 1) return x[0]; if(x.length == 2) return max(x[0], x[1]); if(x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if(a == 0) return 0; int ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if(a == 0) return 0; long ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int)d;}
    static int cei(double d) {return (int)ceil(d);}
    static long fll(double d) {return (long)d;}
    static long cel(double d) {return (long)ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int lcm(int a, int b) {return a * b / gcf(a, b);}
    static long lcm(long a, long b) {return a * b / gcf(a, b);}
    static int randInt(int min, int max) {return __rand.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for(int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for(int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for(int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // graph util
    static List<List<Integer>> g(int n) {List<List<Integer>> g = new ArrayList<>(); for(int i = 0; i < n; ++i) g.add(new ArrayList<>()); return g;}
    static List<Set<Integer>> sg(int n) {List<Set<Integer>> g = new ArrayList<>(); for(int i = 0; i < n; ++i) g.add(new HashSet<>()); return g;}
    static void c(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).add(v); g.get(v).add(u);}
    static void cto(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).add(v);}
    static void dc(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).remove(v); g.get(v).remove(u);}
    static void dcto(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).remove(v);}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for(int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for(int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for(int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    static List<List<Integer>> rg(int n, int m) throws IOException {List<List<Integer>> g = g(n); for(int i = 0; i < m; ++i) c(g, rni() - 1, ni() - 1); return g;}
    static void rg(List<List<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) c(g, rni() - 1, ni() - 1);}
    static List<List<Integer>> rdg(int n, int m) throws IOException {List<List<Integer>> g = g(n); for(int i = 0; i < m; ++i) cto(g, rni() - 1, ni() - 1); return g;}
    static void rdg(List<List<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) cto(g, rni() - 1, ni() - 1);}
    static List<Set<Integer>> rsg(int n, int m) throws IOException {List<Set<Integer>> g = sg(n); for(int i = 0; i < m; ++i) c(g, rni() - 1, ni() - 1); return g;}
    static void rsg(List<Set<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) c(g, rni() - 1, ni() - 1);}
    static List<Set<Integer>> rdsg(int n, int m) throws IOException {List<Set<Integer>> g = sg(n); for(int i = 0; i < m; ++i) cto(g, rni() - 1, ni() - 1); return g;}
    static void rdsg(List<Set<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) cto(g, rni() - 1, ni() - 1);}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {__out.println("yes");}
    static void pry() {__out.println("Yes");}
    static void prY() {__out.println("YES");}
    static void prno() {__out.println("no");}
    static void prn() {__out.println("No");}
    static void prN() {__out.println("NO");}
    static void pryesno(boolean b) {__out.println(b ? "yes" : "no");};
    static void pryn(boolean b) {__out.println(b ? "Yes" : "No");}
    static void prYN(boolean b) {__out.println(b ? "YES" : "NO");}
    static void prln(int... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static void prln(long... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static void prln(double... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for(int i = 0; i < n; __out.print(iter.next()), __out.print(' '), ++i); if(n >= 0) __out.println(iter.next()); else __out.println();}
    static void h() {__out.println("hlfd"); flush();}
    static void flush() {__out.flush();}
    static void close() {__out.close();}
}


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

public class G {
	int oo = (int)1e8;

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

	int SQRT;
	int[] minTandemStart, minTandemEnd, sa, rsa, lcp;
	boolean[] primes;
	RMQ query3RMQ, lcpRMQ;
	String str;

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

		doPrimes();

		int n = fs.nextInt();
		SQRT = (int)Math.sqrt(n);
		str = fs.next();
		FastSuffixArray fsa = new FastSuffixArray();
		sa = fsa.suffixArray(str.toCharArray());
		rsa = new int[sa.length];
		lcp = fsa.lcp(sa, str.toCharArray());
		lcpRMQ = new RMQ(lcp);
		for(int i = 0; i < sa.length; i++) rsa[sa[i]] = i;

		TandemRepeats tr = new TandemRepeats(str);
		minTandemStart = tr.min;
		TandemRepeats tr2 = new TandemRepeats(reverse(str));
		minTandemEnd = reverse(tr2.min);

//		System.out.println(Arrays.toString(minTandemStart));
//		System.out.println(Arrays.toString(minTandemEnd));
//		System.out.println();

		int[] query3Values = new int[n];
		for(int i = 0; i < n; i++) {
			query3Values[i] = i+2*minTandemStart[i];
		}
		query3RMQ = new RMQ(query3Values);

		int[][] pref = new int[26][n];
		for(int i = n-1; i >= 0; i--) {
			for(int j = 0; j < 26 && i+1 < n; j++) pref[j][i] = pref[j][i+1];
			pref[str.charAt(i)-'a'][i]++;
		}

		int Q = fs.nextInt();
		for(int qq = 1; qq <= Q; qq++) {
			int L = fs.nextInt()-1, R = fs.nextInt()-1;

			//case -1
			boolean good = false;
			for(int i = 0; i < 26; i++) {
				int sum = pref[i][L];
				if(R + 1 < n) sum -= pref[i][R+1];
				if(sum > 1) good = true;
			}
			if(!good) {
				out.println(-1);
				continue;
			}

			//case 1:
			boolean ans1 = false;
			int N = R-L+1;
			for(int div = 1; div * div <= N; div++) {
				if(N % div != 0) continue;
				if(!primes[N/div]) continue;

				if(check(L, R, div)) ans1 = true;
				else if(primes[div] && check(L, R, N/div)) ans1 = true;
				if(ans1) break;
			}
			if(ans1) {
				out.println(1);
				continue;
			}

			//case 2:
			boolean ans2 = false;
			if(minTandemStart[L] != oo && L+minTandemStart[L]*2-1 <= R) {
				ans2 = true;
			}
			if(minTandemEnd[R] != oo && R-minTandemEnd[R]*2+1 >= L) {
				ans2 = true;
			}
			if(isBorder(L, R)) {
				ans2 = true;
			}
			if(ans2) {
				out.println(2);
				continue;
			}

			//case 3:
			boolean ans3 = false;
			{ //first character
				int idx = str.charAt(L)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //last character
				int idx = str.charAt(R)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //BAAC
				int min = query3RMQ.query(L, R);
				if(min <= R) ans3 = true;
			}
			if(ans3) {
				out.println(3);
				continue;
			}

			out.println(4);
		}

		out.close();
	}

	boolean check(int L, int R, int div) {
		int minPos = rsa[L], maxPos = rsa[L];
		for(int j = L+div; j <= R; j += div) {
			minPos = Math.min(minPos, rsa[j]);
			maxPos = Math.max(maxPos, rsa[j]);
		}
		int lcp = lcpRMQ.query(minPos, maxPos-1);
		if(lcp >= div) {
			return true;
		}
		return false;
	}

	boolean isBorder(int L, int R) {
		for(int len = 1; len < SQRT; len++) {
			int ptsTo = R-len+1;
			if(ptsTo <= L+len-1) continue;
			int min = Math.min(rsa[L], rsa[ptsTo]);
			int max = Math.max(rsa[L], rsa[ptsTo]);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp >= len) {
				return true;
			}
		}
		int st = Math.max(0, rsa[L]-SQRT-1);
		int en = Math.min(sa.length-1, rsa[L]+SQRT+1);
		int him = rsa[L];

		for(int i = st; i <= en; i++) {
			int idx = sa[i];
			if(L <= idx && idx <= R) {}
			else continue;
			if(idx+SQRT-1 > R) continue;
			int min = Math.min(i, him);
			int max = Math.max(i, him);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp < SQRT) continue;
			int to = L + SQRT;
			if(to <= idx) {
				return true;
			}
		}

		return false;
	}

	class RMQ {
		int[] vs;
		int[][] lift;

		public RMQ(int[] vs) {
			this.vs = vs;
			int n = vs.length;
			int maxlog = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 2;
			lift = new int[maxlog][n];
			for (int i = 0; i < n; i++)
				lift[0][i] = vs[i];
			int lastRange = 1;
			for (int lg = 1; lg < maxlog; lg++) {
				for (int i = 0; i < n; i++) {
					lift[lg][i] = Math.min(lift[lg - 1][i], lift[lg - 1][Math.min(i + lastRange, n - 1)]);
				}
				lastRange *= 2;
			}
		}

		public int query(int low, int hi) {
			if(hi < low) return 0;
			int range = hi - low + 1;
			int exp = Integer.highestOneBit(range);
			int lg = Integer.numberOfTrailingZeros(exp);
			return Math.min(lift[lg][low], lift[lg][hi - exp + 1]);
		}
	}

	class FastSuffixArray {
		public int[] suffixArray(char[] S) {
			int n = S.length;
			Integer[] order = new Integer[n];
			for (int i = 0; i < n; i++)
				order[i] = n - 1 - i;

			Arrays.sort(order, (a, b) -> Character.compare(S[a], S[b]));

			int[] sa = new int[n];
			int[] classes = new int[n];
			for (int i = 0; i < n; i++) {
				sa[i] = order[i];
				classes[i] = S[i];
			}

			for (int len = 1; len < n; len *= 2) {
				int[] c = classes.clone();
				for (int i = 0; i < n; i++) {
					classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
				}
				int[] cnt = new int[n];
				for (int i = 0; i < n; i++)
					cnt[i] = i;
				int[] s = sa.clone();
				for (int i = 0; i < n; i++) {
					int s1 = s[i] - len;
					if (s1 >= 0)
						sa[cnt[classes[s1]]++] = s1;
				}
			}
			return sa;
		}

		public int[] lcp(int[] sa, char[] s) {
			int n = sa.length;
			int[] rank = new int[n];
			for (int i = 0; i < n; i++)
				rank[sa[i]] = i;
			int[] lcp = new int[n - 1];
			for (int i = 0, h = 0; i < n; i++) {
				if (rank[i] < n - 1) {
					for (int j = sa[rank[i] + 1]; Math.max(i, j) + h < s.length && s[i + h] == s[j + h]; ++h)
						;
					lcp[rank[i]] = h;
					if (h > 0)
						--h;
				}
			}
			return lcp;
		}
	}

	class TandemRepeats {
		int[] min;
		TandemRepeats(String str) {
			list = new ArrayList<>();
			findRepetitions(str, 0, str.length()-1);
			Collections.sort(list);
			min = new int[str.length()];
			Arrays.fill(min, oo);

			TreeMap<Integer, Integer> map = new TreeMap<>();
			int ptr = 0;
			for(int i = 0; i < str.length(); i++) {
				while(ptr < list.size()) {
					Event now = list.get(ptr);
					if(now.pos <= i) {
						if(now.type == 0) add(map, now.val);
						else rem(map, now.val);
						ptr++;
					} else break;
				}
				if(!map.isEmpty())
					min[i] = Math.min(min[i], map.firstKey());
			}
		}

		ArrayList<Event> list;
		//Main-Lorentz algorithm
		void findRepetitions(String str, int L, int R) {
			int n = R-L+1;
			if(n < 2 || R < L) return;

			String u = str.substring(0, n/2);
			String v = str.substring(n/2);
			findRepetitions(u, L, L+u.length()-1); findRepetitions(v, L+u.length(), R);

			int[] z1 = zValues(reverse(u));
			int[] z2 = zValues(v + "#" + u);
			int[] z3 = zValues(reverse(u) + "#" + reverse(v));
			int[] z4 = zValues(v);

			int uLen = u.length(), vLen = v.length();
			for(int cntr = 0; cntr < n; cntr++) {
				int totLen, k1, k2;
				if(cntr < uLen) {
					totLen = uLen-cntr;
					k1 = getIdx(z1, uLen-cntr);
					k2 = getIdx(z2, vLen+1+cntr);

					if(k1+k2 >= totLen) {
						int min = find(k1, k2, totLen, true, 0);
						int max = find(k1, k2, totLen, false, 0);
						int start = Math.max(L, L+cntr-max);
						int end = Math.min(L+cntr-1, L+cntr-min);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
				else {
					totLen = cntr-uLen+1;
					k1 = getIdx(z3, uLen + 1 + vLen - 1 - (cntr - uLen));
					k2 = getIdx(z4, (cntr - uLen) + 1);

					if(k1+k2 >= totLen) {
						int max = find(k1, k2, totLen, false, 1);
						int min = find(k1, k2, totLen, true, 1);
						int start = Math.max(L, L+n/2-1 - max + 1);
						int end = Math.min(L+n/2-1, L+n/2-1-min+1);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
			}

		}

		int find(int k1, int k2, int len, boolean small, int lim) {
			int lo = lim, hi = k1, res = 0;
			for(int bs = 0; bs < 50 && lo <= hi; bs++) {
				int mid = (lo+hi)/2;
				int v = len-mid;
				if(v < 0) { //too much
					hi = mid-1;
				}
				else if(v > k2) { //too little
					lo = mid+1;
				}
				else { //great
					res = mid;
					if(small) hi = mid-1;
					else lo = mid+1;
				}
			}
			return res;
		}

		class Event implements Comparable<Event> {
			int type, pos, val;
			Event(int t, int p, int v) {
				type = t; val = v;
				pos = p;
			}
			public int compareTo(Event e) {
				int comp = Integer.compare(pos, e.pos);
				if(comp == 0) comp = Integer.compare(e.type, type);
				return comp;
			}
			public String toString() {
				return String.format("Pos = %d Type = %d V = %d", pos, type, val);
			}
		}

		int getIdx(int[] a, int i) {
			if(i >= 0 && i < a.length) return a[i];
			return 0;
		}

		int[] zValues(String string) {
			int n = string.length();  char[] s = string.toCharArray();
			int[] z = new int[n];  z[0] = n;
			int L = 0, R = 0;
			int[] left = new int[n], right = new int[n];
			for(int i = 1; i < n; ++i) {
				if(i > R) {
					L = R = i;
					while(R < n && s[R-L] == s[R]) R++;
					z[i] = R - L;  R--;
				} else {
					int k = i-L;
					if(z[k] < R-i+1) z[i] = z[k];
					else {
						L = i;
						while(R < n && s[R-L] == s[R]) R++;
						z[i] = R - L;  R--;
					}
				}
				left[i] = L;  right[i] = R;
			}
			return z;
		}

		void add(TreeMap<Integer, Integer> map, int x) {
			map.put(x, map.getOrDefault(x, 0)+1);
		}
		void rem(TreeMap<Integer, Integer> map, int x) {
			int fr = map.get(x)-1;
			if(fr == 0) map.remove(x);
			else map.put(x, fr);
		}
	}

	void doPrimes() {
		primes = new boolean[200200];
		Arrays.fill(primes, true);
		primes[0] = primes[1] = false;
		for(int i = 2; i < primes.length; i++) {
			if(!primes[i]) continue;
			for(int j = i+i; j < primes.length; j += i) primes[j] = false;
		}
	}

	String reverse(String s) {
		return new StringBuilder(s).reverse().toString();
	}
	int[] reverse(int[] a) {
		int n = a.length;
		int[] res = new int[n];
		for(int i = 0, j = n-1; i < n; i++, j--) {
			res[i] = a[j];
		}
		return res;
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer("");
		}
		String next() {
			if(st.hasMoreTokens()) return st.nextToken();
			try { st = new StringTokenizer(br.readLine()); } catch (Exception e) {}
			return next();
		}
		int nextInt() {
			return Integer.parseInt(next());
		}
	}

}


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

public class G {
	int oo = (int)1e8;

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

	int SQRT;
	int[] minTandemStart, minTandemEnd, sa, rsa, lcp;
	boolean[] primes;
	RMQ query3RMQ, lcpRMQ;
	int[] trailingZeros, highestOneBit;
	String str;

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

		trailingZeros = new int[200200];
		highestOneBit = new int[200200];
		for(int i = 1; i < 200200; i++) {
			highestOneBit[i] = Integer.highestOneBit(i);
			trailingZeros[i] = Integer.numberOfTrailingZeros(highestOneBit[i]);
		}

		doPrimes();

		int n = fs.nextInt();
		SQRT = (int)Math.sqrt(n);
		str = fs.next();
		FastSuffixArray fsa = new FastSuffixArray();
		sa = fsa.suffixArray(str.toCharArray());
		rsa = new int[sa.length];
		lcp = fsa.lcp(sa, str.toCharArray());
		lcpRMQ = new RMQ(lcp);
		for(int i = 0; i < sa.length; i++) rsa[sa[i]] = i;

		TandemRepeats tr = new TandemRepeats(str);
		minTandemStart = tr.min;
		TandemRepeats tr2 = new TandemRepeats(reverse(str));
		minTandemEnd = reverse(tr2.min);

		int[] query3Values = new int[n];
		for(int i = 0; i < n; i++) {
			minTandemStart[i] <<= 1;
			minTandemEnd[i] <<= 1;
		}
		for(int i = 0; i < n; i++) {
			query3Values[i] = i+minTandemStart[i];
		}
		query3RMQ = new RMQ(query3Values);

		int[][] pref = new int[26][n];
		for(int i = n-1; i >= 0; i--) {
			for(int j = 0; j < 26 && i+1 < n; j++) pref[j][i] = pref[j][i+1];
			pref[str.charAt(i)-'a'][i]++;
		}

		int Q = fs.nextInt();
		for(int qq = 1; qq <= Q; qq++) {
			int L = fs.nextInt()-1, R = fs.nextInt()-1;

			//case -1
			boolean good = false;
			for(int i = 0; i < 26; i++) {
				int sum = pref[i][L];
				if(R + 1 < n) sum -= pref[i][R+1];
				if(sum > 1) good = true;
			}
			if(!good) {
				out.println(-1);
				continue;
			}

			//case 1:
			boolean ans1 = false;
			int N = R-L+1;
			for(int div = 1; div*div <= N; div++) {
				if(N % div != 0) continue;
				int nd = N/div;
				if(primes[nd] && check(L, R, div)) {
					ans1 = true;
				}
				if(!ans1 && primes[div] && check(L, R, nd)) ans1 = true;
				if(ans1) break;
			}
			if(ans1) {
				out.println(1);
				continue;
			}

			//case 2:
			boolean ans2 = false;
			if(minTandemStart[L] < oo && L+minTandemStart[L]-1 <= R) {
				ans2 = true;
			}
			if(minTandemEnd[R] < oo && R-minTandemEnd[R]+1 >= L) {
				ans2 = true;
			}
			if(!ans2 && isBorder(L, R)) {
				ans2 = true;
			}
			if(ans2) {
				out.println(2);
				continue;
			}

			//case 3:
			boolean ans3 = false;
			{ //first character
				int idx = str.charAt(L)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //last character
				int idx = str.charAt(R)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //BAAC
				int min = query3RMQ.query(L, R);
				if(min <= R) ans3 = true;
			}
			if(ans3) {
				out.println(3);
				continue;
			}

			out.println(4);
		}

		out.close();
	}

	boolean check(int L, int R, int div) {
		int minPos = rsa[L], maxPos = rsa[L];
		char beg = str.charAt(L);
		for(int j = L+div; j <= R; j += div) {
			if(str.charAt(j) != beg) return false;
			minPos = min(minPos, rsa[j]);
			maxPos = max(maxPos, rsa[j]);
		}
		int lcp = lcpRMQ.query(minPos, maxPos-1);
		if(lcp >= div) {
			return true;
		}
		return false;
	}

	Random rand = new Random();
	boolean isBorder(int L, int R) {
		for(int len = 1; len < SQRT; len++) {
			int ptsTo = R-len+1;
			if(ptsTo <= L+len-1) continue;
			int min = min(rsa[L], rsa[ptsTo]);
			int max = max(rsa[L], rsa[ptsTo]);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp >= len) {
				return true;
			}
		}
		int st = max(0, rsa[L]-SQRT/2-1);
		int en = min(sa.length-1, rsa[L]+SQRT/2+1);
		int him = rsa[L];

		for(int i = him-1; i >= st; i--) {
			int idx = sa[i];
			if(L <= idx && idx <= R) {}
			else continue;
			int min = min(i, him);
			int max = max(i, him);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp < SQRT) break;

			if(idx+lcp-1 < R) continue;
			int size = R-idx+1;
			if(L+size-1 >= idx) continue;
			return true;
		}
		for(int i = him+1; i <= en; i++) {
			int idx = sa[i];
			if(L <= idx && idx <= R) {}
			else continue;
			int min = min(i, him);
			int max = max(i, him);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp < SQRT) break;

			if(idx+lcp-1 < R) continue;
			int size = R-idx+1;
			if(L+size-1 >= idx) continue;
			return true;
		}

		return false;
	}

	class RMQ {
		int[] vs;
		int[][] lift;

		public RMQ(int[] vs) {
			this.vs = vs;
			int n = vs.length;
			int maxlog = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 1;
			lift = new int[maxlog][n];
			for (int i = 0; i < n; i++)
				lift[0][i] = vs[i];
			int lastRange = 1;
			for (int lg = 1; lg < maxlog; lg++) {
				for (int i = 0; i < n; i++) {
					lift[lg][i] = min(lift[lg - 1][i], lift[lg - 1][min(i + lastRange, n - 1)]);
				}
				lastRange <<= 1;
			}
		}

		public int query(int low, int hi) {
			if(hi < low) return 0;
			int range = hi - low + 1;
			int exp = highestOneBit[range];
			int lg = trailingZeros[exp];
			return min(lift[lg][low], lift[lg][hi - exp + 1]);
		}
	}

	class FastSuffixArray {
		public int[] suffixArray(char[] S) {
			int n = S.length;
			Integer[] order = new Integer[n];
			for (int i = 0; i < n; i++)
				order[i] = n - 1 - i;

			Arrays.sort(order, (a, b) -> Character.compare(S[a], S[b]));

			int[] sa = new int[n];
			int[] classes = new int[n];
			for (int i = 0; i < n; i++) {
				sa[i] = order[i];
				classes[i] = S[i];
			}

			for (int len = 1; len < n; len <<= 1) {
				int[] c = classes.clone();
				for (int i = 0; i < n; i++) {
					classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
				}
				int[] cnt = new int[n];
				for (int i = 0; i < n; i++)
					cnt[i] = i;
				int[] s = sa.clone();
				for (int i = 0; i < n; i++) {
					int s1 = s[i] - len;
					if (s1 >= 0)
						sa[cnt[classes[s1]]++] = s1;
				}
			}
			return sa;
		}

		public int[] lcp(int[] sa, char[] s) {
			int n = sa.length;
			int[] rank = new int[n];
			for (int i = 0; i < n; i++)
				rank[sa[i]] = i;
			int[] lcp = new int[n - 1];
			for (int i = 0, h = 0; i < n; i++) {
				if (rank[i] < n - 1) {
					for (int j = sa[rank[i] + 1]; max(i, j) + h < s.length && s[i + h] == s[j + h]; ++h)
						;
					lcp[rank[i]] = h;
					if (h > 0)
						--h;
				}
			}
			return lcp;
		}
	}

	int MAX = 7500000;
	class TandemRepeats {
		Event[] list = new Event[MAX];
		int ptr2 = 0;
		int[] min;
		TandemRepeats(String str) {
			ptr2 = 0;
			findRepetitions(str, 0, str.length()-1);
			Arrays.sort(list, 0, ptr2);
			min = new int[str.length()];
			Arrays.fill(min, oo);

			int n = str.length();
			BIT bit = new BIT(n+1);
			int ptr = 0;
			for(int i = 0; i < str.length(); i++) {
				while(ptr < ptr2) {
					Event now = list[ptr];
					if(now.pos <= i) {
						if(now.type == 0) bit.update(now.val, 1);
						else bit.update(now.val, -1);
						ptr++;
					} else break;
				}
				int pos = bit.getKth(0);
				if(pos <= n) min[i] = min(min[i], pos);
			}
		}

		//Main-Lorentz algorithm
		void findRepetitions(String str, int L, int R) {
			int n = R-L+1;
			if(n < 2 || R < L) return;

			String u = str.substring(0, n/2);
			String v = str.substring(n/2);
			findRepetitions(u, L, L+u.length()-1); findRepetitions(v, L+u.length(), R);

			int[] z1 = zValues(reverse(u));
			int[] z2 = zValues(v + "#" + u);
			int[] z3 = zValues(reverse(u) + "#" + reverse(v));
			int[] z4 = zValues(v);

			int uLen = u.length(), vLen = v.length();
			for(int cntr = 0; cntr < n; cntr++) {
				int totLen, k1, k2;
				if(cntr < uLen) {
					totLen = uLen-cntr;
					k1 = getIdx(z1, uLen-cntr);
					k2 = getIdx(z2, vLen+1+cntr);

					if(k1+k2 >= totLen) {
						int min = findSmall1(k1, k2, totLen);
						int max = findLarge1(k1, k2, totLen);
						if(min < 0 || max < 0 || min > k1 || max > k1) continue;
						int start = max(L, L+cntr-max);
						int end = min(L+cntr-1, L+cntr-min);

						if(start <= end) {
							list[ptr2++] = (new Event(0, start, totLen));
							list[ptr2++] = (new Event(1, end+1, totLen));
						}
					}

				}
				else {
					totLen = cntr-uLen+1;
					k1 = getIdx(z3, uLen + 1 + vLen - 1 - (cntr - uLen));
					k2 = getIdx(z4, (cntr - uLen) + 1);

					if(k1+k2 >= totLen && k1 > 0) {
						int min = findSmall2(k1, k2, totLen);
						int max = findLarge1(k1, k2, totLen);
						if(min < 1 || max < 1 || min > k1 || max > k1) continue;
						int start = max(L, L+n/2-1 - max + 1);
						int end = min(L+n/2-1, L+n/2-1-min+1);

						if(start <= end) {
							list[ptr2++] = (new Event(0, start, totLen));
							list[ptr2++] = (new Event(1, end+1, totLen));
						}
					}
				}
			}

		}

		int findSmall1(int k1, int k2, int len) {
			if(k2 >= len) return 0;
			return len-k2;
		}
		int findSmall2(int k1, int k2, int len) {
			if(k2 >= len-1) return 1;
			return min(k1, len - k2);
		}
		int findLarge1(int k1, int k2, int len) {
			if(k1 < len) return k1;
			return len;
		}

		class Event implements Comparable<Event> {
			int type, pos, val;
			Event(int t, int p, int v) {
				type = t; val = v;
				pos = p;
			}
			public int compareTo(Event e) {
				int comp = Integer.compare(pos, e.pos);
				if(comp == 0) comp = Integer.compare(e.type, type);
				return comp;
			}
			public String toString() {
				return String.format("Pos = %d Type = %d V = %d", pos, type, val);
			}
		}

		int getIdx(int[] a, int i) {
			if(i >= 0 && i < a.length) return a[i];
			return 0;
		}

		int[] zValues(String str) {
			int n = str.length();  char[] s = str.toCharArray();
			int[] z = new int[n];  z[0] = n;
			int L = 0, R = 0;
			int[] left = new int[n], right = new int[n];
			for(int i = 1; i < n; ++i) {
				if(i > R) {
					L = R = i;
					while(R < n && s[R-L] == s[R]) R++;
					z[i] = R - L;  R--;
				} else {
					int k = i-L;
					if(z[k] < R-i+1) z[i] = z[k];
					else {
						L = i;
						while(R < n && s[R-L] == s[R]) R++;
						z[i] = R - L;  R--;
					}
				}
				left[i] = L;  right[i] = R;
			}
			return z;
		}

		void add(TreeMap<Integer, Integer> map, int x) {
			map.put(x, map.getOrDefault(x, 0)+1);
		}
		void rem(TreeMap<Integer, Integer> map, int x) {
			int fr = map.get(x)-1;
			if(fr == 0) map.remove(x);
			else map.put(x, fr);
		}
	}

	void doPrimes() {
		primes = new boolean[200200];
		Arrays.fill(primes, true);
		primes[0] = primes[1] = false;
		for(int i = 2; i < primes.length; i++) {
			if(!primes[i]) continue;
			for(int j = i+i; j < primes.length; j += i) primes[j] = false;
		}
	}

	String reverse(String s) {
		return new StringBuilder(s).reverse().toString();
	}
	int[] reverse(int[] a) {
		int n = a.length;
		int[] res = new int[n];
		for(int i = 0, j = n-1; i < n; i++, j--) {
			res[i] = a[j];
		}
		return res;
	}

	int min(int a, int b) {
		return a < b ? a : b;
	}
	int max(int a, int b) {
		return a > b ? a : b;
	}

	class BIT {
		int n, hn;
		int[] tree;

		public BIT(int n) {
			this.n = n;
			tree = new int[n + 2];
			hn = Integer.highestOneBit(n);
		}

		int read(int i) {
			i++;
			int sum = 0;
			while (i > 0) {
				sum += tree[i];
				i -= i & -i;
			}
			return sum;
		}

		void update(int i, int val) {
			i++;
			while (i <= n) {
				tree[i] += val;
				i += i & -i;
			}
		}

		// if the BIT is a freq array, returns the
		// index of the kth item, or n if there are fewer
		// than k items.
		int getKth(int k) {
			int e=hn, o=0;
			for (; e!=0; e>>=1) {
				if (e+o<=n && tree[e+o]<=k) {
					k-=tree[e+o];
					o+=e;
				}
			}
			return o;
		}

	}

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

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

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

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

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

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

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

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

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

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

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

	}

}


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

public class G {
	int oo = (int)1e8;

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

	int SQRT;
	int[] minTandemStart, minTandemEnd, sa, rsa, lcp;
	boolean[] primes;
	RMQ query3RMQ, lcpRMQ;
	String str;

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

		doPrimes();

		int n = fs.nextInt();
		SQRT = (int)Math.sqrt(n);
		str = fs.next();
		FastSuffixArray fsa = new FastSuffixArray();
		sa = fsa.suffixArray(str.toCharArray());
		rsa = new int[sa.length];
		lcp = fsa.lcp(sa, str.toCharArray());
		lcpRMQ = new RMQ(lcp);
		for(int i = 0; i < sa.length; i++) rsa[sa[i]] = i;

		TandemRepeats tr = new TandemRepeats(str);
		minTandemStart = tr.min;
		TandemRepeats tr2 = new TandemRepeats(reverse(str));
		minTandemEnd = reverse(tr2.min);

//		System.out.println(Arrays.toString(minTandemStart));
//		System.out.println(Arrays.toString(minTandemEnd));
//		System.out.println();

		int[] query3Values = new int[n];
		for(int i = 0; i < n; i++) {
			query3Values[i] = i+2*minTandemStart[i];
		}
		query3RMQ = new RMQ(query3Values);

		int[][] pref = new int[26][n];
		for(int i = n-1; i >= 0; i--) {
			for(int j = 0; j < 26 && i+1 < n; j++) pref[j][i] = pref[j][i+1];
			pref[str.charAt(i)-'a'][i]++;
		}

		int Q = fs.nextInt();
		for(int qq = 1; qq <= Q; qq++) {
			int L = fs.nextInt()-1, R = fs.nextInt()-1;

			//case -1
			boolean good = false;
			for(int i = 0; i < 26; i++) {
				int sum = pref[i][L];
				if(R + 1 < n) sum -= pref[i][R+1];
				if(sum > 1) good = true;
			}
			if(!good) {
				out.println(-1);
				continue;
			}

			//case 1:
			boolean ans1 = false;
			int N = R-L+1;
			for(int div = 1; div * div <= N; div++) {
				if(N % div != 0) continue;
				if(primes[N/div] && check(L, R, div)) {
					ans1 = true;
				}
				if(!ans1 && primes[div] && check(L, R, N/div)) ans1 = true;
				if(ans1) break;
			}
			if(ans1) {
				out.println(1);
				continue;
			}

			//case 2:
			boolean ans2 = false;
			if(minTandemStart[L] != oo && L+minTandemStart[L]*2-1 <= R) {
				ans2 = true;
			}
			if(minTandemEnd[R] != oo && R-minTandemEnd[R]*2+1 >= L) {
				ans2 = true;
			}
			if(isBorder(L, R)) {
				ans2 = true;
			}
			if(ans2) {
				out.println(2);
				continue;
			}

			//case 3:
			boolean ans3 = false;
			{ //first character
				int idx = str.charAt(L)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //last character
				int idx = str.charAt(R)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //BAAC
				int min = query3RMQ.query(L, R);
				if(min <= R) ans3 = true;
			}
			if(ans3) {
				out.println(3);
				continue;
			}

			out.println(4);
		}

		out.close();
	}

	boolean check(int L, int R, int div) {
		int minPos = rsa[L], maxPos = rsa[L];
		for(int j = L+div; j <= R; j += div) {
			minPos = Math.min(minPos, rsa[j]);
			maxPos = Math.max(maxPos, rsa[j]);
		}
		int lcp = lcpRMQ.query(minPos, maxPos-1);
		if(lcp >= div) {
			return true;
		}
		return false;
	}

	boolean isBorder(int L, int R) {
		for(int len = 1; len < SQRT; len++) {
			int ptsTo = R-len+1;
			if(ptsTo <= L+len-1) continue;
			int min = Math.min(rsa[L], rsa[ptsTo]);
			int max = Math.max(rsa[L], rsa[ptsTo]);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp >= len) {
				return true;
			}
		}
		int st = Math.max(0, rsa[L]-SQRT-1);
		int en = Math.min(sa.length-1, rsa[L]+SQRT+1);
		int him = rsa[L];

		for(int i = st; i <= en; i++) {
			int idx = sa[i];
			if(L <= idx && idx <= R) {}
			else continue;
			int min = Math.min(i, him);
			int max = Math.max(i, him);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp < SQRT) continue;

			if(idx+lcp-1 < R) continue;
			int size = R-idx+1;
			if(L+size-1 >= idx) continue;
			return true;
		}

		return false;
	}

	class RMQ {
		int[] vs;
		int[][] lift;

		public RMQ(int[] vs) {
			this.vs = vs;
			int n = vs.length;
			int maxlog = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 2;
			lift = new int[maxlog][n];
			for (int i = 0; i < n; i++)
				lift[0][i] = vs[i];
			int lastRange = 1;
			for (int lg = 1; lg < maxlog; lg++) {
				for (int i = 0; i < n; i++) {
					lift[lg][i] = Math.min(lift[lg - 1][i], lift[lg - 1][Math.min(i + lastRange, n - 1)]);
				}
				lastRange *= 2;
			}
		}

		public int query(int low, int hi) {
			if(hi < low) return 0;
			int range = hi - low + 1;
			int exp = Integer.highestOneBit(range);
			int lg = Integer.numberOfTrailingZeros(exp);
			return Math.min(lift[lg][low], lift[lg][hi - exp + 1]);
		}
	}

	class FastSuffixArray {
		public int[] suffixArray(char[] S) {
			int n = S.length;
			Integer[] order = new Integer[n];
			for (int i = 0; i < n; i++)
				order[i] = n - 1 - i;

			Arrays.sort(order, (a, b) -> Character.compare(S[a], S[b]));

			int[] sa = new int[n];
			int[] classes = new int[n];
			for (int i = 0; i < n; i++) {
				sa[i] = order[i];
				classes[i] = S[i];
			}

			for (int len = 1; len < n; len *= 2) {
				int[] c = classes.clone();
				for (int i = 0; i < n; i++) {
					classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
				}
				int[] cnt = new int[n];
				for (int i = 0; i < n; i++)
					cnt[i] = i;
				int[] s = sa.clone();
				for (int i = 0; i < n; i++) {
					int s1 = s[i] - len;
					if (s1 >= 0)
						sa[cnt[classes[s1]]++] = s1;
				}
			}
			return sa;
		}

		public int[] lcp(int[] sa, char[] s) {
			int n = sa.length;
			int[] rank = new int[n];
			for (int i = 0; i < n; i++)
				rank[sa[i]] = i;
			int[] lcp = new int[n - 1];
			for (int i = 0, h = 0; i < n; i++) {
				if (rank[i] < n - 1) {
					for (int j = sa[rank[i] + 1]; Math.max(i, j) + h < s.length && s[i + h] == s[j + h]; ++h)
						;
					lcp[rank[i]] = h;
					if (h > 0)
						--h;
				}
			}
			return lcp;
		}
	}

	class TandemRepeats {
		int[] min;
		TandemRepeats(String str) {
			list = new ArrayList<>();
			findRepetitions(str, 0, str.length()-1);
			Collections.sort(list);
			min = new int[str.length()];
			Arrays.fill(min, oo);

			TreeMap<Integer, Integer> map = new TreeMap<>();
			int ptr = 0;
			for(int i = 0; i < str.length(); i++) {
				while(ptr < list.size()) {
					Event now = list.get(ptr);
					if(now.pos <= i) {
						if(now.type == 0) add(map, now.val);
						else rem(map, now.val);
						ptr++;
					} else break;
				}
				if(!map.isEmpty())
					min[i] = Math.min(min[i], map.firstKey());
			}
		}

		ArrayList<Event> list;
		//Main-Lorentz algorithm
		void findRepetitions(String str, int L, int R) {
			int n = R-L+1;
			if(n < 2 || R < L) return;

			String u = str.substring(0, n/2);
			String v = str.substring(n/2);
			findRepetitions(u, L, L+u.length()-1); findRepetitions(v, L+u.length(), R);

			int[] z1 = zValues(reverse(u));
			int[] z2 = zValues(v + "#" + u);
			int[] z3 = zValues(reverse(u) + "#" + reverse(v));
			int[] z4 = zValues(v);

			int uLen = u.length(), vLen = v.length();
			for(int cntr = 0; cntr < n; cntr++) {
				int totLen, k1, k2;
				if(cntr < uLen) {
					totLen = uLen-cntr;
					k1 = getIdx(z1, uLen-cntr);
					k2 = getIdx(z2, vLen+1+cntr);

					if(k1+k2 >= totLen) {
						int min = find(k1, k2, totLen, true, 0);
						int max = find(k1, k2, totLen, false, 0);
						int start = Math.max(L, L+cntr-max);
						int end = Math.min(L+cntr-1, L+cntr-min);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
				else {
					totLen = cntr-uLen+1;
					k1 = getIdx(z3, uLen + 1 + vLen - 1 - (cntr - uLen));
					k2 = getIdx(z4, (cntr - uLen) + 1);

					if(k1+k2 >= totLen) {
						int max = find(k1, k2, totLen, false, 1);
						int min = find(k1, k2, totLen, true, 1);
						int start = Math.max(L, L+n/2-1 - max + 1);
						int end = Math.min(L+n/2-1, L+n/2-1-min+1);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
			}

		}

		int find(int k1, int k2, int len, boolean small, int lim) {
			int lo = lim, hi = k1, res = 0;
			for(int bs = 0; bs < 50 && lo <= hi; bs++) {
				int mid = (lo+hi)/2;
				int v = len-mid;
				if(v < 0) { //too much
					hi = mid-1;
				}
				else if(v > k2) { //too little
					lo = mid+1;
				}
				else { //great
					res = mid;
					if(small) hi = mid-1;
					else lo = mid+1;
				}
			}
			return res;
		}

		class Event implements Comparable<Event> {
			int type, pos, val;
			Event(int t, int p, int v) {
				type = t; val = v;
				pos = p;
			}
			public int compareTo(Event e) {
				int comp = Integer.compare(pos, e.pos);
				if(comp == 0) comp = Integer.compare(e.type, type);
				return comp;
			}
			public String toString() {
				return String.format("Pos = %d Type = %d V = %d", pos, type, val);
			}
		}

		int getIdx(int[] a, int i) {
			if(i >= 0 && i < a.length) return a[i];
			return 0;
		}

		int[] zValues(String string) {
			int n = string.length();  char[] s = string.toCharArray();
			int[] z = new int[n];  z[0] = n;
			int L = 0, R = 0;
			int[] left = new int[n], right = new int[n];
			for(int i = 1; i < n; ++i) {
				if(i > R) {
					L = R = i;
					while(R < n && s[R-L] == s[R]) R++;
					z[i] = R - L;  R--;
				} else {
					int k = i-L;
					if(z[k] < R-i+1) z[i] = z[k];
					else {
						L = i;
						while(R < n && s[R-L] == s[R]) R++;
						z[i] = R - L;  R--;
					}
				}
				left[i] = L;  right[i] = R;
			}
			return z;
		}

		void add(TreeMap<Integer, Integer> map, int x) {
			map.put(x, map.getOrDefault(x, 0)+1);
		}
		void rem(TreeMap<Integer, Integer> map, int x) {
			int fr = map.get(x)-1;
			if(fr == 0) map.remove(x);
			else map.put(x, fr);
		}
	}

	void doPrimes() {
		primes = new boolean[200200];
		Arrays.fill(primes, true);
		primes[0] = primes[1] = false;
		for(int i = 2; i < primes.length; i++) {
			if(!primes[i]) continue;
			for(int j = i+i; j < primes.length; j += i) primes[j] = false;
		}
	}

	String reverse(String s) {
		return new StringBuilder(s).reverse().toString();
	}
	int[] reverse(int[] a) {
		int n = a.length;
		int[] res = new int[n];
		for(int i = 0, j = n-1; i < n; i++, j--) {
			res[i] = a[j];
		}
		return res;
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer("");
		}
		String next() {
			if(st.hasMoreTokens()) return st.nextToken();
			try { st = new StringTokenizer(br.readLine()); } catch (Exception e) {}
			return next();
		}
		int nextInt() {
			return Integer.parseInt(next());
		}
	}

}


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

public class G {
	int oo = (int)1e8;

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

	int SQRT;
	int[] minTandemStart, minTandemEnd, sa, rsa, lcp;
	boolean[] primes;
	RMQ query3RMQ, lcpRMQ;
	String str;

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

		doPrimes();

		int n = fs.nextInt();
		SQRT = (int)Math.sqrt(n);
		str = fs.next();
		FastSuffixArray fsa = new FastSuffixArray();
		sa = fsa.suffixArray(str.toCharArray());
		rsa = new int[sa.length];
		lcp = fsa.lcp(sa, str.toCharArray());
		lcpRMQ = new RMQ(lcp);
		for(int i = 0; i < sa.length; i++) rsa[sa[i]] = i;

		TandemRepeats tr = new TandemRepeats(str);
		minTandemStart = tr.min;
		TandemRepeats tr2 = new TandemRepeats(reverse(str));
		minTandemEnd = reverse(tr2.min);

//		System.out.println(Arrays.toString(minTandemStart));
//		System.out.println(Arrays.toString(minTandemEnd));
//		System.out.println();

		int[] query3Values = new int[n];
		for(int i = 0; i < n; i++) {
			query3Values[i] = i+2*minTandemStart[i];
		}
		query3RMQ = new RMQ(query3Values);

		int[][] pref = new int[26][n];
		for(int i = n-1; i >= 0; i--) {
			for(int j = 0; j < 26 && i+1 < n; j++) pref[j][i] = pref[j][i+1];
			pref[str.charAt(i)-'a'][i]++;
		}

		int Q = fs.nextInt();
		for(int qq = 1; qq <= Q; qq++) {
			int L = fs.nextInt()-1, R = fs.nextInt()-1;

			//case -1
			boolean good = false;
			for(int i = 0; i < 26; i++) {
				int sum = pref[i][L];
				if(R + 1 < n) sum -= pref[i][R+1];
				if(sum > 1) good = true;
			}
			if(!good) {
				out.println(-1);
				continue;
			}

			//case 1:
			boolean ans1 = false;
			int N = R-L+1;
			for(int div = 1; div * div <= N; div++) {
				if(N % div != 0) continue;
				if(!primes[N/div]) continue;

				if(check(L, R, div)) ans1 = true;
				else if(primes[div] && check(L, R, N/div)) ans1 = true;
				if(ans1) break;
			}
			if(ans1) {
				out.println(1);
				continue;
			}

			//case 2:
			boolean ans2 = false;
			if(minTandemStart[L] != oo && L+minTandemStart[L]*2-1 <= R) {
				ans2 = true;
			}
			if(minTandemEnd[R] != oo && R-minTandemEnd[R]*2+1 >= L) {
				ans2 = true;
			}
			if(isBorder(L, R)) {
				ans2 = true;
			}
			if(ans2) {
				out.println(2);
				continue;
			}

			//case 3:
			boolean ans3 = false;
			{ //first character
				int idx = str.charAt(L)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //last character
				int idx = str.charAt(R)-'a';
				int sum = pref[idx][L];
				if(R+1 < n) sum -= pref[idx][R+1];
				if(sum > 1) ans3 = true;
			}
			{ //BAAC
				int min = query3RMQ.query(L, R);
				if(min <= R) ans3 = true;
			}
			if(ans3) {
				out.println(3);
				continue;
			}

			out.println(4);
		}

		out.close();
	}

	boolean check(int L, int R, int div) {
		int minPos = rsa[L], maxPos = rsa[L];
		for(int j = L+div; j <= R; j += div) {
			minPos = Math.min(minPos, rsa[j]);
			maxPos = Math.max(maxPos, rsa[j]);
		}
		int lcp = lcpRMQ.query(minPos, maxPos-1);
		if(lcp >= div) {
			return true;
		}
		return false;
	}

	boolean isBorder(int L, int R) {
		for(int len = 1; len < SQRT; len++) {
			int ptsTo = R-len+1;
			if(ptsTo <= L+len-1) continue;
			int min = Math.min(rsa[L], rsa[ptsTo]);
			int max = Math.max(rsa[L], rsa[ptsTo]);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp >= len) {
				return true;
			}
		}
		int st = Math.max(0, rsa[L]-SQRT-1);
		int en = Math.min(sa.length-1, rsa[L]+SQRT+1);
		int him = rsa[L];

		for(int i = st; i <= en; i++) {
			int idx = sa[i];
			if(L <= idx && idx <= R) {}
			else continue;
			if(idx+SQRT-1 > R) continue;
			int min = Math.min(i, him);
			int max = Math.max(i, him);
			int lcp = lcpRMQ.query(min, max-1);
			if(lcp < SQRT) continue;
			int to = L + SQRT-1;
			if(to <= idx) {
				return true;
			}
		}

		return false;
	}

	class RMQ {
		int[] vs;
		int[][] lift;

		public RMQ(int[] vs) {
			this.vs = vs;
			int n = vs.length;
			int maxlog = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 2;
			lift = new int[maxlog][n];
			for (int i = 0; i < n; i++)
				lift[0][i] = vs[i];
			int lastRange = 1;
			for (int lg = 1; lg < maxlog; lg++) {
				for (int i = 0; i < n; i++) {
					lift[lg][i] = Math.min(lift[lg - 1][i], lift[lg - 1][Math.min(i + lastRange, n - 1)]);
				}
				lastRange *= 2;
			}
		}

		public int query(int low, int hi) {
			if(hi < low) return 0;
			int range = hi - low + 1;
			int exp = Integer.highestOneBit(range);
			int lg = Integer.numberOfTrailingZeros(exp);
			return Math.min(lift[lg][low], lift[lg][hi - exp + 1]);
		}
	}

	class FastSuffixArray {
		public int[] suffixArray(char[] S) {
			int n = S.length;
			Integer[] order = new Integer[n];
			for (int i = 0; i < n; i++)
				order[i] = n - 1 - i;

			Arrays.sort(order, (a, b) -> Character.compare(S[a], S[b]));

			int[] sa = new int[n];
			int[] classes = new int[n];
			for (int i = 0; i < n; i++) {
				sa[i] = order[i];
				classes[i] = S[i];
			}

			for (int len = 1; len < n; len *= 2) {
				int[] c = classes.clone();
				for (int i = 0; i < n; i++) {
					classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
				}
				int[] cnt = new int[n];
				for (int i = 0; i < n; i++)
					cnt[i] = i;
				int[] s = sa.clone();
				for (int i = 0; i < n; i++) {
					int s1 = s[i] - len;
					if (s1 >= 0)
						sa[cnt[classes[s1]]++] = s1;
				}
			}
			return sa;
		}

		public int[] lcp(int[] sa, char[] s) {
			int n = sa.length;
			int[] rank = new int[n];
			for (int i = 0; i < n; i++)
				rank[sa[i]] = i;
			int[] lcp = new int[n - 1];
			for (int i = 0, h = 0; i < n; i++) {
				if (rank[i] < n - 1) {
					for (int j = sa[rank[i] + 1]; Math.max(i, j) + h < s.length && s[i + h] == s[j + h]; ++h)
						;
					lcp[rank[i]] = h;
					if (h > 0)
						--h;
				}
			}
			return lcp;
		}
	}

	class TandemRepeats {
		int[] min;
		TandemRepeats(String str) {
			list = new ArrayList<>();
			findRepetitions(str, 0, str.length()-1);
			Collections.sort(list);
			min = new int[str.length()];
			Arrays.fill(min, oo);

			TreeMap<Integer, Integer> map = new TreeMap<>();
			int ptr = 0;
			for(int i = 0; i < str.length(); i++) {
				while(ptr < list.size()) {
					Event now = list.get(ptr);
					if(now.pos <= i) {
						if(now.type == 0) add(map, now.val);
						else rem(map, now.val);
						ptr++;
					} else break;
				}
				if(!map.isEmpty())
					min[i] = Math.min(min[i], map.firstKey());
			}
		}

		ArrayList<Event> list;
		//Main-Lorentz algorithm
		void findRepetitions(String str, int L, int R) {
			int n = R-L+1;
			if(n < 2 || R < L) return;

			String u = str.substring(0, n/2);
			String v = str.substring(n/2);
			findRepetitions(u, L, L+u.length()-1); findRepetitions(v, L+u.length(), R);

			int[] z1 = zValues(reverse(u));
			int[] z2 = zValues(v + "#" + u);
			int[] z3 = zValues(reverse(u) + "#" + reverse(v));
			int[] z4 = zValues(v);

			int uLen = u.length(), vLen = v.length();
			for(int cntr = 0; cntr < n; cntr++) {
				int totLen, k1, k2;
				if(cntr < uLen) {
					totLen = uLen-cntr;
					k1 = getIdx(z1, uLen-cntr);
					k2 = getIdx(z2, vLen+1+cntr);

					if(k1+k2 >= totLen) {
						int min = find(k1, k2, totLen, true, 0);
						int max = find(k1, k2, totLen, false, 0);
						int start = Math.max(L, L+cntr-max);
						int end = Math.min(L+cntr-1, L+cntr-min);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
				else {
					totLen = cntr-uLen+1;
					k1 = getIdx(z3, uLen + 1 + vLen - 1 - (cntr - uLen));
					k2 = getIdx(z4, (cntr - uLen) + 1);

					if(k1+k2 >= totLen) {
						int max = find(k1, k2, totLen, false, 1);
						int min = find(k1, k2, totLen, true, 1);
						int start = Math.max(L, L+n/2-1 - max + 1);
						int end = Math.min(L+n/2-1, L+n/2-1-min+1);

						if(start <= end) {
							list.add(new Event(0, start, totLen));
							list.add(new Event(1, end+1, totLen));
						}
					}

				}
			}

		}

		int find(int k1, int k2, int len, boolean small, int lim) {
			int lo = lim, hi = k1, res = 0;
			for(int bs = 0; bs < 50 && lo <= hi; bs++) {
				int mid = (lo+hi)/2;
				int v = len-mid;
				if(v < 0) { //too much
					hi = mid-1;
				}
				else if(v > k2) { //too little
					lo = mid+1;
				}
				else { //great
					res = mid;
					if(small) hi = mid-1;
					else lo = mid+1;
				}
			}
			return res;
		}

		class Event implements Comparable<Event> {
			int type, pos, val;
			Event(int t, int p, int v) {
				type = t; val = v;
				pos = p;
			}
			public int compareTo(Event e) {
				int comp = Integer.compare(pos, e.pos);
				if(comp == 0) comp = Integer.compare(e.type, type);
				return comp;
			}
			public String toString() {
				return String.format("Pos = %d Type = %d V = %d", pos, type, val);
			}
		}

		int getIdx(int[] a, int i) {
			if(i >= 0 && i < a.length) return a[i];
			return 0;
		}

		int[] zValues(String string) {
			int n = string.length();  char[] s = string.toCharArray();
			int[] z = new int[n];  z[0] = n;
			int L = 0, R = 0;
			int[] left = new int[n], right = new int[n];
			for(int i = 1; i < n; ++i) {
				if(i > R) {
					L = R = i;
					while(R < n && s[R-L] == s[R]) R++;
					z[i] = R - L;  R--;
				} else {
					int k = i-L;
					if(z[k] < R-i+1) z[i] = z[k];
					else {
						L = i;
						while(R < n && s[R-L] == s[R]) R++;
						z[i] = R - L;  R--;
					}
				}
				left[i] = L;  right[i] = R;
			}
			return z;
		}

		void add(TreeMap<Integer, Integer> map, int x) {
			map.put(x, map.getOrDefault(x, 0)+1);
		}
		void rem(TreeMap<Integer, Integer> map, int x) {
			int fr = map.get(x)-1;
			if(fr == 0) map.remove(x);
			else map.put(x, fr);
		}
	}

	void doPrimes() {
		primes = new boolean[200200];
		Arrays.fill(primes, true);
		primes[0] = primes[1] = false;
		for(int i = 2; i < primes.length; i++) {
			if(!primes[i]) continue;
			for(int j = i+i; j < primes.length; j += i) primes[j] = false;
		}
	}

	String reverse(String s) {
		return new StringBuilder(s).reverse().toString();
	}
	int[] reverse(int[] a) {
		int n = a.length;
		int[] res = new int[n];
		for(int i = 0, j = n-1; i < n; i++, j--) {
			res[i] = a[j];
		}
		return res;
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer("");
		}
		String next() {
			if(st.hasMoreTokens()) return st.nextToken();
			try { st = new StringTokenizer(br.readLine()); } catch (Exception e) {}
			return next();
		}
		int nextInt() {
			return Integer.parseInt(next());
		}
	}

}


import java.util.Scanner;

public class E {

	private static long MOD = 998244353;

	private static long[][] cache;
	private static long dp(int n, int x, int idx, int used) {
		// impossible
		if (used == 0 && idx + x > n) {
			return 0;
		}
		// base case
		if (idx == n) {
			return used;
		}
		// seen before
		if (cache[idx][used] > -1) {
			return cache[idx][used];
		}
		// recursive case
		long ans = 0;
		for (int diff = 1; diff <= x && idx + diff <= n; ++diff) {
			int nextUsed = used;
			if (diff == x)
				nextUsed = 1;
			ans += dp(n, x, idx + diff, nextUsed);
			ans %= MOD;
		}
		return cache[idx][used] = ans;
	}

	private static long f(int n, int x) {
		if (x <= 0)
			return 0;
		cache = new long[n][2];
		for (int i = 0; i < cache.length; ++i)
			for (int j = 0; j < cache[i].length; ++j)
				cache[i][j] = -1;
		return dp(n, x, 0, 0);
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int k = in.nextInt() - 1;
		long ans = 0;
		for (int i = 1; i <= k && i <= n; ++i) {
			for (int j = 1; j <= k/i; ++j) {
				ans += 2*f(n, i)*f(n, j);
				ans %= MOD;
			}
		}
		System.out.println(ans);
	}

}


//package com.company;

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

public class Main {
    static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        //        Scanner sc = new Scanner(new FileInputStream("Test.in"));
        PrintWriter pw = new PrintWriter(System.out);
        //        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.out"));
        //        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.in"));

        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
        System.out.println("Memory increased:" + (usedMemoryAfter-usedMemoryBefore) / 1000000 );
        System.out.println("Time used: " + (TIME_END - TIME_START) + ".");
    }

    public static class Task {

        public long[][] dp;
        public long[][] subdp;
        public long[] sef;

        public long power(long a, int b) {
            if (b == 0) return 1;
            if (b % 2 == 0) return power(a * a % mod, b >> 1);
            return a * power(a * a % mod, b >> 1) % mod;
        }

        public void calc(int n) {
            dp = new long[n + 1][n + 1];
            subdp = new long[n + 1][n + 1];
            sef = new long[n + 1];
            long t = 1;
            for (int i = 0; i < n + 1; i++) {
                sef[i] = t;
                t *= 2; t %= mod;
            }
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    search(i, j);
                }
            }
            subdp[n][1] = dp[n][1];
            for (int i = 1; i < n; i++) {
                subdp[n][i + 1] = dp[n][i + 1] - dp[n][i];
            }
        }

        public long search(int n, int k) {
            if (dp[n][k] != 0) {
                return dp[n][k];
            }
            if (k >= n) {
                return dp[n][k] = sef[n];
            }
            long s = 0;
            for (int i = 1; i <= k; i++) {
                s += search(n - i, k);
                if (s >= mod) s -= mod;
            }
            return dp[n][k] = s;
        }

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            int k = sc.nextInt();
            calc(n);
            long sum = 0;
            long inv2 = power(2, mod - 2);
            for (int i = 1; i <= n; i++) {
                int otherlen = k % i == 0 ? k / i - 1 : k / i;
                if (otherlen > n) otherlen = n;
                sum += subdp[n][i] * dp[n][otherlen] % mod * inv2 % mod;
                if (sum >= mod) sum -= mod;
            }
            pw.println(sum);
        }

        int mod = 998244353;

    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream s){  br = new BufferedReader(new InputStreamReader(s));}

        public Scanner(FileReader s) throws FileNotFoundException {br = new BufferedReader(s);}

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

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

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

        public String nextLine() throws IOException {return br.readLine();}

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

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


//make sure to make new file!
import java.io.*;
import java.util.*;

public class E1027{

   public static long MOD = 998244353;

   public static void main(String[] args)throws IOException{
      BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
      PrintWriter out = new PrintWriter(System.out);

      StringTokenizer st = new StringTokenizer(f.readLine());

      int n = Integer.parseInt(st.nextToken());
      double m = Double.parseDouble(st.nextToken());

      if(m == 1.0){
         out.println("0");
         out.close();
         return;
      }

      long[] array = new long[n+1];            //number of ways such that max chunk is n
      array[0] = 0;
      array[1] = 1;

      for(int i = 2; i <= n; i++){
         long[][][] dp = new long[n][i][2];

         dp[0][0][0] = 1;

         for(int k = 0; k < n-1; k++){
            for(int j = 0; j < i; j++){
               for(int h = 0; h < 2; h++){
                  //simulate adding same color
                  if(j<i-1){
                     if(j == i-2){
                        dp[k+1][j+1][1] = (dp[k+1][j+1][1]+dp[k][j][h]+MOD)%MOD;
                     } else {
                        dp[k+1][j+1][h] = (dp[k+1][j+1][h]+dp[k][j][h]+MOD)%MOD;
                     }
                  }
                  //simulate adding different color
                  dp[k+1][0][h] = (dp[k+1][0][h]+dp[k][j][h]+MOD)%MOD;
               }
            }
         }

         for(int k = 0; k < i; k++){
            array[i] = (array[i] + dp[n-1][k][1]+MOD)%MOD;
         }
      }

      //psums
      long[] psums = new long[n+2];

      psums[0] = 0L;

      for(int k = 1; k <= n+1; k++){
         psums[k] = (psums[k-1]+array[k-1]+MOD)%MOD;
      }

      long answer = 0L;

      for(int k = 1; k <= n; k++){
         int i = Math.min(n,(int)Math.floor(m/(double)k));
         long prod = (array[k]*psums[i+1]+MOD)%MOD;
         answer = (answer + prod + MOD)%MOD;
      }

      answer = (answer*2 + MOD)%MOD;
      out.println(answer);

      out.close();
   }
}


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

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

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=998244353;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	void work() {
		int n=in.nextInt();
		int k=in.nextInt();
		long[][] dp=new long[n][n+1];
		for(int i=0;i<n;i++) {
			for(int j=1;j<=n;j++) {
				if(i==0)dp[0][j]=1;
				else {
					if(j>i) dp[i][j]=dp[i-1][j]*2;
					else {//j-1,j-2,...,j-k;
						dp[i][j]=2*dp[i-1][j]-(i-j-1<0?1:dp[i-j-1][j]);
						dp[i][j]%=mod;
					}
				}
			}
		}
		long[] f=new long[n+1];
		long ret=0;
		for(int i=1;i<=n;i++) {
			f[i]=(dp[n-1][i]-dp[n-1][i-1]+mod)%mod;
		}
		for(int i=1;i<=n;i++) {
			for(int j=1;i*j<k&&j<=n;j++) {
				ret+=f[i]*f[j];
				ret=ret%mod;
			}
		}
		out.println((ret*2)%mod);
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

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

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

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

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


import java.util.*;

public class SomeClass {
    private static long w, cnt[], all;

    private static int solveDp() {
        int dp[] = new int[1010];
        dp[0] = 1;
        for (int i = 1; i <= 8; i++) {
            for (int j = 0; j < Math.min(cnt[i], 1000); j++) {
                for (int k = 1000 - 1; k >= 0; k--) {
                    if (dp[k] == 1) {
                        dp[k + i] = 1;
                    }
                }
            }
        }
        // System.out.println(w);
        for(int i = (int) w; i >= 0; i--) {
            if (dp[i] == 1) {
                return i;
            }
        }
        return 0;
    }

    private static void reduce() {
        for (int i = 1; i <= 8; i++) {
            if (cnt[i] > 20) {
                long toTake = cnt[i] - 20;
                if (w - toTake * i >= 1000) {
                    w -= toTake * i;
                    cnt[i] = 20;
                } else {
                    long diff = w - 1000;
                    long take = diff / i + 1;
                    cnt[i] -= take;
                    w -= take * i;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        w = input.nextLong();
        cnt = new long[9];
        for (int i = 1; i <= 8; i++) {
            cnt[i] = input.nextLong();
            all += 1L * i * cnt[i];
        }
        if (all <= w) {
            System.out.println(all);
            return;
        }
        long oldW = w;
        if (w > 1000) {
            reduce();
        }
        System.out.println(oldW - w + solveDp());
    }
}