import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Set;

public class Codeforces1 {

    public void solve() {
        InputReader in = new InputReader(System.in);
        OutputWriter out = new OutputWriter(System.out);
        int t = in.readInt();
        while (t-- > 0) {
            int n = in.readInt();
            int a[] = IOUtils.readIntegerArray(in, n);
            int b[] = IOUtils.readIntegerArray(in, n);
            int c[] = IOUtils.readIntegerArray(in, n);
            int inp[] = new int[3 * n + 1];
            int k = 0;
            for (int i = 0; i < n; i++) {
                inp[k++] = a[i];
                if ( k >= 2 && inp[k - 1] == inp[k - 2] ) {
                    inp[k - 1] = b[i];
                    if ( i == n - 1 && inp[k - 1] == inp[0] ) {
                        inp[k - 1] = c[i];
                    }
                }
                else if ( i == n - 1 && inp[k - 1] == inp[0] ) {
                    if(inp[k-2]==b[i])
                        inp[k - 1] = c[i];
                    else inp[k - 1] = b[i];
                }
            }
//            int p[] = new int[n + 1];
            for (int i = 0; i < n; i++) {
                out.print(inp[i] + " ");
            }
            out.printLine();
        }
        out.flush();
    }

    public static void main(String[] args) {
        Codeforces1 solver = new Codeforces1();
        solver.solve();
    }

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

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

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

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

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

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

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

    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();
        }

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

    }

    static class IOUtils {

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

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

        public static List<Integer> readIntegerList(InputReader in, int size) {
            List<Integer> set = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                set.add(in.readInt());
            }
            return set;
        }

        public static Set<Integer> readIntegerSet(InputReader in, int size) {
            Set<Integer> set = new HashSet<Integer>();
            for (int i = 0; i < size; i++) {
                set.add(in.readInt());
            }
            return set;
        }
    }
}


import java.util.Scanner;

public class Codeforces {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            int[] a = new int[n];
            int[] b = new int[n];
            int[] c = new int[n];
            for (int i=0;i<n;i++){
                a[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                b[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                c[i] = sc.nextInt();
            }
            int[] ans = new int[n];
            ans[0] = a[0];
            for (int i=1;i<n;i++){
                if (i==n-1){
                    if (ans[i-1]!=a[i] && ans[0]!=a[i])
                        ans[i] = a[i];
                    else if (ans[i-1]!=b[i] && ans[0]!=b[0])
                        ans[i] = b[i];
                    else
                        ans[i] = c[i];
                }
                else{
                    if (ans[i-1]!=a[i])
                        ans[i] = a[i];
                    else if (ans[i-1]!=b[i])
                        ans[i] = b[i];
                    else
                        ans[i] = c[i];
                }
            }
            for (int x : ans){
                System.out.print(x + " ");
            }
            System.out.println();
        }
    }
}


import java.util.Scanner;

public class Codeforces {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            int[] a = new int[n];
            int[] b = new int[n];
            int[] c = new int[n];
            for (int i=0;i<n;i++){
                a[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                b[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                c[i] = sc.nextInt();
            }
            int[] ans = new int[n];
            ans[0] = a[0];
            for (int i=1;i<n;i++){
                if (i==n-1){
                    if (ans[i-1]!=a[i] && ans[0]!=a[i])
                        ans[i] = a[i];
                    else if (ans[i-1]!=b[i] && ans[0]!=b[i])
                        ans[i] = b[i];
                    else
                        ans[i] = c[i];
                }
                else{
                    if (ans[i-1]!=a[i])
                        ans[i] = a[i];
                    else if (ans[i-1]!=b[i])
                        ans[i] = b[i];
                    else
                        ans[i] = c[i];
                }
            }
            for (int x : ans){
                System.out.print(x + " ");
            }
            System.out.println();
        }
    }
}


import java.util.Scanner;

public class Codeforces {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            int[] a = new int[n];
            int[] b = new int[n];
            int[] c = new int[n];
            for (int i=0;i<n;i++){
                a[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                b[i] = sc.nextInt();
            }
            for (int i=0;i<n;i++){
                c[i] = sc.nextInt();
            }
            int[] ans = new int[n];
            ans[0] = a[0];
            for (int i=1;i<n;i++){
                if (ans[i-1]==a[i]){
                    if (ans[i-1]==b[i])
                        ans[i] = c[i];
                    else
                        ans[i] = b[i];
                }
                else if (ans[i-1]==b[i]){
                    if (ans[i-1]==a[i])
                        ans[i] = c[i];
                    else
                        ans[i] = a[i];
                }
                else{
                    if (ans[i-1]==a[i])
                        ans[i] = b[i];
                    else
                        ans[i] = a[i];
                }
            }
            for (int x : ans){
                System.out.print(x + " ");
            }
            System.out.println();
        }
    }
}


		// Working program using Reader Class
		import java.io.DataInputStream;
		import java.io.FileInputStream;
		import java.io.IOException;
		import java.io.InputStreamReader;
		// import java.util.Scanner;
		// import java.util.StringTokenizer;
		import java.util.* ;

		public class Main {
			static class Reader {
				final private int BUFFER_SIZE = 1 << 16;
				private DataInputStream din;
				private byte[] buffer;
				private int bufferPointer,
				bytesRead;

				public Reader() {
					din = new DataInputStream(System. in );
					buffer = new byte[BUFFER_SIZE];
					bufferPointer = bytesRead = 0;
				}

				public Reader(String file_name) throws IOException {
					din = new DataInputStream(new FileInputStream(file_name));
					buffer = new byte[BUFFER_SIZE];
					bufferPointer = bytesRead = 0;
				}

				public String readLine() throws IOException {
					byte[] buf = new byte[64]; // line length
					int cnt = 0,
					c;
					while ((c = read()) != -1) {
						if (c == '\n') break;
						buf[cnt++] = (byte) c;
					}
					return new String(buf, 0, cnt);
				}

				public int nextInt() throws IOException {
					int ret = 0;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();
					do {
						ret = ret * 10 + c - '0';
					} while (( c = read ()) >= '0' && c <= '9');

					if (neg) return - ret;
					return ret;
				}

				public long nextLong() throws IOException {
					long ret = 0;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();
					do {
						ret = ret * 10 + c - '0';
					}
					while (( c = read ()) >= '0' && c <= '9');
					if (neg) return - ret;
					return ret;
				}

				public double nextDouble() throws IOException {
					double ret = 0,
					div = 1;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();

					do {
						ret = ret * 10 + c - '0';
					}
					while (( c = read ()) >= '0' && c <= '9');

					if (c == '.') {
						while ((c = read()) >= '0' && c <= '9') {
							ret += (c - '0') / (div *= 10);
						}
					}

					if (neg) return - ret;
					return ret;
				}

				private void fillBuffer() throws IOException {
					bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
					if (bytesRead == -1) buffer[0] = -1;
				}

				private byte read() throws IOException {
					if (bufferPointer == bytesRead) fillBuffer();
					return buffer[bufferPointer++];
				}

				public void close() throws IOException {
					if (din == null) return;
					din.close();
				}
			}

			public static void main(String[] args) throws IOException {
				Reader sc = new Reader();
				int test,
				i,
				j,
				k = 0;

				// Scanner Obj=new Scanner(System.in);
				test = sc.nextInt();
				for (k = 0; k < test; k++)
				{
	                int n=sc.nextInt();
	                int a[]=new int[n];
	                int b[]=new int[n];
	                int c[]=new int[n];
	                int p[]=new int[n];
	                for(i=0;i<n;i++)
	                {
	                    a[i]=sc.nextInt();

	                }
	                  for(i=0;i<n;i++)
	                {
	                    c[i]=sc.nextInt();

	                }
	                  for(i=0;i<n;i++)
	                {
	                    b[i]=sc.nextInt();

	                }
	                for(i=0;i<n;i++)
	                {
	                    if(i==0)
	                    {
	                     HashSet<Integer> elements= new HashSet<Integer>();
	                     elements.add(a[i+1]);
	                     elements.add(c[i+1]);
	                     elements.add(c[i+1]);
	                     if(!elements.contains(a[i]))
	                     {
	                        p[i]=a[i];
	                     }
	                     else if(!elements.contains(b[i]))
	                     {
	                         p[i]=b[i];

	                     }
	                     else
	                     {
	                         p[i]=c[i];
	                     }
	                    }else
	                    {
	                        HashSet<Integer> elements= new HashSet<Integer>();
	                     elements.add(p[i-1]);

	                     if(!elements.contains(a[i]))
	                     {
	                        p[i]=a[i];
	                     }
	                     else if(!elements.contains(b[i]))
	                     {
	                         p[i]=b[i];

	                     }
	                     else
	                     {
	                         p[i]=c[i];
	                     }
	                    }
	                }
	                for(i=0;i<n;i++)
	                {
	                    System.out.print(p[i]+" ");
	                }
	                System.out.println();

				}
		}
		}


		// Working program using Reader Class
		import java.io.DataInputStream;
		import java.io.FileInputStream;
		import java.io.IOException;
		import java.io.InputStreamReader;
		// import java.util.Scanner;
		// import java.util.StringTokenizer;
		import java.util.* ;

		public class Main {
			static class Reader {
				final private int BUFFER_SIZE = 1 << 16;
				private DataInputStream din;
				private byte[] buffer;
				private int bufferPointer,
				bytesRead;

				public Reader() {
					din = new DataInputStream(System. in );
					buffer = new byte[BUFFER_SIZE];
					bufferPointer = bytesRead = 0;
				}

				public Reader(String file_name) throws IOException {
					din = new DataInputStream(new FileInputStream(file_name));
					buffer = new byte[BUFFER_SIZE];
					bufferPointer = bytesRead = 0;
				}

				public String readLine() throws IOException {
					byte[] buf = new byte[64]; // line length
					int cnt = 0,
					c;
					while ((c = read()) != -1) {
						if (c == '\n') break;
						buf[cnt++] = (byte) c;
					}
					return new String(buf, 0, cnt);
				}

				public int nextInt() throws IOException {
					int ret = 0;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();
					do {
						ret = ret * 10 + c - '0';
					} while (( c = read ()) >= '0' && c <= '9');

					if (neg) return - ret;
					return ret;
				}

				public long nextLong() throws IOException {
					long ret = 0;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();
					do {
						ret = ret * 10 + c - '0';
					}
					while (( c = read ()) >= '0' && c <= '9');
					if (neg) return - ret;
					return ret;
				}

				public double nextDouble() throws IOException {
					double ret = 0,
					div = 1;
					byte c = read();
					while (c <= ' ')
					c = read();
					boolean neg = (c == '-');
					if (neg) c = read();

					do {
						ret = ret * 10 + c - '0';
					}
					while (( c = read ()) >= '0' && c <= '9');

					if (c == '.') {
						while ((c = read()) >= '0' && c <= '9') {
							ret += (c - '0') / (div *= 10);
						}
					}

					if (neg) return - ret;
					return ret;
				}

				private void fillBuffer() throws IOException {
					bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
					if (bytesRead == -1) buffer[0] = -1;
				}

				private byte read() throws IOException {
					if (bufferPointer == bytesRead) fillBuffer();
					return buffer[bufferPointer++];
				}

				public void close() throws IOException {
					if (din == null) return;
					din.close();
				}
			}

			public static void main(String[] args) throws IOException {
				Reader sc = new Reader();
				int test,
				i,
				j,
				k = 0;

				// Scanner Obj=new Scanner(System.in);
				test = sc.nextInt();
				for (k = 0; k < test; k++)
				{
	                int n=sc.nextInt();
	                int a[]=new int[n];
	                int b[]=new int[n];
	                int c[]=new int[n];
	                int p[]=new int[n];
	                for(i=0;i<n;i++)
	                {
	                    a[i]=sc.nextInt();

	                }
	                  for(i=0;i<n;i++)
	                {
	                    c[i]=sc.nextInt();

	                }
	                  for(i=0;i<n;i++)
	                {
	                    b[i]=sc.nextInt();

	                }
	                for(i=0;i<n;i++)
	                {
	                    if(i==0)
	                    {
	                     HashSet<Integer> elements= new HashSet<Integer>();
	                     elements.add(a[i+1]);
	                     elements.add(c[i+1]);
	                     elements.add(c[i+1]);
	                     if(!elements.contains(a[i]))
	                     {
	                        p[i]=a[i];
	                     }
	                     else if(!elements.contains(b[i]))
	                     {
	                         p[i]=b[i];

	                     }
	                     else
	                     {
	                         p[i]=c[i];
	                     }
	                    }else
	                    {
	                       HashSet<Integer> elements= new HashSet<Integer>();
	                       if(i==n-1)
	                    elements.add(p[0]);
	                     elements.add(p[i-1]);

	                     if(!elements.contains(a[i]))
	                     {
	                        p[i]=a[i];
	                     }
	                     else if(!elements.contains(b[i]))
	                     {
	                         p[i]=b[i];

	                     }
	                     else
	                     {
	                         p[i]=c[i];
	                     }
	                    }
	                }
	                for(i=0;i<n;i++)
	                {
	                    System.out.print(p[i]+" ");
	                }
	                System.out.println();

				}
		}
		}


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

