1111010101110001111010111101011011111010111100100011100011000011001010101010111000011000010000111111000111001111100010100101000000010101110111111101010010101000010101110110110000101101001101111101000000101110001011001010110010101100010000010110110101110000000110010001001100001011101000001001111101111110110100101110011110101111110010010100011011011001111011101111110101000001110100000000001011101000 1100011111001010100110010111001010110101111001111100111011111000110100011011110111010011100001111011001101010000010010010100110101010001011110011000100010101001000101000011001001111011000111101011011100110011010001101001000110011011000011001001110110110000001011011101101011100101110110001110011110110100101000011001110010101000011001101101001100111000101111000110011001011101001101000010000011110011 0111011000110100110101101001010111111110001111011111001000101010010110001111001010010000111100001111101110100010000001000110010010110101001011000000010100111010000101010110000110010110110001000001001101111001110110000000111101010000110101110110000000101010111110101101000010100111100101110110001000100000010100101100000110101100011100101110111111010011000110001010011101010010111010111110010100011000 0101010110111100001110010101011001100101111001111100111010000011100110001000110010110100111101110110111110111101001000001111110111011010011111100001010101001010111011110110101100011001001011111011001110000011010001100011110100011101010100001100011100101111001110010000100001000010111000001011000111010000100101100000101111110011111101000010011111001100011010010101100100011111011110100001000100111101 1111100011101111101110110100100011000011001101101111110010010001011011101110111011011011100001000110110011101000011111100111100101000110111101011110101010110010100001101111111010111001100010111000010111101000100100100000111011010010101001001011001111000001010010100011101000011101100001101110110100101111001101110111011111001001111001100101010011011010010101110110111001010100001011010100101100110011 0111110101110111111101000111010001101111011111110001000011010010010100001110001100111010010010111100011001011101001010010111010010101000001000000001001101001111100100011011111111001110100111011110110110011011110000000111001111111101110110100001000001110011000101100011111011001000100111011010110000000110101011101111100100001111000000000001101111111100000000111111111101001110110101101111110011101001 0111000010101011101110001100100011000100111010101000111110010001000011000000010011011110111101000111010011110011000110000000110110011101010110110000110010111011000111010010011000001011110011101011001001010010100100000001111100111001011001100101100000101110001110001110000100100100011110000101001110110101000100010000101101101100011110010100001001011111100010101110100110101010110100001110100000100000 1111010010101110100011110011000110011110011001110101111010011111010011100010011010000110001101101011010000000111110001110111101101101100111101000001000000010101100010000100010101110010000001011010110111111111011000000010100101000101110110001111101000000101010111101101010100111111001101110111000101110101111101001101001101010000110101000110000000001011011000001010100110000100001100111101100000111010 0000011001000110101101011010100001110000111000011101000001100100010101111101001111000100101001101010001000100101101001001001010001010111001100011110111010111111100110010110101001100001011001001110111100111001111110001111111011000001111100110100101100011100000001100110000111010011101111000011010101100101010100110000111110100010001101010010100010101100000111101000110101101101011001111101010100110001 0010001000001101110011001110001010110000100001110110111111000011000110001110111010110111011111100110001101001011001100100011001101001101010100001011000100011001010101000000110111111001110000110111001110011100110100011111001100110010111111001111001100100111100000001001000100111100110001000110010111000000000101011011111111110011100110110001010010100000111001010000111011010010111000001100111111011110 1000100101000110110110000011010010101000110001100111011110100110110000000101101011101101001110111010011100010111001101001000001101111110001001110001000011001010100010011001100110101001001100111111100010000011100011101110101111100011000100111101011111101010110110100001011000000001000011110110010011010010101011011000110000100001101000010110100011001101011100000011010100011100110110101010001011001010 1101001100111110011000110100011001110010101000111011010000110000100001011100001111000110010010101011000100000001110101110010001010001011100110000001010110011001011100111001100111000111111111010011101001000100110100000001001011101110100001100100110011100100101011100111001100001111010110000111111000010101001011101010110101100011101001001100101111001010000001011010000101110100010101110000010110000101 0001101110100100100011010001011100001011010000001100001101111001001001111100111000011001010101110111010011101101000100101101010011111101000110101011111100111001110011110100111000111001010000001001001001101001101101100110011010000011000011101111100001111101100001010111101011100011010111110010001101011000011110011010111011110001001001001100011001010010100101100011101111111100100001111111000011101101 0010011100010011101000101011001111000100101010010010110110011100101100100010001010110001110100001110100000000010100010000111001110110000100101110101111101001001010101110101000000111000100111100010010111010010001101010111001000101110101110100010000101111010000001110100101101000110110101110000111110010110101001111100001001110011011010111111100011001101100011000100111000101111010100000011100101010001 1101101001001110101001111101001110001111011100000011110101100110101000011111111011010010110000011101101101001000110101001110001010011110001111100000111000011110101001000011010110001011111001000111010000101100011101000111111011000010110100001001111111111110110111100000010101111101010010011010110011100011101111010100001011000110011111001000011100011111110110010001111001000010100101011011011011101101 0010100001100001010111011101010111100011010001010110110011110110001110000110100001001010101011100010101101011001011001000110010111110100011101101011111100010101100111110001101001000010100100100000000010000010010101110111100010100100011101101100110110001001000110001110001000100111001011101011011100000010010011110111101101100110110100000011100101011011111101110000110111110011010101001011110011110011 1011111001111101110000010000101010011110010011010011101111110011111000000000000011001110000000001010111100010011111100000010001001110110101010111110110110100110000100101010000111110110111100000011110011011111110111100110110010101111101100111101001011010111000010110111010110000110010010011010010111000001111010010110010101011010111011100101000101101011101001110100111101000110101111000010010010001110 1001001010000001111000100100010011010111011001101100001100111011100010000010011010110001001101010000110010110101100000000110111110111001110110101000100110111111110111010010110110011011111100110000111001001000110001111101000110101001001001000111111000010110110101101001111010011100011101010100001000011010100101011010100111001011010011101101100001000000101110001000100101001111101001110010010000011101 0101110011001010101001101001111101100011100101000000000110100111001110111000111001111000110101110011101111011111000111011001101001000000111110100100110111100100100100000111100100010010001100110110111101101110110001100111001001100001101001111011111111110001001001110111011000111000000011010000000101000000010000011110100100000100010111011011111111110001001000110000110011001011101111101110011111011001 1111011101000110101110110100011011001000110011100011001110010000011110001101110000010011101001000110101110000100101000001101101010000101110111101001011011010001011010100000110001100000011000100111100100100101011111100101111101010011010000001111100011101011101100101101101000010111110001001110100011101110001000001011110100010011011100111000101110001010001010100011101000000111011101011000001001101011 0010111010110001101110110110110101001011101110110101100100010010000101100110101101001001111100101111010011111000110110100110100010100110001110011100000111010100110011000100000000011011110011010010000000111100111001101101000000001001111100001101010011100010110010111001111010001011001100001001001111001010001101000000001010001101101001011111110010010001000001101011100010101000000101000110100010110010 0110100000110010110000001001110110001110110101101001010011101010000100100111011100101100011101001011110010111101000110011010111101110110000101011101001001111111101100111010001000100001110101101001101111010111000100001000000110111011000011101011010011100001110001111100011101000100101111001000110000101001010010010101011011000011101110011000110001000110111010001101001101101000001011110110110110001111 1101011101110101010111001110011111011111011011111111100011100000011010010011110110110001100000010111100110101011000000111000001001101111010001010001000111111100000100011110101110001110000100001111111100000101000010111010111011000011100100011110000111101000110000100111001010100101001000101010010110110001010100101110101100101100111101010011001000010101011000101010011100110111011010100101010010011011 0111000100011001000110110000000010111110101101111101100001110101010000011101011010011111001011101101010101010000011000010010001100101101100001110001110101010111110010001010100011111110110111010100110101010100110001111100110001110100010010111100100100011110011111101101011011011110110111010000110000100000001010100100100001010011001101101101011010001001100000111000000100001001000001010000100111110110 1000011011101010111100001000001011100000011110111011000110000001000010000010010110110010001000101011000111101111101100010001100001100000000111101111011111010111010100101011110000010001001000101110110101011111001101010011100110100011101010010100001110111010111100001110011111111011011010100011010100100010001110101011110001010000101100100101110101001001010001111010000001110101110101110011011001101100 0110101011101101111011000001001101010101000110000111101000111111101010111110110100000100010110111110001110011001110100111010011111011111100100010100011100101011111100010001001100100010110110010011101011001100101000000100010110101011000111000001011011001000110011111011110101110101110111001001111110110100001010111011000011101011011110101111011001000001001110001101111010001111110000101010110000100010 1000001100000001110011011000001001111001000110110000000011001100110010100010101011011011010011010111100110011010110011101011110110111011100110111000011101111110101101111001000110100110101000101001110000001001111100000100101010100100011011011101100101101000011011110101001110011101101001111011111000010011010000110001000011110111010111001000001001110111111011001101010110111011111001101111101000110011 1110100111111110101100100011111111101111000101000010110110110110010101110111101000010110001000111011010001110001101101010111011101000110100010000111100110001001011100000011011010110011110111001010100000100100011011000011000110010111100100011111001010001101111011000101100111110011100111001111011111010110110101101010001010110011110000110000000101011100011011101010010101011001010101110011100000111011 1101110000011001101000010100001100011000011100001000011010011101011101000000001110010001101101001001101010101110110001011111011100111100000001001110100100010000111000101001110001100011111001001010011100010001000111111000011111001010000101111001110011010101011111000001100011111000100110000011111111110101100100110101001001001011001110110001101101110100010100000110101001011000011011001010011010101101 0110001101010011010101100110100010001011011111111111011111101100101110100111100001011111100000101101011100010011000001101001010111010011011010111111001100111011110100111001001010001011011011101010001110111011001101100001001101101100000000100011001011010001010000000000001010100000110011101101011001111111111001010000101100001110100110000100010110010100011100000101000011000000001111001100001000010110 0100110100111010011111011111000011100110101001010011100000110011011001000000011101001111101110001101111110010010011010010000100100111010011111110101100011001110001101101011000010110010100100011101000101010011110101110110011010110100111000110100111111110001101001100101100100101100001000011101010110100111101011100010001011000100011011100011100000010001110010010110010100000001110111011000100111111100 1111110110000000111111110010101001100001001010000110011010011100101101101010000001001101100011010110101000111000100000011011010001011101111011111110111110110000111100100010000110010000011010010000000011111000011100011011100001110010011011010100011101011100010111101011101111110001111111111000001111011001110100000010001101101010110110100000000100000100100011100110100110100001100011001110101111110101 1110100111100111101000010000101010101001001110100100010110001001110111010010111001001011010001110010010100010111111101101001111100010100110011101001110010101010101100010010111001110100110110110101111000110010101111111000110110101101001010110110101110100100001111001100011101001100001111001011010110011010011011000101001000010000100010111010100110110010110010111110111011110001001101010001001110101011 0100100010010101111011010100000000010111101111011101100100011111100010010111010100011101011101110000000011011001001000110000010100101001101110110111001000001101110110001001010100100111001001101001110100111000000101001011010101000111011100111110111001101001011000101101011011111111100101000010101101110101100100000001101010101111110010110000011011100000001001000000101001101110110111101110101001011111 1010101001111000111000100000101101111100001000011010011001001111011111111110011110110110011000110001100001110100100011000111101000101111010111100111100010011110010001000101101000010101000110000010011110011110101011010110010011000101001010010010111110011110000110010001001111100001111001100011000101101111100100100111000011001000000000101100110010001101011111100000100111110011101110000011011001011000 1001000001001001110001100101000011011011101000000000010000111011010011101001010111011100101010111110000000011010001111100101001100100111001000101111010101011110000100111111011110001110011101011101101110000111001101011011101100010101001110001110100110101110100010110111000110100001000100011101011001111111001110101101001110000000111010001011011111010010011100101000001110111111111000110001100100010110 1101111101010111000000111000100000011101000001000111010010101001101001101110111100000011001010100111001001111001101011101000011011101001000100110010101010011010001011000001001111001001111101101000100000011001001001010110100010000101101111101000111110001010000010011000101100001011001110101011010111000011101111011101001000101011110110110000100001011100000010001000100101101100100100100100101110000011 0000101010001001000100101011001001000010011000101010001101110100110101111111001101101110101011100101000010001000001110111010101100011111011100000000010101100111000000001101010011100101001010000010010100101100111011111100001011001000011001111101000101101110010101000011100110001011100010101100111000100100011010111110100011011110001110110011100101111000100100100010010101010011101111100010010011100001 0001011101100000111100000010001111001010110011001110101000010011011011100110010000111001000010001010100001010100100001101110111111010111100101111111001111001000100010011110111001000100100011000100110100101100001001110000101001011010001000100011011110111010001011011100001001101101101100101010110100100110101110110111100101110011011010011011100000000011110110100011010000101111110110001010001100100101 0111100101111100011100110110111000110111001110010000000000000010111111000100101111100111000110111111010101110010111101010110000011101110101101010010101101010100101001110000011110111100010000101001111110010110110110100001101101100001001000100001010000001101101011011100011011011010110101100111101101100011010101101011000110001001010100000111001111110000001111111000001010001100010000100010101000100111 0111001111111011001101001000001100110001100010010010101111001100101100101111000100010110010001010100100110010101100110110011000000010101100000001000001111100100100111000001101100111110110111110000010101111001111100101100111101000001110000100110011100100110000001010110101010111100111101001111001110100001100101001111101000001011010100111001111101100110000111001100001110100111010111011010000001100110 1010100001011001110011000100001101010101011100010111000011110001010101111100100101001111000011100100000100110000100110010110110001111001011111000010011010101000101100100001110000110010110111010111111101000110010111100110111111011010011111110000100011001000001010011001011001011010001100000010101111101000101000101010111110001001111111000111110001000000000011010111100000001111100111100001000110000110 0110101110001000000011011001101001011000110001101110111110110101000001100110011000010100110011010010111000101011100011011100000000011111000100010000100000011101100000000010111000011010000110011101101010001111011101010010110100111010110000000111001110011111110000001111101000111010000111101001110111111101011111000111100000110010100111011001010100000101101011010011011001100110110010111001001000001010 1000001011100000100000011111111111100101011010011010100001000010010100001000111101010100111000100011001110100111010000010011111011011111010100011110101001100011011110101100000101010000011100110101000000111110110011000100001000101111010101001101110001011111101111111111100011101000111010000101100010101110100000110001110001001111000111010000010111010011010100110000000101111001110011100110001010111000 1101100011001001000111111111101010101110111011000101111010100110000011000011111011110001100011010111000001111010110101110100100100001110001110001111000001001110111010111101110011000010010010010010100101100101010010101111110110100010000110101011110001110001111100111100100010010100111001011000111111000101010111110100101100011100110001110110010110110001010001010011011110010110010101010111001101101000 0101100011101110001010000011000011011110000001111111011101011100110110011011111011010111010000101110111111100001010010001111101001010001110000111111000111101100110110111010001001100010011100010001011001110100010101100001110001000010010101011001000010110011100100101110110110111000001110100000101010011101000011111010011101010101011001101000111010100101111001010111111111100000011010101111001110000000 0000011111111011101101100100000100101111101000110010011001100000010100101000101100010100110111101100000110100101001011110101000111110110001000100010100000110110000001101110100001101000111000010100011000111001100001011011100001011100101101101011101111111110010101001100100010011110001101010100000100100111011001001101111101000011001000001110110101000100000010011101010010101000000100011100000101001001 1101110010011110110010001011000001011010000011101101111100101111010110110011001010101011101111110000110101000111011110110100001010111110010101111110100010001001111111101010111011111100010011101111100010000110011011011101010100011011001111000101100010101011000000101100001000001111100110111100011111010001101101000100110011001011101010101001111100110110001001010110100100000111101011011111010011001010 0011110011011011110000010110010010000011111111000011101100101110100100000000100000011010100001010000010001011001110000011101011111011100101010101101111011001010110011010101011000111110110101000110111011101111000100111101101010101111110001101100101101010110001101001100001110011011111001101010010100001110101000111110011010110010011101010000011010111111001001011111100111100011001101010100111000101101 0100001000111000110000110011001000101010100000001011101001100000110101110100010111000001110010100010001001001010100010000011101001011010101111000110111011111111100110010010011100000011000100000010011011111100110010111100000110001011100011100101001110011110110111011110010100100001101000011111101101110011001011011110100011100001011101101011110100110101010111110011001111101001010010000100010101010010 0011100111111000011101110100110100111101001000010101011111011000110100001110000110101110110011111011100101010100000101110100111101011110100010110010011111100010011010101000000110100011101011001001000111000111011110010010010001011111000001001111110101010011111011111011010001101011110000010000101111000110100000101010010101010001100110000110111000101001000101011001111101011111110011111010010111010101 1010010011011000110110100100110101000010110111010011101001111111010101101110011001010111001100100110001111011010010000110010011000100001011000011101110111110101001010001011000111111011001010110101100011110111011100101110010010101011010010111011101100100011110010011011110110101100001010100100000111000111111100111101010010011000110100010100100110101011011100010100100001100011011011111110011001100111 0111101010101000011001001000101111101010111110100011011001111001001111011101110101011010111011100110111000000011010001000111111111010110111110001100011011111010110100101110001010110110001110101100110000010011010100110101110000101111101111101011011101110011001000101000000101101010001000001111010111111111000010110100010000111011110101011011001101100101100000001101011111010100010101011010111111011010 0010100011101001100100110111011001111011110111010100111010100101010110100111100111011011101101010110111001101001010101010010110001001001001111000110100101001101100100101010011110010011000111000111111111000011100011100101010010100100111010011001001111101101100011001111001010101111101010010101111011101101110001010011010010101100110101100000110111011110100000011110000111110110101111100111001101000100 0110100110100000101111011000010011110001011101101011101110101000000101011000110111010011111111111111110000001111101100010001110101100000101111001000001110110000111010101001000100111000110101110110010100011101101100001101110000010111101110011001111101110101101000100011000001011101110000000000010011001000010111001001010011000010010101011111111010010100000110100110111011111111111100100000011001111011 1101011011101000110000110011000000110000010010110011111110110000110110000100100001000011110001110111011011110011001100101101100001000010001001000111101110111010011001001101001010111100000001010001110000111100000100011110101100101100100010100110000001100101101011001011100110101110110001011111010100111101110100011011001110001111001101001100010110101111011011000101010001110010100000101001100100001011 1101101001001001001110100000110100110011011101101000010101011011011111100100111011101011100001011011010011001100110101011001110001011001001111001001001111001010010011100111001110100010011111011110100101000110101101000101010000011111000000011001110001010011010001110110011110000000111101111100111011011011100100010100000000111000111101011010111100011010101010111011010001111111110110001001110011111000 0001000001010000110000001000100001010000011010010001110011110010010001010011110001101111011111111110111011110011010011011100001101001001111010001100111001101010001101100010101110101111000111011010001101100000010010011001011000010001000001101001001000001001000011000110010101111011001101111100110011100011011001110001000100110100000101101110011100010101101110101100101010001111111101010110101111111111 1111110011000001111111100111101010010011101110010010111010001101000111111011101101001001011000101000111100100001101101111010100000010010100010110110000110011101011100101010000011011100011000001011111110111101111101001100011111011111111001111100001111011101001010000000101010111101110001100101100111101011010110011101011001011010001100010001010110101000110110011011111101111100110000100101000100110011 1001110001001111010100010011010010001011101001010000101110001100110001101111101111101100001100111000100001100111111000000111010001010001101000110110011110001101011100100110011111101000001000111101111011001100110001011010101010010110100000110001111110100100000000110100101100011110100010101010010010000110001100000100110100000001011011001100111100001101110001111010011111111111001100010110100010000110 1010000011011110010001010000100001101010011000010010001001111110011101110100111111100100000010010011100001001100010000000101011000001100111000001001111001110000100100001111100100010101010110010010011000101001111001011111000011011011011000001111101010100011110111100000011111110011101110011101100001010110000111011011110110110000010101101111010011001111110111000100000110010101111110010001100011001011 0111110101000011000010001111000010111101000101010000110000111000000111110011001001010000110101001000011111011100011010110010000100101100100010010110100001111011100010111110011110110111110101011000100010110011001111010011010001110011101111100100101000111001100101101101111101101101100101101001100001101101001010101111010000110000011010101001111110101000011010110011001011011001100110101101011100001011 1011100101000001000111010101110000010110101111000010111010111011101110111111010001000100100001010000100011000100100011110000101011101100111001101000010111010011001110100000010011000110011111100110101100001111001110001100100101010001001100010000110110111100011001010001000011011111011101001001100111010111010001101101000100111100000111010110010110101110100110100100101010000000111100110010010001010100 1100111001100001111011111100111010001100111010000110111111101001101111000011111111110111000000111111010010000011010010100111100000111100101010001011110110101101111101001101000000001001110110100001101111101011001010110100000010110100110000110001101001011000111010001100011101011000001001000000101100001110001111100100111011010100001111001100001000000100101011010100111101001110101011111010010011110101 0000110100001010110100110110110101010011100010111000111100000110010101001111101110001010000001100110111110110011100000001000000100101010100111100101010100100011111111110111100100001100110000011001001000011010100011010111001110101101000001000100100110000001011101101110111110100011001100101000000001110000011101110111010011011010010000011111010111111111110111110001100011100000011110001000011000010101 0000101000100010000001011111111111010010101110010100111100000001101000000010110100011110010000100011100111001010100110010100111010000011101101100110000011000011010010101111010111001101101000011111101110011000010111110111111110101100011100001100000011000011001100010111001110001100000100001111100001001010111010000000011010100001011010000010100011010000000101000111011000101010001100111000111011010111 1111000111101101111000110010011100111100010010110000000010111010110000000100101111010100110110101011010010101100111010011001010000011111000010111001000100101010100110000011001011011000010101011111000011101000100101011100001001111001111100110110001101101100101101100100001111000011000110010110011101011111111001010000010010101011010011000001010000100101100101110100110101001100001001010011111001111110 0000110010010010110010111011011011011101111100111011001000111110111101100010110001000011011010110000000000111111111010011101111111000111010000001101110011110001110000011000110110101000011011011010010011010101111000000010001011100011100000100111011001101010110001001000001110101101111010010110100110001010011101101110101101111000001010011000000101100100001101100111101011010101100010110001000101000110 1100100010001000110101011001001111101000000011111111011001011001001001110011100111011110001111101101000011001100000000101110101001001001011110011011111001010110101011000000101001111110011110110111010001000010000110000011001010111111000001001111101110111101011101101110101101011000100111100111011010101101011011011000100011100101001001010001110000110111111110001110011110110001110100011101000011011110 1111101001100110010110011101011011111100101010011011000100000100000110000100101000110101010100111101010011101111100101001001111100000010000101000110100100011111001001010101110101011011011000110011001010100010110001100010001111111011011101001000010010000100011000110011011101000011111101010010101101000000001010101110101100010001111011110010110101101100100111101101101100000111001101001000111010001110 1011110000001101110011001001010011010011111110110011110111011101000111111100010000110101001101111000000011100101010111000001100001000110010101100010001001100110011011011000101100101011111111110000001110100000000000000011110111010001011111110101010000101110111000011111111111100000111111100100111101000101001001011100100110111011101101101100100010111001101010000011111010000000010111000000100011010100 1111011100001111101001101001100110000110111101000001010101001111110010101110001110010001010000011111000000101110111110010101111000101110000111111111110011100010000111111000011110111110110010011111100010110100101000011110000011111011110101100110111000110000100000010101101100101100111110111001001000111111010110010101011111101010100101011111011000100011110011101110110001100010111000010000000000001000 0100100001100101100100000101111011000010101100100111001001001100000010011001110111100111101110000001001111011011000011111001000111000100010011001000100010100000011011000010101010011100101110000001110110101111100011100010010000110011000011111001110001100111100000011010101100010000111101001000001011111110010001010000000010011001100001100010100100111010101000110110111101000100010101111010001000101010 0010001101101011100010010011101110101010111110010110101100000111110010111001011000001001001000101101100111111001001111010101000111010010110100111010100101011110010101111100101010011100111111010101011011101100011111000000100111100110100101101000100000101111001100111001101111010000110010011101000100010111000101110101010010000000110010111111000000100111000000111110100000011001001001011111010000001010 0110101101111000110101010011111010000001110000110000110011011001100000110000001100111110011110011101111010101001010011110110011010011111101101000101001010011111011100011010010011100100011110101101111001000000011001000000100101110000010010110000011101000101001101111000010110101100000110010000110001101111111110101101011110010000101000010001100111111111000100001001010000010010011111101011011111101101 0010110000100000010011100010001101001011011010001001100100010111001101110110010011011000101011010011000001001101000000110000011110111011100011111100000000101110010011100110110111010101000100010000100100011111010110111111111101000010110010110111100011101100111000100110100011101001011010000110001010101100100110010011011111010000110110000110000001000011010111000010110100001101010111100001110100100100 0100010011010100010011111111101000101111111110111010011100101110100100000011010011110010000011001000011010110001100010111111011110110011011111100110100110110011110010001110011111011111111110010111001011010000011010101110110100010001101001010010001100110001010100111111000101001110001000010111110010101111100011100101001100001010110101001000000111100010110000011001010100000011001000010110000010000011 1111101100000111111000100000110100100010101001010100010011111010100010111011011000111100110111111010000100000011011001010100011110011000011000010011110100001010000011000000000010110001111011000111011000010111100110000101100110110110110101100101100001100100001011010000111111111010111101110011001111000011111011010100011011010001001001010110111001111001010000100011101011101000011111100111100101001001 0011000000100101001110001010001101101000011001101010011100101111010011000001100010010110111001111000010001010010011011111010010101001100011001010111100110100011011111111111000111001110010011101111101010100011101001110111111000000011101101110001010010100110101111111010110011111100110000101011100110000010000101101100100010011101000101000110111110101000111110010001111001001110010111001100010001000001 0011011100011111011000011001100111100000001101010101010101101011001000011000001000000011000000110111111110110010110010010111011101000011111100011000100011011010101101110110101110011011101110011000111011011001011111011000010001101101000000010101101101101000001001100100011001011011110111010100101101011000010111010010100111100100111001101000001001110111110110010000010000000010000110100010110100101000 1110111111011111100001010101010000000100110111010000000100001001100101101111001011101010010110111001000100110010111010110010010010000011000010100101010011000111101110100111000001101000000010011110001000000100011011100101011010100101011000100110110101111010010111011110011100100111100101000111000110110010100001100111100010110111101010011000000001010100001111100010111000100100011000100101011011000011 1011100011100100110110111000111100011011000111000001010110110010101011000100001011001001101000001011000111111111000001111010010010000011001110101111110110000101011001101100110101011110110101000010100011111001011011110010000001100111111111101110011000010101111101111100110100100111010110101011000101101110010000100111010011110011010101010001001000110001011001001001101011110111111111101011100111111110 0111101000111101100100101001100001010110110100011110111111010100101000110011001001001010001100011111101001111010100100111101000011001011001110101010111111111101101000001001101101111100010011111101110100111110100010110010101100011000000011000010000011010110010011001010111101011110100010111101100011101011001010100000011010111001010110010001110100011101001110100101010100111111101011010010010010101000 1001010010100111010001101100011100100101010110110111000011001101000011101000101011011001001111111111001011010011110011100000000100011011100111001011110111100011110000100001110110101010000011011111101111010001110101111001101011111110001100010011111001001000011110111101011100011100000100111101110000001111000001100101100101111010000110000000011110101001010110111110011100111111101011001100100010100100 0011000101100001010010110011100100100101001110001001110011101111100100011010110011000111001010101110011001110111100111100001110100001010110010110000111011001011010110111001111000001000011000111011010011111101101101000111000001111011000010010010110011001010101010111101010011011101100101010011000010000010111111011000001000001011000110001111001010001011001110001111101111111011101101001111101011001100 0101101111111011001010011100000101100100010010100001110001001001111011101010111110101101011010001111000011010110111000011010001011100001001000100011010100100000111110011000001111110001010111111011101110010010110010110101101010111001110011101011011001000010000001111011110010010101010000011111101000000100000011100100110000000011000100001110110100011010100101000010000010001000001011011010000001100001 0000000110101011000110101110111000001110110100111101101101100001101001010010111001001101101101100101100100111100010100101101111110001100110000011111001110010111101001100111010101110111001101001100010011000001001111011011001101001000010011011100100100001100011011000010001101100110101100000011001010010110000000000110111100101110000111110011010011100111101000110100010001101100011010101100101010000110 1111001000101101000101000011000011011001110110000101110001010011010010101110100101011101001111000010101100011100010101011000011010010111110100100001001000110000101100011000011000011110100111111101111001110101110011010000000111100101000001000000011100001001110110101111010001000100000001100100010101100010111111101110010011010001010011100111010101001111111011011100110101111011001001010101111101001001 0000010101101001011011000110011011010000011100001001101001110111010101101110101010100000011001000011100011111000110010110110111100000000011000001110101010100001101101000111000011011110011101001001010111101100001011011011001100010011011011001111000101011110100110010001101011000011100110010100010001001100000100001011000100010010100011111001101011001011111111110101001100010110101000100000011101101101 0110111111010100000010100101101011101100010100011011011110000011000101010101000000110101001011000101000011010010100001111110110010010100111100000011011011110100011111101100110010011000000000101011100110111000111100110011011111111111000110011010111110010110110111101010101110001010110111101101101101101110011010010000101011001110001101110001011001111101001010101100101111101010000111111101110101101110 1000111101100011010100010110100010110011000010110000001110000101000101111100010100000101110000011011110011100111000001100000001100001001101101000111000001010010000110011011110010110000001000001011111101010010011011111010011000001100010111101101001010110111100001011110100101001000100111011011100010010001000111000100101000100001000000011011001010001101111000101100000100001110011100100100011101110101 0000101000011000101100011101111001000011001000011010000001010101111100011000000011001011101100000111000001011111001001111110100000011101110010001111000011110101110111010110001110110001111001111001100010110001010111101011001111100000000111011101100000001101010000000111110011111101000001000010100011010101110011011110010110001100001010110111101001101101011101000101111010100010110001101110011110111100 1011101001100110111100100001100110000010100001010110101001011000110110011100000011001000110001101111101110010100111111011011001011001010000011001110010011001010111110010101001111100111111011000111010111000010100000001010010000000010101110001001000111000101000101111111101100110100110101101011111100001011010110010000010100111011011101010111010110010111110010011011010010000000101111011010001001100111 0011101010111010010111000001111000110000001011001111000001000011000110100111111110001101101100000000000101001100111110100110001000100011101101110001110100011001011100010001010010011110001000000001110101100101010001100110000000111010100111011001110011011000111101111110101100011101001100111110010001011001110101010101001011001010000010001101110100011101110000011101010111111011000011001001000011100010 0110000001111110001110101000110010100111100010010110011000111010111010000011111010000100111100010000001001010110010111000111001001100100000010000001100011111000010011000111000111011001101100001000101011111011011100100110011000010010101000110100110000011011101101100000101101011010110111000100100001011110101010110101000011100001101101010011100011001011100000001110100011100100001011010111100010011001 0101110001010111110110100101000011011001110100001010111101001111110110110001011100011110001110100010001011101011010110000011011100101111010001010010110101110101111101010111010101010010001001011100110101011001100101100001101100000011111011111111110101010111100101001001000011110101011110010101110111100100101001111011000100000001010111101101100110001100110001110011101000110010111000001110100100000001 0011110110101011010000101011110111110101000010101100010101110100111100000001000001110111011101111101011000111101101001000010010110101111001011100010000000001100011001000110101001100110001000001001001001010111001000100011110001111010011101001101001011000110110110110011101111001000001110010010001100001011110001110001111011010000010010111111010111100011001010010111000011100010101000010000110101000000 1010111111100101001001001000001101101110000010100110110110101110110100101111101010001001001000101000000000011010111100001110111101101011001001100000001000110011100010001110010010011011010011111111010001011011011101111101100011010010010010101111000011101111010110100110001101101100110100010110001000011101000110111100010100101111111111000101000001010110001100111001011000010001001100101011010011000011 1010011111101110010101111111110110011011011010001001110111111100100111001000100100000011110101001111100100001110001000101101101001100101110010001001000000001001011110111000011010010011101010000000101100010110011111110001000111111110001110110011110000101101010011001001101011101011001011010001001110010110010010000010110001001000011000100100110001011111011100101010101110011001100010011010011000101000 1111000010011010010110011101101000101000100100011100100001100001100100011100010001101010011110000010100100100000010011111100100011000011110000101010010010000001110001000100000111100011001010011111100001001111101101110111010011001011010100001011000010001011111101111001010011000010010101011001110110010100110100011110001010111001011111110101110000011100010001111111111011010001110101011100111011000010
C#

