import java.util.*;
public class Main {
    public static int n, m;
    public static int[][] arr;
    public static class Item implements Comparable<Item> {
        int i, x;
        public Item(int i, int x) {
            this.i = i;
            this.x = x;
        }
        public int compareTo(Item other) {
            if (x == other.x) {
                return i - other.i;
            }
            return other.x - x;
        }
    }
    public static int calc(int[] cols, int k, String mask) {
        if (k == cols.length) {
            int res = 0;
            for (int i = 0; i < n; i++) {
                int max = 0;
                for (int j = 0; j < cols.length; j++) {
                    int shift = mask.charAt(j) - '0';
                    max = Math.max(max, arr[(shift + i) % n][cols[j]]);
                }
                res += max;
            }
            return res;
        } else {
            int best = 0;
            for (int i = 0; i < n; i++) {
                best = Math.max(best, calc(cols, k + 1, mask + i));
            }
            return best;
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        for (int i = 0; i < t; i++) {
            n = in.nextInt();
            m = in.nextInt();
            arr = new int[n][m];
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < m; k++) {
                    arr[j][k] = in.nextInt();
                }
            }
            Item[] max = new Item[m];
            for (int j = 0; j < m; j++) {
                max[j] = new Item(j, 0);
                for (int k = 0; k < n; k++) {
                    max[j].x = Math.max(max[j].x, arr[k][j]);
                }
            }
            Arrays.sort(max);
            int[] cols = new int[Math.min(n, m)];
            for (int j = 0; j < cols.length; j++) {
                cols[j] = max[j].i;
            }
            System.out.println(calc(cols, 0, ""));
        }
    }
}


//package round584;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;

public class E1 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		for(int T = ni();T > 0;T--){
			int n = ni(), m = ni();
			int[][] a = new int[n][];
			for(int i = 0;i < n;i++)a[i] = na(m);

			int[][] sss = new int[1<<n][m];
			for(int i = 1;i < 1<<n;i+=2){
				int[] ss = new int[m];
				for(int j = 0;j < m;j++){
					int cur = i;
					int lmax = 0;
					for(int sh = 0;sh < n;sh++){
						int s = 0;
						for(int k = 0;k < n;k++){
							if(cur<<~k<0){
								s += a[k][j];
							}
						}
						lmax = Math.max(lmax, s);
						cur = cur>>>1|(cur&1)<<n-1;
					}
					ss[j] = lmax;
				}
				sss[i] = ss;
			}
			ptns = new HashMap<>();
			dfs(new int[n], 0, -1);
			int ans = 0;
			if(n == 4 && m >= 4){
				int[] one = Arrays.copyOf(sss[1], m);
				Arrays.sort(one);
				ans = one[m-1] + one[m-2] + one[m-3] + one[m-4];
			}

			for(int[] cs : ptns.values()){
				if(cs.length == 4)continue;
				int[] u = new int[cs.length];
				inner:
				do{
					for(int i = 0;i < cs.length;i++){
						for(int j = i+1;j < cs.length;j++){
							if(u[i] == u[j])continue inner;
						}
					}
					int val = 0;
					for(int i = 0;i < cs.length;i++){
						val += sss[cs[i]][u[i]];
					}
					ans = Math.max(ans, val);
				}while(inc(u, m));
			}
			out.println(ans);
		}
	}

	public static boolean inc(int[] a, int base) {
		int n = a.length;
		int i;
		for (i = n - 1; i >= 0 && a[i] == base - 1; i--)
			;
		if (i == -1)
			return false;

		a[i]++;
		Arrays.fill(a, i + 1, n, 0);
		return true;
	}

	Map<Long, int[]> ptns = new HashMap<>();
//	Set<Long> all = new HashSet<>();

	void dfs(int[] a, int pos, int max)
	{
		if(pos == a.length){
			int[] ptn = new int[max+1];
			int n = a.length;
			for(int i = 0;i < n;i++){
				ptn[a[i]] |= 1<<i;
			}
			for(int i = 0;i <= max;i++){
				ptn[i] = ptn[i]>>>Integer.numberOfTrailingZeros(ptn[i]);
			}
//			for(int i = 0;i <= max;i++){
//				int min = ptn[i];
//				int k = ptn[i];
//				for(int j = 0;j < 12;j++){
//					int nk = k>>>1|(k&1)<<11;
//					k = nk;
//					min = Math.min(min, k);
//				}
//				ptn[i] = min;
//			}
			Arrays.sort(ptn);
			long h = 0;
			for(int v : ptn){
				h= h * 1000000009 + v;
			}
//			all.add(h);
			ptns.put(h, ptn);
			return;
		}

		for(int i = 0;i <= max+1;i++){
			a[pos] = i;
			dfs(a, pos+1, Math.max(i, max));
		}
	}

	void run() throws Exception
	{
//		int n = 4, m = 100;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(40 + " ");
//		for(int rep = 0;rep < 40;rep++){
//			sb.append(n + " ");
//			sb.append(m + " ");
//			for (int i = 0; i < n*m; i++) {
//				sb.append(gen.nextInt(100000) + " ");
//			}
//		}
//		INPUT = sb.toString();

		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

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

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

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

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

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

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

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

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

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

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

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

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

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

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

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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

public class r584p5 {
    private static BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
    private static PrintWriter pw = new PrintWriter(System.out);
    private static int n, m, arr[][];
    private static ArrayList<HashSet<Integer>> chls;

    private static void gench(){
        chls.add(new HashSet<>());
        chls.get(0).add(0);

        for(int i=1; i<(1<<n); i++){
            int des = i^Integer.highestOneBit(i);
            HashSet<Integer> st = new HashSet<>();
            for(int z : chls.get(des)){
                st.add(z);
                st.add(z|Integer.highestOneBit(i));
            }
            chls.add(st);
        }
    }

    private static void cal(){
        int val[][] = new int[(1<<n)][m];

        for(int j=0; j<m; j++){
            val[0][j] = 0;
            for(int mask=1; mask<(1<<n); mask++){
                int max = 0;
                for(int begin=0; begin<n; begin++){
                    int sum = 0;
                    for(int ptr=begin, pos=0; pos<n; ptr=(ptr+1)%n, pos++){
                        if((mask&(1<<pos)) > 0)
                            sum += arr[ptr][j];
                    }
                    max = Math.max(max, sum);
                }
                val[mask][j] = max;
            }
        }

        int dp[][] = new int[(1<<n)][m];

        for(int mask=0; mask<(1<<n); mask++)
            dp[mask][0] = val[mask][0];

        for(int j=1; j<m; j++){
            dp[0][j] = 0;
            for(int mask=1; mask<(1<<n); mask++){

                dp[mask][j] = 0;
                for(int ch1 : chls.get(mask)){
                    int ch2 = mask^ch1;

                    dp[mask][j] = Math.max(dp[mask][j], val[ch1][j]+dp[ch2][j-1]);
                }
            }
        }

        pw.println(dp[(1<<n)-1][m-1]);
    }

    private static void run()throws IOException{
        StringTokenizer tk = new StringTokenizer(r.readLine());
        n = Integer.parseInt(tk.nextToken());
        m = Integer.parseInt(tk.nextToken());
        arr = new int[n][m];
        chls = new ArrayList<>();

        for(int i=0; i<n; i++){
            tk = new StringTokenizer(r.readLine());
            for(int j=0; j<m; j++)
                arr[i][j] = Integer.parseInt(tk.nextToken());
        }

        gench();
        cal();
    }

    public static void main(String args[])throws IOException{
        int t = Integer.parseInt(r.readLine());

        while(t-->0)
            run();

        pw.flush();
        pw.close();
    }
}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        E2RotateColumnsHardVersion solver = new E2RotateColumnsHardVersion();
        int testCount = Integer.parseInt(in.next());
        for (int i = 1; i <= testCount; i++)
            solver.solve(i, in, out);
        out.close();
    }

    static class E2RotateColumnsHardVersion {
        public void solve(int testNumber, FastReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            E2RotateColumnsHardVersion.Column[] columns = new E2RotateColumnsHardVersion.Column[m];
            for (int i = 0; i < columns.length; ++i) columns[i] = new E2RotateColumnsHardVersion.Column(new int[n]);
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < m; ++j) {
                    columns[j].v[i] = in.nextInt();
                    if (i == n - 1) columns[j].initMax();
                }
            }
            Arrays.sort(columns, (o1, o2) -> o2.max - o1.max);
            if (columns.length > n)
                columns = Arrays.copyOf(columns, n);

            long[] dp = new long[1 << n];
            for (E2RotateColumnsHardVersion.Column c : columns) {
                long[] ndp = new long[1 << n];
                System.arraycopy(dp, 0, ndp, 0, dp.length);

                for (int rot = 0; rot < n; ++rot) {
                    long[] temp = new long[1 << n];
                    System.arraycopy(dp, 0, temp, 0, dp.length);
                    for (int i = 0, pos = rot; i < n; ++i, ++pos) {
                        if (pos >= n) pos = 0;
                        int val = c.v[pos];
                        for (int j = 0; j < temp.length; ++j) {
                            if ((j & (1 << i)) == 0)
                                temp[j | (1 << i)] = Math.max(temp[j | (1 << i)], temp[j] + val);
                        }
                    }
                    for (int i = 0; i < ndp.length; ++i)
                        ndp[i] = Math.max(ndp[i], temp[i]);
                }
                dp = ndp;
            }
            out.println(dp[dp.length - 1]);
        }

        static class Column {
            int[] v;
            int max;

            public Column(int[] v) {
                this.v = v;
            }

            void initMax() {
                max = 0;
                for (int vv : v) max = Math.max(max, vv);
            }

        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int pnumChars;

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

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

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

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

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

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

    }
}


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

