/************************************************************************
 AUTH : krishna-3249
 DATE : 8/29/20
 TIME : 6:12 PM

 Everyone’s a whore, Grace. We just sell different parts of ourselves.

 Simple can be harder than complex:
 you have to work hard to get your thinking clean to make it simple.
 But it's worth it in the end
 because once you get there, you can move mountains.
 ************************************************************************/

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

public class Main {

    private static final long MOD = 1_000_000_000 + 7;

    private long power(long base, long exponent) {
        long res = 1;
        while (exponent > 0) {
            if ((base & 1) == 1) {
                res = (res * base) % MOD;
                exponent--;
            } else {
                res = (res * res) % MOD;
                exponent >>= 1;
            }
        }
        return res;
    }

    private long inverseMod(long number) {
        return power(number, MOD - 2);
    }

    private int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

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

    private List<Integer> sieve(int N) {
        boolean[] mark = new boolean[N+1];
        mark[0] = mark[1] = true;
        for (int i=2;i*i<=N;i++) {
            if (!mark[i]) {
                for (int j=2*i;j<=N;j+=i) {
                    mark[j] = true;
                }
            }
        }
        List<Integer> primes = new ArrayList<>();
        for (int i=0;i<=N;i++) {
            if (!mark[i]) {
                primes.add(i);
            }
        }
        return primes;
    }
    public void solve(Read input, Write output) throws Exception {
        List<Integer> primes = sieve(1000);
        int N = input.readInt();
        int[] arr = input.readIntArray(N);
        int allgcd = -1;
        for (int i=1;i<N;i++) {
            if (i==1) {
                allgcd = gcd(arr[i], arr[i-1]);
                continue;
            }
            allgcd = gcd(arr[i], allgcd);
            if (allgcd==1) {
                break;
            }
        }
        int[] factorcount = new int[1000001];
        boolean found = true;
        for (int i=0;i<N;i++) {
            if (arr[i]==1) {
                continue;
            }
            int val = arr[i];
            for (int j=0;j<primes.size();j++) {
                int prime = primes.get(j);
                boolean taken = false;
                while (val>1) {
                    if (val%prime==0) {
                        val = val/prime;
                        taken = true;
                    } else {
                        break;
                    }
                }
                if (taken) {
                    if (factorcount[prime]+1>1) {
                        found = false;
                        break;
                    } else {
                        factorcount[prime]++;
                    }
                }
            }
            if (val>1) {
                if (factorcount[val]+1>1) {
                    found = false;
                    break;
                } else {
                    factorcount[val]++;
                }
            }
            if (!found) {
                break;
            }
        }
        if (found) {
            output.printLine("pairwise coprime");
        } else {
            if (allgcd==1) {
                output.printLine("setwise coprime");
            } else {
                output.printLine("not coprime");
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Read input = new Read();
        Write output = new Write();
        Main D = new Main();
        D.solve(input, output);
        output.flush();
        output.close();
    }

    // java fast io reader and writer
    // taken from various sources and customized

    static class Read {

        private byte[] buffer = new byte[10 * 1024];
        private int index;
        private InputStream input_stream;
        private int total;

        public Read() {
            input_stream = System.in;
        }

        public int read() throws IOException {
            if (total < 0)
                throw new InputMismatchException();
            if (index >= total) {
                index = 0;
                total = input_stream.read(buffer);
                if (total <= 0)
                    return -1;
            }
            return buffer[index++];
        }

        public long readLong() throws IOException {
            long number = 0;
            int n = read();
            while (isWhiteSpace(n))
                n = read();
            long neg = 1l;
            if (n == '-') {
                neg = -1l;
                n = read();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    number *= 10l;
                    number += (long) (n - '0');
                    n = read();
                } else throw new InputMismatchException();
            }
            return neg * number;
        }

        public int readInt() throws IOException {
            int integer = 0;
            int n = read();
            while (isWhiteSpace(n))
                n = read();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = read();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    integer *= 10;
                    integer += n - '0';
                    n = read();
                } else throw new InputMismatchException();
            }
            return neg * integer;
        }

        public double readDouble() throws IOException {
            double doub = 0;
            int n = read();
            while (isWhiteSpace(n))
                n = read();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = read();
            }
            while (!isWhiteSpace(n) && n != '.') {
                if (n >= '0' && n <= '9') {
                    doub *= 10;
                    doub += n - '0';
                    n = read();
                } else throw new InputMismatchException();
            }

            if (n == '.') {
                n = read();
                double temp = 1;
                while (!isWhiteSpace(n)) {
                    if (n >= '0' && n <= '9') {
                        temp /= 10;
                        doub += (n - '0') * temp;
                        n = read();
                    } else throw new InputMismatchException();
                }
            }
            return doub * neg;
        }

        public String readString() throws IOException {
            StringBuilder sb = new StringBuilder();
            int n = read();
            while (isWhiteSpace(n))
                n = read();
            while (!isWhiteSpace(n)) {
                sb.append((char) n);
                n = read();
            }
            return sb.toString();
        }

        public List<Double> readDoubleList(int size) throws IOException {
            List<Double> res = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                res.add(this.readDouble());
            }
            return res;
        }

        public double[] readDoubleArray(int size) throws IOException {
            double[] res = new double[size];
            for (int i = 0; i < size; i++) {
                res[i] = this.readDouble();
            }
            return res;
        }

        public List<String> readStringList(int size) throws IOException {
            List<String> res = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                res.add(this.readString());
            }
            return res;
        }

        public String[] readStringArray(int size) throws IOException {
            String[] res = new String[size];
            for (int i = 0; i < size; i++) {
                res[i] = this.readString();
            }
            return res;
        }

        public List<Integer> readIntList(int size) throws IOException {
            List<Integer> res = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                res.add(this.readInt());
            }
            return res;
        }

        public List<Long> readLongList(int size) throws IOException {
            List<Long> res = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                res.add(this.readLong());
            }
            return res;
        }

        public int[] readIntArray(int size) throws IOException {
            int[] res = new int[size];
            for (int i = 0; i < size; i++) {
                res[i] = this.readInt();
            }
            return res;
        }

        public long[] readLongArray(int size) throws IOException {
            long[] res = new long[size];
            for (int i = 0; i < size; i++) {
                res[i] = this.readLong();
            }
            return res;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1)
                return true;
            return false;
        }
    }

    static class Write {

        private final BufferedWriter bw;

        public Write() {
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
        }

        public void print(Object str) throws IOException {
            bw.append(str + "");
        }

        public void printLine(Object str) throws IOException {
            print(str);
            bw.append("\n");
        }

        public void close() throws IOException {
            bw.close();
        }

        public void flush() throws IOException {
            bw.flush();
        }
    }
}