【C#】値型と参照型

12/30/2020 1/2/2021

4年以上前の記事です。内容が古くなっている可能性があります。

内部での変数の扱いの違い

似て非なるコード

まず最初に次の2つのプログラムを見てください。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        PlusOne(c);
        Console.WriteLine($"after={c.Count}\n");
    }
    static void PlusOne(Counter c) { c.Count += 1; }
}
struct Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

(cAlgoではなくC#のコンソールアプリケーションです。VisualStudio→新規プロジェクト→C#コンソールアプリケーションで適当な名前で新規作成して、このままコピペで動きます)

Counter型のオブジェクトを作って、Counter型を引数にとるメソッドで中身を+1して、最後に結果を表示させているだけの単純なプログラムです。

このコードの結果はこうなります。

before = 0
after = 0

おや、メソッドで+1されたはずなのに0のままですね。なぜでしょうか。

では次をご覧ください。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        PlusOne(c);
        Console.WriteLine($"after={c.Count}\n");
    }
    static void PlusOne(Counter c) { c.Count += 1; }
}
class Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

ほぼ同じコードですが、Counterが構造体(struct)ではなくクラスになっています。ぱっと見、同じ動きをしそうに見えるかもしれませんが、結果はこうなります。

before = 0
after  = 1

ちゃんとメソッド内で+1されたものが反映されています。これは何が違うのでしょうか。

 