public class A implements Runnable {

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

		new Thread(null, new A(), "SwapnilGanguly", 1 << 26).start();
	}

	public void run() {

		MyScanner sc = new MyScanner();
		PrintWriter pr = new PrintWriter(System.out);

		int T = sc.nextInt();
		while (T-- > 0) {

			int n = sc.nextInt();
			int[] a = new int[n];
			int[] b = new int[n];
			int[] c = new int[n];
			int ans[] = new int[n];

			for (int i = 0; i < n; i++)
				a[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				b[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				c[i] = sc.nextInt();

			ans[0] = a[0];

			for (int i = 1; i < n - 1; i++) {

				if (ans[i - 1] == a[i]) {

					if (ans[i - 1] == b[i])
						ans[i] = c[i];
					else
						ans[i] = b[i];
				} else
					ans[i] = a[i];
			}

			if(a[n - 1] == ans[0]) {

				if(b[n - 1] == ans[0])
					ans[n - 1] = c[n - 1];
				else
					ans[n - 1] = b[n - 1];
			}

			else
				ans[n - 1] = a[n - 1];

			for (int i : ans)
				pr.print(i + " ");

			pr.println();
		}
		pr.close();
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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


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

public class A implements Runnable {

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

		new Thread(null, new A(), "SwapnilGanguly", 1 << 26).start();
	}

	public void run() {

		MyScanner sc = new MyScanner();
		PrintWriter pr = new PrintWriter(System.out);

		int T = sc.nextInt();
		while (T-- > 0) {

			int n = sc.nextInt();
			int[] a = new int[n];
			int[] b = new int[n];
			int[] c = new int[n];
			int ans[] = new int[n];
			int k = 1;

			for (int i = 0; i < n; i++)
				a[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				b[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				c[i] = sc.nextInt();

			ans[0] = a[0];

			for (int i = 1; i < n; i++) {

				if (ans[i - 1] == a[i]) {

					if (ans[i - 1] == b[i])
						ans[i] = c[i];
					else
						ans[i] = b[i];
				} else
					ans[i] = a[i];
			}

			for (int i : ans)
				pr.print(i + " ");

			pr.println();
		}
		pr.close();
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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


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

public class A implements Runnable {

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

		new Thread(null, new A(), "SwapnilGanguly", 1 << 26).start();
	}

	public void run() {

		MyScanner sc = new MyScanner();
		PrintWriter pr = new PrintWriter(System.out);

		int T = sc.nextInt();
		while (T-- > 0) {

			int n = sc.nextInt();
			int[] a = new int[n];
			int[] b = new int[n];
			int[] c = new int[n];
			int ans[] = new int[n];

			for (int i = 0; i < n; i++)
				a[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				b[i] = sc.nextInt();
			for (int i = 0; i < n; i++)
				c[i] = sc.nextInt();

			ans[0] = a[0];

			for (int i = 1; i < n; i++) {

				if (ans[i - 1] == a[i]) {

					if (ans[i - 1] == b[i])
						ans[i] = c[i];
					else
						ans[i] = b[i];
				} else
					ans[i] = a[i];
			}

			int x = a[n - 1], y = b[n - 1], z = c[n - 1];

			if(x != ans[n - 2] && x != ans[0])
				ans[n - 1] = x;
			else if(y != ans[n - 2] && y != ans[0])
				ans[n - 1] = y;
			else
				ans[n - 1] = z;

			for (int i : ans)
				pr.print(i + " ");

			pr.println();
		}
		pr.close();
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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


import java.io.*;
import java.util.*;
import java.lang.*;
public class grakn
{
    public static void main(String[] args) throws IOException
    {
        Scanner sc=new Scanner (System.in);
        int t;
        t=sc.nextInt();
        sc.nextLine();
        int r[][]=new int[t][];
        int i,j;
        for(i=0;i<t;i++)
        {
            int n;
            n=sc.nextInt();
            sc.nextLine();
            int a[]=new int[n];
            int b[]=new int[n];
            int c[]=new int[n];
            for(j=0;j<n;j++)
            {
                a[j]=sc.nextInt();
            }
            sc.nextLine();
            for(j=0;j<n;j++)
            {
                b[j]=sc.nextInt();
            }
            sc.nextLine();
            for(j=0;j<n;j++)
            {
                c[j]=sc.nextInt();
            }
            sc.nextLine();
            r[i]=new int[n];
            r[i][0]=a[0];

            for(j=1;j<n-1;j++)
            {

                if(r[i][j-1]!=a[j])
                r[i][j]=a[j];
                else if(r[i][j-1]!=b[j])
                r[i][j]=b[j];
                else if(r[i][j-1]!=c[j])
                r[i][j]=c[j];
            }
            if(r[i][0]!=a[n-1] && r[i][n-2]!=a[n-1])
            r[i][n-1]=a[n-1];
            else if(r[i][0]!=b[n-1] && r[i][n-2]!=b[n-1])
            r[i][n-1]=b[n-1];
            else
            r[i][n-1]=c[n-1];
        }

        for(i=0;i<t;i++)
        {
            for(j=0;j<r[i].length;j++)
            {
                if(j!=r[i].length-1)
                System.out.print(r[i][j]+" ");
                else
                System.out.println(r[i][j]);
            }
        }
    }
}


import java.io.*;
import java.util.*;
import java.lang.*;
public class grakn
{
    public static void main(String[] args) throws IOException
    {
        Scanner sc=new Scanner (System.in);
        int t;
        t=sc.nextInt();
        sc.nextLine();
        int r[][]=new int[t][];
        int i,j;
        for(i=0;i<t;i++)
        {
            int n;
            n=sc.nextInt();
            sc.nextLine();
            int a[]=new int[n];
            int b[]=new int[n];
            int c[]=new int[n];
            for(j=0;j<n;j++)
            {
                a[j]=sc.nextInt();
            }
            sc.nextLine();
            for(j=0;j<n;j++)
            {
                b[j]=sc.nextInt();
            }
            sc.nextLine();
            for(j=0;j<n;j++)
            {
                c[j]=sc.nextInt();
            }
            sc.nextLine();
            r[i]=new int[n];
            r[i][0]=a[0];

            for(j=1;j<n-1;i++)
            {
                if(r[i][j-1]!=a[j])
                r[i][j]=a[j];
                else if(r[i][j-1]!=b[j])
                r[i][j]=b[j];
                else if(r[i][j-1]!=c[j])
                r[i][j]=c[j];
            }
            if(r[i][0]!=a[n-1] && r[i][n-2]!=a[n-1])
            r[i][n-1]=a[n-1];
            else if(r[i][0]!=b[n-1] && r[i][n-2]!=b[n-1])
            r[i][n-1]=b[n-1];
            else
            r[i][n-1]=c[n-1];
        }

        for(i=0;i<t;i++)
        {
            for(j=0;j<r[i].length;j++)
            {
                if(j!=r[i].length-1)
                System.out.print(r[i][j]+" ");
                else
                System.out.println(r[i][j]);
            }
        }
    }
}


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

public class C {

	static int mod = (int) 1e9 + 7;

	static int ar[];
	static Scanner sc = new Scanner(System.in);
	static StringBuilder out = new StringBuilder();

	static ArrayList<Integer> gr[];
	int n;

	static class pair implements Comparable<pair> {

		int f;
		int s;

		public pair(int a, int b) {
			f = a;
			s = b;
		}

		@Override
		public int compareTo(pair o) {
			// TODO Auto-generated method stub
			if (this.s == o.s)
				return o.f - this.f;
			return this.s - o.s;
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int tc = sc.nextInt();
		while (tc-- > 0) {
			int n = sc.nextInt();
			int a[] = new int[n];
			int b[] = new int[n];
			int c[] = new int[n];
			for (int i = 0; i < n; i++) {

				a[i] = sc.nextInt();
			}
			for (int i = 0; i < n; i++) {

				b[i] = sc.nextInt();
			}

			for(int i=0;i<n;i++){

				c[i]=sc.nextInt();
			}

			int val=-1;
			for(int i=0;i<n;i++){

				if(i==n-1){

					int val1=(int)out.charAt(0)-48;
					int ans =-1;
					if(a[i]!=val && a[i] !=val1){
						ans=a[i];
					}
					else if(b[i]!=val && b[i]!=val1)ans=b[i];
					else if(c[i]!=val && c[i]!=val1)ans=c[i];
					out.append(ans+"\n");
					continue;

				}
				if(a[i]!=val){
					out.append(a[i]+" ");
					val=a[i];
				}
				else if(b[i]!=val){
					out.append(b[i]+" ");
					val=b[i];

				}
				else{
					out.append(c[i]+" ");
				}

			}

		}

		System.out.println(out);

	}

}


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

public class C {

	static int mod = (int) 1e9 + 7;

	static int ar[];
	static Scanner sc = new Scanner(System.in);
	static StringBuilder out = new StringBuilder();

	static ArrayList<Integer> gr[];
	int n;

	static class pair implements Comparable<pair> {

		int f;
		int s;

		public pair(int a, int b) {
			f = a;
			s = b;
		}

		@Override
		public int compareTo(pair o) {
			// TODO Auto-generated method stub
			if (this.s == o.s)
				return o.f - this.f;
			return this.s - o.s;
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int tc = sc.nextInt();
		while (tc-- > 0) {
			int n = sc.nextInt();
			int a[] = new int[n];
			int b[] = new int[n];
			int c[] = new int[n];
			for (int i = 0; i < n; i++) {

				a[i] = sc.nextInt();
			}
			for (int i = 0; i < n; i++) {

				b[i] = sc.nextInt();
			}

			for(int i=0;i<n;i++){

				c[i]=sc.nextInt();
			}

			int val=-1;
			for(int i=0;i<n;i++){

				if(i==n-1){

					int val1=(int)out.charAt(0)-48;
					int ans =-1;
					if(a[i]!=val && a[i] !=val1){
						ans=a[i];
					}
					else if(b[i]!=val && b[i]!=val1)ans=b[i];
					else if(c[i]!=val && c[i]!=val1)ans=c[i];
					out.append(ans+"\n");
					continue;

				}
				if(a[i]!=val){
					out.append(a[i]+" ");
					val=a[i];
				}
				else if(b[i]!=val){
					out.append(b[i]+" ");
					val=b[i];

				}
				else{
					out.append(c[i]+" ");
					val=c[i];
				}

			}

		}

		System.out.println(out);

	}

}


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

public class C {

	static int mod = (int) 1e9 + 7;

	static int ar[];
	static Scanner sc = new Scanner(System.in);
	static StringBuilder out = new StringBuilder();

	static ArrayList<Integer> gr[];
	int n;

	static class pair implements Comparable<pair> {

		int f;
		int s;

		public pair(int a, int b) {
			f = a;
			s = b;
		}

		@Override
		public int compareTo(pair o) {
			// TODO Auto-generated method stub
			if (this.s == o.s)
				return o.f - this.f;
			return this.s - o.s;
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int tc = sc.nextInt();
		while (tc-- > 0) {
			int n = sc.nextInt();
			int a[] = new int[n];
			int b[] = new int[n];
			int c[] = new int[n];
			for (int i = 0; i < n; i++) {

				a[i] = sc.nextInt();
			}
			for (int i = 0; i < n; i++) {

				b[i] = sc.nextInt();
			}

			for(int i=0;i<n;i++){

				c[i]=sc.nextInt();
			}

			int val=-1;

			for(int i=0;i<n;i++){

				if(i==n-1){

					int val1=(int)out.charAt(0)-48;
					int ans =a[i];
					if(ans==val || ans ==val1){
						ans=b[i];
					}
					if(ans==val || ans== val1)ans=c[i];

					out.append(ans+"\n");
					continue;

				}
				if(a[i]!=val){
					out.append(a[i]+" ");
					val=a[i];
				}
				else if(b[i]!=val){
					out.append(b[i]+" ");
					val=b[i];

				}
				else{
					out.append(c[i]+" ");
					val=c[i];
				}

			}

		}

		System.out.println(out);

	}

}


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

public class C {

	static int mod = (int) 1e9 + 7;

	static int ar[];
	static Scanner sc = new Scanner(System.in);
	static StringBuilder out = new StringBuilder();

	static ArrayList<Integer> gr[];
	int n;

	static class pair implements Comparable<pair> {

		int f;
		int s;

		public pair(int a, int b) {
			f = a;
			s = b;
		}

		@Override
		public int compareTo(pair o) {
			// TODO Auto-generated method stub
			if (this.s == o.s)
				return o.f - this.f;
			return this.s - o.s;
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int tc = sc.nextInt();
		while (tc-- > 0) {
			int n = sc.nextInt();
			int a[] = new int[n];
			int b[] = new int[n];
			int c[] = new int[n];
			for (int i = 0; i < n; i++) {

				a[i] = sc.nextInt();
			}
			for (int i = 0; i < n; i++) {

				b[i] = sc.nextInt();
			}

			for(int i=0;i<n;i++){

				c[i]=sc.nextInt();
			}

			int val=-1;
			int dp[]=new int[n];
			for(int i=0;i<n;i++){

				if(i==n-1){

					dp[i]=a[i];
					if(dp[i]==dp[0]  || dp[i]==dp[i-1])dp[i]=b[i];
					if(dp[i]==dp[0] || dp[i]==dp[i-1])dp[i]=c[i];
					continue;

				}
				if(a[i]!=val){
					dp[i]=a[i];
					val=a[i];
				}
				else if(b[i]!=val){
					dp[i]=b[i];
					val=b[i];

				}
				else{
					dp[i]=c[i];
					val=c[i];
				}

			}

			for(int i=0;i<n;i++){
				out.append(dp[i]+" ");
			}

			out.append("\n");
		}

		System.out.println(out);

	}

}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100003,INF=1050000000;
struct node{int delta,mx,m,lm,mr,lmr;}t[maxn<<2];
int n;
char s[maxn];
node operator +(node t2,node t3){
	node t1;
	t1.delta=t2.delta+t3.delta;
	t3.mx+=t2.delta;
	t3.m-=2*t2.delta;
	t3.lm-=t2.delta;
	t3.mr-=t2.delta;
	t1.mx=max(t2.mx,t3.mx);
	t1.m=max(t2.m,t3.m);
	t1.lm=max(max(t2.lm,t3.lm),t2.mx+t3.m);
	t1.mr=max(max(t2.mr,t3.mr),t2.m+t3.mx);
	t1.lmr=max(max(t2.lmr,t3.lmr),max(t2.mx+t3.mr,t2.lm+t3.mx));
	return t1;
}
void build(int p,int l,int r){
	if(l==r){
		t[p].mx=t[p].delta=(s[l]=='('?1:-1);
		t[p].m=-2*t[p].mx;
		t[p].lm=t[p].mr=-INF;
		t[p].lmr=-INF;
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p]=t[p<<1]+t[p<<1|1];
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
}
void change(int p,int l,int r,int pos,char k){
	if(l==r){
		int f=(k=='('?2:-2);
		t[p].delta+=f;
		t[p].mx+=f;
		t[p].m-=2*f;
		t[p].lm-=f;
		t[p].mr-=f;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)change(p<<1,l,mid,pos,k);
	else change(p<<1|1,mid+1,r,pos,k);
	t[p]=t[p<<1]+t[p<<1|1];
}
int query(){
	return max(t[1].mx,t[1].lmr);
}
int main(){
	int Q;
	scanf("%d%d%s",&n,&Q,s+1);
	n=(n-1)<<1;
	build(1,1,n);
	printf("%d\n",query());
	while(Q--){
		int x,y;
		scanf("%d%d",&x,&y);
		change(1,1,n,x,s[x]=(s[x]=='('?')':'('));
		change(1,1,n,y,s[y]=(s[y]=='('?')':'('));
// puts(s+1);
		build(1,1,n);
		printf("%d\n",query());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=200003,INF=1050000000;
struct node{int delta,mx,m,lm,mr,lmr;}t[maxn<<2];
int n;
char s[maxn];
node operator +(node t2,node t3){
	node t1;
	t1.delta=t2.delta+t3.delta;
	t3.mx+=t2.delta;
	t3.m-=2*t2.delta;
	t3.lm-=t2.delta;
	t3.mr-=t2.delta;
	t1.mx=max(t2.mx,t3.mx);
	t1.m=max(t2.m,t3.m);
	t1.lm=max(max(t2.lm,t3.lm),t2.mx+t3.m);
	t1.mr=max(max(t2.mr,t3.mr),t2.m+t3.mx);
	t1.lmr=max(max(t2.lmr,t3.lmr),max(t2.mx+t3.mr,t2.lm+t3.mx));
	return t1;
}
void build(int p,int l,int r){
	if(l==r){
		t[p].mx=t[p].delta=(s[l]=='('?1:-1);
		t[p].m=-2*t[p].mx;
		t[p].lm=t[p].mr=-INF;
		t[p].lmr=-INF;
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p]=t[p<<1]+t[p<<1|1];
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
}
void change(int p,int l,int r,int pos,char k){
	if(l==r){
		int f=(k=='('?2:-2);
		t[p].delta+=f;
		t[p].mx+=f;
		t[p].m-=2*f;
		t[p].lm-=f;
		t[p].mr-=f;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)change(p<<1,l,mid,pos,k);
	else change(p<<1|1,mid+1,r,pos,k);
	t[p]=t[p<<1]+t[p<<1|1];
}
int query(){
	return max(t[1].mx,t[1].lmr);
}
int main(){
	int Q;
	scanf("%d%d%s",&n,&Q,s+1);
	n=(n-1)<<1;
	build(1,1,n);
	printf("%d\n",query());
	while(Q--){
		int x,y;
		scanf("%d%d",&x,&y);
		change(1,1,n,x,s[x]=(s[x]=='('?')':'('));
		change(1,1,n,y,s[y]=(s[y]=='('?')':'('));
// puts(s+1);
		build(1,1,n);
		printf("%d\n",query());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=200003,INF=1050000000;
struct node{int delta,mx,m,lm,mr,lmr;}t[maxn<<2];
int n;
char s[maxn];
node operator +(node t2,node t3){
	node t1;
	t1.delta=t2.delta+t3.delta;
	t3.mx+=t2.delta;
	t3.m-=2*t2.delta;
	t3.lm-=t2.delta;
	t3.mr-=t2.delta;
	t1.mx=max(t2.mx,t3.mx);
	t1.m=max(t2.m,t3.m);
	t1.lm=max(max(t2.lm,t3.lm),t2.mx+t3.m);
	t1.mr=max(max(t2.mr,t3.mr),t2.m+t3.mx);
	t1.lmr=max(max(t2.lmr,t3.lmr),max(t2.mx+t3.mr,t2.lm+t3.mx));
	return t1;
}
void build(int p,int l,int r){
	if(l==r){
		t[p].mx=t[p].delta=(s[l]=='('?1:-1);
		t[p].m=-2*t[p].mx;
		t[p].lm=t[p].mr=-INF;
		t[p].lmr=-INF;
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p]=t[p<<1]+t[p<<1|1];
// printf("l:%d r:%d delta:%d mx:%d m:%d lm:%d mr:%d lmr:%d\n",l,r,t[p].delta,t[p].mx,t[p].m,t[p].lm,t[p].mr,t[p].lmr);
}
void change(int p,int l,int r,int pos,char k){
	if(l==r){
		int f=(k=='('?2:-2);
		t[p].delta+=f;
		t[p].mx+=f;
		t[p].m-=2*f;
		t[p].lm-=f;
		t[p].mr-=f;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)change(p<<1,l,mid,pos,k);
	else change(p<<1|1,mid+1,r,pos,k);
	t[p]=t[p<<1]+t[p<<1|1];
}
int query(){
	return max(t[1].mx,t[1].lmr);
}
int main(){
	int Q;
	scanf("%d%d%s",&n,&Q,s+1);
	n=(n-1)<<1;
	build(1,1,n);
	printf("%d\n",query());
	while(Q--){
		int x,y;
		scanf("%d%d",&x,&y);
		change(1,1,n,x,s[x]=(s[x]=='('?')':'('));
		change(1,1,n,y,s[y]=(s[y]=='('?')':'('));
// puts(s+1);
		printf("%d\n",query());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=100003,INF=1050000000;
struct node{int delta,mx,m,lm,mr,lmr;}t[maxn<<2];
int n;
char s[maxn];
node operator +(node t2,node t3){
	node t1;
	t1.delta=t2.delta+t3.delta;
	t3.mx+=t2.delta;
	t3.m-=2*t2.delta;
	t3.lm-=t2.delta;
	t3.mr-=t2.delta;
	t1.mx=max(t2.mx,t3.mx);
	t1.m=max(t2.m,t3.m);
	t1.lm=max(max(t2.lm,t3.lm),t2.mx+t3.m);
	t1.mr=max(max(t2.mr,t3.mr),t2.m+t3.mx);
	t1.lmr=max(max(t2.lmr,t3.lmr),max(t2.mx+t3.mr,t2.lm+t3.mx));
	return t1;
}
void build(int p,int l,int r){
	if(l==r){
		t[p].mx=t[p].delta=(s[l]=='('?1:-1);
		t[p].m=-2*t[p].mx;
		t[p].lm=t[p].mr=-INF;
		t[p].lmr=-INF;
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p]=t[p<<1]+t[p<<1|1];
}
void change(int p,int l,int r,int pos,char k){
	if(l==r){
		int f=(k=='('?2:-2);
		t[p].delta+=f;
		t[p].mx+=f;
		t[p].m-=2*f;
		t[p].lm-=f;
		t[p].mr-=f;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)change(p<<1,l,mid,pos,k);
	else change(p<<1|1,mid+1,r,pos,k);
	t[p]=t[p<<1]+t[p<<1|1];
}
int query(){
	return max(t[1].mx,t[1].lmr);
}
int main(){
	int Q;
	scanf("%d%d%s",&n,&Q,s+1);
	build(1,1,n);
	printf("%d\n",query());
	while(Q--){
		int x,y;
		scanf("%d%d",&x,&y);
		change(1,1,n,x,s[x]=(s[x]=='('?')':'('));
		change(1,1,n,y,s[y]=(s[y]=='('?')':'('));
// puts(s+1);
		build(1,1,n);
		printf("%d\n",query());
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=3e5+10;
const double eps=1e-8;
const int mod=1e9+9;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}

typedef struct node{
    int pmx,lmx,sum,ans,maxx,minn;
}node;
node d[MAXN<<2];
char str[MAXN];
void up(int x){
    d[x].sum=d[x<<1].sum+d[x<<1|1].sum;
    d[x].pmx=max(d[x<<1].pmx,max(d[x<<1|1].maxx-2*d[x<<1].minn+d[x<<1].sum,d[x<<1|1].pmx-d[x<<1].sum));
    d[x].lmx=max(d[x<<1].lmx,max(d[x<<1|1].lmx-d[x<<1].sum,d[x<<1].maxx-2*d[x<<1|1].minn-2*d[x<<1].sum));
    d[x].minn=min(d[x<<1].minn,d[x<<1|1].minn+d[x<<1].sum);
    d[x].maxx=max(d[x<<1].maxx,d[x<<1|1].maxx+d[x<<1].sum);
    d[x].ans=max(d[x<<1].ans,max(d[x<<1|1].ans,d[x<<1].lmx+d[x<<1].sum+d[x<<1|1].maxx));
   // cout<<d[x].ans<<"======"<<" "<<d[x<<1].lmx<<" "<<d[x<<1].sum<<" "<<d[x<<1|1].maxx<<endl;
    d[x].ans=max(d[x].ans,d[x<<1].maxx+d[x<<1|1].pmx-d[x<<1].sum);
}
int a[MAXN];
void built(int x,int l,int r){
    if(l==r){
    	if(str[l]=='(')a[l]=1;else a[l]=-1;
	d[x].ans=0;d[x].minn=d[x].sum=d[x].maxx=a[l];
	d[x].pmx=d[x].lmx=-a[l];
	return ;
    }
    int mid=(l+r)>>1;
    built(x<<1,l,mid);built(x<<1|1,mid+1,r);
    up(x);
    //cout<<x<<" "<<l<<" "<<r<<" "<<d[x].ans<<endl;
}
void update(int x,int l,int r,int t,int k){
    if(l==r){
	d[x].sum=d[x].maxx=d[x].minn=k;
	d[x].pmx=d[x].lmx=-k;d[x].ans=0;
	return ;
    }
    int mid=(l+r)>>1;
    if(t<=mid)update(x<<1,l,mid,t,k);
    else update(x<<1|1,mid+1,r,t,k);
    up(x);
}

int main(){
    int n=read();int m=read();
    scanf("%s",str+1);
    built(1,1,2*n-2);
    printf("%d\n",d[1].ans);
    while(m--){
	int x=read();int y=read();
	swap(a[x],a[y]);
	update(1,1,2*n-2,x,a[x]);
	update(1,1,2*n-2,y,a[y]);
	printf("%d\n",d[1].ans);
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
template<typename T1, typename T2> inline bool Min(T1 &a, const T2 &b){ if (b >= a) return false; a = b; return true; }
template<typename T1, typename T2> inline bool Max(T1 &a, const T2 &b){ if (b <= a) return false; a = b; return true; }
template<typename T1, typename T2> inline void Mad(T1 &a, const T2 &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }

const int N = 1e5 + 10;
int n, q;
char s[N];
int a[N]; //括号前缀序列 左括号1右括号-1
/*
设位置a<=b<=c
ac两点距离等于dep(a)+dep(c)-2*lca(a,c)
在括号前缀序列上 当前位置的值就代表图中当前节点深度
ac两点的lca点就在前缀序列的最小值b上
则当前树最大距离为Max(a-2b+c)
*/
struct tree //线段树维护当前区间 最大的a 最小的b 最大的a-2b、c-2b、a-2b+c
{
	int l, r;
	int a, b, ab, bc, abc, lzy;
	void Modify(int v) //将当前区间前缀加上v
	{
		a += v, b += v; //最大a最小b直接受到影响
		ab -= v, bc -= v; //由于-2b ab和bc都缩小
	}
}tre[N * 4];
#define ls x << 1
#define rs x << 1 | 1

void PushUp(int x)
{
	tre[x].a = max(tre[ls].a, tre[rs].a); //a左右儿子取最大
	tre[x].b = min(tre[ls].b, tre[rs].b); //a左右儿子取最小
	tre[x].ab = max({ tre[ls].ab, tre[rs].ab, tre[ls].a - 2 * tre[rs].b }); //左右儿子取最大 尝试左儿子a-2*右儿子b
	tre[x].bc = max({ tre[ls].bc, tre[rs].bc, tre[rs].a - 2 * tre[ls].b }); //尝试右儿子a-2*左儿子b 右儿子a相当于c
	tre[x].abc = max({ tre[ls].abc, tre[rs].abc, tre[ls].ab + tre[rs].a, tre[ls].a + tre[rs].bc }); //左a+右bc 左ab+右a
}
void PushDown(int x)
{
	if (tre[x].lzy)
	{
		tre[ls].Modify(tre[x].lzy), tre[rs].Modify(tre[x].lzy);
		tre[x].lzy = 0;
	}
}
void Build(int x, int l, int r)
{
	tre[x].l = l, tre[x].r = r, tre[x].lzy = 0;
	if (l == r)
	{
		tre[x].Modify(a[l]);
		return;
	}
	int m = l + r >> 1;
	Build(ls, l, m);
	Build(rs, m + 1, r);
	PushUp(x);
}
void Update(int x, int pl, int pr, int v) //将[pl, pr]值+v
{
	int l = tre[x].l, r = tre[x].r;
	if (pl <= l && r <= pr)
	{
		tre[x].Modify(v);
		return;
	}
	PushDown(x);
	int m = l + r >> 1;
	if (pl <= m)
		Update(ls, pl, pr, v);
	if (pr > m)
		Update(rs, pl, pr, v);
	PushUp(x);
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	cin >> n >> q;
	n = (n - 1) * 2;
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i)
		a[i] = a[i - 1] + (s[i] == '(' ? 1 : -1);
	Build(1, 1, n);
	printf("%d\n", tre[1].abc); //整个树的abc
	while (q--)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		if (l > r)
			swap(l, r);
		if (s[l] != s[r]) //括号相同则不造成影响
		{
			Update(1, l, r - 1, s[l] == '(' ? -2 : 2); //如果l为左括号则前缀序列[l, r-1]会减少2否则增加2
			swap(s[l], s[r]);
		}
		printf("%d\n", tre[1].abc);
	}

	return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
template<typename T1, typename T2> inline bool Min(T1 &a, const T2 &b){ if (b >= a) return false; a = b; return true; }
template<typename T1, typename T2> inline bool Max(T1 &a, const T2 &b){ if (b <= a) return false; a = b; return true; }
template<typename T1, typename T2> inline void Mad(T1 &a, const T2 &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }

const int N = 2e5 + 10;
int n, q;
char s[N];
int a[N]; //括号前缀序列 左括号1右括号-1
/*
设位置a<=b<=c
ac两点距离等于dep(a)+dep(c)-2*lca(a,c)
在括号前缀序列上 当前位置的值就代表图中当前节点深度
ac两点的lca点就在前缀序列的最小值b上
则当前树最大距离为Max(a-2b+c)
*/
struct tree //线段树维护当前区间 最大的a 最小的b 最大的a-2b、c-2b、a-2b+c
{
	int l, r;
	int a, b, ab, bc, abc, lzy;
	void Modify(int v) //将当前区间前缀加上v
	{
		a += v, b += v; //最大a最小b直接受到影响
		ab -= v, bc -= v; //由于-2b ab和bc都缩小
		lzy += v; //lzy累加直到pushdown清空
	}
}tre[N * 4];
#define ls x << 1
#define rs x << 1 | 1

void PushUp(int x)
{
	tre[x].a = max(tre[ls].a, tre[rs].a); //a左右儿子取最大
	tre[x].b = min(tre[ls].b, tre[rs].b); //a左右儿子取最小
	tre[x].ab = max({ tre[ls].ab, tre[rs].ab, tre[ls].a - 2 * tre[rs].b }); //左右儿子取最大 尝试左儿子a-2*右儿子b
	tre[x].bc = max({ tre[ls].bc, tre[rs].bc, tre[rs].a - 2 * tre[ls].b }); //尝试右儿子a-2*左儿子b 右儿子a相当于c
	tre[x].abc = max({ tre[ls].abc, tre[rs].abc, tre[ls].ab + tre[rs].a, tre[ls].a + tre[rs].bc }); //左a+右bc 左ab+右a
}
void PushDown(int x)
{
	if (tre[x].lzy)
	{
		tre[ls].Modify(tre[x].lzy), tre[rs].Modify(tre[x].lzy);
		tre[x].lzy = 0;
	}
}
void Build(int x, int l, int r)
{
	tre[x].l = l, tre[x].r = r, tre[x].lzy = 0;
	if (l == r)
	{
		tre[x].Modify(a[l]);
		return;
	}
	int m = l + r >> 1;
	Build(ls, l, m);
	Build(rs, m + 1, r);
	PushUp(x);
}
void Update(int x, int pl, int pr, int v) //将[pl, pr]值+v
{
	int l = tre[x].l, r = tre[x].r;
	if (pl <= l && r <= pr)
	{
		tre[x].Modify(v);
		return;
	}
	PushDown(x);
	int m = l + r >> 1;
	if (pl <= m)
		Update(ls, pl, pr, v);
	if (pr > m)
		Update(rs, pl, pr, v);
	PushUp(x);
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	cin >> n >> q;
	n = (n - 1) * 2;
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i)
		a[i] = a[i - 1] + (s[i] == '(' ? 1 : -1);
	Build(1, 1, n);
	printf("%d\n", tre[1].abc); //整个树的abc
	while (q--)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		if (l > r)
			swap(l, r);
		if (s[l] != s[r]) //括号相同则不造成影响
		{
			Update(1, l, r - 1, s[l] == '(' ? -2 : 2); //如果l为左括号则前缀序列[l, r-1]会减少2否则增加2
			swap(s[l], s[r]);
		}
		printf("%d\n", tre[1].abc);
	}

	return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
template<typename T1, typename T2> inline bool Min(T1 &a, const T2 &b){ if (b >= a) return false; a = b; return true; }
template<typename T1, typename T2> inline bool Max(T1 &a, const T2 &b){ if (b <= a) return false; a = b; return true; }
template<typename T1, typename T2> inline void Mad(T1 &a, const T2 &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }

const int N = 2e5 + 10;
int n, q;
char s[N];
int a[N]; //括号前缀序列 左括号1右括号-1
/*
设位置a<=b<=c
ac两点距离等于dep(a)+dep(c)-2*lca(a,c)
在括号前缀序列上 当前位置的值就代表图中当前节点深度
ac两点的lca点就在前缀序列的最小值b上
则当前树最大距离为Max(a-2b+c)
*/
struct tree //线段树维护当前区间 最大的a 最小的b 最大的a-2b、c-2b、a-2b+c
{
	int l, r;
	int a, b, ab, bc, abc, lzy;
	void Modify(int v) //将当前区间前缀加上v
	{
		a += v, b += v; //最大a最小b直接受到影响
		ab -= v, bc -= v; //由于-2b ab和bc都缩小
		lzy = v;
	}
}tre[N * 4];
#define ls x << 1
#define rs x << 1 | 1

void PushUp(int x)
{
	tre[x].a = max(tre[ls].a, tre[rs].a); //a左右儿子取最大
	tre[x].b = min(tre[ls].b, tre[rs].b); //a左右儿子取最小
	tre[x].ab = max({ tre[ls].ab, tre[rs].ab, tre[ls].a - 2 * tre[rs].b }); //左右儿子取最大 尝试左儿子a-2*右儿子b
	tre[x].bc = max({ tre[ls].bc, tre[rs].bc, tre[rs].a - 2 * tre[ls].b }); //尝试右儿子a-2*左儿子b 右儿子a相当于c
	tre[x].abc = max({ tre[ls].abc, tre[rs].abc, tre[ls].ab + tre[rs].a, tre[ls].a + tre[rs].bc }); //左a+右bc 左ab+右a
}
void PushDown(int x)
{
	if (tre[x].lzy)
	{
		tre[ls].Modify(tre[x].lzy), tre[rs].Modify(tre[x].lzy);
		tre[x].lzy = 0;
	}
}
void Build(int x, int l, int r)
{
	tre[x].l = l, tre[x].r = r, tre[x].lzy = 0;
	if (l == r)
	{
		tre[x].Modify(a[l]);
		return;
	}
	int m = l + r >> 1;
	Build(ls, l, m);
	Build(rs, m + 1, r);
	PushUp(x);
}
void Update(int x, int pl, int pr, int v) //将[pl, pr]值+v
{
	int l = tre[x].l, r = tre[x].r;
	if (pl <= l && r <= pr)
	{
		tre[x].Modify(v);
		return;
	}
	PushDown(x);
	int m = l + r >> 1;
	if (pl <= m)
		Update(ls, pl, pr, v);
	if (pr > m)
		Update(rs, pl, pr, v);
	PushUp(x);
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	cin >> n >> q;
	n = (n - 1) * 2;
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i)
		a[i] = a[i - 1] + (s[i] == '(' ? 1 : -1);
	Build(1, 1, n);
	printf("%d\n", tre[1].abc); //整个树的abc
	while (q--)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		if (l > r)
			swap(l, r);
		if (s[l] != s[r]) //括号相同则不造成影响
		{
			Update(1, l, r - 1, s[l] == '(' ? -2 : 2); //如果l为左括号则前缀序列[l, r-1]会减少2否则增加2
			swap(s[l], s[r]);
		}
		printf("%d\n", tre[1].abc);
	}

	return 0;
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

char s[100010];
int num[100010];

struct SEG_Tree{
    struct SEG{
        int l;
        int r;
        int f0;
        int f1;
        int f2;
        int f3;
        int sum;
        int min;
        int max;

        void init(char x){
            f0 = f1 = f2 = f3 = 1;
            if(x == '('){
                min = 0;
                max = 1;
                sum = 1;
            } else {
                min = -1;
                max = 0;
                sum = -1;
            }
        }

        void print(){
            printf("[%d, %d] = {%d, %d, %d, %d, %d, %d, %d}\n", l, r, min, max, sum, f0, f1, f2, f3);
        }
    }t[400010];

    void push_up(int cur){
        t[cur].min = std::min(t[lc(cur)].min, t[lc(cur)].sum + t[rc(cur)].min);
        t[cur].max = std::max(t[lc(cur)].max, t[lc(cur)].sum + t[rc(cur)].max);
        t[cur].f0 = std::max(std::max(t[lc(cur)].f0, t[rc(cur)].f0), std::max(t[lc(cur)].f2 + t[rc(cur)].max, t[rc(cur)].f1 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f1 = std::max(-t[lc(cur)].sum + t[rc(cur)].f1, std::max(t[lc(cur)].f1, t[lc(cur)].f3 + t[rc(cur)].max));
        t[cur].f2 = std::max(t[rc(cur)].sum + t[lc(cur)].f2, std::max(t[rc(cur)].f2, t[rc(cur)].f3 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f3 = std::max(t[lc(cur)].f3 + t[rc(cur)].sum, t[rc(cur)].f3 - t[lc(cur)].sum);
        t[cur].sum = t[lc(cur)].sum + t[rc(cur)].sum;
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].init(s[l]);
            num[l] = cur;
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
        // t[cur].print();
    }

    void modify(int cur){
        cur >>= 1;
        while(cur){
            push_up(cur);
            cur >>= 1;
        }
    }
}t;

int main(){
    int n = (inp() << 1) - 2;
    int m = inp();
    scanf("%s", s + 1);
    t.build(1, 1, n);
    printf("%d\n", t.t[1].f0);
    while(m--){
        int x = inp();
        int y = inp();
        std::swap(s[x], s[y]);
        t.t[num[x]].init(s[x]);
        t.t[num[y]].init(s[y]);
        t.modify(num[x]);
        t.modify(num[y]);
        printf("%d\n", t.t[1].f0);
    }
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

char s[200010];
int num[200010];

struct SEG_Tree{
    struct SEG{
        int l;
        int r;
        int f0;
        int f1;
        int f2;
        int f3;
        int sum;
        int min;
        int max;

        void init(char x){
            f0 = f1 = f2 = f3 = 1;
            if(x == '('){
                min = 0;
                max = 1;
                sum = 1;
            } else {
                min = -1;
                max = 0;
                sum = -1;
            }
        }

        void print(){
            printf("[%d, %d] = {%d, %d, %d, %d, %d, %d, %d}\n", l, r, min, max, sum, f0, f1, f2, f3);
        }
    }t[800010];

    void push_up(int cur){
        t[cur].min = std::min(t[lc(cur)].min, t[lc(cur)].sum + t[rc(cur)].min);
        t[cur].max = std::max(t[lc(cur)].max, t[lc(cur)].sum + t[rc(cur)].max);
        t[cur].f0 = std::max(std::max(t[lc(cur)].f0, t[rc(cur)].f0), std::max(t[lc(cur)].f2 + t[rc(cur)].max, t[rc(cur)].f1 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f1 = std::max(-t[lc(cur)].sum + t[rc(cur)].f1, std::max(t[lc(cur)].f1, t[lc(cur)].f3 + t[rc(cur)].max));
        t[cur].f2 = std::max(t[rc(cur)].sum + t[lc(cur)].f2, std::max(t[rc(cur)].f2, t[rc(cur)].f3 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f3 = std::max(t[lc(cur)].f3 + t[rc(cur)].sum, t[rc(cur)].f3 - t[lc(cur)].sum);
        t[cur].sum = t[lc(cur)].sum + t[rc(cur)].sum;
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].init(s[l]);
            num[l] = cur;
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
        // t[cur].print();
    }

    void modify(int cur){
        cur >>= 1;
        while(cur){
            push_up(cur);
            cur >>= 1;
        }
    }
}t;

int main(){
    int n = (inp() << 1) - 2;
    int m = inp();
    scanf("%s", s + 1);
    t.build(1, 1, n);
    printf("%d\n", t.t[1].f0);
    while(m--){
        int x = inp();
        int y = inp();
        std::swap(s[x], s[y]);
        t.t[num[x]].init(s[x]);
        t.t[num[y]].init(s[y]);
        t.modify(num[x]);
        t.modify(num[y]);
        printf("%d\n", t.t[1].f0);
    }
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

char s[100010];
int num[100010];

struct SEG_Tree{
    struct SEG{
        int l;
        int r;
        int f0;
        int f1;
        int f2;
        int f3;
        int sum;
        int min;
        int max;

        void init(char x){
            f0 = f1 = f2 = f3 = 1;
            if(x == '('){
                min = 0;
                max = 1;
                sum = 1;
            } else {
                min = -1;
                max = 0;
                sum = -1;
            }
        }

        void print(){
            printf("[%d, %d] = {%d, %d, %d, %d, %d, %d, %d}\n", l, r, min, max, sum, f0, f1, f2, f3);
        }
    }t[400010];

    void push_up(int cur){
        t[cur].min = std::min(t[lc(cur)].min, t[lc(cur)].sum + t[rc(cur)].min);
        t[cur].max = std::max(t[lc(cur)].max, t[lc(cur)].sum + t[rc(cur)].max);
        t[cur].f0 = std::max(std::max(t[lc(cur)].f0, t[rc(cur)].f0), std::max(t[lc(cur)].f2 + t[rc(cur)].max, t[rc(cur)].f1 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f1 = std::max(-t[lc(cur)].sum + t[rc(cur)].f1, std::max(t[lc(cur)].f1, t[lc(cur)].f3 + t[rc(cur)].max));
        t[cur].f2 = std::max(t[rc(cur)].sum + t[lc(cur)].f2, std::max(t[lc(cur)].f2, t[rc(cur)].f3 - (t[lc(cur)].sum - t[lc(cur)].max)));
        t[cur].f3 = std::max(t[lc(cur)].f3 + t[rc(cur)].sum, t[rc(cur)].f3 - t[lc(cur)].sum);
        t[cur].sum = t[lc(cur)].sum + t[rc(cur)].sum;
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].init(s[l]);
            num[l] = cur;
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
        // t[cur].print();
    }

    void modify(int cur){
        cur >>= 1;
        while(cur){
            push_up(cur);
            cur >>= 1;
        }
    }
}t;

int main(){
    int n = (inp() << 1) - 2;
    int m = inp();
    scanf("%s", s + 1);
    t.build(1, 1, n);
    printf("%d\n", t.t[1].f0);
    while(m--){
        int x = inp();
        int y = inp();
        std::swap(s[x], s[y]);
        t.t[num[x]].init(s[x]);
        t.t[num[y]].init(s[y]);
        t.modify(num[x]);
        t.modify(num[y]);
        printf("%d\n", t.t[1].f0);
    }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define  rs (x<<1|1)
#define mid ((l+r)>>1)
#define N 200000
using namespace std;
struct zero{
int sum,prex,prem,sucx,sucm,pred,sucd,d,ans;
zero(){}
zero(int p1,int p2,int p3,int p4,int p5,int p6,int p7,int p8,int p9){sum=p1,prex=p2,prem=p3,sucx=p4,sucm=p5,pred=p6,sucd=p7,d=p8,ans=p9;}
}tree[N<<2];
// sum:Çø¼äºÍ
// ans:Çø¼ä´ð°¸
// pre/suc-x/m Çø¼ä Ç°/ºó ×º×î ´ó/Ð¡ Öµ
// pre/suc-d Ç°/ºó ×º DÖµ
// d Çø¼äD Öµ
const zero L=zero(1,1,0,1,0,1,1,1,1);
const zero R=zero(-1,0,-1,0,-1,1,1,1,1);
char input[N];
zero operator +(const zero &a,const zero &b){
    zero c;
    c.prex=max(a.prex,a.sum+b.prex);
    c.sucx=max(b.sucx,a.sucx+b.sum);
    c.prem=min(a.prem,a.sum+b.prem);
    c.sucm=min(b.sucm,a.sucm+b.sum);
    c.d=max(b.d-a.sum,a.d+b.sum);//Õû¸öÇø¼äµÄDÖµ£¬¾ÍÊÇÕû¸öÇø¼äµÄÉî¶È
    c.pred=max(a.pred,max(b.pred-a.sum,a.d+b.prex));
    c.sucd=max(b.sucd,max(b.sum+a.sucd,b.d-a.sucm));
    c.sum=a.sum+b.sum;
    c.ans=max(max(a.ans,b.ans),max(b.pred-a.sucm,a.sucd+b.prex));
    return c;
}
void build(int x,int l,int r){
    if(l==r){if(input[l]=='(')tree[x]=L;else tree[x]=R;return;}
    build(ls,l,mid),build(rs,mid+1,r);
    tree[x]=tree[ls]+tree[rs];
}
void update(int x,int l,int r,int pos){
    if(l==r){if(input[l]=='(')tree[x]=L;else tree[x]=R;return;}
    if(pos<=mid)update(ls,l,mid,pos);else update(rs,mid+1,r,pos);
    tree[x]=tree[ls]+tree[rs];
}
int n,m;
int main()
{
    scanf("%d%d",&n,&m);n=(n-1)*2;
    scanf("%s",input+1);
    build(1,1,n);
    printf("%d\n",tree[1].ans);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        swap(input[a],input[b]);
        update(1,1,n,a),update(1,1,n,b);
        printf("%d\n",tree[1].ans);
    }
}


#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
const int inf = 0x3f3f3f3f;
int n,q;
char s[maxn];
struct node{
	int a,b,l1,l2,r1,r2,dis;
	inline void init(char x){
		a=b=0,dis=-inf;
		l1=r1=1;
		if(x=='(') b=1,l2=1,r2=0;
		else if(x==')') a=1,r2=1,l2=0;
	}
}t[maxn<<2];
void upd(int i){
	int lc=i<<1,rc=i<<1|1;
	if(t[lc].b>t[rc].a) t[i].a=t[lc].a,t[i].b=t[lc].b-t[rc].a+t[rc].b;
	else t[i].a=t[lc].a+t[rc].a-t[lc].b,t[i].b=t[rc].b;
	t[i].dis=max(max(t[lc].r1+t[rc].l2,t[lc].r2+t[rc].l1),max(t[lc].dis,t[rc].dis));
	t[i].l1=max(t[lc].l1,max(t[lc].a+t[lc].b+t[rc].l2,t[lc].a-t[lc].b+t[rc].l1));
	t[i].l2=max(t[lc].l2,t[lc].b-t[lc].a+t[rc].l2);
	t[i].r1=max(t[rc].r1,max(t[rc].a+t[rc].b+t[lc].r2,t[rc].b-t[rc].a+t[lc].r1));
	t[i].r2=max(t[rc].r2,t[rc].a-t[rc].b+t[lc].r2);
}
void build(int i,int l,int r){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	build(i<<1,l,mid),build(i<<1|1,mid+1,r);
	upd(i);
}
void insert(int i,int l,int r,int x){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	if(x<=mid) insert(i<<1,l,mid,x);
	else insert(i<<1|1,mid+1,r,x);
	upd(i);
}
int main()
{
	scanf("%d%d%s",&n,&q,s+1),n=(n-1)<<1;
	build(1,1,n);
	printf("%d\n",t[1].dis);
	while(q--){
		int x,y;
		scanf("%d%d",&x,&y),swap(s[x],s[y]);
		insert(1,1,n,x),insert(1,1,n,y);
		printf("%d\n",t[1].dis);
	}
}


#include<bits/stdc++.h>
#define maxn 200005
using namespace std;
const int inf = 0x3f3f3f3f;
int n,q;
char s[maxn];
struct node{
	int a,b,l1,l2,r1,r2,dis;
	inline void init(char x){
		a=b=0,dis=-inf;
		l1=r1=1;
		if(x=='(') b=1,l2=1,r2=-1;
		else if(x==')') a=1,l2=-1,r2=1;
	}
}t[maxn<<2];
void upd(int i){
	int lc=i<<1,rc=i<<1|1;
	if(t[lc].b>t[rc].a) t[i].a=t[lc].a,t[i].b=t[lc].b-t[rc].a+t[rc].b;
	else t[i].a=t[lc].a+t[rc].a-t[lc].b,t[i].b=t[rc].b;
	t[i].dis=max(max(t[lc].r1+t[rc].l2,t[lc].r2+t[rc].l1),max(t[lc].dis,t[rc].dis));
	t[i].l1=max(t[lc].l1,max(t[lc].a+t[lc].b+t[rc].l2,t[lc].a-t[lc].b+t[rc].l1));
	t[i].l2=max(t[lc].l2,t[lc].b-t[lc].a+t[rc].l2);
	t[i].r1=max(t[rc].r1,max(t[rc].a+t[rc].b+t[lc].r2,t[rc].b-t[rc].a+t[lc].r1));
	t[i].r2=max(t[rc].r2,t[rc].a-t[rc].b+t[lc].r2);
}
void build(int i,int l,int r){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	build(i<<1,l,mid),build(i<<1|1,mid+1,r);
	upd(i);
}
void insert(int i,int l,int r,int x){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	if(x<=mid) insert(i<<1,l,mid,x);
	else insert(i<<1|1,mid+1,r,x);
	upd(i);
}
int main()
{
	scanf("%d%d%s",&n,&q,s+1),n<<=1;
	build(1,1,n);
	printf("%d\n",t[1].dis);
	while(q--){
		int x,y;
		scanf("%d%d",&x,&y),swap(s[x],s[y]);
		insert(1,1,n,x),insert(1,1,n,y);
		printf("%d\n",t[1].dis);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
char s[MAXN];
struct node
{
    int l,r;
    int delta;
    int mx,mxa2b,mxc2b,mxac2b,min2b;
}tree[MAXN<<2];
int dep[MAXN],n,q;
void maintain(int rt)
{
    tree[rt].mx=max(tree[rt*2].mx,tree[rt*2+1].mx);
    tree[rt].mxa2b=max(tree[rt*2].mx-tree[rt*2+1].min2b,max(tree[rt*2].mxa2b,tree[rt*2+1].mxa2b));
    tree[rt].mxc2b=max(-tree[rt*2].min2b+tree[rt*2+1].mx,max(tree[rt*2].mxc2b,tree[rt*2+1].mxc2b));
    tree[rt].mxac2b=max(max(tree[rt*2].mx+tree[rt*2+1].mxc2b,tree[rt*2].mxa2b+tree[rt*2+1].mx),max(tree[rt*2].mxac2b,tree[rt*2+1].mxac2b));
    tree[rt].min2b=min(tree[rt*2].min2b,tree[rt*2+1].min2b);
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].l=l,tree[rt].r=r;
        tree[rt].mx=dep[l];
        tree[rt].mxa2b=tree[rt].mxc2b=-tree[rt].mx;
        tree[rt].mxac2b=0;
        tree[rt].min2b=2*dep[l];
        return;
    }
    int mid=(l+r)/2;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);
    tree[rt].l=l,tree[rt].r=r;
    maintain(rt);
}
void change(int rt,int l,int r,int val)
{
    if(tree[rt].l>r||tree[rt].r<l)return;
    if(tree[rt].l>=l&&tree[rt].r<=r)
    {
        tree[rt].delta+=val;
        tree[rt].mx+=tree[rt].delta;
        if(tree[rt].l!=tree[rt].r)
        {
            tree[2*rt].delta+=tree[rt].delta;
            tree[2*rt+1].delta+=tree[rt].delta;
        }
        tree[rt].mxa2b-=tree[rt].delta;
        tree[rt].mxc2b-=tree[rt].delta;
        tree[rt].min2b+=tree[rt].delta*2;
        tree[rt].delta=0;
        return;
    }
    tree[rt].mx+=tree[rt].delta;
    tree[2*rt].delta+=tree[rt].delta;
    tree[2*rt+1].delta+=tree[rt].delta;
    tree[rt].delta=0;
    change(rt*2,l,r,val);
    change(rt*2+1,l,r,val);
    maintain(rt);
}
int main()
{
    int a,b;
    scanf("%d%d",&n,&q);
    n=(n-1)<<1;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='(')
            dep[i]=dep[i-1]+1;
        else dep[i]=dep[i-1]-1;
    }
    build(1,0,n);
    printf("%d\n",tree[1].mxac2b);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&a,&b);
        if(a>b)swap(a,b);
        if(s[a]!=s[b])
        {

            if(s[a]=='(')
            {
               change(1,a,b-1,-2);
            }
            else
            {
               change(1,a,b-1,2);
            }
            swap(s[a],s[b]);
        }
        printf("%d\n",tree[1].mxac2b);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
char s[MAXN];
struct node
{
    int l,r;
    int delta;
    int mx,mxa2b,mxc2b,mxac2b,min2b;
}tree[MAXN<<2];
int dep[MAXN],n,q;
void maintain(int rt)
{
    tree[rt].mx=max(tree[rt*2].mx,tree[rt*2+1].mx);
    tree[rt].mxa2b=max(tree[rt*2].mx-tree[rt*2+1].min2b,max(tree[rt*2].mxa2b,tree[rt*2+1].mxa2b));
    tree[rt].mxc2b=max(-tree[rt*2].min2b+tree[rt*2+1].mx,max(tree[rt*2].mxc2b,tree[rt*2+1].mxc2b));
    tree[rt].mxac2b=max(max(tree[rt*2].mx+tree[rt*2+1].mxc2b,tree[rt*2].mxa2b+tree[rt*2+1].mx),max(tree[rt*2].mxac2b,tree[rt*2+1].mxac2b));
    tree[rt].min2b=min(tree[rt*2].min2b,tree[rt*2+1].min2b);
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].l=l,tree[rt].r=r;
        tree[rt].mx=dep[l];
        tree[rt].mxa2b=tree[rt].mxc2b=-tree[rt].mx;
        tree[rt].mxac2b=0;
        tree[rt].min2b=2*dep[l];
        return;
    }
    int mid=(l+r)/2;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);
    tree[rt].l=l,tree[rt].r=r;
    maintain(rt);
}
void change(int rt,int l,int r,int val)
{
    if(tree[rt].l>r||tree[rt].r<l)return;
    if(tree[rt].l>=l&&tree[rt].r<=r)
    {
        tree[rt].delta+=val;
        tree[rt].mx+=tree[rt].delta;
        if(tree[rt].l!=tree[rt].r)
        {
            tree[2*rt].delta+=tree[rt].delta;
            tree[2*rt+1].delta+=tree[rt].delta;
        }
        tree[rt].mxa2b-=tree[rt].delta;
        tree[rt].mxc2b-=tree[rt].delta;
        tree[rt].min2b+=tree[rt].delta*2;
        tree[rt].delta=0;
        return;
    }
    tree[rt].mx+=tree[rt].delta;
    tree[2*rt].delta+=tree[rt].delta;
    tree[2*rt+1].delta+=tree[rt].delta;
    tree[rt].delta=0;
    change(rt*2,l,r,val);
    change(rt*2+1,l,r,val);
    maintain(rt);
}
int main()
{
    int a,b;
    scanf("%d%d",&n,&q);
    n=(n-1)<<1;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='(')
            dep[i]=dep[i-1]+1;
        else dep[i]=dep[i-1]-1;
    }
    build(1,1,n);
    printf("%d\n",tree[1].mxac2b);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&a,&b);
        if(a>b)swap(a,b);
        if(s[a]!=s[b])
        {

            if(s[a]=='(')
            {
               change(1,a,b-1,-2);
            }
            else
            {
               change(1,a,b-1,2);
            }
            swap(s[a],s[b]);
        }
        printf("%d\n",tree[1].mxac2b);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
char s[MAXN];
struct node
{
    int l,r;
    int delta;
    int mx,mxa2b,mxc2b,mxac2b,min2b;
}tree[MAXN<<2];
int dep[MAXN],n,q;
void maintain(int rt)
{
    tree[rt].mx=max(tree[rt*2].mx,tree[rt*2+1].mx)+tree[rt].delta;
    tree[rt].mxa2b=max(tree[rt*2].mx-tree[rt*2+1].min2b,max(tree[rt*2].mxa2b,tree[rt*2+1].mxa2b));
    tree[rt].mxc2b=max(-tree[rt*2].min2b+tree[rt*2+1].mx,max(tree[rt*2].mxc2b,tree[rt*2+1].mxc2b));
    tree[rt].mxac2b=max(max(tree[rt*2].mx+tree[rt*2+1].mxc2b,tree[rt*2].mxa2b+tree[rt*2+1].mx),max(tree[rt*2].mxac2b,tree[rt*2+1].mxac2b));
    tree[rt].min2b=min(tree[rt*2].min2b,tree[rt*2+1].min2b)+2*tree[rt].delta;
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].l=l,tree[rt].r=r;
        tree[rt].mx=dep[l];
        tree[rt].mxa2b=tree[rt].mxc2b=-tree[rt].mx;
        tree[rt].mxac2b=0;
        tree[rt].min2b=2*dep[l];
        return;
    }
    int mid=(l+r)/2;
    tree[rt].l=l,tree[rt].r=r;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);

    maintain(rt);
}
void change(int rt,int l,int r,int val)
{
    if(tree[rt].l>r||tree[rt].r<l)
    {
        tree[rt].mx+=tree[rt].delta;
        if(tree[rt].l!=tree[rt].r)
        {
            tree[2*rt].delta+=tree[rt].delta;
            tree[2*rt+1].delta+=tree[rt].delta;
        }
        tree[rt].mxa2b-=tree[rt].delta;
        tree[rt].mxc2b-=tree[rt].delta;
        tree[rt].min2b+=tree[rt].delta*2;
        tree[rt].delta=0;
        return;
    }
    if(tree[rt].l>=l&&tree[rt].r<=r)
    {
        tree[rt].delta+=val;
        tree[rt].mx+=tree[rt].delta;
        if(tree[rt].l!=tree[rt].r)
        {
            tree[2*rt].delta+=tree[rt].delta;
            tree[2*rt+1].delta+=tree[rt].delta;
        }
        tree[rt].mxa2b-=tree[rt].delta;
        tree[rt].mxc2b-=tree[rt].delta;
        tree[rt].min2b+=tree[rt].delta*2;
        tree[rt].delta=0;
        return;
    }
    tree[rt].mx+=tree[rt].delta;
    tree[2*rt].delta+=tree[rt].delta;
    tree[2*rt+1].delta+=tree[rt].delta;
    tree[rt].delta=0;
    change(rt*2,l,r,val);
    change(rt*2+1,l,r,val);
    maintain(rt);
}
int main()
{
    int a,b;
    scanf("%d%d",&n,&q);
    n=(n-1)<<1;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='(')
            dep[i]=dep[i-1]+1;
        else dep[i]=dep[i-1]-1;
    }
    build(1,1,n);
    printf("%d\n",tree[1].mxac2b);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&a,&b);
        if(a>b)swap(a,b);
        if(s[a]!=s[b])
        {

            if(s[a]=='(')
            {
               change(1,a,b-1,-2);
            }
            else
            {
               change(1,a,b-1,2);
            }
            swap(s[a],s[b]);
        }
        printf("%d\n",tree[1].mxac2b);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
char s[MAXN];
struct node
{
    int l,r;
    int mx,mxa2b,mxc2b,mxac2b,min2b;
}tree[MAXN<<2];
int dep[MAXN],n,q;
void maintain(int rt)
{
    tree[rt].mx=max(tree[rt*2].mx,tree[rt*2+1].mx);
    tree[rt].mxa2b=max(tree[rt*2].mx-tree[rt*2+1].min2b,max(tree[rt*2].mxa2b,tree[rt*2+1].mxa2b));
    tree[rt].mxc2b=max(-tree[rt*2].min2b+tree[rt*2+1].mx,max(tree[rt*2].mxc2b,tree[rt*2+1].mxc2b));
    tree[rt].mxac2b=max(max(tree[rt*2].mx+tree[rt*2+1].mxc2b,tree[rt*2].mxa2b+tree[rt*2+1].mx),max(tree[rt*2].mxac2b,tree[rt*2+1].mxac2b));
    tree[rt].min2b=min(tree[rt*2].min2b,tree[rt*2+1].min2b);
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].l=l,tree[rt].r=r;
        tree[rt].mx=dep[l];
        tree[rt].mxa2b=tree[rt].mxc2b=-tree[rt].mx;
        tree[rt].mxac2b=0;
        tree[rt].min2b=2*dep[l];
        return;
    }
    int mid=(l+r)/2;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);
    tree[rt].l=l,tree[rt].r=r;
    maintain(rt);
}
void change(int rt,int l,int r,int val)
{
    if(tree[rt].l>r||tree[rt].r<l)return;
    if(tree[rt].l>=l&&tree[rt].r<=r)
    {
        tree[rt].mx+=val;
        tree[rt].mxa2b-=val;
        tree[rt].mxc2b-=val;
        tree[rt].min2b+=val*2;
        return;
    }
    change(rt*2,l,r,val);
    change(rt*2+1,l,r,val);
    maintain(rt);
}
int main()
{
    int a,b;
    scanf("%d%d",&n,&q);
    n=(n-1)<<1;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='(')
            dep[i]=dep[i-1]+1;
        else dep[i]=dep[i-1]-1;
    }
    build(1,0,n);
    printf("%d\n",tree[1].mxac2b);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&a,&b);
        if(a>b)swap(a,b);
        if(s[a]!=s[b])
        {

            if(s[a]=='(')
            {
               change(1,a,b-1,-2);
            }
            else
            {
               change(1,a,b-1,2);
            }
            swap(s[a],s[b]);
        }
        printf("%d\n",tree[1].mxac2b);
    }
    return 0;
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 800000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l==r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
    //print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
     //   print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 300000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l==r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
    //print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
     //   print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 600000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l==r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
    //print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
     //   print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 300000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l>=r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
    print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    if(l>r)return;

    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
        //print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 4000000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l>=r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
   // print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    if(l>r)return;

    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
        //print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#define N 1000000
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
using namespace std;

int max_v[N],max_l[N],max_r[N],max_ans[N];
int min_v[N];
int add_v[N];
int a[N];
string s;

int n,q;

void update(int t, int v) {
    add_v[t] += v;
    max_v[t] += v;
    min_v[t] += v;
    max_l[t] -= v;
    max_r[t] -= v;
}

void push_down(int t, int l, int r) {
    if(add_v[t]==0)return;
    update(t<<1,add_v[t]);
    update(t<<1|1,add_v[t]);
    add_v[t] = 0;
}

void print(int t,int l, int r) {
    printf("t = %d l = %d r = %d max_ans = %d max_v = %d min_v = %d  max_l = %d max_r = %d\n",t,l,r,max_ans[t],max_v[t], min_v[t],max_l[t],max_r[t]);
}

void push_up(int t, int l, int r) {
    int t1 = max(max_ans[t<<1], max_ans[t<<1|1]);
    int t2 = max_r[t<<1] + max_v[t<<1|1];
    int t3 = max_v[t<<1] + max_l[t<<1|1];

    max_ans[t] = max(t1,max(t2,t3));
    max_v[t] = max(max_v[t<<1], max_v[t<<1|1]);
    min_v[t] = min(min_v[t<<1],min_v[t<<1|1]);

    max_l[t] = max(max(max_l[t<<1],max_l[t<<1|1]),max_v[t<<1|1]-2*min_v[t<<1]);
    max_r[t] = max(max(max_r[t<<1],max_r[t<<1|1]), max_v[t<<1]-2*min_v[t<<1|1]);
}

void build(int t, int l, int r) {

    add_v[t] = 0;
    if(l>=r) {
        max_v[t] = a[l];
        min_v[t] = a[l];
        max_l[t] = max_r[t] = a[l]-2*a[l];
        max_ans[t] = 0;
    //print(t,l,r);
        return;
    }

    push_down(t,l,r);

    int mid = (l+r)>>1;

    build(t<<1, l, mid);
    build(t<<1|1, mid+1,r);

    push_up(t,l,r);
   // print(t,l,r);
}

void update(int t, int l, int r, int ql, int qr) {

    //printf("t = %d l = %d r = %d ql = %d qr = %d\n",t,l,r,ql,qr);
    if(l>r)return;

    push_down(t,l,r);
    if(ql<=l && qr >=r) {
        if(s[ql]=='(')
            update(t,2);
        else
            update(t,-2);
        //print(t,l,r);
        return;
    }

    int mid = (l+r)>>1;

    if(ql<=mid)
        update(t<<1, l, mid, ql, qr);
    if(qr>mid)
        update(t<<1|1, mid+1, r, ql, qr);

    push_up(t,l,r);
    //print(t,l,r);
}

int main() {
    cin>>n>>q;
    n = 2*(n-1);
    cin>>s;
    int t = 0;
    for(int i = 0;i < n; ++i) {
        if(s[i]=='(')t++;
        else t--;
        a[i] = t;
    }

    build(1,0,n-1);
    printf("%d\n",max_ans[1]);
    for(int i = 0; i < q; ++i) {
        int l, r;
        cin>>l>>r;
        if(l>r)swap(l,r);
        l--;r--;
        swap(s[l],s[r]);
        //printf("update l = %d r = %d\n",l,r);
        update(1,0,n-1,l,r-1);
        printf("%d\n",max_ans[1]);
    }
}


#include<bits/stdc++.h>
using namespace std;
const int N=200005;
char s[N],c1,c2;
int n,q,a,b;
struct node{
    int d,a,b,ab,ba,abc;
    node operator+(int x){
        return (node){d,a+x,b-(x<<1),ab-x,ba-x,abc};
    }
}tre[N<<2],lp,rp;
node operator+(const node &a,node b){
    b=b+a.d;
    static node c;
    c.d=a.d+b.d;
    c.a=max(a.a,b.a);
    c.b=max(a.b,b.b);
    c.ab=max(max(a.ab,b.ab),a.a+b.b);
    c.ba=max(max(a.ba,b.ba),a.b+b.a);
    c.abc=max(max(a.abc,b.abc),max(a.ab+b.a,a.a+b.ba));
    return c;
}
#define mid (l+r>>1)
#define ls o<<1,l,mid
#define rs o<<1|1,mid+1,r
void add(int o,int l,int r,int v,char ch){
    if(l==r){
        if(ch=='(')tre[o]=lp;
        else       tre[o]=rp;
        return;
    }
    if(v<=mid)add(ls,v,ch);else add(rs,v,ch);
    tre[o]=tre[o<<1]+tre[o<<1|1];
}
void dbg(int o,int l,int r){
    printf("%d [%d,%d]: %d %d %d %d %d %d\n",o,l,r,tre[o].d,tre[o].a,tre[o].b,tre[o].ab,tre[o].ba,tre[o].abc);
    if(l==r)return;
    dbg(ls);dbg(rs);
}
int main(){
    scanf("%d%d%s",&n,&q,s+1);n=(n-1)<<1;
    lp=(node){ 1,1,0,0,1,1};
    rp=(node){-1,0,2,2,1,1};
    for(int i=1;i<=n;i++)add(1,1,n,i,s[i]);
    printf("%d\n",tre[1].abc);//dbg(1,1,n);
    while(q--){
        scanf("%d%d",&a,&b);
        c1=s[b];c2=s[a];
        add(1,1,n,a,c1);
        add(1,1,n,b,c2);
        s[a]=c1;s[b]=c2;
        printf("%d\n",tre[1].abc);//dbg(1,1,n);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mid (l+r)/2
int i,i0,n,m;
struct node
{
    int a,b,ab,bc,abc;
}tree[800020];
int lazy[800020];
node operator+(node a,node b)
{
    node c;
    c.a=max(a.a,b.a);
    c.b=max(a.b,b.b);
    c.ab=max(a.a+b.b,max(a.ab,b.ab));
    c.bc=max(a.b+b.a,max(a.bc,b.bc));
    c.abc=max(max(a.a+b.bc,a.ab+b.a),max(a.abc,b.abc));
    return c;
}
node operator+(node a,int b)
{
    node c;
    c.a=a.a+b;
    c.b=a.b-2*b;
    c.ab=a.ab-b;
    c.bc=a.bc-b;
    c.abc=a.abc;
    return c;
}
void p_tree(int l,int r,int p)
{
    lazy[p*2]+=lazy[p],lazy[p*2+1]+=lazy[p];
    tree[p*2]=tree[p*2]+lazy[p],tree[p*2+1]=tree[p*2+1]+lazy[p];
    lazy[p]=0;
}
void c_tree(int l,int r,int p,int a,int b,int v)
{
    if(l==a&&r==b)lazy[p]+=v,tree[p]=tree[p]+v;
    else
    {
        p_tree(l,r,p);
        if(b<=mid) c_tree(l,mid,p*2,a,b,v);
        else if(a>=mid+1)c_tree(mid+1,r,p*2+1,a,b,v);
        else c_tree(l,mid,p*2,a,mid,v),c_tree(mid+1,r,p*2+1,mid+1,b,v);
        tree[p]=tree[p*2]+tree[p*2+1];
    }
}
char s[200005];
int main()
{
    scanf("%d %d",&n,&m);
    scanf("%s",s+1);
    int len=strlen(s+1);
    for(i=1;i<=len;i++)
    {
        if(s[i]=='(')c_tree(1,len,1,i,len,1);
        else c_tree(1,len,1,i,len,-1);
    }
    printf("%d\n",tree[1].abc);
    while(m--)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        if(s[x]=='(')c_tree(1,len,1,x,len,-1),c_tree(1,len,1,y,len,1);
        else c_tree(1,len,1,x,len,1),c_tree(1,len,1,y,len,-1);
        if(s[y]=='(')c_tree(1,len,1,y,len,-1),c_tree(1,len,1,x,len,1);
        else c_tree(1,len,1,y,len,1),c_tree(1,len,1,x,len,-1);
        swap(s[x],s[y]);
        printf("%d\n",tree[1].abc);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;

const int maxn = 8e5+50;
int n, q;
char s[200005];
struct node
{
    int d, m1, m2, m3, m4, m5; //d为深度，m1为h(a), m2为-2h(b), m3为h(a)-2h(b), m4为-2h(b)+h(c), m5为h(a)-2h(b)+h(c), a<=b<=c
}a[maxn];

void pushup(int rt)
{
    a[rt].d = a[rt<<1].d + a[rt<<1|1].d;
    a[rt].m1 = max(a[rt<<1].m1, a[rt<<1|1].m1+a[rt<<1].d);
    a[rt].m2 = max(a[rt<<1].m2, a[rt<<1|1].m2-2*a[rt<<1].d);
    a[rt].m3 = max(a[rt<<1].m1-2*a[rt<<1].d+a[rt<<1|1].m2, max(a[rt<<1].m3, a[rt<<1|1].m3-a[rt<<1].d));
    a[rt].m4 = max(a[rt<<1].m2+a[rt<<1].d+a[rt<<1|1].m1 ,max(a[rt<<1].m4, a[rt<<1|1].m4-a[rt<<1].d));
    a[rt].m5 = max(max(a[rt<<1].m5, a[rt<<1|1].m5), max(a[rt<<1].m3+a[rt<<1|1].m1+a[rt<<1].d, a[rt<<1].m1-a[rt<<1].d+a[rt<<1|1].m4));
}

void se(int u, int x)
{
    if(s[x] == '(')
        a[u] = (node){1,1,0,0,1,1};
    else
        a[u] = (node){-1,0,2,2,1,1};
}

void build(int u, int l, int r)
{
    if(l==r)
    {
        se(u,l);
        return;
    }
    int mid = (l+r)>>1;
    build(u<<1, l, mid);
    build(u<<1|1, mid+1, r);
    pushup(u);
}

void update(int u, int l, int r, int x)
{
    if(l==r)
    {
        if(s[x] == '(')
            s[x] = ')';
        else
            s[x] = '(';
        se(u, x);
        return;
    }
    int mid = (l+r)>>1;
    if(x<=mid)
        update(u<<1, l, mid, x);
    else
        update(u<<1|1, mid+1, r, x);
    pushup(u);
}

int main()
{
    while(~scanf("%d%d%s", &n, &q, s+1))
    {
        build(1, 1, 2*(n-1));
        printf("%d\n", a[1].m5);
        for(int x, y, i=1; i <= q; i++)
        {
            scanf("%d%d", &x, &y);
            update(1, 1, 2*(n-1), x);
            update(1, 1, 2*(n-1), y);
            printf("%d\n", a[1].m5);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define mid (l + r >> 1)
#define ls (k << 1)
#define rs (k << 1 | 1)
using namespace std;

const int maxn = 200010;
int n, q; char s[maxn];
struct node { int lmx, rmn, d, ld, rd, s, ans; } L, R, t[maxn << 2];

void upd(node &c, node &a, node &b) {
    c.lmx = max(a.lmx, a.s + b.lmx), c.rmn = min(b.rmn, a.rmn + b.s);
    c.d = max(b.d - a.s, a.d + b.s), c.s = a.s + b.s;
    c.ld = max({a.ld, b.ld - a.s, a.d + b.lmx});
    c.rd = max({b.rd, a.rd + b.s, b.d - a.rmn});
    c.ans = max({a.ans, b.ans, b.ld - a.rmn, a.rd + b.lmx});
}

void build(int k, int l, int r) {
    if (l == r) { t[k] = s[l] == '(' ? L : R; return; }
    build(ls, l, mid), build(rs, mid + 1, r), upd(t[k], t[ls], t[rs]);
}

void modify(int k, int l, int r, int p) {
    if (l == r) { t[k] = s[l] == '(' ? L : R; return; }
    mid >= p ? modify(ls, l, mid, p) : modify(rs, mid + 1, r, p);
    upd(t[k], t[ls], t[rs]);
}

int main() {
    L = (node){1, 0, 1, 1, 1, 1, 1}, R = (node){0, -1, 1, 1, 1, -1, 1};
    scanf("%d %d %s", &n, &q, s + 1), n = (n - 1) << 1;
    build(1, 1, n), printf("%d\n", t[1].ans);
    for (int i = 1, a, b; i <= q; i++) {
        scanf("%d %d", &a, &b), swap(s[a], s[b]);
        modify(1, 1, n, a), modify(1, 1, n, b);
        printf("%d\n", t[1].ans);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
#define N  210000
#define M  410000
#define fi first
#define se second
#define MP make_pair
#define pi 	acos(-1)
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1

const int MOD=1e9+7;
      double eps=1e-8;

char ch[N];

int read()
{
   int v=0,f=1;
   char c=getchar();
   while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
   while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
   return v*f;
}

struct node
{
	int t1,t2,t3,t4,t5,t6,t7,t8,t9;
}t[N<<2];

node merge(node x,node y)
{
	node re;
	if(x.t2<=y.t1)
	{
		re.t1=y.t1-x.t2+x.t1;
		re.t2=y.t2;
	}
	 else
	 {
	 	re.t1=x.t1;
	 	re.t2=x.t2-y.t1+y.t2;
	 }
	//������ε�a��b����a,b���Ұ�μ���c,d
	//a+b=a+|b-c|+d
    //=max(a+b-c+d,a-b+c+d)
    //=max((a+b)+(d-c),(a-b)+(c+d))
	re.t3=max(x.t3,max(x.t1+x.t2+y.t7,x.t1-x.t2+y.t3));
	re.t4=max(y.t4,max(y.t1+y.t2+x.t6,y.t2-y.t1+x.t4));
	re.t5=max(x.t5,x.t1-x.t2+y.t5);
	re.t6=max(y.t6,y.t1-y.t2+x.t6);
	re.t7=max(x.t7,x.t2-x.t1+y.t7);
	re.t8=max(y.t8,y.t2-y.t1+x.t8);
	re.t9=max(max(x.t9,y.t9),max(x.t4+y.t7,x.t6+y.t3));
	return re;
}

void build(int l,int r,int p)
{
	if(l==r)
	{
		if(ch[l]=='(') t[p]=(node){0,1,1,1,0,0,1,1,1};
				  else t[p]=(node){1,0,1,1,1,1,0,0,1};
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls);
	build(mid+1,r,rs);
	t[p]=merge(t[ls],t[rs]);
}

void update(int l,int r,int x,char y,int p)
{
	if(l==r)
	{
		if(y=='(') t[p]=(node){0,1,1,1,0,0,1,1,1};
		      else t[p]=(node){1,0,1,1,1,1,0,0,1};
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid) update(l,mid,x,y,ls);
	 else update(mid+1,r,x,y,rs);
	t[p]=merge(t[ls],t[rs]);
}

int main()
{
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
	int n=read(),q=read();
	scanf("%s",ch+1);
	n=strlen(ch+1);
	build(1,n,1);
	printf("%d\n",t[1].t9);
	while(q--)
	{
		int x=read(),y=read();
		update(1,n,x,ch[y],1);
		update(1,n,y,ch[x],1);
		swap(ch[x],ch[y]);
		printf("%d\n",t[1].t9);
	}
    return 0;
}