import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = sc.nextInt();
        }
        Arrays.sort(arr);
        int[] div = new int[arr[0] + 1];
        for(int i = 0; i < n; i++){
            helper(arr[i],div);
        }
        boolean pair = true, set = true;
        for(int i = 2; i < div.length; i++){
            if(div[i] > 1)
                pair = false;
            if(div[i] == n)
                set = false;
        }
        if(pair)
            System.out.println("pairwise coprime");
        else if(set)
            System.out.println("setwise coprime");
        else
            System.out.println("not coprime");
    }
    public static void helper(int num, int[] div){
        for(int i = 2; i <= Math.min(Math.sqrt(num) + 1, div.length - 1); i++){
            if(num % i == 0){
                div[i]++;
                if(i * i < num)
                    div[num / i]++;
            }
        }
    }
}

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

Score : 500 points

Problem Statement

We have N integers. The i-th number is A_i.

\{A_i\} is said to be pairwise coprime when GCD(A_i,A_j)=1 holds for every pair (i, j) such that 1\leq i < j \leq N.

\{A_i\} is said to be setwise coprime when \{A_i\} is not pairwise coprime but GCD(A_1,\ldots,A_N)=1.

Determine if \{A_i\} is pairwise coprime, setwise coprime, or neither.

Here, GCD(\ldots) denotes greatest common divisor.

Constraints

2 \leq N \leq 10^6

1 \leq A_i\leq 10^6

Input

Input is given from Standard Input in the following format:

N
A_1 \ldots A_N

Output

If \{A_i\} is pairwise coprime, print pairwise coprime; if \{A_i\} is setwise coprime, print setwise coprime; if neither, print not coprime.

Sample Input 1

3
3 4 5

Sample Output 1

pairwise coprime

GCD(3,4)=GCD(3,5)=GCD(4,5)=1, so they are pairwise coprime.

Sample Input 2

3
6 10 15

Sample Output 2

setwise coprime

Since GCD(6,10)=2, they are not pairwise coprime. However, since GCD(6,10,15)=1, they are setwise coprime.

Sample Input 3

3
6 10 16

Sample Output 3

not coprime

GCD(6,10,16)=2, so they are neither pairwise coprime nor setwise coprime.

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.NoSuchElementException;
public class Main {
	public static void main(String[] args)throws Exception{
		PrintWriter out = new PrintWriter(System.out);
		int N=nextInt();
		ArrayList<Integer> prime=new ArrayList<Integer>();
		HashMap<Integer,Boolean> map=new HashMap<Integer,Boolean>();
		boolean pair=true;
		int ans=0;
		prime.add(2);
		map.put(2,false);
		for(int i=3;i<=Math.sqrt(1000000);i+=2){
			boolean key=false;
			for(int j=0;j<prime.size();j++){
				if(i%prime.get(j)==0){
					key=true;
					break;
				}
			}
			if(key==false){
				prime.add(i);
				map.put(i,false);
			}
		}
		for(int i=0;i<N;i++){
			int A=nextInt();
			if(i==0)
				ans=A;
			else
				ans=gcd(ans,A);
			if(pair) for(int j=0;j<prime.size()&&A>=prime.get(j);j++){
				if(A%prime.get(j)==0){
					while(A%prime.get(j)==0){
						A/=prime.get(j);
					}
					if(map.get(prime.get(j))==false){
						map.put(prime.get(j),true);
					}
					else{
						pair=false;
						break;
					}
				}
			}
			if(A!=1&&map.containsKey(A)==false){
				map.put(A,true);
			}
		}
		if(pair)
			System.out.println("pairwise coprime");
		else if(ans==1)
			System.out.println("setwise coprime");
		else
			System.out.println("not coprime");
	}
	public static int gcd(int m, int n) {
        int r;
        while (n > 0) {
            r = m % n;
            m = n;
            n = r;
        }
        return m;
    }
	public static long lmod(long i, long j) {
	     return (i%j)<0?(i%j)+0+(j<0?-j:j):(i%j+0);
	 }
	static boolean isOK(int index,int key,ArrayList<Integer> a){
		if (a.get(index)>=key) return true;
	    else return false;
	}
	static int binary(int key,ArrayList<Integer> a) {
	    int ng = -1; //「index = 0」が条件を満たすこともあるので、初期値は -1
	    int ok = (int)a.size(); // 「index = a.size()-1」が条件を満たさないこともあるので、初期値は a.size()
	    while (Math.abs(ok - ng) > 1) {
	        int mid = (ok + ng) / 2;
	        if (isOK(mid,key,a)) ok = mid;
	        else ng = mid;
	    }
	    return ok;
	}
	//FastScanner
	static InputStream in = System.in;
	static  byte[] buffer = new byte[1024];
	static int length = 0, p = 0;
	public static boolean hasNextByte () {
		if (p < length) return true;
		else {
			p = 0;
			try {length = in.read(buffer);}
			catch (Exception e) {e.printStackTrace();}
			if (length == 0) return false;
		}
		return true;
	}
	public static int readByte () {
		if (hasNextByte() == true) return buffer[p++];
		return -1;
	}
	public static boolean isPrintable (int n) {return 33<=n&&n<=126;}
	public static void skip () {
		while (hasNextByte() && !isPrintable(buffer[p])) p++;
	}
	public static boolean hasNext () {skip(); return hasNextByte();}
	public static String next () {
		if (!hasNext()) throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int temp = readByte();
		while (isPrintable(temp)) {
			sb.appendCodePoint(temp);
			temp = readByte();
		}
		return sb.toString();
	}
	public static int nextInt () {return Math.toIntExact(nextLong());}
	public static int[] nextInts (int n) {
		int[] ar = new int[n];
		for (int i=0; i<n; i++) ar[i] = nextInt();
		return ar;
	}
	public static long nextLong () {
		if (!hasNext()) throw new NoSuchElementException();
		boolean minus = false;
		int temp = readByte();
		if (temp == '-') {
			minus = true;
			temp = readByte();
		}
		if (temp<'0' || '9'<temp) throw new NumberFormatException();
		long n = 0;
		while (isPrintable(temp)) {
			if ('0'<=temp && temp<='9') {
				n *= 10;
				n += temp - '0';
			}
			temp = readByte();
		}
		return minus? -n : n;
	}
}


import java.util.*;
public class Main{