値型と参照型

この違いが値型と参照型の違いなんです。

 

説明の前に

オブジェクト指向では変数=オブジェクトと考えることが多いですが、この記事では「変数」と「オブジェクト」は概念的に別の意味を持つと思って読んでください。

ここでは「変数」と言ったらCounter cなどと宣言された c を指します。「オブジェクト」と言ったら、どっかのメモリ上に存在する c が表すモノ(値)本体を指します。

この定義であれば「値型」と「参照型」は変数の型の種類ということになります。そして、変数をメソッドの引数に渡すということは一般的に「変数の中身をそのままコピーしてメソッドに渡す」ということ示します。

重要なのでもう一度。引数に渡すということは、その変数の型が値型であろうと参照型であろうと「変数の中身をそのままコピーしてメソッドに渡す」ということなのです。

これを念頭に置いたうえでこの先をどうぞ。

 

構造体Counter型の変数は値型

C#では構造体は値型になります。

値型の変数はオブジェクト本体を自分で持ちます。つまり上記変数c の中身をのぞくとCounter型構造体オブジェクトそのものが入ってるイメージです。オブジェクトを使うときは中身のオブジェクトを直接使います。

引数に渡すときは「変数の中身をそのままコピーして渡す」ので、このCounter型オブジェクト本体をコピーしてメソッドに渡してあげてます。メソッドが使うのはび出し元が用意したオブジェクトのコピー品なのです。

