//package year2019.month03.cf.round547div3;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class round547div3D {

    boolean ONLINE_JUDGE = (System.getProperty("ONLINE_JUDGE") != null);

    public round547div3D() throws IOException {
        InputReader in;
        if (ONLINE_JUDGE) {
            in = new InputReader(System.in);
        } else {
            in = new InputReader(new FileInputStream("/Users/karj/cp/input.txt"));
        }
        PrintWriter out = new PrintWriter(System.out);

        int T = 1;
        for (int caseNo = 1; caseNo <= T; caseNo++) {
            solve(caseNo, in, out);
        }

        out.close();
    }

    private void solve(int caseNo, InputReader in, PrintWriter out) throws IOException {
        debug((int)'a');
        debug((int)'z' );
        debug((char)('a' + (122 - 97)));
        debug((int)'?' );
        int n = in.nextInt();
        String l = in.nextString();
        String r = in.nextString();
        HashMap<Character, TreeSet<Integer>> lmap = new HashMap<>();
        HashMap<Character, TreeSet<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < n; i++) {
            TreeSet<Integer> s1 = new TreeSet<>();
            if (lmap.containsKey(l.charAt(i))) {
                s1 = lmap.get(l.charAt(i));
            }
            s1.add(i + 1);
            lmap.put(l.charAt(i), s1);

            TreeSet<Integer> s2 = new TreeSet<>();
            if (rmap.containsKey(r.charAt(i))) {
                s2 = rmap.get(r.charAt(i));
            }
            s2.add(i + 1);
            rmap.put(r.charAt(i), s2);
        }
        debug(lmap);
        debug(rmap);
        StringBuilder ans = new StringBuilder("");
        int k = 0;
        for (char c = 'a'; c <= 'z'; c++) {
            TreeSet<Integer> s1 = lmap.getOrDefault(c, new TreeSet<>());
            TreeSet<Integer> s2 = rmap.getOrDefault(c, new TreeSet<>());
//            debug(c, s1, s2);
            int is = min(s1.size(), s2.size());
            for (int i = 0; i < is; i++) {
                ans.append(s1.pollFirst() + " " + s2.pollFirst() + "\n");
                k++;
            }
            if (s1.size() == 0) {
                lmap.remove(c);
            }
            if (s2.size() == 0) {
                rmap.remove(c);
            }
        }
        TreeSet<Integer> lqn = lmap.getOrDefault('?', new TreeSet<>());
        int is = lqn.size();
        for (int i = 0; i < is; i++) {
            for (Map.Entry<Character, TreeSet<Integer>> entry : rmap.entrySet()) {
                int key = entry.getKey();
                TreeSet<Integer> rqq = entry.getValue();
                if (key == '?') {
                    continue;
                }
                debug(lqn, rqq);
                int js = min(lqn.size(), rqq.size());
                for (int j = 0; j < js; j++) {
                    ans.append(lqn.pollFirst() + " " + rqq.pollFirst() + "\n");
                    k++;
                }
                if (lqn.size() == 0) {
                    lmap.remove('?');
                }
                if (rqq.size() == 0) {
                    rmap.remove(key);
                }
            }
        }
        TreeSet<Integer> rqn = rmap.getOrDefault('?', new TreeSet<>());
        is = rqn.size();
        for (int i = 0; i < is; i++) {
            for (Map.Entry<Character, TreeSet<Integer>> entry : lmap.entrySet()) {
                int key = entry.getKey();
                TreeSet<Integer> lqq = entry.getValue();
                if (key == '?') {
                    continue;
                }
                debug(rqn, lqq);
                int js = min(rqn.size(), lqq.size());
                for (int j = 0; j < js; j++) {
                    ans.append(rqn.pollFirst() + " " + lqq.pollFirst() + "\n");
                    k++;
                }
                if (rqn.size() == 0) {
                    lmap.remove('?');
                }
                if (lqq.size() == 0) {
                    rmap.remove(key);
                }
            }
        }
        for (char c = '?'; c <= '?'; c++) {
            TreeSet<Integer> s1 = lmap.getOrDefault(c, new TreeSet<>());
            TreeSet<Integer> s2 = rmap.getOrDefault(c, new TreeSet<>());
//            debug(c, s1, s2);
            is = min(s1.size(), s2.size());
            for (int i = 0; i < is; i++) {
                ans.append(s1.pollFirst() + " " + s2.pollFirst() + "\n");
                k++;
            }
            if (s1.size() == 0) {
                lmap.remove(c);
            }
            if (s2.size() == 0) {
                rmap.remove(c);
            }
        }
        out.println(k);
        if (k > 0) {
            out.print(ans);
        }
    }

    static class InputReader {

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

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

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

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

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

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }

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

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

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

        public Long nextLong() {
            return Long.parseLong(nextString());
        }

        public Double nextDouble() {
            return Double.parseDouble(nextString());
        }

        public char nextCharacter() {
            return nextString().charAt(0);
        }

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

        public long[] nextLongArray(int N) {
            long A[] = new long[N];
            for (int i = 0; i < N; i++) {
                A[i] = nextLong();
            }
            return A;
        }

        public double[] nextDoubleArray(int N) {
            double A[] = new double[N];
            for (int i = 0; i < N; i++) {
                A[i] = nextDouble();
            }
            return A;
        }
    }

    int min(int... a) {
        int min = Integer.MAX_VALUE;
        for (int v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    long min(long... a) {
        long min = Long.MAX_VALUE;
        for (long v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    double min(double... a) {
        double min = Double.MAX_VALUE;
        for (double v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    int max(int... a) {
        int max = Integer.MIN_VALUE;
        for (int v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    long max(long... a) {
        long max = Long.MIN_VALUE;
        for (long v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    double max(double... a) {
        double max = Double.MIN_VALUE;
        for (double v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    public <A, B> Pair MP(A a, B b) {
        return new Pair<A, B>(a, b);
    }

    class Pair<F, S> {
        public final F f;
        public final S s;

        public Pair(F f, S s) {
            this.f = f;
            this.s = s;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(f, pair.f) &&
                    Objects.equals(s, pair.s);
        }

        @Override
        public int hashCode() {

            return Objects.hash(f, s);
        }

        @Override
        public String toString() {
            return f.toString() + " " + s.toString();
        }
    }

    private void debug(Object... o) {
        if (ONLINE_JUDGE) {
            return;
        }
        System.err.println(Arrays.deepToString(o));
    }

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


//package year2019.month03.cf.round547div3;

import jdk.nashorn.api.tree.Tree;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class round547div3D {

    boolean ONLINE_JUDGE = (System.getProperty("ONLINE_JUDGE") != null);

    public round547div3D() throws IOException {
        InputReader in;
        if (ONLINE_JUDGE) {
            in = new InputReader(System.in);
        } else {
            in = new InputReader(new FileInputStream("/Users/karj/cp/input.txt"));
        }
        PrintWriter out = new PrintWriter(System.out);

        int T = 1;
        for (int caseNo = 1; caseNo <= T; caseNo++) {
            solve(caseNo, in, out);
        }

        out.close();
    }

    private void solve(int caseNo, InputReader in, PrintWriter out) throws IOException {
        debug((int)'a');
        debug((int)'z' );
        debug((char)('a' + (122 - 97)));
        debug((int)'?' );
        int n = in.nextInt();
        String l = in.nextString();
        String r = in.nextString();
        HashMap<Character, TreeSet<Integer>> lmap = new HashMap<>();
        HashMap<Character, TreeSet<Integer>> rmap = new HashMap<>();
        for (int i = 0; i < n; i++) {
            TreeSet<Integer> s1 = new TreeSet<>();
            if (lmap.containsKey(l.charAt(i))) {
                s1 = lmap.get(l.charAt(i));
            }
            s1.add(i + 1);
            lmap.put(l.charAt(i), s1);

            TreeSet<Integer> s2 = new TreeSet<>();
            if (rmap.containsKey(r.charAt(i))) {
                s2 = rmap.get(r.charAt(i));
            }
            s2.add(i + 1);
            rmap.put(r.charAt(i), s2);
        }
        debug(lmap);
        debug(rmap);
        StringBuilder ans = new StringBuilder("");
        int k = 0;
        for (char c = 'a'; c <= 'z'; c++) {
            TreeSet<Integer> s1 = lmap.getOrDefault(c, new TreeSet<>());
            TreeSet<Integer> s2 = rmap.getOrDefault(c, new TreeSet<>());
//            debug(c, s1, s2);
            int is = min(s1.size(), s2.size());
            for (int i = 0; i < is; i++) {
                ans.append(s1.pollFirst() + " " + s2.pollFirst() + "\n");
                k++;
            }
            if (s1.size() == 0) {
                lmap.remove(c);
            }
            if (s2.size() == 0) {
                rmap.remove(c);
            }
        }
        TreeSet<Integer> lqn = lmap.getOrDefault('?', new TreeSet<>());
        int is = lqn.size();
        for (int i = 0; i < is; i++) {
            for (Map.Entry<Character, TreeSet<Integer>> entry : rmap.entrySet()) {
                int key = entry.getKey();
                TreeSet<Integer> rqq = entry.getValue();
                if (key == '?') {
                    continue;
                }
                debug(lqn, rqq);
                int js = min(lqn.size(), rqq.size());
                for (int j = 0; j < js; j++) {
                    ans.append(lqn.pollFirst() + " " + rqq.pollFirst() + "\n");
                    k++;
                }
                if (lqn.size() == 0) {
                    lmap.remove('?');
                }
                if (rqq.size() == 0) {
                    rmap.remove(key);
                }
            }
        }
        TreeSet<Integer> rqn = rmap.getOrDefault('?', new TreeSet<>());
        is = rqn.size();
        for (int i = 0; i < is; i++) {
            for (Map.Entry<Character, TreeSet<Integer>> entry : lmap.entrySet()) {
                int key = entry.getKey();
                TreeSet<Integer> lqq = entry.getValue();
                if (key == '?') {
                    continue;
                }
                debug(rqn, lqq);
                int js = min(rqn.size(), lqq.size());
                for (int j = 0; j < js; j++) {
                    ans.append(rqn.pollFirst() + " " + lqq.pollFirst() + "\n");
                    k++;
                }
                if (rqn.size() == 0) {
                    lmap.remove('?');
                }
                if (lqq.size() == 0) {
                    rmap.remove(key);
                }
            }
        }
        for (char c = '?'; c <= '?'; c++) {
            TreeSet<Integer> s1 = lmap.getOrDefault(c, new TreeSet<>());
            TreeSet<Integer> s2 = rmap.getOrDefault(c, new TreeSet<>());
//            debug(c, s1, s2);
            is = min(s1.size(), s2.size());
            for (int i = 0; i < is; i++) {
                ans.append(s1.pollFirst() + " " + s2.pollFirst() + "\n");
                k++;
            }
            if (s1.size() == 0) {
                lmap.remove(c);
            }
            if (s2.size() == 0) {
                rmap.remove(c);
            }
        }
        out.println(k);
        if (k > 0) {
            out.print(ans);
        }
    }

    static class InputReader {

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

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

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

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

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

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }

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

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

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

        public Long nextLong() {
            return Long.parseLong(nextString());
        }

        public Double nextDouble() {
            return Double.parseDouble(nextString());
        }

        public char nextCharacter() {
            return nextString().charAt(0);
        }

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

        public long[] nextLongArray(int N) {
            long A[] = new long[N];
            for (int i = 0; i < N; i++) {
                A[i] = nextLong();
            }
            return A;
        }

        public double[] nextDoubleArray(int N) {
            double A[] = new double[N];
            for (int i = 0; i < N; i++) {
                A[i] = nextDouble();
            }
            return A;
        }
    }

    int min(int... a) {
        int min = Integer.MAX_VALUE;
        for (int v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    long min(long... a) {
        long min = Long.MAX_VALUE;
        for (long v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    double min(double... a) {
        double min = Double.MAX_VALUE;
        for (double v : a) {
            min = Math.min(min, v);
        }
        return min;
    }

    int max(int... a) {
        int max = Integer.MIN_VALUE;
        for (int v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    long max(long... a) {
        long max = Long.MIN_VALUE;
        for (long v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    double max(double... a) {
        double max = Double.MIN_VALUE;
        for (double v : a) {
            max = Math.max(max, v);
        }
        return max;
    }

    public <A, B> Pair MP(A a, B b) {
        return new Pair<A, B>(a, b);
    }

    class Pair<F, S> {
        public final F f;
        public final S s;

        public Pair(F f, S s) {
            this.f = f;
            this.s = s;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(f, pair.f) &&
                    Objects.equals(s, pair.s);
        }

        @Override
        public int hashCode() {

            return Objects.hash(f, s);
        }

        @Override
        public String toString() {
            return f.toString() + " " + s.toString();
        }
    }

    private void debug(Object... o) {
        if (ONLINE_JUDGE) {
            return;
        }
        System.err.println(Arrays.deepToString(o));
    }

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


import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.concurrent.LinkedBlockingQueue;

public class Main
{

	public static void main(String[] args) throws NumberFormatException, IOException
	{
		Reader s=new Reader(System.in);
		HashMap<Character,LinkedBlockingQueue<Integer>> map=new HashMap<>();
		int n=s.nextInt();
		String A=s.next();
		String B=s.next();
		for(int a=0;a<B.length();a++)
		{
			Character key=B.charAt(a);
			LinkedBlockingQueue<Integer> queue=map.get(key);
			if(queue==null)
			{
				queue=new LinkedBlockingQueue<Integer>();
				queue.add(a+1);
			}
			else
				queue.add(a+1);
			map.put(key, queue);
		}
		int count=0;
		int countQuestionMark=0;
		String[] output=new String[A.length()];
		ArrayList<Integer> list=new ArrayList<>();
		for(int a=0;a<A.length();a++)
		{
			Character key=A.charAt(a);
			if(key=='?')
			{
				countQuestionMark++;
				list.add(a+1);
				continue;
			}
			else
			{
				LinkedBlockingQueue<Integer> queue=map.get(key);
				if(queue==null||queue.isEmpty())
				{
					LinkedBlockingQueue<Integer> q=map.get('?');
					if(q==null)
						continue;
					else
					{
						output[count]=new String(new Integer(a+1).toString()+" "+new Integer(q.poll()).toString());
						count++;
					}
				}
				else
				{
					output[count]=new String(new Integer(a+1).toString()+" "+new Integer(queue.poll()).toString());
					count++;
				}
			}
		}
		Iterator<Entry<Character,LinkedBlockingQueue<Integer>>> iterator=map.entrySet().iterator();
		while(iterator.hasNext())
		{
			if(countQuestionMark==0)
				break;
			LinkedBlockingQueue<Integer> queue=iterator.next().getValue();
			while(queue.isEmpty()==false)
			{
				output[count]=new String(new Integer(list.get(countQuestionMark-1)).toString()+" "+new Integer(queue.poll().toString()));
				count++;
				countQuestionMark--;
				if(countQuestionMark==0)
					break;
			}
		}
		System.out.println(count);
		for(int a=0;a<count;a++)
		{
			System.out.println(output[a]);
		}

	}

}
class Reader
{
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public Reader(InputStream input)
	{
		reader=new BufferedReader(new InputStreamReader(input));
		tokenizer=new StringTokenizer("");
	}
	public String next() throws IOException
	{
		while(tokenizer.hasMoreTokens()==false)
		{
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	public String nextLine() throws IOException
	{
		return reader.readLine();
	}
	public int nextInt() throws NumberFormatException, IOException
	{
		return Integer.parseInt(next());
	}
	public double nextDouble() throws NumberFormatException, IOException
	{
		return Double.parseDouble(next());
	}
	public long nextLong() throws NumberFormatException, IOException
	{
		return Long.parseLong(next());
	}
}


import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.concurrent.LinkedBlockingQueue;

public class Main
{

	public static void main(String[] args) throws NumberFormatException, IOException
	{
		Reader s=new Reader(System.in);
		HashMap<Character,LinkedBlockingQueue<Integer>> map=new HashMap<>();
		int n=s.nextInt();
		String A=s.next();
		String B=s.next();
		for(int a=0;a<B.length();a++)
		{
			Character key=B.charAt(a);
			LinkedBlockingQueue<Integer> queue=map.get(key);
			if(queue==null)
			{
				queue=new LinkedBlockingQueue<Integer>();
				queue.add(a+1);
			}
			else
				queue.add(a+1);
			map.put(key, queue);
		}
		int count=0;
		int countQuestionMark=0;
		String[] output=new String[A.length()];
		ArrayList<Integer> list=new ArrayList<>();
		for(int a=0;a<A.length();a++)
		{
			Character key=A.charAt(a);
			if(key=='?')
			{
				countQuestionMark++;
				list.add(a+1);
				continue;
			}
			else
			{
				LinkedBlockingQueue<Integer> queue=map.get(key);
				if(queue==null||queue.isEmpty())
				{
					LinkedBlockingQueue<Integer> q=map.get('?');
					if(q==null||q.isEmpty())
						continue;
					else
					{
						output[count]=new String(new Integer(a+1).toString()+" "+new Integer(q.poll()).toString());
						count++;
					}
				}
				else
				{
					output[count]=new String(new Integer(a+1).toString()+" "+new Integer(queue.poll()).toString());
					count++;
				}
			}
		}
		Iterator<Entry<Character,LinkedBlockingQueue<Integer>>> iterator=map.entrySet().iterator();
		while(iterator.hasNext())
		{
			if(countQuestionMark==0)
				break;
			LinkedBlockingQueue<Integer> queue=iterator.next().getValue();
			while(queue.isEmpty()==false)
			{
				output[count]=new String(new Integer(list.get(countQuestionMark-1)).toString()+" "+new Integer(queue.poll().toString()));
				count++;
				countQuestionMark--;
				if(countQuestionMark==0)
					break;
			}
		}
		System.out.println(count);
		for(int a=0;a<count;a++)
		{
			System.out.println(output[a]);
		}

	}

}
class Reader
{
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public Reader(InputStream input)
	{
		reader=new BufferedReader(new InputStreamReader(input));
		tokenizer=new StringTokenizer("");
	}
	public String next() throws IOException
	{
		while(tokenizer.hasMoreTokens()==false)
		{
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	public String nextLine() throws IOException
	{
		return reader.readLine();
	}
	public int nextInt() throws NumberFormatException, IOException
	{
		return Integer.parseInt(next());
	}
	public double nextDouble() throws NumberFormatException, IOException
	{
		return Double.parseDouble(next());
	}
	public long nextLong() throws NumberFormatException, IOException
	{
		return Long.parseLong(next());
	}
}


import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.concurrent.LinkedBlockingQueue;

public class Main
{

	public static void main(String[] args) throws NumberFormatException, IOException
	{
		Reader s=new Reader(System.in);
		HashMap<Character,LinkedBlockingQueue<Integer>> map=new HashMap<>();
		int n=s.nextInt();
		String A=s.next();
		String B=s.next();
		for(int a=0;a<B.length();a++)
		{
			Character key=B.charAt(a);
			LinkedBlockingQueue<Integer> queue=map.get(key);
			if(queue==null)
			{
				queue=new LinkedBlockingQueue<Integer>();
				queue.add(a+1);
			}
			else
				queue.add(a);
			map.put(key, queue);
		}
		int count=0;
		int countQuestionMark=0;
		String[] output=new String[A.length()];
		ArrayList<Integer> list=new ArrayList<>();
		for(int a=0;a<A.length();a++)
		{
			Character key=A.charAt(a);
			if(key=='?')
			{
				countQuestionMark++;
				list.add(a+1);
				continue;
			}
			else
			{
				LinkedBlockingQueue<Integer> queue=map.get(key);
				if(queue==null||queue.isEmpty())
				{
					LinkedBlockingQueue<Integer> q=map.get('?');
					if(q==null)
						continue;
					else
					{
						output[count]=new String(new Integer(a+1).toString()+" "+new Integer(q.poll()).toString());
						count++;
					}
				}
				else
				{
					output[count]=new String(new Integer(a+1).toString()+" "+new Integer(queue.poll()).toString());
					count++;
				}
			}
		}
		Iterator<Entry<Character,LinkedBlockingQueue<Integer>>> iterator=map.entrySet().iterator();
		while(iterator.hasNext())
		{
			if(countQuestionMark==0)
				break;
			LinkedBlockingQueue<Integer> queue=iterator.next().getValue();
			while(queue.isEmpty()==false)
			{
				output[count]=new String(new Integer(list.get(countQuestionMark-1)).toString()+" "+new Integer(queue.poll().toString()));
				count++;
				countQuestionMark--;
				if(countQuestionMark==0)
					break;
			}
		}
		System.out.println(count);
		for(int a=0;a<count;a++)
		{
			System.out.println(output[a]);
		}

	}

}
class Reader
{
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public Reader(InputStream input)
	{
		reader=new BufferedReader(new InputStreamReader(input));
		tokenizer=new StringTokenizer("");
	}
	public String next() throws IOException
	{
		while(tokenizer.hasMoreTokens()==false)
		{
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	public String nextLine() throws IOException
	{
		return reader.readLine();
	}
	public int nextInt() throws NumberFormatException, IOException
	{
		return Integer.parseInt(next());
	}
	public double nextDouble() throws NumberFormatException, IOException
	{
		return Double.parseDouble(next());
	}
	public long nextLong() throws NumberFormatException, IOException
	{
		return Long.parseLong(next());
	}
}


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

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

    static class DColoredBoots {
        public void solve(int testNumber, InputReader in, OutputWriter out) throws IOException {
            int n;
            n = in.nextInt();
            String l, r;
            l = in.nextString();
            r = in.nextString();
        /*pair<char,int> li[n];
        pair<char,int> ri[n];*/
            int freq[][] = new int[27][2];
            for (int i = 0; i < 27; i++)
                for (int j = 0; j < 2; j++)
                    freq[i][j] = 0;
            boolean isUsed[][] = new boolean[n][2];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < 2; j++)
                    isUsed[i][j] = false;
            for (int i = 0; i < n; i++) {
                if (l.charAt(i) == '?')
                    freq[26][0]++;
                else
                    freq[l.charAt(i) - 'a'][0]++;
                if (r.charAt(i) == '?')
                    freq[26][1]++;
                else
                    freq[r.charAt(i) - 'a'][1]++;
            }
            ArrayList<Integer[]> ans = new ArrayList<>();
            int num;
            int x = 0, y = 0;
            int temp[] = new int[2];
            for (int i = 0; i < 26; i++) {
                x = 0;
                y = 0;
                num = Math.min(freq[i][0], freq[i][1]);
                for (int j = 0; j < num; j++) {
                    while (l.charAt(x) != ('a' + i)) x++;
                    while (r.charAt(y) != ('a' + i)) y++;
                    ans.add(new Integer[2]);
                    ans.get(ans.size() - 1)[0] = x;
                    ans.get(ans.size() - 1)[1] = y;
                    isUsed[x][0] = true;
                    isUsed[y][1] = true;
                    x++;
                    y++;
                }
            }
            x = 0;
            y = 0;
            for (int i = 0; i < n && freq[26][0] > 0 && ans.size() != n; i++) {
                while (x < n && (l.charAt(x) != '?' || isUsed[x][0])) x++;
                while (i < n && isUsed[i][1]) i++;
                if (x == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = x;
                ans.get(ans.size() - 1)[1] = i;
                isUsed[x][0] = true;
                isUsed[i][1] = true;
                x++;
            }
            for (int i = 0; i < n && freq[26][1] > 0 && ans.size() != n; i++) {
                while (y < n && (r.charAt(y) != '?' || isUsed[y][1])) y++;
                while (i < n && isUsed[i][0]) i++;
                if (y == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = i;
                ans.get(ans.size() - 1)[1] = y;
                isUsed[i][0] = true;
                isUsed[y][1] = true;
                y++;
            }
            out.printLine(ans.size());
            for (int i = 0; i < ans.size(); i++)
                out.printLine((ans.get(i)[0] + 1) + " " + (ans.get(i)[1] + 1));
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

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

    }

    static class InputReader {
        private static final int DEFAULT_BUFFER_SIZE = 1 << 16;
        private static final InputStream DEFAULT_STREAM = System.in;
        private int c;
        private byte[] buf;
        private int bufferSize;
        private int bufIndex;
        private int numBytesRead;
        private InputStream stream;
        private static final byte EOF = -1;
        private static final byte SPACE = 32;
        private static final byte DASH = 45;
        private char[] charBuffer;
        private static byte[] bytes = new byte[58];
        private static int[] ints = new int[58];
        private static char[] chars = new char[128];

        static {
            char ch = ' ';
            int value = 0;
            byte _byte = 0;
            for (int i = 48; i < 58; i++) bytes[i] = _byte++;
            for (int i = 48; i < 58; i++) ints[i] = value++;
            for (int i = 32; i < 128; i++) chars[i] = ch++;
        }

        public InputReader() {
            this(DEFAULT_STREAM, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(int bufferSize) {
            this(DEFAULT_STREAM, bufferSize);
        }

        public InputReader(InputStream stream) {
            this(stream, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(InputStream stream, int bufferSize) {
            if (stream == null || bufferSize <= 0)
                throw new IllegalArgumentException();
            buf = new byte[bufferSize];
            charBuffer = new char[128];
            this.bufferSize = bufferSize;
            this.stream = stream;
        }

        private int readJunk(int token) throws IOException {

            if (numBytesRead == EOF) return EOF;

            // Seek to the first valid position index
            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > token) return 0;
                    bufIndex++;
                }

                // reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return EOF;
                bufIndex = 0;

            } while (true);

        }

        public int nextInt() throws IOException {

            if (readJunk(DASH - 1) == EOF) throw new IOException();
            int sgn = 1, res = 0;

            c = buf[bufIndex];
            if (c == DASH) {
                sgn = -1;
                bufIndex++;
            }

            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        res = (res << 3) + (res << 1);
                        res += ints[buf[bufIndex++]];
                    } else {
                        bufIndex++;
                        return res * sgn;
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return res * sgn;
                bufIndex = 0;

            } while (true);

        }

        private void doubleCharBufferSize() {
            char[] newBuffer = new char[charBuffer.length << 1];
            for (int i = 0; i < charBuffer.length; i++) newBuffer[i] = charBuffer[i];
            charBuffer = newBuffer;
        }

        public String nextString() throws IOException {
            if (numBytesRead == EOF) return null;
            if (readJunk(SPACE) == EOF) return null;

            for (int i = 0; ; ) {
                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        if (i == charBuffer.length) doubleCharBufferSize();
                        charBuffer[i++] = (char) buf[bufIndex++];
                    } else {
                        bufIndex++;
                        return new String(charBuffer, 0, i);
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return new String(charBuffer, 0, i);
                bufIndex = 0;
            }
        }

    }
}


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

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

    static class DColoredBoots {
        public void solve(int testNumber, InputReader in, OutputWriter out) throws IOException {
            int n;
            n = in.nextInt();
            String l, r;
            l = in.nextString();
            r = in.nextString();
        /*pair<char,int> li[n];
        pair<char,int> ri[n];*/
            int freq[][] = new int[27][2];
            for (int i = 0; i < 27; i++)
                for (int j = 0; j < 2; j++)
                    freq[i][j] = 0;
            boolean isUsed[][] = new boolean[n][2];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < 2; j++)
                    isUsed[i][j] = false;
            for (int i = 0; i < n; i++) {
                if (l.charAt(i) == '?')
                    freq[26][0]++;
                else
                    freq[l.charAt(i) - 'a'][0]++;
                if (r.charAt(i) == '?')
                    freq[26][1]++;
                else
                    freq[r.charAt(i) - 'a'][1]++;
            }
            ArrayList<Integer[]> ans = new ArrayList<>();
            int num;
            int x = 0, y = 0;
            int temp[] = new int[2];
            for (int i = 0; i < 26; i++) {
                x = 0;
                y = 0;
                num = Math.min(freq[i][0], freq[i][1]);
                for (int j = 0; j < num; j++) {
                    while (l.charAt(x) != ('a' + i)) x++;
                    while (r.charAt(y) != ('a' + i)) y++;
                    ans.add(new Integer[2]);
                    ans.get(ans.size() - 1)[0] = x;
                    ans.get(ans.size() - 1)[1] = y;
                    isUsed[x][0] = true;
                    isUsed[y][1] = true;
                    x++;
                    y++;
                }
            }
            x = 0;
            y = 0;
            for (int i = 0; i < n && freq[26][0] > 0 && ans.size() != n; i++) {
                while (x < n && l.charAt(x) != '?') x++;
                while (i < n && isUsed[i][1]) i++;
                if (x == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = x;
                ans.get(ans.size() - 1)[1] = i;
                isUsed[x][0] = true;
                isUsed[i][1] = true;
                x++;
            }
            for (int i = 0; i < n && freq[26][1] > 0 && ans.size() != n; i++) {
                while (y < n && r.charAt(y) != '?') y++;
                while (i < n && isUsed[i][0]) i++;
                if (y == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = i;
                ans.get(ans.size() - 1)[1] = y;
                isUsed[i][0] = true;
                isUsed[y][1] = true;
                y++;
            }
            out.printLine(ans.size());
            for (int i = 0; i < ans.size(); i++)
                out.printLine((ans.get(i)[0] + 1) + " " + (ans.get(i)[1] + 1));
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

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

    }

    static class InputReader {
        private static final int DEFAULT_BUFFER_SIZE = 1 << 16;
        private static final InputStream DEFAULT_STREAM = System.in;
        private int c;
        private byte[] buf;
        private int bufferSize;
        private int bufIndex;
        private int numBytesRead;
        private InputStream stream;
        private static final byte EOF = -1;
        private static final byte SPACE = 32;
        private static final byte DASH = 45;
        private char[] charBuffer;
        private static byte[] bytes = new byte[58];
        private static int[] ints = new int[58];
        private static char[] chars = new char[128];

        static {
            char ch = ' ';
            int value = 0;
            byte _byte = 0;
            for (int i = 48; i < 58; i++) bytes[i] = _byte++;
            for (int i = 48; i < 58; i++) ints[i] = value++;
            for (int i = 32; i < 128; i++) chars[i] = ch++;
        }

        public InputReader() {
            this(DEFAULT_STREAM, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(int bufferSize) {
            this(DEFAULT_STREAM, bufferSize);
        }

        public InputReader(InputStream stream) {
            this(stream, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(InputStream stream, int bufferSize) {
            if (stream == null || bufferSize <= 0)
                throw new IllegalArgumentException();
            buf = new byte[bufferSize];
            charBuffer = new char[128];
            this.bufferSize = bufferSize;
            this.stream = stream;
        }

        private int readJunk(int token) throws IOException {

            if (numBytesRead == EOF) return EOF;

            // Seek to the first valid position index
            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > token) return 0;
                    bufIndex++;
                }

                // reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return EOF;
                bufIndex = 0;

            } while (true);

        }

        public int nextInt() throws IOException {

            if (readJunk(DASH - 1) == EOF) throw new IOException();
            int sgn = 1, res = 0;

            c = buf[bufIndex];
            if (c == DASH) {
                sgn = -1;
                bufIndex++;
            }

            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        res = (res << 3) + (res << 1);
                        res += ints[buf[bufIndex++]];
                    } else {
                        bufIndex++;
                        return res * sgn;
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return res * sgn;
                bufIndex = 0;

            } while (true);

        }

        private void doubleCharBufferSize() {
            char[] newBuffer = new char[charBuffer.length << 1];
            for (int i = 0; i < charBuffer.length; i++) newBuffer[i] = charBuffer[i];
            charBuffer = newBuffer;
        }

        public String nextString() throws IOException {
            if (numBytesRead == EOF) return null;
            if (readJunk(SPACE) == EOF) return null;

            for (int i = 0; ; ) {
                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        if (i == charBuffer.length) doubleCharBufferSize();
                        charBuffer[i++] = (char) buf[bufIndex++];
                    } else {
                        bufIndex++;
                        return new String(charBuffer, 0, i);
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return new String(charBuffer, 0, i);
                bufIndex = 0;
            }
        }

    }
}


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

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

    static class DColoredBoots {
        public void solve(int testNumber, InputReader in, OutputWriter out) throws IOException {
            int n;
            n = in.nextInt();
            String l, r;
            l = in.nextString();
            r = in.nextString();
        /*pair<char,int> li[n];
        pair<char,int> ri[n];*/
            int freq[][] = new int[27][2];
            for (int i = 0; i < 27; i++)
                for (int j = 0; j < 2; j++)
                    freq[i][j] = 0;
            boolean isUsed[][] = new boolean[n][2];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < 2; j++)
                    isUsed[i][j] = false;
            for (int i = 0; i < n; i++) {
                if (l.charAt(i) == '?')
                    freq[26][0]++;
                else
                    freq[l.charAt(i) - 'a'][0]++;
                if (r.charAt(i) == '?')
                    freq[26][1]++;
                else
                    freq[r.charAt(i) - 'a'][1]++;
            }
            ArrayList<Integer[]> ans = new ArrayList<>();
            int num;
            int x = 0, y = 0;
            int temp[] = new int[2];
            for (int i = 0; i < 26; i++) {
                x = 0;
                y = 0;
                num = Math.min(freq[i][0], freq[i][1]);
                for (int j = 0; j < num; j++) {
                    while (l.charAt(x) != ('a' + i)) x++;
                    while (r.charAt(y) != ('a' + i)) y++;
                    ans.add(new Integer[2]);
                    ans.get(ans.size() - 1)[0] = x;
                    ans.get(ans.size() - 1)[1] = y;
                    isUsed[x][0] = true;
                    isUsed[y][1] = true;
                    x++;
                    y++;
                }
            }
            x = 0;
            y = 0;
            for (int i = 0; i < n && freq[26][0] > 0 && ans.size() != n; i++) {
                while (x < n && (l.charAt(x) != '?' || isUsed[x][0])) x++;
                while (i < n && (isUsed[i][1] || r.charAt(i) == '?')) i++;
                if (x == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = x;
                ans.get(ans.size() - 1)[1] = i;
                isUsed[x][0] = true;
                isUsed[i][1] = true;
                x++;
            }
            for (int i = 0; i < n && freq[26][1] > 0 && ans.size() != n; i++) {
                while (y < n && (r.charAt(y) != '?' || isUsed[y][1])) y++;
                while (i < n && (isUsed[i][0] || l.charAt(i) == '?')) i++;
                if (y == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = i;
                ans.get(ans.size() - 1)[1] = y;
                isUsed[i][0] = true;
                isUsed[y][1] = true;
                y++;
            }
            for (int i = 0; i < n && freq[26][0] > 0 && ans.size() != n; i++) {
                while (x < n && (l.charAt(x) != '?' || isUsed[x][0])) x++;
                while (i < n && (isUsed[i][1] || r.charAt(i) != '?')) i++;
                if (x == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = x;
                ans.get(ans.size() - 1)[1] = i;
                isUsed[x][0] = true;
                isUsed[i][1] = true;
                x++;
            }
            for (int i = 0; i < n && freq[26][1] > 0 && ans.size() != n; i++) {
                while (y < n && (r.charAt(y) != '?' || isUsed[y][1])) y++;
                while (i < n && (isUsed[i][0] || l.charAt(i) != '?')) i++;
                if (y == n || i == n)
                    break;
                ans.add(new Integer[2]);
                ans.get(ans.size() - 1)[0] = i;
                ans.get(ans.size() - 1)[1] = y;
                isUsed[i][0] = true;
                isUsed[y][1] = true;
                y++;
            }
            out.printLine(ans.size());
            for (int i = 0; i < ans.size(); i++)
                out.printLine((ans.get(i)[0] + 1) + " " + (ans.get(i)[1] + 1));
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

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

    }

    static class InputReader {
        private static final int DEFAULT_BUFFER_SIZE = 1 << 16;
        private static final InputStream DEFAULT_STREAM = System.in;
        private int c;
        private byte[] buf;
        private int bufferSize;
        private int bufIndex;
        private int numBytesRead;
        private InputStream stream;
        private static final byte EOF = -1;
        private static final byte SPACE = 32;
        private static final byte DASH = 45;
        private char[] charBuffer;
        private static byte[] bytes = new byte[58];
        private static int[] ints = new int[58];
        private static char[] chars = new char[128];

        static {
            char ch = ' ';
            int value = 0;
            byte _byte = 0;
            for (int i = 48; i < 58; i++) bytes[i] = _byte++;
            for (int i = 48; i < 58; i++) ints[i] = value++;
            for (int i = 32; i < 128; i++) chars[i] = ch++;
        }

        public InputReader() {
            this(DEFAULT_STREAM, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(int bufferSize) {
            this(DEFAULT_STREAM, bufferSize);
        }

        public InputReader(InputStream stream) {
            this(stream, DEFAULT_BUFFER_SIZE);
        }

        public InputReader(InputStream stream, int bufferSize) {
            if (stream == null || bufferSize <= 0)
                throw new IllegalArgumentException();
            buf = new byte[bufferSize];
            charBuffer = new char[128];
            this.bufferSize = bufferSize;
            this.stream = stream;
        }

        private int readJunk(int token) throws IOException {

            if (numBytesRead == EOF) return EOF;

            // Seek to the first valid position index
            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > token) return 0;
                    bufIndex++;
                }

                // reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return EOF;
                bufIndex = 0;

            } while (true);

        }

        public int nextInt() throws IOException {

            if (readJunk(DASH - 1) == EOF) throw new IOException();
            int sgn = 1, res = 0;

            c = buf[bufIndex];
            if (c == DASH) {
                sgn = -1;
                bufIndex++;
            }

            do {

                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        res = (res << 3) + (res << 1);
                        res += ints[buf[bufIndex++]];
                    } else {
                        bufIndex++;
                        return res * sgn;
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return res * sgn;
                bufIndex = 0;

            } while (true);

        }

        private void doubleCharBufferSize() {
            char[] newBuffer = new char[charBuffer.length << 1];
            for (int i = 0; i < charBuffer.length; i++) newBuffer[i] = charBuffer[i];
            charBuffer = newBuffer;
        }

        public String nextString() throws IOException {
            if (numBytesRead == EOF) return null;
            if (readJunk(SPACE) == EOF) return null;

            for (int i = 0; ; ) {
                while (bufIndex < numBytesRead) {
                    if (buf[bufIndex] > SPACE) {
                        if (i == charBuffer.length) doubleCharBufferSize();
                        charBuffer[i++] = (char) buf[bufIndex++];
                    } else {
                        bufIndex++;
                        return new String(charBuffer, 0, i);
                    }
                }

                // Reload buffer
                numBytesRead = stream.read(buf);
                if (numBytesRead == EOF) return new String(charBuffer, 0, i);
                bufIndex = 0;
            }
        }

    }
}


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

public class D {
	public static void main(String[] args) throws FileNotFoundException {
		int toFile = 0;
		InputStream inputStream;
		OutputStream outputStream;
		if (toFile == 0) {
			inputStream = System.in;
			outputStream = System.out;
		} else {
			inputStream = new FileInputStream(new File("D.in"));
			outputStream = new FileOutputStream(new File("D.out"));
		}
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(in, out);
		out.close();
	}

	static class TaskD {

		public void solve(InputReader in, PrintWriter out) {
			int n = in.nextInt();
			String l = in.next();
			String r = in.next();

			List<LinkedList<Integer>> ll = new ArrayList<>();
			List<LinkedList<Integer>> rr = new ArrayList<>();

			int k = 'z' - 'a' + 2;
			for (int i = 0; i < k; i++) {
				ll.add(new LinkedList<>());
				rr.add(new LinkedList<>());
			}

			for (int i = 0; i < n; i++) {
				if (l.charAt(i) == '?') {
					ll.get(ll.size() - 1).add(i);
				} else {
					ll.get(l.charAt(i) - 'a').add(i);
				}

				if (r.charAt(i) == '?') {
					rr.get(rr.size() - 1).add(i);
				} else {
					rr.get(r.charAt(i) - 'a').add(i);
				}
			}

//			for (int j = 0; j < k; j++) {
//				System.out.println((char)('a' + j));
//				int sz = ll.get(j).size();
//				for (int i = 0; i < sz; i++) {
//					System.out.print(ll.get(j).iterator().next() + " ");
//					ll.get(j).remove(ll.get(j).iterator().next());
//				}
//				System.out.println();
//			}

			int ans = 0;
			List<Integer> ans1 = new ArrayList<>();
			List<Integer> ans2 = new ArrayList<>();

			for (int i = 0; i < k; i++) {
				int lls = ll.get(i).size();
				int rrs = rr.get(i).size();
				for (int j = 0; j < lls; j++) {
					if (rr.get(i).size() > 0) {
						ans++;
						ans1.add(ll.get(i).getFirst());
						ans2.add(rr.get(i).getFirst());

						ll.get(i).removeFirst();
						rr.get(i).removeFirst();
					}
				}

				lls = ll.get(i).size();
				rrs = rr.get(rr.size() - 1).size();
				for (int j = 0; j < lls; j++)
					if (rr.get(rr.size() - 1).size() > 0) {
						ans++;
						ans1.add(ll.get(i).getFirst());
						ans2.add(rr.get(rr.size() - 1).getFirst());

						ll.get(i).removeFirst();
						rr.get(rr.size() - 1).removeFirst();
					}

				lls = ll.get(ll.size() - 1).size();
				rrs = rr.get(i).size();
				for (int j = 0; j < lls; j++)
					if (rr.get(i).size() > 0) {
						ans++;
						ans1.add(ll.get(ll.size() - 1).getFirst());
						ans2.add(rr.get(i).getFirst());

						ll.get(ll.size() - 1).removeFirst();
						rr.get(i).removeFirst();
					}
			}

			System.out.println(ans);
			for (int i = 0; i < ans1.size(); i++) {
				System.out.println((ans1.get(i) + 1) + " " + (ans2.get(i) + 1));
			}

		}

	}

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

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

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

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

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


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

public class D {
	public static void main(String[] args) throws FileNotFoundException {
		int toFile = 0;
		InputStream inputStream;
		OutputStream outputStream;
		if (toFile == 0) {
			inputStream = System.in;
			outputStream = System.out;
		} else {
			inputStream = new FileInputStream(new File("D.in"));
			outputStream = new FileOutputStream(new File("D.out"));
		}
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(in, out);
		out.close();
	}

	static class TaskD {

		public void solve(InputReader in, PrintWriter out) {
			int n = in.nextInt();
			String l = in.next();
			String r = in.next();

			List<List<Integer>> ll = new ArrayList<>();
			List<List<Integer>> rr = new ArrayList<>();

			List<List<Boolean>> ans1b = new ArrayList<>();
			List<List<Boolean>> ans2b = new ArrayList<>();

			int k = 'z' - 'a' + 2;
			for (int i = 0; i < k; i++) {
				ll.add(new ArrayList<>());
				rr.add(new ArrayList<>());
				ans1b.add(new ArrayList<>());
				ans2b.add(new ArrayList<>());
			}

			for (int i = 0; i < n; i++) {
				if (l.charAt(i) == '?') {
					ll.get(ll.size() - 1).add(i);
					ans1b.get(ll.size() - 1).add(false);
				} else {
					ll.get(l.charAt(i) - 'a').add(i);
					ans1b.get(l.charAt(i) - 'a').add(false);
				}

				if (r.charAt(i) == '?') {
					rr.get(rr.size() - 1).add(i);
					ans2b.get(rr.size() - 1).add(false);
				} else {
					rr.get(r.charAt(i) - 'a').add(i);
					ans2b.get(r.charAt(i) - 'a').add(false);
				}
			}
			int ans = 0;
			List<Integer> ans1 = new ArrayList<>();
			List<Integer> ans2 = new ArrayList<>();

			for (int i = 0; i < k; i++) {
				for (int j = 0; j < ll.get(i).size(); j++)
					for (int t = 0; t < rr.get(i).size(); t++) {
						if (!ans1b.get(i).get(j) && !ans2b.get(i).get(t)) {
							ans++;
							ans1.add(ll.get(i).get(j));
							ans2.add(rr.get(i).get(t));

							ans1b.get(i).set(j, true);
							ans2b.get(i).set(t, true);
						}
					}

				for (int j = 0; j < ll.get(i).size(); j++)
					for (int t = 0; t < rr.get(rr.size() - 1).size(); t++) {
						if (!ans1b.get(i).get(j) && !ans2b.get(rr.size() - 1).get(t)) {
							ans++;
							ans1.add(ll.get(i).get(j));
							ans2.add(rr.get(rr.size() - 1).get(t));

							ans1b.get(i).set(j, true);
							ans2b.get(rr.size() - 1).set(t, true);
						}
					}

				for (int j = 0; j < ll.get(ll.size() - 1).size(); j++)
					for (int t = 0; t < rr.get(i).size(); t++) {
						if (!ans1b.get(ll.size() - 1).get(j) && !ans2b.get(i).get(t)) {
							ans++;
							ans1.add(ll.get(ll.size() - 1).get(j));
							ans2.add(rr.get(i).get(t));

							ans1b.get(ll.size() - 1).set(j, true);
							ans2b.get(i).set(t, true);
						}
					}
			}

			System.out.println(ans);
			for (int i = 0; i < ans1.size(); i++) {
				System.out.println((ans1.get(i) + 1) + " " + (ans2.get(i) + 1));
			}
//			for (int j = 0; j < k; j++) {
//				System.out.println((char)('a' + j));
//				for (int i = 0; i < ll.get(j).size(); i++) {
//					System.out.print(ll.get(j).get(i) + " ");
//				}
//				System.out.println();
//			}
		}

	}

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

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

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

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

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


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class colored_boots {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String left=sc.next();
		String right=sc.next();
		int pair=0;
		ArrayList<num_2>list=new ArrayList<>();
		int un_l=0;
		int un_r=0;
		HashMap<Character,Integer>map1=new HashMap<>();
		HashMap<Character,Integer>map2=new HashMap<>();
		int[]left_used=new int[n];
		int[]right_used=new int[n];
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)!='?')
			{
				if(map1.containsKey(left.charAt(i)))
				{
					int freq=map1.get(left.charAt(i))+1;
					map1.put(left.charAt(i),freq);
				}
				else
					map1.put(left.charAt(i),1);
			}
			else
			{
				un_l++;
			}
			if(right.charAt(i)!='?')
			{
				if(map2.containsKey(right.charAt(i)))
				{
					int freq=map2.get(right.charAt(i))+1;
					map2.put(right.charAt(i),freq);
				}
				else
					map2.put(right.charAt(i),1);
			}
			else
			{
				un_r++;
			}
		}
		for(int i=0;i<n;i++)
		{
			Character ch=left.charAt(i);
			if(map2.containsKey(ch)&&map2.get(ch)>=1)
			{
				pair++;
				int freq=map2.get(ch)-1;
				map2.put(ch,freq);
				int j=0;
				while(true)
				{
					if(right.charAt(j)==ch && right_used[j]==0)
					{
						num_2 te=new num_2(i+1,j+1);
						list.add(te);
						right_used[j]=1;
						break;
					}
					j++;
				}
				left_used[i]=1;
			}
		}
		if(un_l>0)
		{
			int j=0;
			for(int i=0;i<n && un_l>0;i++)
			{
				if(right_used[i]==0 && right.charAt(i)!='?')
				{
					while(left_used[j]==1 || left.charAt(j)!='?')
						j++;
					num_2 te=new num_2(j+1,i+1);
					list.add(te);
					left_used[j]=1;
					right_used[i]=1;
					un_l--;
					pair++;
				}
			}
		}
		if(un_r>0)
		{
			int j=0;
			for(int i=0;i<n && un_r>0;i++)
			{
				if(left_used[i]==0 && left.charAt(i)!='?')
				{
					while(right_used[j]==1 || right.charAt(j)!='?')
						j++;
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
					un_r--;
					pair++;
				}
			}
		}
		if(un_l>0 && un_r>0)
		{
			pair=pair+Integer.min(un_l,un_r);
			int i=0,j=0;
			while(un_l>0 && un_r>0)
			{
				while(left.charAt(i)!='?' || left_used[i]==1)
					i++;
				while(right.charAt(j)!='?' || right_used[j]==1)
					j++;
				num_2 te=new num_2(i+1,j+1);
				list.add(te);
				right_used[j]=1;
				left_used[i]=1;
				un_r--;
				un_l--;
			}
		}
		System.out.println(pair);
		for(int i=0;i<pair;i++)
		{
			num_2 temp=list.get(i);
			System.out.println(temp.l+" "+temp.r);
		}

	}

}

class num_2{
	int l,r;
	public num_2(int l,int r)
	{
		this.l=l;
		this.r=r;
	}
}


import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class colored_boots {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String left=sc.next();
		String right=sc.next();
		int pair=0;
		ArrayList<num_2>list=new ArrayList<>();
		int un_l=0;
		int un_r=0;
		HashMap<Character,random>map1=new HashMap<>();
		HashMap<Character,random>map2=new HashMap<>();
		int[]left_used=new int[n];
		int[]right_used=new int[n];
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)!='?')
			{
				if(map1.containsKey(left.charAt(i)))
				{
					map1.get(left.charAt(i)).size++;
					map1.get(left.charAt(i)).list.add(i);
				}
				else
				{
					ArrayList<Integer>l=new ArrayList<>();
					l.add(i);
					random r=new random(1,l);
					map1.put(left.charAt(i),r);
				}
			}
			else
			{
				un_l++;
			}
			if(right.charAt(i)!='?')
			{
				if(map2.containsKey(right.charAt(i)))
				{
					map2.get(right.charAt(i)).size++;
					map2.get(right.charAt(i)).list.add(i);
				}
				else
				{
					ArrayList<Integer>rlist=new ArrayList<>();
					rlist.add(i);
					random r=new random(1,rlist);
					map2.put(right.charAt(i),r);
				}
			}
			else
			{
				un_r++;
			}
		}
		for(int i=0;i<n;i++)
		{
			Character ch=left.charAt(i);
			if(map2.containsKey(ch)&&map2.get(ch).size>=1)
			{
				pair++;
				map2.get(ch).size--;
				int index=map2.get(ch).list.get(0);
				map2.get(ch).list.remove(0);
				num_2 te=new num_2(i+1,index+1);
				list.add(te);
				right_used[index]=1;
				left_used[i]=1;
			}
		}
		if(un_l>0)
		{
			int j=0;
			for(int i=0;i<n && un_l>0;i++)
			{
				if(right_used[i]==0 && right.charAt(i)!='?')
				{
					while(left_used[j]==1 || left.charAt(j)!='?')
						j++;
					num_2 te=new num_2(j+1,i+1);
					list.add(te);
					left_used[j]=1;
					right_used[i]=1;
					un_l--;
					pair++;
				}
			}
		}
		if(un_r>0)
		{
			int j=0;
			for(int i=0;i<n && un_r>0;i++)
			{
				if(left_used[i]==0 && left.charAt(i)!='?')
				{
					while(right_used[j]==1 || right.charAt(j)!='?')
						j++;
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
					un_r--;
					pair++;
				}
			}
		}
		if(un_l>0 && un_r>0)
		{
			pair=pair+Integer.min(un_l,un_r);
			int i=0,j=0;
			while(un_l>0 && un_r>0)
			{
				while(left.charAt(i)!='?' || left_used[i]==1)
					i++;
				while(right.charAt(j)!='?' || right_used[j]==1)
					j++;
				num_2 te=new num_2(i+1,j+1);
				list.add(te);
				right_used[j]=1;
				left_used[i]=1;
				un_r--;
				un_l--;
			}
		}
		System.out.println(pair);
		for(int i=0;i<pair;i++)
		{
			num_2 temp=list.get(i);
			System.out.println(temp.l+" "+temp.r);
		}

	}

}

class num_2{
	int l,r;
	public num_2(int l,int r)
	{
		this.l=l;
		this.r=r;
	}
}

class random{
	int size;
	ArrayList<Integer>list;
	public random(int size,ArrayList<Integer>l)
	{
		this.size=size;
		this.list=l;
	}
}


import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class colored_boots {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String left=sc.next();
		String right=sc.next();
		int pair=0;
		ArrayList<num_2>list=new ArrayList<>();
		int un_l=0;
		int un_r=0;
		HashMap<Character,random>map1=new HashMap<>();
		HashMap<Character,random>map2=new HashMap<>();
		int[]left_used=new int[n];
		int[]right_used=new int[n];
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)!='?')
			{
				if(map1.containsKey(left.charAt(i)))
				{
					map1.get(left.charAt(i)).size++;
					map1.get(left.charAt(i)).list.add(i);
				}
				else
				{
					ArrayList<Integer>l=new ArrayList<>();
					l.add(i);
					random r=new random(1,l);
					map1.put(left.charAt(i),r);
				}
			}
			else
			{
				un_l++;
			}
			if(right.charAt(i)!='?')
			{
				if(map2.containsKey(right.charAt(i)))
				{
					map2.get(right.charAt(i)).size++;
					map2.get(right.charAt(i)).list.add(i);
				}
				else
				{
					ArrayList<Integer>rlist=new ArrayList<>();
					rlist.add(i);
					random r=new random(1,rlist);
					map2.put(right.charAt(i),r);
				}
			}
			else
			{
				un_r++;
			}
		}
		for(int i=0;i<n;i++)
		{
			Character ch=left.charAt(i);
			if(map2.containsKey(ch)&&map2.get(ch).size>=1)
			{
				pair++;
				int freq=map2.get(ch).size-1;
				ArrayList<Integer>li=map2.get(ch).list;
				int index=li.get(0);
				li.remove(0);
				num_2 te=new num_2(i+1,index+1);
				list.add(te);
				right_used[index]=1;
				left_used[i]=1;
				random r=new random(freq,li);
				map2.put(ch,r);
			}
		}
		if(un_l>0)
		{
			int j=0;
			for(int i=0;i<n && un_l>0;i++)
			{
				if(right_used[i]==0 && right.charAt(i)!='?')
				{
					while(left_used[j]==1 || left.charAt(j)!='?')
						j++;
					num_2 te=new num_2(j+1,i+1);
					list.add(te);
					left_used[j]=1;
					right_used[i]=1;
					un_l--;
					pair++;
				}
			}
		}
		if(un_r>0)
		{
			int j=0;
			for(int i=0;i<n && un_r>0;i++)
			{
				if(left_used[i]==0 && left.charAt(i)!='?')
				{
					while(right_used[j]==1 || right.charAt(j)!='?')
						j++;
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
					un_r--;
					pair++;
				}
			}
		}
		if(un_l>0 && un_r>0)
		{
			pair=pair+Integer.min(un_l,un_r);
			int i=0,j=0;
			while(un_l>0 && un_r>0)
			{
				while(left.charAt(i)!='?' || left_used[i]==1)
					i++;
				while(right.charAt(j)!='?' || right_used[j]==1)
					j++;
				num_2 te=new num_2(i+1,j+1);
				list.add(te);
				right_used[j]=1;
				left_used[i]=1;
				un_r--;
				un_l--;
			}
		}
		System.out.println(pair);
		for(int i=0;i<pair;i++)
		{
			num_2 temp=list.get(i);
			System.out.println(temp.l+" "+temp.r);
		}

	}

}

class num_2{
	int l,r;
	public num_2(int l,int r)
	{
		this.l=l;
		this.r=r;
	}
}

class random{
	int size;
	ArrayList<Integer>list;
	public random(int size,ArrayList<Integer>l)
	{
		this.size=size;
		this.list=l;
	}
}


import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;

public class colored_boots {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String left=sc.next();
		String right=sc.next();
		int pair=0;
		ArrayList<num_2>list=new ArrayList<>();
		linked[]indices=new linked[27];
		int un_l=0;
		int un_r=0;
		int[]left_used=new int[n];
		int[]right_used=new int[n];
		for(int i=0;i<27;i++)
		{
			indices[i]=new linked();
		}
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)=='?')
			{
				un_l++;
			}
			if(right.charAt(i)!='?')
			{
				int index=(int)right.charAt(i)-'a';
				indices[index].size++;
				indices[index].list.addFirst(i);
			}
			else
			{
				un_r++;
				indices[26].size++;
				indices[26].list.addFirst(i);
			}
		}
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)!='?')
			{
				int index=(int)left.charAt(i)-'a';
				if(indices[index].size>0)
				{
					pair++;
					indices[index].size--;
					int j=indices[index].list.getFirst();
					indices[index].list.removeFirst();
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
				}
			}
		}
		if(un_l>0)
		{
			int j=0;
			for(int i=0;i<n && un_l>0;i++)
			{
				if(right_used[i]==0 && right.charAt(i)!='?')
				{
					while(left_used[j]==1 || left.charAt(j)!='?')
						j++;
					num_2 te=new num_2(j+1,i+1);
					list.add(te);
					left_used[j]=1;
					right_used[i]=1;
					un_l--;
					pair++;
				}
			}
		}
		if(un_r>0)
		{
			int j=0;
			for(int i=0;i<n && un_r>0;i++)
			{
				if(left_used[i]==0 && left.charAt(i)!='?')
				{
					while(right_used[j]==1 || right.charAt(j)!='?')
						j++;
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
					un_r--;
					pair++;
				}
			}
		}
		if(un_l>0 && un_r>0)
		{
			pair=pair+Integer.min(un_l,un_r);
			int i=0,j=0;
			while(un_l>0 && un_r>0)
			{
				while(left.charAt(i)!='?' || left_used[i]==1)
					i++;
				while(right.charAt(j)!='?' || right_used[j]==1)
					j++;
				num_2 te=new num_2(i+1,j+1);
				list.add(te);
				right_used[j]=1;
				left_used[i]=1;
				un_r--;
				un_l--;
			}
		}
		System.out.println(pair);
		for(int i=0;i<pair;i++)
		{
			num_2 temp=list.get(i);
			System.out.println(temp.l+" "+temp.r);
		}

	}

}

class num_2{
	int l,r;
	public num_2(int l,int r)
	{
		this.l=l;
		this.r=r;
	}
}

class linked{
	int size;
	LinkedList<Integer>list;
	public linked()
	{
		this.size=0;
		this.list=new LinkedList<>();
	}
}


import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class colored_boots {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String left=sc.next();
		String right=sc.next();
		int pair=0;
		ArrayList<num_2>list=new ArrayList<>();
		int un_l=0;
		int un_r=0;
		HashMap<Character,random>map1=new HashMap<>();
		HashMap<Character,random>map2=new HashMap<>();
		int[]left_used=new int[n];
		int[]right_used=new int[n];
		for(int i=0;i<n;i++)
		{
			if(left.charAt(i)!='?')
			{
				if(map1.containsKey(left.charAt(i)))
				{
					int freq=map1.get(left.charAt(i)).size+1;
					ArrayList<Integer>l=map1.get(left.charAt(i)).list;
					l.add(i);
					random r=new random(freq,l);
					map1.put(left.charAt(i),r);
				}
				else
				{
					ArrayList<Integer>l=new ArrayList<>();
					l.add(i);
					random r=new random(1,l);
					map1.put(left.charAt(i),r);
				}
			}
			else
			{
				un_l++;
			}
			if(right.charAt(i)!='?')
			{
				if(map2.containsKey(right.charAt(i)))
				{
					int freq=map2.get(right.charAt(i)).size+1;
					ArrayList<Integer>rlist=map2.get(right.charAt(i)).list;
					rlist.add(i);
					random r=new random(freq,rlist);
					map2.put(right.charAt(i),r);
				}
				else
				{
					ArrayList<Integer>rlist=new ArrayList<>();
					rlist.add(i);
					random r=new random(1,rlist);
					map2.put(right.charAt(i),r);
				}
			}
			else
			{
				un_r++;
			}
		}
		for(int i=0;i<n;i++)
		{
			Character ch=left.charAt(i);
			if(map2.containsKey(ch)&&map2.get(ch).size>=1)
			{
				pair++;
				int freq=map2.get(ch).size-1;
				ArrayList<Integer>li=map2.get(ch).list;
				int index=li.get(0);
				li.remove(0);
				num_2 te=new num_2(i+1,index+1);
				list.add(te);
				right_used[index]=1;
				left_used[i]=1;
				random r=new random(freq,li);
				map2.put(ch,r);
			}
		}
		if(un_l>0)
		{
			int j=0;
			for(int i=0;i<n && un_l>0;i++)
			{
				if(right_used[i]==0 && right.charAt(i)!='?')
				{
					while(left_used[j]==1 || left.charAt(j)!='?')
						j++;
					num_2 te=new num_2(j+1,i+1);
					list.add(te);
					left_used[j]=1;
					right_used[i]=1;
					un_l--;
					pair++;
				}
			}
		}
		if(un_r>0)
		{
			int j=0;
			for(int i=0;i<n && un_r>0;i++)
			{
				if(left_used[i]==0 && left.charAt(i)!='?')
				{
					while(right_used[j]==1 || right.charAt(j)!='?')
						j++;
					num_2 te=new num_2(i+1,j+1);
					list.add(te);
					right_used[j]=1;
					left_used[i]=1;
					un_r--;
					pair++;
				}
			}
		}
		if(un_l>0 && un_r>0)
		{
			pair=pair+Integer.min(un_l,un_r);
			int i=0,j=0;
			while(un_l>0 && un_r>0)
			{
				while(left.charAt(i)!='?' || left_used[i]==1)
					i++;
				while(right.charAt(j)!='?' || right_used[j]==1)
					j++;
				num_2 te=new num_2(i+1,j+1);
				list.add(te);
				right_used[j]=1;
				left_used[i]=1;
				un_r--;
				un_l--;
			}
		}
		System.out.println(pair);
		for(int i=0;i<pair;i++)
		{
			num_2 temp=list.get(i);
			System.out.println(temp.l+" "+temp.r);
		}

	}

}

class random{
	int size;
	ArrayList<Integer>list;
	public random(int size,ArrayList<Integer>l)
	{
		this.size=size;
		this.list=l;
	}
}

class num_2{
	int l,r;
	public num_2(int l,int r)
	{
		this.l=l;
		this.r=r;
	}
}


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

public class ddd {
    FastScanner in;
    PrintWriter out;
    boolean systemIO = true;

    private void solve() throws IOException {
        int n = in.nextInt();
        String a = in.next();
        String b = in.next();
        int one[] = new int[27];
        int two[] = new int[27];
        Stack<Integer> first[] = new Stack[27];
        Stack<Integer> second[] = new Stack[27];
        Stack<Integer> ans1 = new Stack<>();
        Stack<Integer> ans2 = new Stack<>();
        for (int i = 0; i < 27; i++) {
            first[i] = new Stack<>();
            second[i] = new Stack<>();
        }

        for (int i = 0; i < n; i++) {
            if (a.charAt(i) == '?') {
                one[26]++;
                first[26].add(i);
            } else {
                one[a.charAt(i) - 'a']++;
                first[a.charAt(i) - 'a'].add(i);
            }
            if (b.charAt(i) == '?') {
                two[26]++;
                second[26].add(i);
            } else {
                second[b.charAt(i) - 'a'].add(i);
                two[b.charAt(i) - 'a']++;
            }

        }

        long ans = 0;

        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[i]);
            one[i] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[i].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[26]);
            one[i] -= x;
            two[26] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[26].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[26], two[i]);
            one[26] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[26].pop());
                ans2.push(second[i].pop());
            }
        }
        long x = Math.min(one[26], two[26]);
        for (int j = 0; j < x; j++) {
            ans1.push(first[26].pop());
            ans2.push(second[26].pop());
        }
        ans += x;
        System.out.println(ans);
        for (int i = 0; i < ans; i++) {
            System.out.println((ans1.pop()+1) + " " + (ans2.pop()+1));
        }

    }

    private void run() throws IOException {
        if (systemIO) {
            in = new ddd.FastScanner(System.in);
            out = new PrintWriter(System.out);
        } else {
            in = new ddd.FastScanner(new File("input.txt"));
            out = new PrintWriter(new File("output.txt"));
        }
        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String nextLine() {
            try {
                return br.readLine();
            } catch (IOException e) {
                return null;
            }
        }

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

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

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

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

    }

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


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

public class ddd {
    FastScanner in;
    PrintWriter out;
    boolean systemIO = true;

    private void solve() throws IOException {
        int n = in.nextInt();
        String a = in.next();
        String b = in.next();
        int one[] = new int[27];
        int two[] = new int[27];
        Stack<Integer> first[] = new Stack[27];
        Stack<Integer> second[] = new Stack[27];
        Stack<Integer> ans1 = new Stack<>();
        Stack<Integer> ans2 = new Stack<>();
        for (int i = 0; i < 27; i++) {
            first[i] = new Stack<>();
            second[i] = new Stack<>();
        }

        for (int i = 0; i < n; i++) {
            if (a.charAt(i) == '?') {
                one[26]++;
                first[26].add(i);
            } else {
                one[a.charAt(i) - 'a']++;
                first[a.charAt(i) - 'a'].add(i);
            }
            if (b.charAt(i) == '?') {
                two[26]++;
                second[26].add(i);
            } else {
                second[b.charAt(i) - 'a'].add(i);
                two[b.charAt(i) - 'a']++;
            }

        }

        long ans = 0;

        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[i]);
            one[i] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[i].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[26]);
            one[i] -= x;
            two[26] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[26].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[26], two[i]);
            one[26] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[26].pop());
                ans2.push(second[i].pop());
            }
        }
        long x = Math.min(one[26], two[26]);
        for (int j = 0; j < x; j++) {
            ans1.push(first[26].pop());
            ans2.push(second[26].pop());
        }
        ans += x;
        System.out.println(ans);
        for (int i = 0; i < ans; i++) {
            out.println((ans1.pop()+1) + " " + (ans2.pop()+1));
        }
        out.close();

    }

    private void run() throws IOException {
        if (systemIO) {
            in = new ddd.FastScanner(System.in);
            out = new PrintWriter(System.out);
        } else {
            in = new ddd.FastScanner(new File("input.txt"));
            out = new PrintWriter(new File("output.txt"));
        }
        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String nextLine() {
            try {
                return br.readLine();
            } catch (IOException e) {
                return null;
            }
        }

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

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

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

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

    }

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


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

public class ddd {
    FastScanner in;
    PrintWriter out;
    boolean systemIO = true;

    private void solve() throws IOException {
        int n = in.nextInt();
        String a = in.next();
        String b = in.next();
        int one[] = new int[27];
        int two[] = new int[27];
        Stack<Integer> first[] = new Stack[27];
        Stack<Integer> second[] = new Stack[27];
        Stack<Integer> ans1 = new Stack<>();
        Stack<Integer> ans2 = new Stack<>();
        for (int i = 0; i < 27; i++) {
            first[i] = new Stack<>();
            second[i] = new Stack<>();
        }

        for (int i = 0; i < n; i++) {
            if (a.charAt(i) == '?') {
                one[26]++;
                first[26].add(i);
            } else {
                one[a.charAt(i) - 'a']++;
                first[a.charAt(i) - 'a'].add(i);
            }
            if (b.charAt(i) == '?') {
                two[26]++;
                second[26].add(i);
            } else {
                second[b.charAt(i) - 'a'].add(i);
                two[b.charAt(i) - 'a']++;
            }

        }

        long ans = 0;

        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[i]);
            one[i] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[i].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[i], two[26]);
            one[i] -= x;
            two[26] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[i].pop());
                ans2.push(second[26].pop());
            }
        }
        for (int i = 0; i < 26; i++) {
            long x = Math.min(one[26], two[i]);
            one[26] -= x;
            two[i] -= x;
            ans += x;
            for (int j = 0; j < x; j++) {
                ans1.push(first[26].pop());
                ans2.push(second[i].pop());
            }
        }
        long x = Math.min(one[26], two[26]);
        for (int j = 0; j < x; j++) {
            ans1.push(first[26].pop());
            ans2.push(second[26].pop());
        }
        ans += x;
        System.out.println(ans);
        for (int i = 0; i < ans; i++) {
            System.out.println(ans1.pop() + " " + ans2.pop());
        }

    }

    private void run() throws IOException {
        if (systemIO) {
            in = new ddd.FastScanner(System.in);
            out = new PrintWriter(System.out);
        } else {
            in = new ddd.FastScanner(new File("input.txt"));
            out = new PrintWriter(new File("output.txt"));
        }
        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String nextLine() {
            try {
                return br.readLine();
            } catch (IOException e) {
                return null;
            }
        }

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

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

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

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

    }

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