    static final int MOD = (int)1e9+7;
    static final int MAX = (int)1e6+1;

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);

        int n = Integer.parseInt(sc.next());
        int[] a = new int[n];
        HashMap<Integer, Integer> h = new HashMap<>();
        for(int i=0; i<n; i++){
            a[i] = Integer.parseInt(sc.next());
            h.put(a[i], h.getOrDefault(a[i], 0)+1);
        }
        Arrays.sort(a);

        boolean[] prime = new boolean[MAX];
        Arrays.fill(prime, true);
        boolean pc = true;
        for(int i=2; i<MAX; i++){
            if(!prime[i]){
                continue;
            }
            int cnt = 0;
            for(int j=i; j<MAX; j+=i){
                prime[j] = false;
                cnt += h.getOrDefault(j, 0);
            }
            if(cnt > 1){
                pc = false;
            }
        }

        long gcd = a[0];
        for(int i=1; i<n; i++){
            gcd = gcd(a[i], gcd);
        }

        if(pc && gcd==1){
            System.out.println("pairwise coprime");
        }else if(gcd==1){
            System.out.println("setwise coprime");
        }else{
            System.out.println("not coprime");
        }

    }

    static long gcd (long a, long b){
        if(a < b){
            return gcd(b, a);
        }
        return b>0 ? gcd(b,a%b) : a;
    }
}


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

public class Main {

    public static void main(String[] args) {

        var sc = new Scanner(System.in);

        int n = Integer.parseInt(sc.next());
        var a = new int[n];
        var set = new HashSet<Integer>();
        for(int i = 0; i < n; i++){
            a[i] = Integer.parseInt(sc.next());
            set.add(a[i]);
        }

        List<Integer> list = sieve(1000);
        boolean b = true;
        if(set.size() < n){
            b = false;
        }else{
            for(int x : list){
                int count = 0;
                for(int i = 0; i < n; i++){
                    if(a[i] % x == 0){
                        count++;
                    }
                }
                if(count >= 2){
                    b = false;
                    break;
                }
            }
        }

        if(b){
            System.out.println("pairwise coprime");
        }else{
            long gcd = gcd(a[0], a[1]);
            for(int i = 2; i < n; i++){
                gcd = gcd(gcd, a[i]);
            }
            if(gcd == 1){
                System.out.println("setwise coprime");
            }else{
                System.out.println("not coprime");
            }
        }
    }

    static List<Integer> sieve(int x){

        var p = new boolean[x+1];
        Arrays.fill(p, true);
        int sqrt = (int)Math.sqrt(x+1);
        for(int i = 2; i <= sqrt; i++){
            if(!p[i]) continue;
            for(int j = i*i; j <= x; j += i){
                p[j] = false;
            }
        }
        var list = new ArrayList<Integer>();
        if(x >= 2) list.add(2);
        for(int i = 3; i <= x; i += 2){
            if(p[i]) list.add(i);
        }
        return list;
    }

    static long gcd(long a, long b){
        return b == 0 ? a : gcd(b, a%b);
    }
}


import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Map.Entry;

import java.util.PriorityQueue;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Main {

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

	public static void main(String[] args) throws IOException {
		try(final Scanner sc = new Scanner(System.in)){
			final int N = sc.nextInt();
			int[] as = new int[N];
			for(int i = 0; i < N; i++) {
				as[i] = sc.nextInt();
			}
			Arrays.sort(as);

			final int LIMIT = 1000000;
			boolean[] is_prime = new boolean[LIMIT + 1];
			Arrays.fill(is_prime, true);
			is_prime[0] = is_prime[1] = false;

			ArrayList<Integer> primes = new ArrayList<Integer>();
			for(int i = 2; i <= LIMIT; i++) {
				if(!is_prime[i]){ continue; }
				primes.add(i);

				for(int j = 2 * i; j <= LIMIT; j += i) {
					is_prime[j] = false;
				}
			}

			boolean pairwise_coprime = true;
			boolean[] used_primes = new boolean[LIMIT + 1];

			LOOP: for(final int a : as) {
				for(final int prime : primes) {
					if(a < prime) { break; }
					if(a % prime != 0) { continue; }

					if(used_primes[prime]) {
						pairwise_coprime = false;
						break LOOP;
					}

					used_primes[prime] = true;
				}
			}

			if(pairwise_coprime) {
				System.out.println("pairwise coprime");
				return;
			}

			long gcd = as[0];
			for(int i = 1; i < N; i++) {
				gcd = gcd(gcd, as[i]);
			}

			if(gcd == 1) {
				System.out.println("setwise coprime");
			}else {
				System.out.println("not coprime");
			}
		}
	}

	public static class Scanner implements Closeable {
		private BufferedReader br;
		private StringTokenizer tok;

		public Scanner(InputStream is) throws IOException {
			br = new BufferedReader(new InputStreamReader(is));
		}

		private void getLine() throws IOException {
			while(!hasNext()){
				tok = new StringTokenizer(br.readLine());
			}
		}

		private boolean hasNext() {
			return tok != null && tok.hasMoreTokens();
		}

		public String next() throws IOException {
			getLine();
			return tok.nextToken();
		}

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

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

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

		public int[] nextIntArray(int n) throws IOException {
			final int[] ret = new int[n];
			for(int i = 0; i < n; i++){
				ret[i] = this.nextInt();
			}
			return ret;
		}

		public long[] nextLongArray(int n) throws IOException {
			final long[] ret = new long[n];
			for(int i = 0; i < n; i++){
				ret[i] = this.nextLong();
			}
			return ret;
		}

		public void close() throws IOException {
			br.close();
		}
	}
}