上記一つ目のプログラムではメソッド内で+1されたCounter型オブジェクトはMain内で宣言して最後に内容を表示させたCounter型オブジェクトとは全くの別物なので、メソッド内で+1されようとなにしようと、最後の表示には何ら影響を与えません。

Main内の変数cが指すオブジェクトのプロパティは初期値0で作られて表示されただけなので、当然結果は0のままです。

 

クラスCounter型の変数は参照型

C#ではクラスは参照型になります。

参照型の変数はオブジェクト本体はどっか別の場所に置いておき、その場所情報だけを自分で持ちます。つまり変数cの中身をのぞくと、Counter型クラスオブジェクトが入ってると思いきや、そこにはオブジェクトがある場所だけがメモしてあるだけなんです。オブジェクトを使うときはその場所を「参照」して、その先にあるオブジェクトを使います。

引数に渡すときは「変数の中身をそのままコピーして渡す」ので、このオブジェクト場所のメモをコピーして渡してあげるのです。メソッドはその場所情報を「参照」して、そこにあるオブジェクト、つまり結果的に呼び出しが用意したものと全く同じオブジェクトを使います

であれば、上記2つ目のプログラムではMainでの変数cが指すオブジェクトのプロパティは、初期値0で作られてから、PlusOneメソッド内で+1されて、表示されたということになるため、結果は1になるのです。

 