/*
 * Author:Kongwen Lu
 * Created Time:  2012-09-17-11.05
 * File Name:
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define FORD(i,a,b) for (int i=(a); i>=(b); i--)
#define REP(i,b) FOR(i,0,b)
#define tests(tc) int tc;scanf("%d",&tc);while(tc--)
#define sf scanf
#define pf printf
using namespace std;
const int maxint = -1u>>1;
const double pi = 3.14159265358979323;
const double eps = 1e-8;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<int>::iterator vit;
struct node
{
  char ch;
  int id;
};
char s[200000];
int main()
{
   // freopen("input.txt","r",stdin);
   // freopen("output.txt","w",stdout);
   gets(s);
   stack<node> st;
   node now;
   int len=strlen(s);
   int ans=0,tmp=0;
   int ansl,ansr,l=-1,r=-1;
   REP(i,len)
   {
       now.ch=s[i];
       now.id=i;
       if(s[i]=='('||s[i]=='[')
          st.push(now);
          else
          if(!st.empty())
          {
              if(s[i]==')'&&st.top().ch=='(')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
              }
              else
              if(s[i]==']'&&st.top().ch=='[')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
                  tmp++;
              }
              else
              {
                  //cout<<'#'<<endl;
                  if(tmp>ans)
                  {
                     ans=tmp;
                     ansl=l;
                     ansr=r;
                  }
                  l=-1;
                  tmp=0;
                  while(!st.empty())
                  st.pop();
              }
          }
   }
   if(tmp>ans)
    {
        ans=tmp;
        ansl=l;
        ansr=r;
    }
   if(!ans) pf("0\n");
   else
   {
       //cout<<ansl<<'#'<<ansr<<endl;
       pf("%d\n",ans);
       FOR(i,ansl,ansr+1)
       pf("%c",s[i]);
       pf("\n");
   }
      return 0;
}


/*
 * Author:Kongwen Lu
 * Created Time:  2012-09-17-11.05
 * File Name:
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define FORD(i,a,b) for (int i=(a); i>=(b); i--)
#define REP(i,b) FOR(i,0,b)
#define tests(tc) int tc;scanf("%d",&tc);while(tc--)
#define sf scanf
#define pf printf
using namespace std;
const int maxint = -1u>>1;
const double pi = 3.14159265358979323;
const double eps = 1e-8;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<int>::iterator vit;
struct node
{
  char ch;
  int id;
};
char s[200000];
int main()
{
   // freopen("input.txt","r",stdin);
   // freopen("output.txt","w",stdout);
   gets(s);
   stack<node> st;
   node now;
   int len=strlen(s);
   int ans=0,tmp=0;
   int ansl,ansr,l=-1,r=-1;
   REP(i,len)
   {
       now.ch=s[i];
       now.id=i;
       if(s[i]=='('||s[i]=='[')
       {
           st.push(now);
           continue;
       }
       if(st.empty())
       {
           if(tmp>ans)
           {
              ans=tmp;
              ansl=l;
              ansr=r;
           }
           l=-1;
           tmp=0;
       }
       else
          {
              if(s[i]==')'&&st.top().ch=='(')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
              }
              else
              if(s[i]==']'&&st.top().ch=='[')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
                  tmp++;
              }
              else
              {
                  //cout<<'#'<<endl;
                  if(!st.empty())
                  if(tmp>ans)
                  {
                     ans=tmp;
                     ansl=l;
                     ansr=r;
                  }
                  l=-1;
                  tmp=0;
                  while(!st.empty())
                  st.pop();
              }
          }

   }
   if(st.empty())
   if(tmp>ans)
    {
        ans=tmp;
        ansl=l;
        ansr=r;
    }
   if(!ans) pf("0\n");
   else
   {
       //cout<<ansl<<'#'<<ansr<<endl;
       pf("%d\n",ans);
       FOR(i,ansl,ansr+1)
       pf("%c",s[i]);
       pf("\n");
   }
      return 0;
}


/*
 * Author:Kongwen Lu
 * Created Time:  2012-09-17-11.05
 * File Name:
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define FORD(i,a,b) for (int i=(a); i>=(b); i--)
#define REP(i,b) FOR(i,0,b)
#define tests(tc) int tc;scanf("%d",&tc);while(tc--)
#define sf scanf
#define pf printf
using namespace std;
const int maxint = -1u>>1;
const double pi = 3.14159265358979323;
const double eps = 1e-8;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<int>::iterator vit;
struct node
{
  char ch;
  int id;
};
char s[200000];
int main()
{
   // freopen("input.txt","r",stdin);
   // freopen("output.txt","w",stdout);
   gets(s);
   stack<node> st;
   node now;
   int len=strlen(s);
   int ans=0,tmp=0;
   int ansl,ansr,l=-1,r=-1;
   REP(i,len)
   {
       now.ch=s[i];
       now.id=i;
       if(s[i]=='('||s[i]=='[')
       {
           st.push(now);
           continue;
       }
       if(st.empty())
       {
           if(tmp>ans)
           {
              ans=tmp;
              ansl=l;
              ansr=r;
           }
           l=-1;
           tmp=0;
       }
       else
          {
              if(s[i]==')'&&st.top().ch=='(')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
              }
              else
              if(s[i]==']'&&st.top().ch=='[')
              {
                  if(l==-1)
                  l=st.top().id;
                  else
                  if(l>st.top().id)
                  l=st.top().id;
                  r=i;
                  st.pop();
                  tmp++;
                  if(st.empty())
                  if(tmp>ans)
                  {
                     ans=tmp;
                     ansl=l;
                     ansr=r;
                  }
              }
              else
              {
                  //cout<<'#'<<endl;
                /*  if(st.empty())
                  if(tmp>ans)
                  {
                     ans=tmp;
                     ansl=l;
                     ansr=r;
                  }
                  */
                  l=-1;
                  tmp=0;
                  while(!st.empty())
                  st.pop();
              }
          }

   }
   if(st.empty())
   if(tmp>ans)
    {
        ans=tmp;
        ansl=l;
        ansr=r;
    }
   if(!ans) pf("0\n");
   else
   {
       //cout<<ansl<<'#'<<ansr<<endl;
       pf("%d\n",ans);
       FOR(i,ansl,ansr+1)
       pf("%c",s[i]);
       pf("\n");
   }
      return 0;
}