import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Main {

  private static void solve() {
    int n = ni();
    int[] a = na(n);

    int g = a[0];
    Set<Integer> set = new HashSet<>();
    int[] primes = sieveEratosthenes(2000000);
    boolean pairwis = true;
    for (int v : a) {
      g = gcd(g, v);

      int[][] f = factor(v, primes);
      for (int[] u : f) {
        int div = u[0];
        if (set.contains(div)) {
          pairwis = false;
        }
        set.add(div);
      }
    }

    if (pairwis) {
      System.out.println("pairwise coprime");
    } else if (g == 1) {
      System.out.println("setwise coprime");
    } else {
      System.out.println("not coprime");
    }
  }

  public static int gcd(int a, int b) {
    while (b > 0) {
      int c = a;
      a = b;
      b = c % b;
    }
    return a;
  }

  public static int[][] factor(int n, int[] primes) {
    int[][] ret = new int[9][2];
    int rp = 0;
    for (int p : primes) {
      if (p * p > n)
        break;
      int i;
      for (i = 0; n % p == 0; n /= p, i++)
        ;
      if (i > 0) {
        ret[rp][0] = p;
        ret[rp][1] = i;
        rp++;
      }
    }
    if (n != 1) {
      ret[rp][0] = n;
      ret[rp][1] = 1;
      rp++;
    }
    return Arrays.copyOf(ret, rp);
  }

  public static int[] sieveEratosthenes(int n) {
    if (n <= 32) {
      int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
      for (int i = 0; i < primes.length; i++) {
        if (n < primes[i]) {
          return Arrays.copyOf(primes, i);
        }
      }
      return primes;
    }

    int u = n + 32;
    double lu = Math.log(u);
    int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
    ret[0] = 2;
    int pos = 1;

    int[] isnp = new int[(n + 1) / 32 / 2 + 1];
    int sup = (n + 1) / 32 / 2 + 1;

    int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
    for (int tp : tprimes) {
      ret[pos++] = tp;
      int[] ptn = new int[tp];
      for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
        ptn[i >> 5] |= 1 << i;
      for (int j = 0; j < sup; j += tp) {
        for (int i = 0; i < tp && i + j < sup; i++) {
          isnp[j + i] |= ptn[i];
        }
      }
    }

    // 3,5,7
    // 2x+3=n
    int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9,
        6, 16, 5, 15, 14 };
    int h = n / 2;
    for (int i = 0; i < sup; i++) {
      for (int j = ~isnp[i]; j != 0; j &= j - 1) {
        int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
        int p = 2 * pp + 3;
        if (p > n)
          break;
        ret[pos++] = p;
        if ((long) p * p > n)
          continue;
        for (int q = (p * p - 3) / 2; q <= h; q += p)
          isnp[q >> 5] |= 1 << q;
      }
    }

    return Arrays.copyOf(ret, pos);
  }

  public static void main(String[] args) {
    new Thread(null, new Runnable() {
      @Override
      public void run() {
        long start = System.currentTimeMillis();
        String debug = args.length > 0 ? args[0] : null;
        if (debug != null) {
          try {
            is = java.nio.file.Files.newInputStream(java.nio.file.Paths.get(debug));
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }
        reader = new java.io.BufferedReader(new java.io.InputStreamReader(is), 32768);
        solve();
        out.flush();
        tr((System.currentTimeMillis() - start) + "ms");
      }
    }, "", 64000000).start();
  }

  private static java.io.InputStream is = System.in;
  private static java.io.PrintWriter out = new java.io.PrintWriter(System.out);
  private static java.util.StringTokenizer tokenizer = null;
  private static java.io.BufferedReader reader;

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

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

  private static long nl() {
    return Long.parseLong(next());
  }

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

  private static char[] ns() {
    return next().toCharArray();
  }

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

  private static int[][] ntable(int n, int m) {
    int[][] table = new int[n][m];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        table[i][j] = ni();
      }
    }
    return table;
  }

  private static int[][] nlist(int n, int m) {
    int[][] table = new int[m][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        table[j][i] = ni();
      }
    }
    return table;
  }

  private static int ni() {
    return Integer.parseInt(next());
  }

  private static void tr(Object... o) {
    if (is != System.in)
      System.out.println(java.util.Arrays.deepToString(o));
  }
}


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

public class Main {

	public static void main(String[] args) {
		InputReader sc = new InputReader(System.in);
		PrintWriter pw = new PrintWriter(System.out);
		int h = sc.nextInt();
		int w = sc.nextInt();
		int m = sc.nextInt();
		HashMap<Integer, ArrayList<Integer>> hmr = new HashMap<>();
		HashMap<Integer, Integer> hmc = new HashMap<>();

		for(int i = 0; i < m ;i ++){
			int r = sc.nextInt();
			int c = sc.nextInt();
			ArrayList<Integer> al = hmr.getOrDefault(r, new ArrayList<Integer>());
			al.add(c);
			hmr.put(r, al);
			hmc.put(c,  hmc.getOrDefault(c, 0)+1);
		}

		int max = 0, maxc = 0;
		int row = -1;
		for(int r : hmr.keySet()){
			if(hmr.get(r).size() > max){
				max = hmr.get(r).size();
				row = r;
			}else if(hmr.get(r).size() == max){
				int max1 = 0;
				for(int c : hmr.get(r)){
					max1 = Math.max(max1, hmc.get(c));
				}
				int max2 = 0;
				for(int c : hmr.get(row)){
					max2 = Math.max(max2,  hmc.get(c));
				}
				if(max1 > max2){
					row = r;
					max = max1;
				}
			}
		}

		for(int c : hmr.get(row)){
			hmc.put(c, hmc.get(c)-1);
		}
		int max2 = 0;
		for(int s : hmc.values()){
			max2 = Math.max(max2, s);
		}

		pw.println((max+max2));

		pw.close();
	}

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

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

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