C#では型の種類により自動的に決まる

C#ではint,doubleなどの組み込みの単純な値と構造体、列挙型は値型文字列(string)やその他クラスはすべて参照型と決まっています。

プログラマが、参照型にするか値型にするかというのを考える必要はありません。その代わり自分の使ってる型がどっちなのかを意識し、挙動を把握したうえでコーディングしていくことが重要となります。

 

 

参照渡し」別の話

「参照渡し」は引数の渡し方を示す言葉

上記は型の種類の話でしたが、似た用語で、メソッドへの引数のを渡し方を表す言葉として「参照渡し」「値渡し」があります。

勘違いしないでいただきたいのですが、「参照型変数を引数に渡すのが参照渡し」ではありません!他の言語でそのような使い方をする人も一部いるようなのでややこしいのですが、少なくともC#では違う意味で使いますので注意してください。

 

C#でいう参照渡し

最初に「メソッドの引数に渡すというのは『変数の中身をそのままコピーしてメソッドに渡す』ということ」と言いました。これがC#を含む多くのプログラミング言語で一般的な引数の渡され方で、引数の「値渡し」と呼ばれます。

これに対し、C#では「参照渡し」という特別な引数の渡し方ができます。「変数自身の参照(場所情報だけ)を渡す」ということができるんです。メソッドの定義時にパラメータにrefキーワードやout,inキーワードをつけることで参照渡しとすることができます。