public class E
{
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer tok;

    public void go() throws IOException
    {
        StringTokenizer tok = new StringTokenizer(in.readLine());
        int zzz = Integer.parseInt(tok.nextToken());
        for (int zz = 0; zz < zzz; zz++)
        {
            ntok();
            int n = ipar();
            int m = ipar();
            int[][] mat = new int[n][m];
            for (int i = 0; i < n; i++)
            {
                ntok();
                mat[i] = iapar(m);
            }
            long[][] dp = new long[1 << n][m+1];
            for (int i = 0; i < 1 << n; i++)
            {
                dp[i][m] = -1000000000;
            }
            dp[(1 << n) - 1][m] = 0;
            for (int i = m-1; i >= 0; i--)
            {
                for (int e = 0; e < 1 << n; e++)
                {
                    dp[e][i] = dp[e][i+1];
                    for (int w = 0; w < 1 << n; w++)
                    {
                        if ((e & w) == 0)
                        {
                            dp[e][i] = Math.max(dp[e][i], best(w, mat, i) + dp[e|w][i+1]);
                        }
                    }
                }
            }
            // for (long[] arr : dp)
            // {
            //     out.println(Arrays.toString(arr));
            // }
            out.println(dp[0][0]);
        }

        out.flush();
        in.close();
    }

    public long best(int mask, int[][] mat, int col)
    {
        long max = 0;
        for (int t = 0; t < mat.length; t++)
        {
            long sum = 0;
            int mk = mask;
            for (int i = 0; i < mat.length; i++)
            {
                if (mk % 2 == 1)
                {
                    sum += mat[i][col];
                }
                mk /= 2;
            }
            max = Math.max(max, sum);
            cycle(mat, col);
        }
        return max;
    }

    public void cycle(int[][] mat, int col)
    {
        int temp = mat[0][col];
        for (int i = 0; i < mat.length-1; i++)
        {
            mat[i][col] = mat[i+1][col];
        }
        mat[mat.length-1][col] = temp;
    }

    public void ntok() throws IOException
    {
        tok = new StringTokenizer(in.readLine());
    }

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

    public int[] iapar(int n)
    {
        int[] arr = new int[n];
        for (int i = 0; i < n; i++)
        {
            arr[i] = ipar();
        }
        return arr;
    }

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

    public long[] lapar(int n)
    {
        long[] arr = new long[n];
        for (int i = 0; i < n; i++)
        {
            arr[i] = lpar();
        }
        return arr;
    }

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

    public String spar()
    {
        return tok.nextToken();
    }

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


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.IntStream;

public class Test {
  static PrintWriter writer =
      new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