				if (numChars <= 0)
					return -1;
			}

			return buf[curChar++];
		}

		public String nextLine() {
			BufferedReader br = new BufferedReader(new InputStreamReader(stream));
			String stock = "";
			try {
				stock = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return stock;
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

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

			return res * sgn;
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;

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

		public double nextDouble() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.') {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.') {
				c = read();
				double m = 1;
				while (!isSpaceChar(c)) {
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

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

			return res.toString();
		}

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

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

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

}

Score : 500 points

Problem Statement

We have a two-dimensional grid with H \times W squares. There are M targets to destroy in this grid - the position of the i-th target is \left(h_i, w_i \right).

Takahashi will choose one square in this grid, place a bomb there, and ignite it. The bomb will destroy all targets that are in the row or the column where the bomb is placed. It is possible to place the bomb at a square with a target.

Takahashi is trying to maximize the number of targets to destroy. Find the maximum number of targets that can be destroyed.

Constraints

All values in input are integers.

1 \leq H, W \leq 3 \times 10^5

1 \leq M \leq \min\left(H\times W, 3 \times 10^5\right)

1 \leq h_i \leq H

1 \leq w_i \leq W

\left(h_i, w_i\right) \neq \left(h_j, w_j\right) \left(i \neq j\right)

Input

Input is given from Standard Input in the following format:

H W M
h_1 w_1
\vdots
h_M w_M

Output

Print the answer.

Sample Input 1

2 3 3
2 2
1 1
1 3

Sample Output 1

3

We can destroy all the targets by placing the bomb at \left(1, 2\right).

Sample Input 2

3 3 4
3 3
3 1
1 1
1 2

Sample Output 2

3

Sample Input 3

5 5 10
2 5
4 3
2 3
5 5
2 2
5 4
5 3
5 1
3 5
1 4

Sample Output 3

6


import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;

public class Main {

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

	private static void execute20_3() {
		try (Scanner sc = new Scanner(System.in)) {
			int h = sc.nextInt();
			int w = sc.nextInt();
			int m = sc.nextInt();

			int[] hnum= new int[h];
			int[] wnum= new int[w];
			int[][] put = new int[h][w];
			for (int i = 0; i < m; i++) {
				int hb = sc.nextInt()-1;
				int wb = sc.nextInt()-1;
				hnum[hb]++;
				wnum[wb]++;
				put[hb][wb]=1;
			}
			int ans=0;
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					ans = Math.max(ans, hnum[i]+wnum[j]-put[i][j]);
				}
			}
			System.out.println(ans);
		}
	}
}


	import java.util.*;
	import java.util.Map.Entry;

	 class Main {
		 static int mod =  (int) (Math.pow(10,9)+7);
//		 static int mod =  (int) 998244353;
		 static List<ArrayList<Integer>> list= new ArrayList<ArrayList<Integer>>();
		 static int a_dist[];
		 public static void main(String[] args) {

	        Scanner sc = new Scanner(System.in);
	        int H = sc.nextInt();
	        int W = sc.nextInt();
	        int M = sc.nextInt();
	        long[] m = new long[M];
	        int[][] h = new int[H][2];
	        int[][] w = new int[W][2];
	        int ans=0;
	        for(int i=0;i<H;i++)h[i][1]=i;
	        for(int i=0;i<W;i++)w[i][1]=i;
	        for(int i=0;i<M;i++) {
	        	int x =sc.nextInt()-1;
	        	int y =sc.nextInt()-1;

	        	m[i]=1000000*x+y;
	        	h[x][0]++;
	        	w[y][0]++;
	        }
	        Arrays.sort(h, (b, c) -> Integer.compare(b[0], c[0]));
	        Arrays.sort(w, (b, c) -> Integer.compare(b[0], c[0]));
	        Arrays.sort(m);
	        for(int i=H-1;i>=0&&h[i][0]>=h[H-1][0]-1;i--) {
	        	for(int j=W-1;j>=0&&w[j][0]+h[i][0]>=w[W-1][0]+h[H-1][0]-1;j--) {
	        		long t=1000000*h[i][1]+w[j][1];
	        		int right = M-1;
	        		int left = 0;
	        		int n =0;
	        		while(right>=left) {
	        			int mid = (right+left)/2;
	        			if(m[mid]==t) {
	        				n++;
	        				break;
	        			}
	        			else if(m[mid]>t)right=mid-1;
	        			else left=mid+1;
	        		}

	        		ans=Math.max(ans, h[i][0]+w[j][0]-n);

	        	}
	        }
	        System.out.println(ans);
		 }

	}


	import java.util.*;
	import java.util.Map.Entry;

	 class Main {
		 static int mod =  (int) (Math.pow(10,9)+7);
//		 static int mod =  (int) 998244353;
		 static List<ArrayList<Integer>> list= new ArrayList<ArrayList<Integer>>();
		 static int a_dist[];
		 public static void main(String[] args) {

	        Scanner sc = new Scanner(System.in);
	        int H = sc.nextInt();
	        int W = sc.nextInt();
	        int M = sc.nextInt();
	        int[][] m = new int[H][W];
	        int[][] h = new int[H][2];
	        int[][] w = new int[W][2];
	        int ans=0;
	        for(int i=0;i<H;i++)h[i][1]=i;
	        for(int i=0;i<W;i++)w[i][1]=i;
	        for(int i=0;i<M;i++) {
	        	int x =sc.nextInt()-1;
	        	int y =sc.nextInt()-1;
	        	m[x][y]++;
	        	h[x][0]++;
	        	w[y][0]++;
	        }
	        Arrays.sort(h, (b, c) -> Integer.compare(b[0], c[0]));
	        Arrays.sort(w, (b, c) -> Integer.compare(b[0], c[0]));
	        for(int i=H-1;i>=0&&h[i][0]>=h[H-1][0]-1;i--) {
	        	for(int j=W-1;j>=0&&w[j][0]>=w[W-1][0];j--) {
	        		ans=Math.max(ans, h[i][0]+w[j][0]-m[h[i][1]][w[j][1]]);

	        	}
	        }
	        System.out.println(ans);
		 }

	}


import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {

	public static void main(String[] args) {
		try (Scanner sc = new Scanner(System.in)) {
			int H = sc.nextInt();
			int W = sc.nextInt();
			int M = sc.nextInt();
			int[] h = new int[H];
			int[] w = new int[W];
			Set<Integer> hset = new HashSet<>();
			Set<Integer> wset = new HashSet<>();
			Set<Point> pset = new HashSet<>();
			for (int i = 0; i < M; i++) {
				int tmph = sc.nextInt() - 1;
				int tmpw = sc.nextInt() - 1;
				hset.add(tmph);
				wset.add(tmpw);
				h[tmph]++;
				w[tmpw]++;
				pset.add(new Point(tmph, tmpw));
			}
			int max = 0;
			for (int i : hset) {
				for (int j : wset) {
					int tmp = h[i] + w[j];
					if (pset.contains(new Point(i, j))) {
						tmp--;
					}
					max = Math.max(max, tmp);
				}
			}
			System.out.println(max);
		}
	}

	static class Point {
		int h;
		int w;

		public Point(int h, int w) {
			this.h = h;
			this.w = w;
		}

		@Override
		public boolean equals(Object o) {
			Point p = (Point) o;
			return this.h == p.h && this.w == p.w;
		}

		@Override
		public int hashCode() {
			int val = 31;
			val += 31 * val + h;
			val += 31 * val + w;
			return val;
		}
	}
}


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

public class Main

{

	 static FastReader sc=new FastReader();