渡される変数自身が値型か参照型かは関係ありません。何を渡されようとも、その変数の参照で渡すのが参照渡しですので、値型を渡されたら値型の参照を渡しますし、参照型を渡されれば参照型の参照で渡します。

using System;

class Program {
    static void Main(string[] args) {
        int n = 0;
        Console.WriteLine($"before={n}\n");
        // ↓呼び出し時も参照渡しであることを示すrefが必要
        EditParam(ref n); 
        Console.WriteLine($"after={n}\n");
    }
    //-------------------------------------------
    // 引数を参照渡しでもらって編集するメソッド
    static void EditParam(ref int param) { //← ref をつけると参照渡しになる
        // ここでのparamはMainのnを別の名前で持ち込んでると考えていい。
        // こんな風に代入してもnの値も連動して変わる。
        param = 100; 
    }
}

結果はこうなります。

before = 0
after = 100

なにが違うかわかりにくければ、refキーワードを消して動作の違いを確かめてみてください。

参照型の参照とか言われてもわかりにくければ、「参照渡しでは他で宣言された変数をそのまま持ち込むことができる」と考えるとわかりやすいかもしれません。

 

値型の「参照渡し」=参照型の「値渡し」?

違います!実行してみると全く違うのがわかります。

値型の参照渡し