  static int readInt() {
    int ans = 0;
    boolean neg = false;
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (c == '-') {
          start = true;
          neg = true;
          continue;
        } else if (c >= '0' && c <= '9') {
          start = true;
          ans = ans * 10 + c - '0';
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return neg ? -ans : ans;
  }

  static long readLong() {
    long ans = 0;
    boolean neg = false;
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (c == '-') {
          start = true;
          neg = true;
          continue;
        } else if (c >= '0' && c <= '9') {
          start = true;
          ans = ans * 10 + c - '0';
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return neg ? -ans : ans;
  }

  static String readLine() {
    StringBuilder b = new StringBuilder();
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (Character.isLetterOrDigit(c)) {
          start = true;
          b.append((char) c);
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return b.toString();
  }

  public static void main(String[] args) {
    Test te = new Test();
    te.start();
    writer.flush();
  }

  void start() {
    int t = readInt();
    while (t-- > 0) {
      int n = readInt(), m = readInt();
      int[][] a = new int[n][m];
      for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
          a[i][j] = readInt();
      int[] dp = new int[1<<n];
      Arrays.fill(dp, -1);
      dp[0] = 0;
      for (int c = 0; c < m; c++) {
        for (int i = (1 << n) - 1; i >= 0; i--) {
          int u = (1 << n) - 1 - i;
          int p = u;
          if (dp[i] >= 0)
            while (p > 0) {
              for (int r = 0; r < n; r++) {
                  int sum = 0;
                  for (int j = 0; j < n; j++) if (((p >> j) & 1) != 0) sum += a[(j + r) % n][c];
                  dp[i | p] = Math.max(dp[i | p], dp[i] + sum);
                }
              p = (p - 1) & u;
            }
        }
      }
      writer.println(dp[(1<<n) - 1]);
    }
  }
}


import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;

public class E1 {

	public static void main(String[] args) throws Exception {
		FastScanner sc = new FastScanner(System.in);
		FastPrinter out = new FastPrinter(System.out);
		int T = sc.nextInt();
		for (int i = 0; i < T; i++) {
			new E1().run(sc, out);
		}
		out.close();
	}

	int N, M, arr[][], ans;

	public void run(FastScanner sc, FastPrinter out) throws Exception {
		N = sc.nextInt();
		M = sc.nextInt();
		arr = new int[N][M];
		int[][] nums = new int[N * M][3];
		int count = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				int v = sc.nextInt();
				arr[i][j] = v;
				nums[count++] = new int[] { v, j, i };
			}
		}
		Arrays.sort(nums, new Comparator<int[]>() {
			@Override
			public int compare(int[] a, int[] b) {
				return b[0] - a[0];
			}
		});
		// System.err.println(Arrays.deepToString(arr));
		// System.err.println(Arrays.deepToString(nums));
		if (N == 4 && M > 1) {
			int colCount = 0;
			HashMap<Integer, Integer> map = new HashMap<>();
			// I believe you only need top 6 numbers?
			for (int i = 0; i < 8; i++) {
				int col = nums[i][1];
				Integer newCol = map.get(col);
				if (newCol == null) {
					map.put(col, colCount++);
				}
			}
			int[][] arr = new int[N][colCount];
			for (int i = 0; i < 8; i++) {
				int val = nums[i][0];
				int col = map.get(nums[i][1]);
				int row = nums[i][2];
				arr[row][col] = val;
			}
			// System.err.println(Arrays.deepToString(arr));
			solve(0, arr);
		} else {
			ans = 0;
			for (int i = 0; i < N; i++) {
				ans += nums[i][0];
			}
		}
		System.out.println(ans);
	}

	private void solve(int index, int[][] arr) {
		if (index == arr[0].length) {
			int temp = 0;
			for (int i = 0; i < arr.length; i++) {
				int m = 0;
				for (int j = 0; j < arr[i].length; j++) {
					m = Math.max(m, arr[i][j]);
				}
				temp += m;
			}
			ans = Math.max(temp, ans);
		} else {
			for (int t = 0; t < N; t++) {
				int v = arr[0][index];
				for (int i = 0; i < N - 1; i++) {
					arr[i][index] = arr[i + 1][index];
				}
				arr[N - 1][index] = v;
				solve(index + 1, arr);
			}
		}

	}

	static class FastScanner {
		final private int BUFFER_SIZE = 1 << 10;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public FastScanner() {
			this(System.in);
		}

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

		public FastScanner(String fileName) throws IOException {
			Path p = Paths.get(fileName);
			buffer = Files.readAllBytes(p);
			bytesRead = buffer.length;
		}

		int[] nextIntArray(int N) throws IOException {
			int[] arr = new int[N];
			for (int i = 0; i < N; i++) {
				arr[i] = nextInt();
			}
			return arr;
		}

		String nextLine() throws IOException {
			int c = read();
			while (c != -1 && isEndline(c))
				c = read();
			if (c == -1) {
				return null;
			}
			StringBuilder res = new StringBuilder();
			do {
				if (c >= 0) {
					res.appendCodePoint(c);
				}
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}

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

		String next() throws Exception {
			int c = readOutSpaces();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

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

		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 {
			if (din == null) {
				bufferPointer = 0;
				bytesRead = -1;
			} else {
				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++];
		}

		private int readOutSpaces() throws IOException {
			while (true) {
				if (bufferPointer == bytesRead) fillBuffer();
				int c = buffer[bufferPointer++];
				if (!isSpaceChar(c)) {
					return c;
				}
			}
		}

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

		public int[][] readGraph(int N, int M, boolean zeroIndexed, boolean bidirectional) throws Exception {
			int[][] adj = new int[N][];
			int[] numNodes = new int[N];
			int[][] input = new int[M][2];
			for (int i = 0; i < M; i++) {
				int a = nextInt();
				int b = nextInt();
				if (zeroIndexed) {
					a--;
					b--;
				}
				input[i][0] = a;
				input[i][1] = b;
				numNodes[a]++;
				if (bidirectional) numNodes[b]++;
			}
			for (int i = 0; i < N; i++) {
				adj[i] = new int[numNodes[i]];
				numNodes[i] = 0;
			}
			for (int i = 0; i < M; i++) {
				int a = input[i][0];
				int b = input[i][1];
				adj[a][numNodes[a]++] = b;
				if (bidirectional) adj[b][numNodes[b]++] = a;
			}
			return adj;
		}

		public int[][][] readWeightedGraph(int N, int M, boolean zeroIndexed, boolean bidirectional) throws Exception {
			int[][][] adj = new int[N][][];
			int[] numNodes = new int[N];
			int[][] input = new int[M][3];
			for (int i = 0; i < M; i++) {
				int a = nextInt();
				int b = nextInt();
				if (zeroIndexed) {
					a--;
					b--;
				}
				int d = nextInt();
				input[i][0] = a;
				input[i][1] = b;
				input[i][2] = d;
				numNodes[a]++;
				if (bidirectional) numNodes[b]++;
			}
			for (int i = 0; i < N; i++) {
				adj[i] = new int[numNodes[i]][2];
				numNodes[i] = 0;
			}
			for (int i = 0; i < M; i++) {
				int a = input[i][0];
				int b = input[i][1];
				int d = input[i][2];
				adj[a][numNodes[a]][0] = b;
				adj[a][numNodes[a]][1] = d;
				numNodes[a]++;
				if (bidirectional) {
					adj[b][numNodes[b]][0] = a;
					adj[b][numNodes[b]][1] = d;
					numNodes[b]++;
				}
			}
			return adj;
		}
	}

	static class FastPrinter {
		static final char ENDL = '\n';
		StringBuilder buf;
		PrintWriter pw;

		public FastPrinter(OutputStream stream) {
			buf = new StringBuilder();
			pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream)));
		}

		public FastPrinter(String fileName) throws Exception {
			buf = new StringBuilder();
			pw = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
		}

		public FastPrinter(StringBuilder buf) {
			this.buf = buf;
		}

		public void print(int a) {
			buf.append(a);
		}

		public void print(long a) {
			buf.append(a);
		}

		public void print(char a) {
			buf.append(a);
		}

		public void print(char[] a) {
			buf.append(a);
		}

		public void print(double a) {
			buf.append(a);
		}

		public void print(String a) {
			buf.append(a);
		}

		public void print(Object a) {
			buf.append(a.toString());
		}

		public void println() {
			buf.append(ENDL);
		}

		public void println(int a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(long a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(char a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(char[] a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(double a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(String a) {
			buf.append(a);
			buf.append(ENDL);
		}

		public void println(Object a) {
			buf.append(a.toString());
			buf.append(ENDL);
		}

		public void printf(String format, Object... args) {
			buf.append(String.format(format, args));
		}

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

		public void flush() {
			pw.print(buf);
			pw.flush();
			buf.setLength(0);
		}

	}

}


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.IntStream;

public class Test {
  static PrintWriter writer =
      new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

  static int readInt() {
    int ans = 0;
    boolean neg = false;
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (c == '-') {
          start = true;
          neg = true;
          continue;
        } else if (c >= '0' && c <= '9') {
          start = true;
          ans = ans * 10 + c - '0';
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return neg ? -ans : ans;
  }

  static long readLong() {
    long ans = 0;
    boolean neg = false;
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (c == '-') {
          start = true;
          neg = true;
          continue;
        } else if (c >= '0' && c <= '9') {
          start = true;
          ans = ans * 10 + c - '0';
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return neg ? -ans : ans;
  }

  static String readLine() {
    StringBuilder b = new StringBuilder();
    try {
      boolean start = false;
      for (int c = 0; (c = System.in.read()) != -1; ) {
        if (Character.isLetterOrDigit(c)) {
          start = true;
          b.append((char) c);
        } else if (start) break;
      }
    } catch (IOException e) {
    }
    return b.toString();
  }

  public static void main(String[] args) {
    Test te = new Test();
    te.start();
    writer.flush();
  }

  void start() {
    int t = readInt();
    while (t-- > 0) {
      int n = readInt(), m = readInt();
      int[][] a = new int[n][m];
      int[][] e = new int[n*m][];
      for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
          a[i][j] = readInt();
          e[i*m+j] = new int[]{a[i][j], j};
        }
      Arrays.sort(e, (x, y) -> x[0] == y[0] ? Integer.compare(x[1], y[1])
          : Integer.compare(y[0], x[0]));
      Set<Integer> cols = new HashSet<>();
      for (int[] x : e) {
        cols.add(x[1]);
        if (cols.size() >= n) break;
      }
      int[] dp = new int[1<<n];
      Arrays.fill(dp, -1);
      dp[0] = 0;
      for (int c : cols) {
        for (int i = (1 << n) - 1; i >= 0; i--) {
          int u = (1 << n) - 1 - i;
          int p = u;
          if (dp[i] >= 0)
            while (p > 0) {
              for (int r = 0; r < n; r++) {
                  int sum = 0;
                  for (int j = 0; j < n; j++) if (((p >> j) & 1) != 0) sum += a[(j + r) % n][c];
                  dp[i | p] = Math.max(dp[i | p], dp[i] + sum);
                }
              p = (p - 1) & u;
            }
        }
      }
      writer.println(dp[(1<<n) - 1]);
    }
  }
}


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

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

    static class TaskE {
        public void solve(int testNumber, Input in, PrintWriter out) {
            try {
                int kt = in.readInt();
                for (int nt = 0; nt < kt; nt++) {
                    int n = in.readInt();
                    int m = in.readInt();
                    int[][] a = new int[m][n];
                    for (int i = 0; i < n; i++) {
                        for (int j = 0; j < m; j++) {
                            a[j][i] = in.readInt();
                        }
                    }

                    Arrays.sort(a, (x, y) -> {
                        int xMax = 0;
                        for (int i = 0; i < x.length; i++) {
                            xMax = Math.max(xMax, x[i]);
                        }
                        int yMax = 0;
                        for (int i = 0; i < y.length; i++) {
                            yMax = Math.max(yMax, y[i]);
                        }
                        return Integer.compare(-xMax, -yMax);
                    });

                    int ans = 0;
                    int[] s = new int[4];
                    for (s[0] = 0; s[0] < n; s[0]++) {
                        for (s[1] = 0; s[1] < n; s[1]++) {
                            for (s[2] = 0; s[2] < n; s[2]++) {
                                for (s[3] = 0; s[3] < n; s[3]++) {
                                    int cur = 0;
                                    for (int i = 0; i < n; i++) {
                                        int max = 0;
                                        for (int j = 0; j < Math.min(m, n); j++) {
                                            max = Math.max(max, a[j][(i + s[j]) % n]);
                                        }
                                        cur += max;
                                    }
                                    ans = Math.max(cur, ans);
                                }
                            }
                        }
                    }

                    out.println(ans);
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }

    static class Input {
        public final BufferedReader reader;
        private String line = "";
        private int pos = 0;

        public Input(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        private boolean isSpace(char ch) {
            return ch <= 32;
        }

        public String readWord() throws IOException {
            skip();
            int start = pos;
            while (pos < line.length() && !isSpace(line.charAt(pos))) {
                pos++;
            }
            return line.substring(start, pos);
        }

        public int readInt() throws IOException {
            return Integer.parseInt(readWord());
        }

        private void skip() throws IOException {
            while (true) {
                if (pos >= line.length()) {
                    line = reader.readLine();
                    pos = 0;
                }
                while (pos < line.length() && isSpace(line.charAt(pos))) {
                    pos++;
                }
                if (pos < line.length()) {
                    return;
                }
            }
        }

    }
}


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

public class C {

	static int n, m, a[][];
	static int[][] memo;

	static int[] getCol(int col, int shift) {
		int[] ans = new int[n];
		for (int i = 0, j = shift; i < n; i++, j = (j + 1) % n) {
			ans[i] = a[j][col];
		}
		return ans;

	}

	static int dp(int col, int msk) {
		if (col == m)
			return 0;
		if (memo[msk][col] != -1)
			return memo[msk][col];
		int ans = 0;
		for (int shift = 0; shift < n; shift++) {
			int[] currCol = getCol(col, shift);
			for (int nxtMsk = 0; nxtMsk < 1 << n; nxtMsk++) {
				if ((nxtMsk & msk) != msk)
					continue;
				int curr = 0;
				int diff = msk ^ nxtMsk;
				for (int i = 0; i < n; i++)
					if ((diff & 1 << i) != 0)
						curr += currCol[i];
				ans = Math.max(ans, dp(col + 1, nxtMsk) + curr);
			}
		}
		return memo[msk][col] = ans;
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		int tc = sc.nextInt();
		while (tc-- > 0) {
			n = sc.nextInt();
			m = sc.nextInt();
			memo = new int[1 << n][m];
			for (int[] x : memo)
				Arrays.fill(x, -1);
			a = new int[n][m];
			for (int i = 0; i < n; i++)
				for (int j = 0; j < m; j++)
					a[i][j] = sc.nextInt();
			out.println(dp(0, 0));
		}
		out.close();

	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

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

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

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

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

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

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

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

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

	}

	static void sort(int[] a) {
		shuffle(a);
		Arrays.sort(a);
	}

	static void shuffle(int[] a) {
		int n = a.length;
		Random rand = new Random();
		for (int i = 0; i < n; i++) {
			int tmpIdx = rand.nextInt(n);
			int tmp = a[i];
			a[i] = a[tmpIdx];
			a[tmpIdx] = tmp;
		}
	}

}


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

public class Main {
    static int inf = (int) 1e9 + 7;
    static int n, m, a[][];
    static ArrayList<Integer> used;
    static int num[];
    static int ans;

    static void rec(int id) {
        if (id == used.size()) {
            check();
            return;
        }

        for(int i = 0;i < n;i++) {
            num[id] = i;
            rec(id + 1);
        }
    }

    static void check() {
        int new_ans = 0;
        for(int i = 0;i < n;i++) {
            int max = 0;
            for(int j = 0;j < used.size();j++) {
                max = Math.max(max, a[(i + num[j]) % n][used.get(j)]);
            }
            new_ans += max;
        }
        ans = Math.max(ans, new_ans);
    }

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
        int test = nextInt();
        while(test-- > 0) {
            n = nextInt();
            m = nextInt();
            a = new int [n][m];
            for(int i = 0;i < n;i++) {
                for(int j = 0;j < m;j++) a[i][j] = nextInt();
            }
            used = new ArrayList<>();
            num = new int [n * m];
            ans = 0;

            pair b[] = new pair[n * m];

            for(int i = 0;i < n;i++) {
                for(int j = 0;j < m;j++) {
                    b[i * m + j] = new pair(a[i][j], j);
                }
            }

            Arrays.sort(b, new pair());

            for(int i = b.length - 1;i >= Math.max(0, b.length - 5);i--) {
                int v = b[i].y;

                boolean bad = false;

                for(int j = 0;j < used.size();j++) if (used.get(j) == v) bad = true;

                if (!bad) used.add(v);
            }

            rec(0);

            pw.println(ans);
        }
        pw.close();
    }

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

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

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

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

class pair implements Comparator<pair>{
    int x, y;
    pair(int x, int y) {
        this.x = x;
        this.y = y;
    }

    pair() {}

    @Override
    public int compare(pair o1, pair o2) {
        return Integer.compare(o1.x, o2.x);
    }
}


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

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

  public static void main(String[] args) {
    InputStream inputStream = System.in;
    OutputStream outputStream = System.out;
    InputReader in = new InputReader(inputStream);
    OutputWriter out = new OutputWriter(outputStream);
    TaskE1 solver = new TaskE1();
    int testCount = Integer.parseInt(in.next());
    for (int i = 1; i <= testCount; i++) {
      solver.solve(i, in, out);
    }
    out.close();
  }

  static class TaskE1 {

    public void solve(int testNumber, InputReader in, OutputWriter out) {
      int n = in.nextInt();
      int m = in.nextInt();
      int[][] d = new int[2][1 << n];
      int[] buf = new int[1 << n];
      int[][] a = new int[m][n];
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
          a[j][i] = in.nextInt();
        }
      }
      for (int i = 0; i < m; ++i) {
        int[] prev = d[i % 2], nx = d[(i + 1) % 2];
        for (int shift = 0; shift < n; ++shift) {
          int[] b = new int[n];
          for (int j = 0; j < n; ++j) {
            b[j] = a[i][(j + shift) % n];
          }
          System.arraycopy(prev, 0, buf, 0, prev.length);
          for (int mask = 0; mask < (1 << n); ++mask) {
            int val0 = buf[mask];
            for (int j = 0; j < n; ++j) {
              if ((mask >> j) % 2 == 0) {
                int val = val0 + b[j];
                int nm = mask ^ (1 << j);
                if (val > buf[nm]) {
                  buf[nm] = val;
                }
              }
            }
          }
          for (int mask = 0; mask < (1 << n); ++mask) {
            if (nx[mask] < buf[mask]) {
              nx[mask] = buf[mask];
            }
          }
        }
      }
      out.printLine(d[m % 2][(1 << n) - 1]);
    }

  }

  static class OutputWriter {

    private final PrintWriter writer;

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

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

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

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

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

  }

  static class InputReader {

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

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

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

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

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

    public String nextToken() {
      int c = readSkipSpace();
      StringBuilder sb = new StringBuilder();
      while (!isSpace(c)) {
        sb.append((char) c);
        c = read();
      }
      return sb.toString();
    }

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

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

  }
}


//package cf584d12;
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class E {
	public static void main(String[] args) {
		MyScanner sc = new MyScanner();
		int t = sc.nextInt();
		for(int w = 0; w < t; w++) {
			int n = sc.nextInt(), m = sc.nextInt();
			TreeSet<X> set = new TreeSet<X>();
			int[][] grid = new int[n][m];
			for(int i = 0; i < n; i++)
				for(int j = 0; j < m; j++) {
					grid[i][j] = sc.nextInt();
					set.add(new X(i, j, grid[i][j]));
				}
			Y[] top4 = new Y[n];
			int sum = 0;
			for(int i = 0; i < n; i++) {
				top4[i] = new Y(set.pollLast());
				sum += top4[i].a;
			}
			Arrays.sort(top4);
			HashSet<String> strs = new HashSet<String>();
			AAA[] sss = new AAA[n];
			boolean[] used = new boolean[n];
			if(n == 4) {
				for(int i = 0; i < 4; i++) {
					int max = -1, jj = -1;
					for(int j = 0; j < 4; j++) {
						if(!used[j] && top4[j].a > max) {
							max = top4[j].a;
							jj = j;
						}
					}
					used[jj] = true;
					sss[i] = new AAA(max, jj);
				}
				for(int i = 0; i < n; i++)
					strs.add(top4[i].i + " " + top4[i].j);
			}
			int ans = sum;
			if(n == 4 && top4[0].j == top4[1].j && top4[2].j == top4[3].j && top4[0].j != top4[2].j) {
				if(two(top4[0], top4[1]) != two(top4[2], top4[3])) {
					ans = 0;
					int oneCol = two(top4[0], top4[1]) ? top4[2].j : top4[0].j;
					for(int i = 0; i < n; i++)
						for(int j = 0; j < m; j++)
							if(!strs.contains(i + " " + j)){
								int no = -1;
								for(int k = 0; k < 4; k++)
									if(j == oneCol && top4[k].j == oneCol && two(top4[k], new Y(new X(i, j, 0))))
										no = k;
								ans = max(ans, sum - sss[no == sss[3].i ? 2 : 3].a + grid[i][j]);
							}
				}
			}
			out.println(ans);
		}
		out.close();
	}
	static class AAA {
		int a, i;
		public AAA(int A, int I) {
			a = A;
			i = I;
		}
	}
	static boolean two(Y y1, Y y2) {
		return (y1.i - y2.i + 4) % 4 == 2;
	}
	static class Y implements Comparable<Y> {
		int i, j, a;
		public Y(X x) {
			i = x.i;
			j = x.j;
			a = x.a;
		}
		public int compareTo(Y x) {
			if(j == x.j)
				return i - x.i;
			return j - x.j;
		}
	}
	static class X implements Comparable<X> {
		int i, j, a;
		public X(int I, int J, int A) {
			i = I;
			j = J;
			a = A;
		}
		public int compareTo(X x) {
			if(a == x.a && i == x.i)
				return j - x.j;
			else if(a == x.a)
				return i - x.i;
			return a - x.a;
		}
	}
	public static PrintWriter out  = new PrintWriter(new BufferedOutputStream(System.out));
	public static class MyScanner {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		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.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Main2 {

    static long mod = 998244353;
    static FastScanner scanner;

    static StringBuilder result = new StringBuilder();

    public static void main(String[] args) {
        scanner = new FastScanner();
        int t = scanner.nextInt();
        for (int i = 0; i < t; i++) {
            solve();
            result.append("\n");
        }
        System.out.print(result.toString());
    }

    static void solve() {
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        PriorityQueue<WithIdx2> queue = new PriorityQueue<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                queue.add(new WithIdx2(scanner.nextInt(), i, j));
            }
        }

        if (n <= 3) {
            int res = 0;
            for (int k = 0; k < n; k++) {
                res += queue.poll().val;
            }
            result.append(res);
        } else {

            List<WithIdx2> a = new ArrayList<>();
            for (int i = 0; i < 9; i++) {
                if (!queue.isEmpty()) a.add(queue.poll());
            }
            int[] offsets = new int[m];
            best = -1;
            Arrays.fill(offsets, -100);
            put(0, a, offsets, new int[4]);
            result.append(best);
        }
    }

    static int best = -1;

    static void put(int current, List<WithIdx2> vals, int[] offsets, int[] rows) {
        if (current == vals.size()) {
            for (int i = 0; i < rows.length; i++) if (rows[i] == 0) return;
            int sum = IntStream.of(rows).sum();
            best = Math.max(best, sum);
            return;
        }
        for (int row = 0; row < 4; row++) {
            if (rows[row] == 0) {
                WithIdx2 c = vals.get(current);
                if (offsets[c.y] == -100) {
                    rows[row] = c.val;
                    offsets[c.y] = row - c.x;
                    put(current + 1, vals, offsets, rows);
                    rows[row] = 0;
                    offsets[c.y] = -100;
                } else {
                    int bind = c.x + offsets[c.y];
                    if (bind < 0) bind += 4;
                    if (bind >= 4) bind -= 4;
                    if (row == bind) {
                        rows[row] = c.val;
                        put(current + 1, vals, offsets, rows);
                        rows[row] = 0;
                    }
                }
            }
        }
        put(current + 1, vals, offsets, rows);
    }

    static class WithIdx2 implements Comparable<WithIdx2>{
        int x, y, val;

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

        @Override
        public int compareTo(WithIdx2 o) {
            return -Integer.compare(val, o.val);
        }
    }

    static class WithIdx implements Comparable<WithIdx>{
        int val, idx;

        public WithIdx(int val, int idx) {
            this.val = val;
            this.idx = idx;
        }

        @Override
        public int compareTo(WithIdx o) {
            return Integer.compare(val, o.val);
        }
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine() {
            try {
                return br.readLine();
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

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

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

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

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

        long[] nextLongArray(int n) {
            long[] res = new long[n];
            for (int i = 0; i < n; i++) res[i] = nextLong();
            return res;
        }

        String[] nextStringArray(int n) {
            String[] res = new String[n];
            for (int i = 0; i < n; i++) res[i] = nextToken();
            return res;
        }
    }

    static class PrefixSums {
        long[] sums;

        public PrefixSums(long[] sums) {
            this.sums = sums;
        }

        public long sum(int fromInclusive, int toExclusive) {
            if (fromInclusive > toExclusive) throw new IllegalArgumentException("Wrong value");
            return sums[toExclusive] - sums[fromInclusive];
        }

        public static PrefixSums of(int[] ar) {
            long[] sums = new long[ar.length + 1];
            for (int i = 1; i <= ar.length; i++) {
                sums[i] = sums[i - 1] + ar[i - 1];
            }
            return new PrefixSums(sums);
        }

        public static PrefixSums of(long[] ar) {
            long[] sums = new long[ar.length + 1];
            for (int i = 1; i <= ar.length; i++) {
                sums[i] = sums[i - 1] + ar[i - 1];
            }
            return new PrefixSums(sums);
        }
    }

    static class ADUtils {
        static void sort(int[] ar) {
            Random rnd = ThreadLocalRandom.current();
            for (int i = ar.length - 1; i > 0; i--)
            {
                int index = rnd.nextInt(i + 1);
                // Simple swap
                int a = ar[index];
                ar[index] = ar[i];
                ar[i] = a;
            }
            Arrays.sort(ar);
        }

        static void reverse(int[] arr) {
            int last = arr.length / 2;
            for (int i = 0; i < last; i++) {
                int tmp = arr[i];
                arr[i] = arr[arr.length - 1 - i];
                arr[arr.length - 1 - i] = tmp;
            }
        }

        static void sort(long[] ar) {
            Random rnd = ThreadLocalRandom.current();
            for (int i = ar.length - 1; i > 0; i--)
            {
                int index = rnd.nextInt(i + 1);
                // Simple swap
                long a = ar[index];
                ar[index] = ar[i];
                ar[i] = a;
            }
            Arrays.sort(ar);
        }
    }

    static class MathUtils {
        static long[] FIRST_PRIMES = {
                2,     3,      5,      7,     11,     13,     17,     19,     23,     29,
                31,     37,     41,     43,     47,     53,     59,     61,     67,     71,
                73,     79,     83,     89  ,   97 ,    101,    103,    107,    109,    113,
                127,    131,    137,    139,    149,    151,    157,    163,    167,    173,
                179,    181,    191,    193,    197,    199,    211,    223,    227,    229,
                233,    239,    241,    251,    257,    263,    269,    271,    277,    281,
                283,    293,    307,    311,    313,    317,    331,    337,    347,    349,
                353,    359,    367,    373,    379,    383,    389,    397,    401,    409,
                419,    421,    431,    433,    439,    443,    449,    457,    461,    463,
                467,    479,    487,    491,    499,    503,    509,    521,    523,    541,
                547,    557,    563,    569,    571,    577,    587,    593,    599,    601,
                607,    613,    617,    619,    631,    641,    643,    647,    653,    659,
                661,    673,    677,    683,    691,    701,    709,    719,    727,    733,
                739,    743,    751,    757,    761,    769,    773,    787,    797,    809,
                811,    821,    823,    827,    829,    839,    853,    857,    859,    863,
                877,    881,    883,    887,    907,    911,    919,    929,    937,    941,
                947,    953,    967,    971,    977,    983,    991,    997,   1009,   1013,
                1019,   1021,   1031,   1033,   1039,   1049,   1051};

        static long[] primes(int to) {
            long[] all = new long[to + 1];
            long[] primes = new long[to + 1];
            all[1] = 1;
            int primesLength = 0;
            for (int i = 2; i <= to; i ++) {
                if (all[i] == 0) {
                    primes[primesLength++] = i;
                    all[i] = i;
                }
                for (int j = 0; j < primesLength && i * primes[j] <= to && all[i] >= primes[j]; j++) {
                    all[(int) (i * primes[j])] = primes[j];
                }
            }
            return Arrays.copyOf(primes, primesLength);
        }

        static long modpow(long b, long e, long m) {
            long result = 1;

            while (e > 0) {
                if ((e & 1) == 1) {
                    /* multiply in this bit's contribution while using modulus to keep
                     * result small */
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                e >>= 1;
            }

            return result;
        }

        static long submod(long x, long y, long m) {
            return (x - y + m) % m;
        }
    }
}

/*
1
4 2
5 7 6 2 2 5 3 6
 */


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.stream.IntStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.util.stream.Stream;
import java.nio.charset.Charset;
import java.util.StringTokenizer;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStream;

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

    static class E1RotateColumnsEasyVersion {
        public void solve(int testNumber, LightScanner in, LightWriter out) {
            // out.setBoolLabel(LightWriter.BoolLabel.YES_NO_FIRST_UP);
            int testCases = in.ints();
            for (int testCase = 0; testCase < testCases; testCase++) {
                int n = in.ints(), m = in.ints();
                int pow = 1;
                for (int i = 0; i < n; i++) pow *= n;
                int[][] a = in.ints(n, m);
                E1RotateColumnsEasyVersion.P[] columns = new E1RotateColumnsEasyVersion.P[m];
                for (int i = 0; i < m; i++) {
                    int max = 0;
                    for (int j = 0; j < n; j++) max = Math.max(max, a[j][i]);
                    columns[i] = new E1RotateColumnsEasyVersion.P(i, max);
                }
                IntroSort.sort(columns, Comparator.comparing(column -> -column.m));

                int ans = 0;
                for (int i = 0; i < pow; i++) {
                    int[] res = new int[n];
                    int t = i;
                    for (int j = 0; j < Math.min(n, m); j++) {
                        int shift = t % n;
                        t /= n;
                        for (int k = 0; k < n; k++) {
                            res[(k + shift) % n] = Math.max(res[(k + shift) % n], a[k][columns[j].i]);
                        }
                    }
                    int sum = 0;
                    for (int j = 0; j < n; j++) {
                        sum += res[j];
                    }
                    ans = Math.max(ans, sum);
                }
                out.ans(ans).ln();
            }
        }

        private static class P {
            int i;
            int m;

            P(int i, int m) {
                this.i = i;
                this.m = m;
            }

        }

    }

    static class InsertionSort {
        private InsertionSort() {
        }

        static <T> void sort(T[] a, int low, int high, Comparator<? super T> comparator) {
            for (int i = low; i < high; i++) {
                for (int j = i; j > low && comparator.compare(a[j - 1], a[j]) > 0; j--) {
                    ArrayUtil.swap(a, j - 1, j);
                }
            }
        }

    }

    static class HeapSort {
        private HeapSort() {
        }

        private static <T> void heapfy(T[] a, int low, int high, int i, T val, Comparator<? super T> comparator) {
            int child = 2 * i - low + 1;
            while (child < high) {
                if (child + 1 < high && comparator.compare(a[child], a[child + 1]) < 0) {
                    child++;
                }
                if (comparator.compare(val, a[child]) >= 0) {
                    break;
                }
                a[i] = a[child];
                i = child;
                child = 2 * i - low + 1;
            }
            a[i] = val;
        }

        static <T> void sort(T[] a, int low, int high, Comparator<T> comparator) {
            for (int p = (high + low) / 2 - 1; p >= low; p--) {
                heapfy(a, low, high, p, a[p], comparator);
            }
            while (high > low) {
                high--;
                T pval = a[high];
                a[high] = a[low];
                heapfy(a, low, high, low, pval, comparator);
            }
        }

    }

    static class QuickSort {
        private QuickSort() {
        }

        private static <T> void med(T[] a, int low, int x, int y, int z, Comparator<? super T> comparator) {
            if (comparator.compare(a[z], a[x]) < 0) {
                ArrayUtil.swap(a, low, x);
            } else if (comparator.compare(a[y], a[z]) < 0) {
                ArrayUtil.swap(a, low, y);
            } else {
                ArrayUtil.swap(a, low, z);
            }
        }

        static <T> int step(T[] a, int low, int high, Comparator<? super T> comparator) {
            int x = low + 1, y = low + (high - low) / 2, z = high - 1;
            if (comparator.compare(a[x], a[y]) < 0) {
                med(a, low, x, y, z, comparator);
            } else {
                med(a, low, y, x, z, comparator);
            }

            int lb = low + 1, ub = high;
            while (true) {
                while (comparator.compare(a[lb], a[low]) < 0) {
                    lb++;
                }
                ub--;
                while (comparator.compare(a[low], a[ub]) < 0) {
                    ub--;
                }
                if (lb >= ub) {
                    return lb;
                }
                ArrayUtil.swap(a, lb, ub);
                lb++;
            }
        }

    }

    static final class BitMath {
        private BitMath() {
        }

        public static int count(int v) {
            v = (v & 0x55555555) + ((v >> 1) & 0x55555555);
            v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
            v = (v & 0x0f0f0f0f) + ((v >> 4) & 0x0f0f0f0f);
            v = (v & 0x00ff00ff) + ((v >> 8) & 0x00ff00ff);
            v = (v & 0x0000ffff) + ((v >> 16) & 0x0000ffff);
            return v;
        }

        public static int msb(int v) {
            if (v == 0) {
                throw new IllegalArgumentException("Bit not found");
            }
            v |= (v >> 1);
            v |= (v >> 2);
            v |= (v >> 4);
            v |= (v >> 8);
            v |= (v >> 16);
            return count(v) - 1;
        }

    }

    static interface Verified {
    }

    static class LightWriter implements AutoCloseable {
        private final Writer out;
        private boolean autoflush = false;
        private boolean breaked = true;

        public LightWriter(Writer out) {
            this.out = out;
        }

        public LightWriter(OutputStream out) {
            this(new BufferedWriter(new OutputStreamWriter(out, Charset.defaultCharset())));
        }

        public LightWriter print(char c) {
            try {
                out.write(c);
                breaked = false;
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
            return this;
        }

        public LightWriter print(String s) {
            try {
                out.write(s, 0, s.length());
                breaked = false;
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
            return this;
        }

        public LightWriter ans(String s) {
            if (!breaked) {
                print(' ');
            }
            return print(s);
        }

        public LightWriter ans(int i) {
            return ans(Integer.toString(i));
        }

        public LightWriter ln() {
            print(System.lineSeparator());
            breaked = true;
            if (autoflush) {
                try {
                    out.flush();
                } catch (IOException ex) {
                    throw new UncheckedIOException(ex);
                }
            }
            return this;
        }

        public void close() {
            try {
                out.close();
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        }

    }

    static class IntroSort {
        private static int INSERTIONSORT_THRESHOLD = 16;

        private IntroSort() {
        }

        static <T> void sort(T[] a, int low, int high, int maxDepth, Comparator<T> comparator) {
            while (high - low > INSERTIONSORT_THRESHOLD) {
                if (maxDepth-- == 0) {
                    HeapSort.sort(a, low, high, comparator);
                    return;
                }
                int cut = QuickSort.step(a, low, high, comparator);
                sort(a, cut, high, maxDepth, comparator);
                high = cut;
            }
            InsertionSort.sort(a, low, high, comparator);
        }

        public static <T> void sort(T[] a, Comparator<T> comparator) {
            if (a.length <= INSERTIONSORT_THRESHOLD) {
                InsertionSort.sort(a, 0, a.length, comparator);
            } else {
                sort(a, 0, a.length, 2 * BitMath.msb(a.length), comparator);
            }
        }

    }

    static final class ArrayUtil {
        private ArrayUtil() {
        }

        public static <T> void swap(T[] a, int x, int y) {
            T t = a[x];
            a[x] = a[y];
            a[y] = t;
        }

    }

    static class LightScanner {
        private BufferedReader reader = null;
        private StringTokenizer tokenizer = null;

        public LightScanner(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
        }

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

        public int ints() {
            return Integer.parseInt(string());
        }

        public int[] ints(int length) {
            return IntStream.range(0, length).map(x -> ints()).toArray();
        }

        public int[][] ints(int height, int width) {
            return IntStream.range(0, height).mapToObj(x -> ints(width)).toArray(int[][]::new);
        }

    }
}


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

/*

*/

public class e1 {

	static int n;
	static int m;
	static int[][] mat;

	public static void main(String[] args){
		JS scan = new JS();
		PrintWriter out = new PrintWriter(System.out);
		int t = scan.nextInt();
		for(int q = 1; q <= t; q++){
			ans = 0;
			n = scan.nextInt();
			m = scan.nextInt();
			mat = new int[n][m];
			for(int i = 0; i < n; i++){
				for(int j = 0; j < m; j++){
					mat[i][j] = scan.nextInt();
				}
			}
			int[] max = new int[m];
			PriorityQueue<Item> pq = new PriorityQueue<Item>();
			for(int i = 0; i < m; i++){
				for(int j = 0; j < n; j++){
					max[i] = Math.max(max[i], mat[j][i]);
				}
				pq.add(new Item(i, max[i]));
			}
			ArrayList<Item> guys = new ArrayList<Item>();
			while(!pq.isEmpty() && guys.size() < 8){
				Item tt = pq.poll();
				guys.add(tt);
			}
			perm(guys, 0, new int[guys.size()]);
			out.println(ans);
		}
		out.flush();
	}

	static int ans = 0;

	static void perm(ArrayList<Item> guys, int me, int[] shift){
		if(me == guys.size()){
			// System.out.println(Arrays.toString(shift));
			int res = 0;
			int[] best = new int[n];
			for(int j = 0; j < guys.size(); j++){
				Item g = guys.get(j);
				int pp = g.a;
				for(int i = 0; i < n; i++){
					best[(i+shift[j])%n] = Math.max(best[(i+shift[j])%n], mat[i][pp]);
				}
			}
			for(int i = 0; i < n; i++) res += best[i];
			ans = Math.max(res, ans);
			return;
		}
		for(int i = 0; i < n; i++){
			shift[me] = i;
			perm(guys, me+1, shift);
		}
	}

	static class Item implements Comparable<Item>{

		int a;
		int b;

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

		public int compareTo(Item o){
			return o.b-this.b;
		}
	}

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

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

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

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

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

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

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

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

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

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


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

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

    static class TaskE1 {
        int n;
        int m;
        int[][] map;
        int[][] dp;

        int two(int idx) {
            return 1 << idx;
        }

        boolean contain(int mask, int idx) {
            return (mask & two(idx)) > 0;
        }

        int best(int mask, int col) {
            int res = 0;
            for (int rot = 0; rot < n; rot++) {
                int sum = 0;
                for (int i = 0; i < n; i++) {
                    int curRow = (rot + i) % n;
                    if (contain(mask, curRow)) {
                        sum += map[i][col];
                    }
                }
                res = Math.max(res, sum);
            }
            return res;
        }

        int rec(int col, int used) {
            if (col == m)
                return 0;

            int res = dp[col][used];
            if (res != -1)
                return res;
            res = 0;
            for (int mask = 0; mask < two(n); mask++)
                if ((mask & used) == 0) {
                    res = Math.max(res, rec(col + 1, used | mask) + best(mask, col));
                }
            dp[col][used] = res;
            return res;
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int t = in.nextInt();
            for (int test = 0; test < t; test++) {
                n = in.nextInt();
                m = in.nextInt();
                map = new int[n][m];
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < m; j++) {
                        map[i][j] = in.nextInt();
                    }
                }
                dp = new int[m][1 << n];
                for (int[] aux : dp)
                    Arrays.fill(aux, -1);
                int ans = rec(0, 0);
                out.println(ans);
            }
        }

    }

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

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

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

        private 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 nextInt() {
            int c = read();
            while (isWhitespace(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 (!isWhitespace(c));
            return res * sgn;
        }

    }
}


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

public class Main{
	static int[][]memo;
	static int n,m,in[][];
	static int dp(int col,int maxRowMask) {
		if(col>=m)return 0;
		if(memo[col][maxRowMask]!=-1)return memo[col][maxRowMask];

		int ans=0;

		for(int colMask=0;colMask<(1<<n);colMask++) {

			int sum=0;
			for(int i=0;i<n;i++) {
				if(((colMask>>i)&1)!=0) {
					sum+=in[i][col];
				}
			}
			int curMask=colMask;
			for(int cyclicShift=0;cyclicShift<n;cyclicShift++) {
				if((curMask&maxRowMask)!=0) {//some row has max value already determined
					int lastBit=curMask&1;
					curMask>>=1;
					curMask|=(lastBit<<(n-1));
					continue;
				}

				ans=Math.max(ans, sum+dp(col+1, maxRowMask|curMask));

				int lastBit=curMask&1;
				curMask>>=1;
				curMask|=(lastBit<<(n-1));

			}

		}
		return memo[col][maxRowMask]=ans;
	}
	public static void main(String[] args) throws Exception{
		pw=new PrintWriter(System.out);
		sc = new MScanner(System.in);
		int tc=sc.nextInt();
		while(tc-->0) {
			n=sc.nextInt();m=sc.nextInt();
			in=new int[n][m];
			for(int i=0;i<n;i++)in[i]=sc.intArr(m);
			memo=new int[m][1<<n];
			for(int i=0;i<m;i++)Arrays.fill(memo[i], -1);
			pw.println(dp(0, 0));
		}

		pw.flush();
	}
	static PrintWriter pw;
	static MScanner  sc;
	static class MScanner {
		StringTokenizer st;
		BufferedReader br;
		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

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

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

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

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

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

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

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

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


import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.System.exit;
import static java.util.Arrays.fill;

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

public class E {

	static void solve() throws Exception {
		int tests = scanInt();
//		int tests = 40;
		for (int test = 0; test < tests; test++) {
			int n = scanInt(), m = scanInt(), a[][] = new int[n][m];
//			int n = 12, m = 2000, a[][] = new int[n][m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					a[i][j] = scanInt();
				}
			}
			int bestCols[] = new int[min(m, n)];
			for (int i = 0; i < bestCols.length; i++) {
				bestCols[i] = i;
			}
			if (m > n) {
				int bestColMax[] = new int[n];
				for (int i = 0; i < n; i++) {
					int cmax = 0;
					for (int j = 0; j < n; j++) {
						cmax = max(cmax, a[j][i]);
					}
					bestColMax[i] = cmax;
				}
				for (int i = n; i < m; i++) {
					int cmax = 0;
					for (int j = 0; j < n; j++) {
						cmax = max(cmax, a[j][i]);
					}
					int minBC = 0, minBCM = Integer.MAX_VALUE;
					for (int j = 0; j < n; j++) {
						if (bestColMax[j] < minBCM) {
							minBC = j;
							minBCM = bestColMax[j];
						}
					}
					if (cmax > minBCM) {
						bestCols[minBC] = i;
						bestColMax[minBC] = cmax;
					}
				}
			}
			int dyn[] = new int[1 << n], dynNext[] = new int[1 << n], sums[] = new int[1 << n], csums[] = new int[1 << n];
			for (int i: bestCols) {
				fill(dynNext, 0);
				fill(sums, 0);
				for (int j = 0; j < n; j++) {
					for (int k = 1, bit = 0; k < 1 << n; k++) {
						if (k == 1 << (bit + 1)) {
							++bit;
						}
						sums[k] = max(sums[k], csums[k] = csums[k ^ (1 << bit)] + a[(bit + j) % n][i]);
					}
				}
				for (int mask1 = 0; mask1 < 1 << n; mask1++) {
					int cdyn = dynNext[mask1];
					for (int mask2 = mask1;; mask2 = (mask2 - 1) & mask1) {
						cdyn = max(cdyn, dyn[mask2] + sums[mask1 ^ mask2]);
						if (mask2 == 0) {
							break;
						}
					}
					dynNext[mask1] = cdyn;
				}
				int t[] = dyn;
				dyn = dynNext;
				dynNext = t;
			}
			out.println(dyn[(1 << n) - 1]);
		}
	}

	static int scanInt() throws IOException {
		return parseInt(scanString());
	}

	static long scanLong() throws IOException {
		return parseLong(scanString());
	}

	static String scanString() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}


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

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

    static class TaskE1 {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int numTests = in.nextInt();
            for (int test = 0; test < numTests; test++) {
                int n = in.nextInt();
                int m = in.nextInt();
                int[][] a = new int[n][m];
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < m; j++) {
                        a[i][j] = in.nextInt();
                    }
                }
                int[] d = new int[1 << n];
                int[] nd = new int[1 << n];
                for (int j = 0; j < m; j++) {
                    System.arraycopy(d, 0, nd, 0, d.length);
                    for (int mask = 0; mask < 1 << n; mask++) {
                        for (int submask = mask; submask > 0; submask = (submask - 1) & mask) {
                            for (int shift = 0; shift < n; shift++) {
                                int sum = 0;
                                for (int i = 0; i < n; i++) {
                                    if ((submask & (1 << i)) > 0) {
                                        sum += a[(i + shift) % n][j];
                                    }
                                }
                                nd[mask] = Math.max(nd[mask], d[mask ^ submask] + sum);
                            }
                        }
                    }
                    int[] t = d;
                    d = nd;
                    nd = t;
                }
                int ans = 0;
                for (int x : d) {
                    ans = Math.max(ans, x);
                }
                out.println(ans);
            }
        }

    }

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

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

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

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

    }
}


import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

    static ArrayList<Integer> cols;
    static int ans, n, a[][];

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int tc = sc.nextInt();
        while (tc-- > 0) {
            ans = 0;
            n = sc.nextInt();
            int m = sc.nextInt();
            boolean[] taken = new boolean[m];
            PriorityQueue<Pair> pq = new PriorityQueue<>();
            a = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++) {
                    int cur = sc.nextInt();
                    pq.add(new Pair(i, j, cur));
                    a[i][j] = cur;
                }
            cols = new ArrayList<>();
            while (!pq.isEmpty() && cols.size() < 8) {
                Pair cur = pq.remove();
                if (!taken[cur.j]) cols.add(cur.j);
                taken[cur.j] = true;
            }
            solve(0,new int [cols.size()]);
            out.println(ans);
        }
        out.flush();
        out.close();
    }

    static void solve(int i, int[] p) {
        if (i == cols.size()) {
            int[] max = new int[n];
            for (int k = 0; k < cols.size(); k++) {
                int j = cols.get(k);
                for (int ii = 0; ii < n; ii++) {
                    int idx = (ii + p[k]) % n;
                    max[idx] = Math.max(max[idx], a[ii][j]);
                }
            }
            int poss = 0;
            for (int x : max)
                poss += x;
            ans = Math.max(ans, poss);
            return;
        }
        for (int j = 0; j < n; j++) {
            p[i] = j;
            solve(i + 1, p);
        }
    }

    static class Pair implements Comparable<Pair> {
        int i, j, val;

        public Pair(int i, int j, int val) {
            this.i = i;
            this.j = j;
            this.val = val;
        }

        @Override
        public int compareTo(Pair o) {
            return o.val - val;
        }
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

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

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

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

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

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

        public void waitForInput() throws InterruptedException {
            Thread.sleep(3000);
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.*;
public class Main{
    //SOLUTION BEGIN
    //Into the Hardware Mode
    void pre() throws Exception{}
    void solve(int TC)throws Exception{
        int n = ni(), m = ni();
        long[][] a = new long[n][m];
        long[] col = new long[m];
        for(int i = 0; i< n; i++){
            for(int j = 0; j< m; j++){
                a[i][j] = nl();
                col[j] = Math.max(a[i][j], col[j]);
            }
        }
        Integer[] p = new Integer[m];
        for(int i = 0; i< m; i++)p[i] = i;
        Arrays.sort(p, (Integer i1, Integer i2) -> Long.compare(col[i2], col[i1]));
        long[][] mat = new long[n][Math.min(m, 6)];
        for(int i = 0; i< Math.min(m, 6); i++){
            for(int j = 0; j< n; j++)mat[j][i] = a[j][p[i]];
        }
        long pow = 1;
        for(int i = 0; i< Math.min(m, 6); i++)pow *= n;
        int[] sh = new int[Math.min(m, 6)];
        long ans = 0;
        for(int i = 0; i< pow; i++){
            int x = i;
            for(int j = 0; j< Math.min(m, 6); j++){
                sh[j] = x%n;
                x/=n;
            }
            long cur = 0;
            for(int ro = 0; ro < n; ro++){
                long cR = 0;
                for(int j = 0; j < Math.min(m, 6); j++)cR = Math.max(cR, mat[(ro+sh[j])%n][j]);
                cur += cR;
            }
            ans = Math.max(ans, cur);
        }
        pn(ans);
    }
    //SOLUTION END
    void hold(boolean b)throws Exception{if(!b)throw new Exception("Hold right there, Sparky!");}
    void exit(boolean b){if(!b)System.exit(0);}
    long IINF = (long)1e18, mod = (long)1e9+7;
    final int INF = (int)1e9, MX = (int)2e6+5;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399, eps = 1e-6;
    static boolean multipleTC = true, memory = false, fileIO = false;
    FastReader in;PrintWriter out;
    void run() throws Exception{
        if(fileIO){
            in = new FastReader("input.txt");
            out = new PrintWriter("output.txt");
        }else {
            in = new FastReader();
            out = new PrintWriter(System.out);
        }
        //Solution Credits: Taranpreet Singh
        int T = (multipleTC)?ni():1;
        pre();
        for(int t = 1; t<= T; t++)solve(t);
        out.flush();
        out.close();
    }
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    int digit(long s){int ans = 0;while(s>0){s/=10;ans++;}return ans;}
    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n()throws Exception{return in.next();}
    String nln()throws Exception{return in.nextLine();}
    int ni()throws Exception{return Integer.parseInt(in.next());}
    long nl()throws Exception{return Long.parseLong(in.next());}
    double nd()throws Exception{return Double.parseDouble(in.next());}

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

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

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

        String nextLine() throws Exception{
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                throw new Exception(e.toString());
            }
            return str;
        }
    }
}