		  public static void main(String[] args)
    {

			  long h=l();
			  long w=l();
			  long m=l();
			  int A[][]=new int[3000001][3000001];
			  long row[]=new long[3000001];
			  long col[]=new long[3000001];
			  while(m-- > 0) {
				  long r=l();
				  long c=l();
				  row[(int)r]++;
				  col[(int)c]++;
				  A[(int)r][(int)c]=1;

			  }
			  long maxr=Integer.MIN_VALUE,maxc=Integer.MIN_VALUE;
			  int indr=-1,indc=-1;
			  int cc=-1;
			  for(int i=0;i<row.length;i++) {
				  if(row[i]>maxr) {
					  maxr=row[i];
					  indr=i;
				  }
			  }
			  for(int i=0;i<col.length;i++) {
				  if(col[i]>=maxc) {
					  maxc=col[i];
					  indc=i;
					  if(cc==-1)
						  cc=indc;
					  if(A[indr][indc]!=1)
						  cc=indc;
					  if(col[cc]!=maxc)
						  cc=i;
				  }
			  }
			  if(indr>0&&indr<h && cc>0&&cc<w &&A[indr][cc]!=1)
				  System.out.println(maxr+maxc);
			  else
				  System.out.println(maxr+maxc-1);

//			  long m=l();
//			  int A[][]=new int[h+h][w+w];
//			  int rr[]=new int[(int)m];
//			  int ccc[]=new int[(int)m];
//			  for(int i=0;i<m;i++) {
//				  int r=i();
//				  if(row.containsKey(r)) {
//					  row.put(r,row.get(r)+1);
//				  }
//				  else
//					  row.put(r,(long)1);
//				  int c=i();
//				  if(col.containsKey(c)) {
//					  col.put(c,col.get(c)+1);
//				  }
//				  else
//					  col.put(c,(long)1);
//
//				  rr[i]=r;
//				  ccc[i]=c;
//				  A[r][c]=1;
//			  }
//			  long maxr=0;
//			  int keyr=0;
//			  for(int i : rr) {
//				  long g=row.get(i);
//				  if(g>maxr) {
//					  maxr=g;
//					  keyr=i;
//				  }
//			  }
//
//			  long maxc=0;
//			  int keyc=-1;
//			  int keycc=ccc[0];
//			  for(int i : ccc) {
//				  long cc=col.get(i);
//				  if(cc>=maxc) {
//					keyc=i;
//					if(keycc==-1)
//						keycc=i;
//					  maxc=cc;
//					if(A[keyr][i]!=1)
//						keycc=i;
//					if(col.get(keycc)!=maxc)
//						keycc=i;
//				  }
//
//			  }
////			  if(keycc==-1)
////				  keycc=keyc;
////			  //System.out.println(keyr+" "+keycc);
////			  long res=maxc+maxr;
////			  if(A[keyr][keycc]!=1)
////			  System.out.println(res);
////			  else
//				  System.out.println(res-1);
//

    }

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

		  static boolean is(int x)
		    {
		        double sr = Math.sqrt(x);

		        return ((sr - Math.floor(sr)) == 0);
		    }

static void input(int A[]) {
	   for(int i=0;i<A.length;i++) {
		   A[i]=sc.nextInt();
	   }
   }
static void input(int A[],int B[]) {
	   for(int i=0;i<A.length;i++) {
		   A[i]=sc.nextInt();
		   B[i]=sc.nextInt();
	   }
}
     static int i() {
    	 return sc.nextInt();
     }
     static String s() {
    	 return sc.next();
     }
     static long l() {
    	 return sc.nextLong();
     }
        static void shuffleArray(int[] arr){
        int n = arr.length;
        Random rnd = new Random();
        for(int i=0; i<n; ++i){
            int tmp = arr[i];
            int randomPos = i + rnd.nextInt(n-i);
            arr[i] = arr[randomPos];
            arr[randomPos] = tmp;
        }
}

    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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


import java.util.*;

public class Main {

    private static final int INF = 1_000_000_000;

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int H = sc.nextInt();
        int W = sc.nextInt();
        int M = sc.nextInt();
        int[] rowCnt = new int[H];
        int[] colCnt = new int[W];
        int[] HH = new int[M];
        int[] WW = new int[M];
        for (int i = 0; i < M; i++) {
            int h = sc.nextInt()-1;
            int w = sc.nextInt()-1;
            rowCnt[h]++;
            colCnt[w]++;
            HH[i] = h;
            WW[i] = w;
        }

        int maxRowCnt = 0;
        for (int i = 0; i < H; i++) {
            maxRowCnt = Math.max(maxRowCnt, rowCnt[i]);
        }
        int mr = 0;
        for (int i = 0; i < H; i++) {
            if (rowCnt[i] == maxRowCnt) mr++;
        }

        int maxColCnt = 0;
        for (int i = 0; i < W; i++) {
            maxColCnt = Math.max(maxColCnt, colCnt[i]);
        }
        int mc = 0;
        for (int i = 0; i < W; i++) {
            if (colCnt[i] == maxColCnt) mc++;
        }

        long mm = 0;
        for (int i = 0; i < M; i++) {
            if (rowCnt[HH[i]] + colCnt[WW[i]] == maxRowCnt + maxColCnt) mm++;
        }

        System.out.println(mm == (long)mc*mr ? maxRowCnt+maxColCnt-1 : maxRowCnt+maxColCnt);
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h = Integer.parseInt(sc.next());
        int w = Integer.parseInt(sc.next());
        int m = Integer.parseInt(sc.next());
        int[] hs = new int[h];
        int[] ws = new int[w];
        int[] x = new int[m];
        int[] y = new int[m];
        for(int i=0; i<m; i++) {
            x[i] = Integer.parseInt(sc.next())-1;
            y[i] = Integer.parseInt(sc.next())-1;
            hs[x[i]]++;
            ws[y[i]]++;
        }

        int hmax = 0;
        for(int i=0; i<h; i++) {
            if(hmax < hs[i]) {
                hmax = hs[i];
            }
        }

        List<Integer> hmaxidx = new ArrayList<>();
        for(int i=0; i<h; i++) {
            if(hmax == hs[i]) {
                hmaxidx.add(i);
            }
        }

        List<int[]> mapw = new ArrayList<>();
        for(int i=0; i<hmaxidx.size(); i++) {
            mapw.add(new int[w]);
            for(int j=0; j<m; j++) {
                if(x[j] == hmaxidx.get(i)) {
                    mapw.get(i)[y[j]] = 1;
                }
            }
        }

        int count = 0;
        int max = 0;
        for(int i=0; i<hmaxidx.size(); i++) {
            for(int j=0; j<w; j++) {
                count = hmax + ws[j];
                if(mapw.get(i)[j] == 1) {
                    count--;
                }

                if(max < count) {
                    max = count;
                }
            }
        }

        System.out.println(max);

    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            // # In
            // area
            int H = Integer.parseInt(sc.next());    // height
            int W = Integer.parseInt(sc.next());    // width

            // mine
            int M = Integer.parseInt(sc.next());
            int[] hnum = new int[H];
            int[] wnum = new int[W];
            List<Integer>[] mines = new ArrayList[H];
            for (int i = 0; i < M; i++) {
                int hi = Integer.parseInt(sc.next()) - 1;
                int wi = Integer.parseInt(sc.next()) - 1;
                hnum[hi]++;
                wnum[wi]++;

                if (mines[hi] == null) {
                    mines[hi] = new ArrayList<Integer>();
                    mines[hi].add(wi);
                } else {
                    mines[hi].add(wi);
                }
            }