これは値型を参照渡しするコードですが、一番わかりやすい違いは13行目、引数に直接代入処理をしたときの挙動です。

using System;

class Program {
    static void Main(string[] args) {
        Counter c = new Counter(0);
        Console.WriteLine($"before={c.Count}\n");
        EditParam(ref c); 
        Console.WriteLine($"after={c.Count}\n");
    }
    //-------------------------------------------
    // 引数を参照渡しでもらって編集するメソッド
    static void EditParam(ref Counter param) { 
        param = new Counter(100); 
    }
}
struct Counter {
    public int Count { get; set; }
    public Counter(int initialValue) {
        Count = initialValue;
    }
}

結果はこうなります。まぁ実質的に前項と同じコードですからね。

before = 0
after = 100

代入処理をしてもMain側の変数まで連動して変わるというのがポイントです。

 

参照型の値渡し

上のコードの2か所のrefキーワードを消して、structをclassに置き変えるだけで、参照型の「値渡し」になります。

そうすると、結果は当然こうなります。

before = 0
after = 0

むしろ引数に直接別のものを代入した時の挙動としては、こっちのが自然に感じる方が多いのではないでしょうか。

 

挙動の違い

引数に「参照渡し」で渡された場合は、参照型値型にかかわらず、変数自体が共有されます。引数本体が「参照の参照」となるため、引数=変数として扱えるのです。引数に別のものを代入すれば、呼び出し元の変数内のオブジェクトも連動して変わり、引き続き共有されます。

