C# static problem. Making menu. Need advice, how to customize the game.

I’m very new to unity and to C#. The code I wrote works well, but I have difficulties in customizing it.
I would like to make main menu, where gamer could choose not only statically assigned difficulties(like 2x2 or 4x4)but also to choose his own (for example 1x5 or 3x9)
C# says that i & j must be static. But I cant understand why.

using UnityEngine;
using System.Collections;

public class start : MonoBehaviour {
	public GameObject cube1;
	public GameObject sphere1;
	public  int counter=0;
	public static int j=30;
	public static int i=30;
	

	public int[,] table = new int[i, j];
	
	public GameObject[,] grid = new GameObject[i,j];
	
	
	void Start () {
	GenField();
	}
	void Update () {
	}
	
	void OnGUI() {
        GUI.Label(new Rect (10,10,150,20), "Turns: "+counter); 
	//	if(win){
	//		 GUI.Label (new Rect (Screen.width/2-50, Screen.height/2-25, 150, 20), "You Win"); 
	//	}
    }
	
	
	
	void GenField(){
	float x1;
	float y1;
            for (int a = 0; a <= i-1; a++) {
                for (int b = 0; b <= j-1; b++) {
                    table[a, b] = Random.Range(0, 2);
				
				x1=(float)a;
				y1=(float)b;
				if(table[a,b]==0){
                grid[a,b] = Instantiate(cube1) as GameObject ;
				grid[a,b].transform.position= new  Vector3(x1, y1);
				grid[a,b].name="obj"+a+""+b;
				} else {
				grid[a,b] = Instantiate(sphere1) as GameObject ;
				grid[a,b].transform.position= new  Vector3(x1, y1);
				grid[a,b].name="obj"+a+""+b;
				}
                
            }
		}
	}
	
	
	public void ReceiveID(string name){
		//Debug.Log("received: "+name);
		
		
		for (int a = 0; a <= i-1; a++) {
                for (int b = 0; b <= j-1; b++) {
				
		if(grid[a,b].name==name){
					
					Inverser(a,b);
					
					CrossInverse(a,b);
					
					FieldCheckDestroy();
				}
			}
		}
	}
	void CrossInverse(int a, int b){
		
		for(int z=0;z<=i-1;z++){
			if(z!=a){
				Inverser(z,b);
			}
		}
		
		for(int z=0;z<=j-1;z++){
			if(z!=b){
				Inverser(a,z);
			}
		}
		
	}
	void Inverser(int a, int b){
	float x1;
	float y1;
				
				x1=(float)a;
				y1=(float)b;
				
					Destroy(grid[a,b]);
					
					if(table[a,b]==0){
						grid[a,b] = Instantiate(sphere1) as GameObject ;
						grid[a,b].transform.position= new  Vector3(x1, y1);
						grid[a,b].name="obj"+a+""+b;
						
						table[a,b]=1;
					}else {
						grid[a,b] = Instantiate(cube1) as GameObject ;
						grid[a,b].transform.position= new  Vector3(x1, y1);
						grid[a,b].name="obj"+a+""+b;
						table[a,b]=0;
					}
					
	}
	void FieldCheckDestroy(){
		bool win = true;
		for(int d=0;d<=i-1;d++){
			for(int f=0;f<=j-1;f++)
				if(table[d,f]==0) win=false;
		}
		
		if(win){
			for(int d=0;d<=i-1;d++){
			for(int f=0;f<=j-1;f++){
					Destroy(grid[d,f]);
					
				}
			}
			
			
		}
		
	}
}

It needs to be static only if you instantiate the array (give it value) in the class definition.

If you instantiate it within the code (for example in the Start() method) then you can use variables:

public int[,] table = null;

void Start () {
    table = new int[i, j]; // i,j don't need to be static now
    GenField();
}