            // # Solve
            int hmax = 0, wmax = 0;
            List<Integer> hmax_index = new ArrayList<>();
            List<Integer> wmax_index = new ArrayList<>();
            for (int i = 0; i < H; i++) {
                if (hmax < hnum[i]) {
                    hmax = hnum[i];
                    hmax_index.clear();
                    hmax_index.add(i);
                } else if (hmax == hnum[i]) {
                    hmax_index.add(i);
                }
            }
            for (int i = 0; i < W; i++) {
                if (wmax < wnum[i]) {
                    wmax = wnum[i];
                    wmax_index.clear();
                    wmax_index.add(i);
                } else if (wmax == wnum[i]) {
                    wmax_index.add(i);
                }
            }

            boolean hit = false;
            for (int h : hmax_index) {
                for (int maxw : wmax_index) {
                    if (!mines[h].contains(maxw)) {
                        hit = true;
                    }
                }
                if (hit) break;
            }
            System.out.println(hmax + wmax + (hit ? 0 : -1));
        }
    }
}


// Submitted By Subhash Yadav
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

import java.util.*;

public class Main {

	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		int h=sc.nextInt(),w=sc.nextInt(),m=sc.nextInt();
		int a[][]=new int[m][2];

		int row[]=new int[h+1];
		int col[]=new int[w+1];
		for(int i=0;i<m;i++) {
			int x=sc.nextInt(),y=sc.nextInt();
			a[i][0]=x;
			a[i][1]=y;

			row[x]++;
			col[y]++;

		}

		long ans=Long.MIN_VALUE;
		long count=0;
		for(int i=1;i<=h;i++) {
			for(int j=1;j<=w;j++) {
				long total=row[i]+col[j];
				if(ans<total) {
					ans=total;
					count=1;
				}
				else if(ans==total) count++;
			}
		}

		for(int i=0;i<m;i++) {
			int x=a[i][0],y=a[i][1];
			if(row[x]+col[y]==ans) {
				count--;
			}
		}

		if(count==0) ans--;
		System.out.println(ans);