対して、参照型変数が引数に「値渡し」で渡された場合は、引数中身の参照が指し示すオブジェクトのみが共有されます。引数本体はただの「参照のコピー」ですので、引数自体を書き換える代入では、引数側は変わりますが、オブジェクトの共有は切れ、呼び出し元の変数にはなにも影響ありません

値型の参照渡しと参照型の値渡し、字面だけ見ると同じように見えてしまいますが、別物ですので間違いないようにしましょう。

 

「参照渡し」は何に使うのか

どういうときに使うのか、一つ実例を示します。

文字列を数値に変換するメソッドを作りたいと思ったとします。しかし、この処理は失敗することもあり、成功したかどうかを返り値で受け取りたい、しかし変換した結果の数値もなんらかの形で受け取りたいという状況を考えてください。

さてC#ではメソッドの返り値は一つしか受け取れません。どうしましょうか。いくつか手段はありますが、ここでは引数で結果を受け取る方向で考えます。このときに結果を入れるための引数を「参照渡し」で渡しておき、結果を入れてもらうような設計にするのです。

例えばこんな感じ。最後の引数はoutキーワードを付けることで「参照渡し」で受け取るようにしています。(refキーワードでも内部的には同じですが、返り値代わりのように必ずメソッド内で代入する場合はoutキーワードの方がおすすめです。)

bool TryParse(string s, out int result);

あ、もしかしてこんなメソッド見たことありますか?ですよね、もともとある組み込みのメソッドですからね。

参考までにintやdoubleの静的メソッドTryParseはこんな風に使えます。

class Program {
    static void Main(string[] args) {
        string str = Console.ReadLine();
        int n;
        bool res = int.TryParse(str, out n);
        if (res) {
            Console.WriteLine($"入力は整数{n}です。");
        } else {
            Console.WriteLine("入力は整数ではありません。");
        }
    }
}

 参照渡しする変数nは初期化の必要はありませんし、なんなら渡すときに宣言してもかまいません。(outキーワードなら。refキーワードだとこれができません。)

この「参照渡し」自体は自分から積極的に使う必要はないのですが、こんな感じで使われてるメソッドもあるため、使い方くらいは知っておいてもいいかもしれません。

 

 

まとめ

値型と参照型の挙動の違いはしっかり理解しておいた方がいいです。「参照渡し」は仕組みとして一応知っておきましょう。

値型  → 型の種類。値型変数を他で使うときはコピーを渡すので基本的に他のメソッドと共有はできない

参照型 → 型の種類。参照型変数の指すオブジェクト本体は他のメソッドと共有可能

値渡し  → 変数を引数に渡す普通の渡し方。特に意識しなくていい。

参照渡し → 引数に渡すときの特別な渡し方。メソッド内に他で宣言された変数をそのまま持ち込める
       渡される変数が値型か参照型かは関係ない。

あと、繰り返しになりますが単に参照型変数を引数に渡すことを「参照渡し」と呼ぶ人もいるみたいなので、その辺は空気読んでうまく対応しましょう。

 


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2025 ajinori