		out.close();

	}

	static class FastScanner {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

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

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

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

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


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;

public class Main {

	static int[][] map;
	static int[][] directions8= {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
	static int[][] directions25= {{-2,-2},{-2,-1},{-2,0},{-2,1},{-2,2},{-1,-2},{-1,-1},{-1,1},{-1, 2}
	,{0,-2},{0,2},{1,-2},{1,-1},{1,1},{1,2},{2,-2},{2, -1},{2,0},{2,1},{2,2}};
	static int[][] directions4= {{-1,0},{1,0},{0,-1},{0,1}};
	static int ans;
	static int[] parent;//union-find用
	static int[] rank;//union-find用
	static int[][] warp;
	static Queue<int[]> q;
	static int H;
	static int W;
	static int Dh;
	static int Dw;
	static char[][] S;

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

		Scanner sc = new Scanner(System.in);
		int H = sc.nextInt();
		int W = sc.nextInt();
		int M = sc.nextInt();

		int[] h = new int[H];
		int[] w = new int[W];
		HashSet<String> exists = new HashSet<>();

		for(int i = 0;i<M ; i++) {
			int nowH =sc.nextInt()-1;
			int nowW =sc.nextInt()-1;
			h[nowH]++;
			w[nowW]++;
			String now =nowH+","+nowW;
			exists.add(now);
		}

		int maxH = 0;
		int maxW = 0;
		List<Integer> selectedH = new ArrayList<Integer>();
		List<Integer> selectedW = new ArrayList<Integer>();

		for(int i = 0;i<H ; i++) {
			if(maxH < h[i] ) {
				maxH = h[i];
				selectedH.clear();
				selectedH.add(i);
			}else if(maxH == h[i]) {
				selectedH.add(i);
			}
		}
		for(int i = 0;i<W ; i++) {
			if(maxW < w[i] ) {
				maxW = w[i];
				selectedW.clear();
				selectedW.add(i);
			}else if(maxW == w[i]) {
				selectedW.add(i);
			}
		}

		boolean allExist = true;

		for(int sH:selectedH) {
			for(int sW: selectedW) {
				if(!exists.contains(sH+","+sW)) {
					allExist = false;
				}
			}
		}
		ans = maxH + maxW;

		if(allExist) {
			ans--;
		}

		System.out.println(ans);
	}

//	public static void walk(int nowH, int nowW, int warped) {
//		if(nowH < 0 || nowH >= H || nowW <0 || nowW >= W || S[nowH][nowW] == '#' || warped >= warp[nowH][nowW]) {
//			return;
//		}
//		if(nowH == Dh && nowW == Dw && ans > warped) {
//			ans = warped;
//		}
//		int[] now = {nowH, nowW, warped};
//		q.add(now);
//		warp[nowH][nowW] = warped;
//		for(int i = 0;i<4 ; i++) {
//			walk(nowH+directions4[i][0], nowW+directions4[i][1], warped);
//		}
//	}
	//	public static void warp(int nowH, int nowW, int warped) {
	//
	//
	//
	//
	//	}

	//素数判定
	public static boolean isPrime(long num) {
		if (num < 2) return false;
		else if (num == 2) return true;
		else if (num % 2 == 0) return false; // 偶数はあらかじめ除く

		double sqrtNum = Math.sqrt(num);
		for (int i = 3; i <= sqrtNum; i += 2)
		{
			if (num % i == 0)
			{
				// 素数ではない
				return false;
			}
		}

		// 素数である
		return true;
	}

	//BFS用に二つの配列を足し算する
	static int[] addArrayElms(int[] a, int[] b) {
		int[] c = new int[a.length];
		for(int i = 0; i < a.length; i++) {
			c[i] = a[i] + b[i];
		}
		return c;
	}

	//	//二分探索
	//k <= num となる最小の配列要素kのインデックスを返す
	static private int binarySearch(long num, long[] orderedArray){
		int lowerBorder = -1;
		int upperBorder = orderedArray.length;
		int mid;

		while(upperBorder - lowerBorder >1) {
			mid = (upperBorder + lowerBorder)/2;
			if(orderedArray[mid]<=num) {
				lowerBorder = mid;
			}else {
				upperBorder = mid;
			}
		}
		return lowerBorder;
	}

	//二分探索
	//k <= num となる最小のList要素kのインデックスを返す
	static private int binarySearch(long num, ArrayList<Long> orderedList){
		int lowerBorder = -1;
		int upperBorder = orderedList.size();
		int mid;

		while(upperBorder - lowerBorder >1) {
			mid = (upperBorder + lowerBorder)/2;
			if(orderedList.get(mid)<=num) {
				lowerBorder = mid;
			}else {
				upperBorder = mid;
			}
		}
		return lowerBorder;
	}

	//aとbの最小公倍数を求める
	public static int gcd(int a, int b) {
		return b == 0 ? a: gcd(b, a % b);
	}
	public static long gcd(long a, long b) {
		return b == 0 ? a: gcd(b, a % b);
	}

	//Union-Find用の配列を要素数nで初期化
	static void ufInit(int n){
		parent = new int[n];
		rank = new int[n];
	}

	//Union-Findの要素の最上位の親（グループ名）を返す
	static int ufFind(int a) {
		if(parent[a]==a) {
			return a;
		}else {
			return ufFind(parent[a]);
		}
	}

	//Union-Find木を連結する
	static void ufUnite(int a, int b) {
		a = parent[a];
		b = parent[b];

		if(a==b) {
			return;
		}
		if(rank[a] > rank[b]){
			parent[b]=a;
		}else {
			parent[a]=b;
			if(rank[a]==rank[b]) {
				rank[b]++;
			}
		}
	}

	static boolean ufSame(int a, int b) {
		return ufFind(a)==ufFind(b);
	}
}


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

public class Main

{

	 static FastReader sc=new FastReader();

		  public static void main(String[] args)
    {
			  HashMap<Integer,Integer> row=new HashMap<Integer, Integer>();
			  HashMap<Integer,Integer> col=new HashMap<Integer, Integer>();
			  int h=i();
			  int w=i();
			  int m=i();
			  int A[][]=new int[h+1][w+1];
			  for(int i=0;i<m;i++) {
				  int r=i();
				  if(row.containsKey(r)) {
					  row.put(r,row.get(r)+1);
				  }
				  else
					  row.put(r,1);
				  int c=i();
				  if(col.containsKey(c)) {
					  col.put(c,col.get(c)+1);
				  }
				  else
					  col.put(c,1);

				  A[r][c]=1;
			  }
			  int maxr=0;
			  int keyr=-1;
			  for(int i : row.keySet()) {
				  int g=row.get(i);
				  if(g>maxr) {
					  maxr=g;
					  keyr=i;
				  }
			  }

			  int maxc=0;
			  int keyc=-1;
			  int keycc=-1;
			  for(int i : col.keySet()) {
				  int cc=col.get(i);
				  if(cc>=maxc) {
					keyc=i;
					if(keycc==-1)
						keycc=keyc;
					  maxc=cc;
					if(A[keyr][i]!=1)
						keycc=i;
					if(col.get(keycc)!=maxc)
						keycc=i;
				  }

			  }
			  if(keycc==-1)
				  keycc=keyc;
			  //System.out.println(keyr+" "+keycc);
			  if(A[keyr][keycc]!=1)
			  System.out.println(maxc+maxr);
			  else
				  System.out.println(maxc+maxr-1);

    }

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

		  static boolean is(int x)
		    {
		        double sr = Math.sqrt(x);

		        return ((sr - Math.floor(sr)) == 0);
		    }

static void input(int A[]) {
	   for(int i=0;i<A.length;i++) {
		   A[i]=sc.nextInt();
	   }
   }
static void input(int A[],int B[]) {
	   for(int i=0;i<A.length;i++) {
		   A[i]=sc.nextInt();
		   B[i]=sc.nextInt();
	   }
}
     static int i() {
    	 return sc.nextInt();
     }
     static String s() {
    	 return sc.next();
     }
     static long l() {
    	 return sc.nextLong();
     }
        static void shuffleArray(int[] arr){
        int n = arr.length;
        Random rnd = new Random();
        for(int i=0; i<n; ++i){
            int tmp = arr[i];
            int randomPos = i + rnd.nextInt(n-i);
            arr[i] = arr[randomPos];
            arr[randomPos] = tmp;
        }
}

    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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


import java.util.*;

public class Main {
    static int h;
    static int w;
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc = new Scanner(System.in);
        h = sc.nextInt();
        w = sc.nextInt();
        int m = sc.nextInt();
        long[][] array = new long[h][w];
        for (int i = 0; i < m; i++) {
            int row = sc.nextInt()-1;
            int col = sc.nextInt()-1;
            array[row][col] = 1;
        }
        // for (long[] c : array) System.out.println(Arrays.toString(c));
        // System.out.println(231);

        // cumsum: 累積和
        long[][] cumsum = new long[h+1][w+1];
        for (int i = 1; i <= h; i++) {
            for (int j = 1; j <= w; j++) {
                cumsum[i][j] = array[i-1][j-1] + cumsum[i-1][j] + cumsum[i][j-1] - cumsum[i-1][j-1];
            }
        }
        // for (long[] c : cumsum) System.out.println(Arrays.toString(c));

        long ans = 0;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                // if (array[i][j] == 0) continue;

                long res = calc(cumsum, i, j, array[i][j]);
                ans = Math.max(ans, res);
                // System.out.println(res);
            }
        }
        System.out.println(ans);
    }

    public static long calc(long[][] cumsum, int r, int c, long self) {
        // score: 右下 - 左下 - 右上 + 左上 (包除原理)
        // System.out.println(r + " " + c);
        long score = cumsum[h][c+1] + cumsum[r+1][w] - self;
        score -= cumsum[r][w];
        score -= cumsum[h][c];

        return score;
//   +maxr,nowc
//   +nowr,maxc
//   -nowr-1,maxc
//   -maxr,nowc-1
//   -nowr,nowc
    }
}


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

public class Main {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt(), m = sc.nextInt(), q = sc.nextInt();
		if (Math.min(n, m) == 1) {
			System.out.println(q);
			return;
		}
		ArrayList<Integer>[]adj=new ArrayList[n];
		Integer[] row = new Integer[n], col = new Integer[m], indices = new Integer[m];
		for (int i = 0; i < m; i++) {
			indices[i] = i;
			col[i]=0;
		}
		for(int i=0;i<n;i++) {
			row[i]=0;
			adj[i]=new ArrayList();
		}
//		HashSet<Long>set=new HashSet();
		while (q-- > 0) {
			int i=sc.nextInt()-1,j=sc.nextInt()-1;
			row[i]++;
			col[j]++;
//			set.add(i*1L*m+j);
			adj[i].add(j);
		}

		Arrays.sort(indices, Comparator.comparingInt(i -> -col[i]));
		int options=0;
		int bestCol=col[indices[0]];
		for(int i=0;i<m;i++)
			if(col[indices[i]]==bestCol)
				options++;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			int val=row[i]+bestCol;
			int cnt=0;
			for(int j:adj[i])
				if(col[j]==bestCol)
					cnt++;
			if(cnt==options)
				val--;
			ans=Math.max(ans, val);
		}
		System.out.println(ans);
		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();
		}

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

	}

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

}