1101101011101010010101010000100101000111010010100011101101110010001100110100011101000110001111001011101111101101111001001001010000111000111110100110101011100110100010000000111100110011011111100111111000101001010011101000101001101111111111000100001011011110110001100111000001111001001010110110011000111101101010010101110100011001100101100100101011011100101110101010001000010101011111110011110100001100 1110011001010100000111000101110110101111001100001100010101101110001100111010110010000110101010101101000011100111000011101111000110011101111001000100100001010100111001111100111100100101011110101000100011000010000101001011010100011110010111001110110011100101001110110101010111000000101110001100011000101011000010111010000000100110010001001110110011011010110110110011010100010011110010000110001011100000 0001101111100101000101110000100101011001010100000000100100000100000010110101100010101100010110001010010111001111101011011001111111110010011100011100011111100110010110011001000100100101101110000110110100001000100001110001010110000000100110111101110111100000101100100001101010010111011100101111101001101100000010100100011110101111101110101110010110101010110101110111100001101010000110100111010101111001 0011010011010110000001000110101100001010110011110111000100001011111100100001000100110111010011110100001111111110111111111011100001001011110010100100010101010001000000100110111001101010011000011010111001101101000010001100100001010010011110011000011000001101100101100010001101101011011110101111010100101000110001100000001010010000000011110110110111011001000100011001001000011000000100111001100101000010 1010001000000000010111011101100001000010100001110000100011101100010010011110101010011110111010001100001011011010100000100000011110011110101001110101011110101110001100010000111001001011101000001001100000011000110110001010000110011101111101101110111101011110000010101101001111010010111110100001110110010110101101110101111011000010100010000000111111011010000000001010101110101111010100110010011100001001 0100110100101001101100000001101110000010011001111010110001100011111100000111001101101111010001000101111011111100101111111101100001101111000110011101110001101101001101011001001110011100111110011011110110001010010000110111111111000001110101111010100011011000110111101100001010100101110001011101101011001100101001011111011101101000101110101011010010001010110000100111111001111000000000100100001011110010 1110000111101110011001010011001111010011011011111111000010010011110110011001100110110001111111101101010110110010010001010111000111011111000100010110100000101110001110011110100000110110001001101111000101010100100010011110011010001111111011111001011110001101000110100011010101010010101001101110010110111110010000110011001110111100100110001100111111100101001100001000000000100101110000111100100010001001 1010100001010011111000100000011110101001001011101000100011101110111101101110111010101001010110101000001101111011010001000111110010011110010011010100110010000010000010000101000101101010101100010011100101100011010010001101100000000001111100100000001110001110000000000000101100011110000111101110111010100101110000101011101010100001110010010100100011110010100011001010100111111101011001001000101100010010 1110000110011010100111110011010000111010110010000001101100111110100111010110001011011101101110011001000101101000111111011010011000000110100011000111101111101110000101110000011000010100111101111001001111001011100101011001110101001101101010110001110011111010010101100101101010101000110001010100000001101100011101101000000001011001001000110010000110110101000110111110111100100011100110011110110010111111 0110000010011011100010011100110010110000110000001100101100100010011000010101101101011111100000111101100100101000010000011001100101111011011111101001100111101011100010001100011110011000101110001111010011111111110001001111101010011101111001100001100011011100110001000001000110000111110011000110110101011000010011000000000001000111000001001110100101101000101110111100100000111100111111000111100010011100 0000111100000001100010100001111000001110100001110101110000101010001011100001110010010100000001011111111000100001111101000100100110111111000000101010110100111010101100111111011111001010011110011000001100000100111010110001011110011111000010101110011001110111100011101101000000001001000100010010000011011001011110010001001010011100101011111110110111110000111111111111110010111101000001001101101111010100 1010100110110001101010101110000110111011000110110110010111010011010110000000011010001011011001111100101100100111011000010101101111000110110010000000110110001101101000000000100110000110010110010010011000001001101101010010110001000010001110001110110000101001011101001110101010110100010001100110011011100101010110110101101000101100110000011111010000011111101110110101110000101110111100000011001011000101 0000011011111101111001000101011111101000101001100000000000100000000010001100101011011111100100101000011010010111111001001101001001101111100100011011101001110110000011000000100111100001100110111110001111011101101001010100001010011100111100010001010011000101000001000100100010001010101110100110111011111101010001111101010110011010110110100010111001011011011010011111001000111101110110100001001011110011 1010101110101100011110011010111011111001010111110110000100000100000110100000111111100100110101011011001101100000000001111111110001001011100111010001001110110110110110100000111100110011100110001111110100001001001001111010010010100000100111111000101000101000011111111001111101111001110000101010001001100001111011010010101111100001100010110010011001101001101101010111001111111001010010100010110111010101 1101110000011011100101111111101111001000010011011000001001001010101001001000111111111001111101111101000000000101001011101110000000110110101010100011100000100110111010101001000110010001011110011010010010110111100011100101000100000011100101101110111010000011100001100100110111101111000010000001101001000110010011110100011000011000011110000010010110010000110000010000000010111101011011000100101111001000 0011000100100010101000000001010100011000100101110101000011101000010000000111110010101101100001001000011101011101110111001011010100000011111011101110111010000010010010110011111110001111111110101101111111111011100110100000100100111000000101010000010100000010101001010000000011000011001110001100011101010110101011100101011110110000001000001010110110111011001010000100011101101110101000000010000110011000 0011011101001100010111110000010100010001000010001110111001001011001101100000010000100010011001011100100010100110111010010010000110010011010001000010111111101011111010011000111111110111000110000100000011011001110001111111010010100100110001100010010001100110110001100000111011111100100110010001001101010100101111101010101001010111010101101110100111001011101101010011101101110001100101100000101001101001 0111010111000110100100010111111010001000101100101111111110110001110111010100000001101001100101000000010111000100100101001110001010010010011110111010100111100100110000100011000010011100011100000010111101001101101010011010101101011111111011100100101001110111111100011011011101000111000100101000011110010110110111001110011101000000010011011101110001110010001110100101110100011111110011011110001111000001 1101111111111010000111100100100000010111101111111100111100010000001010011011000111010011110101001011000001110100110100010001001000010100011100011001001001010110111111000100101010100001100001111011001111000011111101011000100110010100110001000011000100111011001000001110100100110110001101111001011000111111000110001000110001101011110101110111010100111110101010010101010110010110100000110011110001111011 1000001001010011011010011111100101111100010101010011001111111011010001001000100100100001010010111110011011100011110100110101110001111111010101010001011011111101010000001110111011011010001100010000011101001011001011111110110011101011010100111011000110100110000000111100000111000011100010100011011010000110101100001000100100111111001001011001100101000010110001110010101010010111011110110101111111010100 1010010111110011110100110000101110101110100110011001111000111000110110101101110010000100111011011111011101101001001111001110011111011101101001011011110111111101110010101100010011111011010011000101001001010101100111001011100011111111011101101100101110001101100100100011010100011111000001001011100101001000001011110101111111001111010010011110110111001100111011101010100101110110100110111101001101110101 0001000110000010010010101010100011111101000110010100111101000010111100011101010001010100111000100100001110000111111010100100010001000111011010001101001111110000011000100001000110001111010000110001010001111001001100110110110110100010101101101000001000101110000110011101000001101000011001111111110010000000110011001010100101100011010100011010000001010111011111000101001010110000010100001001000110101011 1001110000000000100010111110000011001000010101100000101110011101010011011001011001011111101001011101101001110010110111010100010011111011110011110000010001000000001010100101110100000001001001001001001111010111011100110111011001111110010100001000000000001100101011001111011011001101010000010000010101010001110110000110110011010001011110100101101101110100110110110010111001001011100001101110110101011101 1100011111010100010000010100110000010100100011111100000101010101011111110010110100111001111001110010001010000000010110011110011111110110101110010111111111110111010111010010111000000111000001110111011000110110111110011101111111110010111110001101001000000000101100011100101100111101100101010010001011110010100011011110101011111100000101111000000001101110000000111111100110111111000001011010010000111111 0001100011011101010011011010000110010001001100010010100100011000111010100110010101100000011011000100101000110100101101011110011000101101010011100110011011010111110000001110110000010101100011101100100111011011101100111101010101011101001100010010001001010100001011100011101110011001111111011000100101110010000000100000110010100101101010000000100100110110101010100110011110001010010001110110111101111101 0100011000000011001010101000110111010101100001010101110101011001001100011010100001010000000110010110111110100101000011011100000100100011011011110101000101110110010101011000011000000011001000010110000110111010110010010101101000011010011001010011101010000001010101011100101110100101010001011100001011011111100000010101111011111010001101100111000101111110011011001100000111111101011101100110101010101011 0011100101110111000101010000001100101011111110110011111101101100101110110100010011011000011111110011110000010111011100101101000000011110100101101010101001101100011001100101001001011011111010111011001110110000001110011011110100110000000100110011110100101111100000000010111101011100011010010111010100110100101010101111100001101000100001011101000110011001110011110001010001010001001010010000010101100110 0100010111100011011001010100111010111011011001011110101111111100100100110010111011101100110011111011101001000001111100110010101010011111111110111101101000110110001000001100011111100001100110110111011110000001110000100011100011010010101110111110101110100111111111111111101010101111110000101110100111100100110100100100001101110100101010001101110100110011010001110000000001111110110011010000010001101100 0010111010100011111011110100001110000000111100011000110110010001110000110101001000010010110000100110000010100110111000111010100010001001110000010001010011100101000011010011101100100101101101011011110111101110010111101011100010001011100101110010000001011101111111101000010001100100100100100100111110001111010110110011100101001101001111110110010111010100001111000111110000100100110111110010010111000101 0101110111010111011110000110011010000101110100010111110110011011010110011000101010000100111100111110001001111110101111011111110100001100100010110101001000000010000111100011010011101110110001100000111111101000111100000111100100101111010010011100001100110000100001111110111101101010100000101111100100110100000010111100100011110110011111001110101101101111110101101011000100110000001111110111110111111111 0111010000110101110011100110011111001110010010110110001000110001001101100100111000101011110010100001100010111011011100000000000001010101010011010101001111111001101110001111000001100000010111001101100000000101111010010011000100001101001000010101000111011100111011010100110000101111001001100101100011010100001100001010101100110101010111000110110101001100001001000010110110101001011111101110101001000110 1101101000011001111010010101001111110100001111101000110011010001101110111111001010010100100100011110000101100111001010100010101011000111111001110100111110010001001100011100100001001100010100001000101000110001110011000000001110111110001010001011011000000100111001100100111001100001000111010110100011111111110011110010011100000010011111110101101101001100110010101000011001001111010010011100001100001100 0101000000110001000001100100000011100000101101001010010000110001100100001011110010110100110000001001010011000010001001011000011010111010110101101000110110000111010101001010111000000101010010001101010011011100101000010000101110101010000011110110100000100000001000010011111010111011010010111100010010111010110100100110011111101110110001111111010100010100010010100101101110000010111100111000111110101001 1110011101001111110011111100111011110010110110011111101001011010000111100000100100001111000001011100010101001000000000001111101001111111101110110001101010011101100010000011010101011101101000001100010010111010001000110000010111010101100100101010100001101111101111110001110101011100000100110000001001000010101101010100110011101000001011100110000111010000101001011101011101001110001001111010100110011011 1001001011011010000110110111011100110100010011011001001001010100110100111001011100100000011111101111100000101110101101001011111100000011000110100100010100000101001111001010111010101010110001110010011101111000111001110110000101001101000101111111111001111101100000000110110010111110001100110101010010100000110110000100101010100101000011010010001000110101111110010111101111011010001101010110110000111100 0011000111100100001000110011100001011110011111011010001011111111010111110100000111111011111010100111101100000101001000110110011111001011111000010010011011010000100111100110110011001010001011010000100110001001001100011010100111010101101100100000101111010000010111100011011111100010011111101110000000100000000000001011110010101011000001010001100100111100111001100110101000100010010001101100000111111000 1101011011111100011010000000111010100111001110001100110110001010101100110000010001000110101010001110110000110011000000110011010000101101101000000000101011100010100100010100000001100010010011001110110000011000010000000010100101101110101010111001011100011110111111101010000001110111100001110011111101110100110110101101001111100001101100010001001001010011100001101110111011011100010000010000100100111000 1100111100111110011001100011100110001111001110111001000111101111011011010011000011111110010101100101110100011011010111100010011000110011101111110100111001010100111110001000000001000010010100011111110011011101100000101110101011101111010001110111101110100101110111000110111100001101100111010011100010011111100111010101000011110001110011010101000000110001000100101101000101000010000011010100001001000111 0111111011101111111001000010001000100010101011110011110110111001010101101001000111100010001101000100110000111111010101010010000000100110111001011011011011110010010000011010000111001001010001001011101010111110111000101011011110001101111000111100111110010011111110100111010011000011110100011111010000001010011000000010001001111110110100111110111001110010001100111100010110010010000000101011101001101110 0111000000101111010011101010010111111011100000101101000100001011001101011110011111011000011001011101011110100110010010110100001000101001111000001101010000110001000110101010001101111000001101001101111010111000000001111100110110110000011001110010000001011110101110010110011011001100101101110111100011010101110111100111001100110100111010000000111110100010101110001111000100110010111010010011001111110010 0000110101101010000000011111010010110011001011111000101011011100010011001101111001100000011110001001110010001011111101000001010100100101110001101110010100010010111010001010111011111010110010101011111101010101100101111010011110111000011010000110110111110000011100001111011010011010000111010011001011001101110010000101101000011001111101100101100101001000011111101000100101100111000111011101000110001100 1011011000101010010011110101110011100110110000110101010000100001000110111011111110011111110010110100110001001110100000110100100011011111011101111111001011100011100111010100111000011001111001011100001011001111110001000101010101101011101110011100001101111101101101110011101101111100111100100011001011001101000001111010010101011011010111101000001101110010100100001000110011001001111010110110110001100101 1011111100111110011001010010101000100001001101011011101110100110011000010100011110010000000110110010110100010010111100110000011001000110101000101111111100001011001000000100010011111100011001010111101101001001010010111111100001001110101001000101101100101110010001011001111100001110111101001011000000100001000011111001011111110110011001111011011010110100010100010101001100011111101000110100110110010111 0111010100110010000000000111111000111001000110100101010111001111101101010100110001101010111011010011000110110011111011011001111011111100010101011001000001101101100111101110100010111110101111100100111001100010011111000010110110010111011100001010011001010100001010111011101111101011001001001100010011110100001000000111011000110011111111000010100001000001001011101010100111111010011000001000011100001000 1010110001100011011011110110101111111000110110010000110101000100011110100011010011011100101011000001001010100011001100111111111010000101000000101111111000011110000000001100110110101010111011110001100101111110111010011010001010001000010110011010110101100101000001011011111000001001111000001110001111000100010111011001001100110110111111111001101110011101000110001011110000101001101010111000000110101000 1110010110110010110110110011000001110111011110000100111010010100000101100010011101011001001010010011101011010010010000100011000000111111000001101000101101000100111010010010101100000110111001000011100101000111110111001010110000110101111101011101101011000110110111111001110000100101001101101110110001000101111010011111110000110101011011000110110000001100101001111100010110001111011000001011010011010010 0011010010101011010110111011001101101101001101101101011001001001100100010001000001000111000011010010110110010010110010000100010110011101110100010110110101110100010110001011000000100110111101100010010010110100010100000001000100010100101011011001110100101101110101111100100110001000111101111110000010011110111010101000101101001011100001010111110010100111010000110100000100001010111011000101110001111100 1011110110010111100100111100100101100111101000011100110011101010101110110110010011010110000010100001110000001101110111000100111101011011000010000001010100111100001111100011111111101000110000100110001111011001010110110010011011100111111001111010000110100111110100011110111000100010000101000111100010110011001010011111010010100111010100011001100110111101010100110111000000001001110001010000110000010100 1000000011111010000001011011101011100000101110110100011111100101000011010110001101010000100000101011011001000110011111000010110010010000111101010111110110011111000000110011011001010010010111001010001110111000010010111110101011001011110001111101001010111111010100010100000000001101100000100001111110101110011000100010111010111111001000001001010011011000000110011011011010001010101010101000011100001010 0100011110101111111010011101101111110011110101110010010100010110001111100100001010111000011010100001001000101011111111010011101100110100101101001001111010010011111001100010000010000100111100001001011101011000001011100100100011011001001011001111011011001011110011000100001001010001011100000010100110101001001011001111110110111100000110010001000100110001110100100111011101010011100001001100011011100110 1100110101101010001001110001010011010011101011100101110001010000110010101000101110001100000101010011010110000010111011011000000010101110100010011010111101101101011110110101100101010110000001111101101010111000000001100110010100010111110101111000000101100101111110110000101010010000100111111100110110100111001001101111000110001010110110001100101100001110010001010110110101011100001001101001111011010101 1111010100111001011111001011001001000001110110010001100101010000010001011010001011010011111000111111001111100100110010100101110111010001111111110111011011010110110110010001010000111111110001111001100010110101000000001111100110000100100100011000101111001111011011011110010001000101101101000100110110111111001110010101010100111100010111011100011100011010111011100110100000110110010101111110010010010111 0010011010000011110101101111100101010100111100111111101100110111111011101100010010101010111101001011011100000010011111011011010000101011100100110100001111000111110101100101001010011011101111011111100101100101101111110111110011101010110010000000110011011100101001010011001111010011000111101010100011100110001100001110010010011000101000110001100000011011100001101010111111100000110101101000010110011000 1011010110100111011110110000010110101001001101011110110001101001101111100100000010111001110111011111011101001100011011111010010010000011011001000001111010010010001111110110100001001111000001111101010010001000000011011010000101010010110011110000000111010100101000001111100110010110010100111110111000111010111101100011011101111001100100011001010110100001011000000010000001101001101000100010011011101011 0010101010001100100000101110011111011001010010101101011011101000001100110111100111101010001110010111011100111001001110011101000001000110101101100110110100101110111111111110111101010010000101101010111001100011100111011010011110010110010100111101000001111010011110000010011001100111111000101001000111111111011001101101100101001001011001010011110111001010100111010011110111100111010000101100011101100110 1011101000110100111110010101110001011000111010101110000010100100011110001010101101011100010100110011001011111101101001011101100000000101001110111001000001011010101110011110100111110000000101010001110011000110011101111100110010101000001111111010000011110100001011100111010011111010101011011111111100011001001011100101100110111110100001000000100000001111010110100001101001100100101100111101100011001101 1110110001001001110010000001101001011001111011001101011111011011000111000011011100001110001110110111100000000010101001101010001001110110010010001100000001011111011110000110001100010001100011010100010110011011100001111111010001110000101010110101110010110001011110011001011101100000011110000000010110111010000100110000000000010101111001100100000000000110101000010000011100101011110000110110110010000001 1111111000110010000100100000011111000000011000111111011000100011101110010100110000100111011101010101011100000100000101101101010011100000011001110110001110000101110010011111010110000001010011000100101110110001101010100001100010100110110000111110010101101111100010111010000011010110101111100110100011010001111001001101011000001010100110101100110011101101000101110001011000001100001000111011101101111101 1110111100011001111100111100100111000010000100010011111001110110011010011110010011110011110000001100001111001000100010101010110000001000111010010001111110011100110001111101111111111000110001111110000110100111010110010111011100111101011111110000010000010101101000011000101100100111110000000111101000001110100111000101000001010000101010101011100100010101110011101111100010010101100111001100111011010101 0001000110110011000011000000100101100001110110101100111010011110011000101101011101001010110111100100111110101110110011011101111101010001000010011011100011101000000101111111000001001001101110110110110100010111100010101001101001111010100111110100011011001101100101111101011110010010100000011010101000101000101100111100001011010010111101001001000101100110011110110011001101010100111110111100110000001101 0000110100100110010010111010110001000010010101101001011011010001111010111111010000010100110000101111010111000011101101010001000101101001000000101111010110001101011000000011000000100110101000000110110000001111111110001001100101111001100010100000101111111001101011001000000010100100110010111001111100110010110011111000100110010011101011111101010011011000101010000100000001000111101101001110000111110010 1001010101101010000000000000001111101110010100011101001101010010000100111111001000100011001100000110101111101000011000110011101110001000010001110001001000110110001000111011001111010011111111101100101101011101001001011100010110011101110110010010010011000001101001001111011001100000100101100111001110010001001010010011101110000011011100100111111010110001010110001000111110001100100110101100010000010010 1010100010111111110000110010010111110110010010010011010010011000000100010101111011001011101000110011111011111100011011101100111001001011001000111111111110110000110100001100000010101011000000011010011101110001100001110001111010001011111001111001011111110011101100111001111100010001101101111100100110000110101001101001001111101101101110000011000000010100100100110110010110001010001111110001111011011010 1011101011000011010110011011111100110110110000011111101111000100001011000010010010100000110011111110111011111101111101100101100111101110010010011100001001000000011011001100011110010111000011111000010001111000101010110000010111111100110100011111001011110100001011000001000000111001000101101101101110010000011111101111011000100010100111011110010100000000010000010000110010100101101110001011100111001000 0001011001000000100010011101110011000000110111100001010010101011010000101000011110010011010100110110011111100100010001000110000011100111101010101100110101001000101001010111110000101110100011000011111110001110110101110001111001100101101010101010101011000011111001000010111001100010001001001111111001000011011000001100000010100010010100011111101100101101101001000000100001101000010111111010000000000101 0001110011000001101110100011010100010010101101111100100010110011001101011100001101100111000111000011101110010011001001011111010001011001111011011100100100000100001001101001100101111000110010100011110100100011011001101000001000111011101010101001100101011100111010111110101101000001011010101101001000010111111001000000100010010111000000100010110110111001010001100111111100011110111110110111111001110101 0101001001001010100011011011100000011001000010111101001100101010001111001001110011010000101011000110110111111010111011010011010011111000101100010000101100100000000100101001110000001110011101101001000010100000011110001100000011010010011001010001000101100110001011100010000011100111110000110011001100100100110011110001111000101100100111000101010000010100010011111101111101000011111101001100111001110110 0011110110110001001010100001101000100111110100101010010101001111111100011001111000011011110101111110001111011100000101001001111110101110110100111110010111101001010111110100101110000011111011101100101011110110111111110010010001101100100000110110000110101010110111001101001010010110101111111011101000100100010111001111101000000110101101011000011010000101010111101010011010101011111100010100111110011001 1001100001101100111010011100001001001001111110001010111111101001010001011001101100100111111110100100101110000000101001001001100101110111101101101010010100010010010101110001010000111100011100001101111100000000111011001101001000100011111110111100001100100110101111110100000011111000010010000111001100010001110001111101110100110010111101000001011001000111010100110110000000101110010000010000100010110011 0001101110001000101101110101001000000100101100111001010010010001101110000010001010000000000100100101011111110001001011100110100101011111001111110110001000000110111101010011011011100000001101100111110001010000010010010001111111111011100001101011011101100000111110110111101110111100110010010110010011100111110100101001011110000000101010100110111011011000110111101100011111110101010010000110100000010011 1101110100110111001011010010110111011000001000000000010001010000000001011011011111111111011111111111111001000100011101111101010001000110101001000010000011110000001000010011110010100001111011100010000001000001000010100011010010101110011011111110011011111001010100101101001101010100010101111001110011001011111101110111000110101100010111010101100111001010010000100000001111010100000110001101001100001010 0000010100100010100111000011001101000101010100101110100100100110110010000100100101110010111101100101100100001000110001110100111010010110001001110100000110011111000001001001101010101110100111001011010001101110011001000011010011100001000000010010000001010111111101010000000001000001111100111011001000010101101100110000011100011001001110101000001101001110100011011101110000011110100011100100110001000001 1111000010010110011111110111000011010101000110010111100110011101101101110110100100011110010110000100000000010110110001000100110001100101001000111000000110001001000111001110001100111001011101111111111011001011111011100100010001111001000000101011100000011110000011110010011010110011100101001111010010010110101011000010000111111111001011111000100101100111110111001110011001001111010001010101100111011001 1010010000000101010001100100010001101001111001110000011011000011101110100101011010000101000111110010001110111010000011101111101101110011010000001111101111111001011111100011111101101110000101111001100010111100110100111011101010111011111000100110100000100011011111110110101100001101111000111000110001100001010111000111001011010101011010100110110000100000111101000000010001111110000011111101101110110001 0000110011001100000101000000100001100000111101100001110100001010000000010111000110001110001011101011011010111101101010101010101101001101111100000100100000100100010100001000001101110101100010010011001100100100010110100101110011110101011100100001101101100011011111010100110101010100111110101000011110010000110010001000011010000000000111101101111111110000101110110010000001110000010001111100110101101110 1111110111110011110111000000111110010110110010001010101001100011101000110001010110000100111001101111001010011010110110100110111001001001010110100001001011100111110010001100011001101111001101010110100011010011010010010110010001111001101001011111000000000010000111100100110000110101001011101110011010000001001111000101110001101100100110111010111100111110101010011010001000001110011001110101101110110011 0000110011001111111010110001011110001101111001001110100110100111100001010100010100100111111100101101000100110010010111010110011000001011010000011111100111101010001010101111010110011001111101101001110001110111101011101000000000101110000000000011100111101110000000001110000101000111101000111100001010001101101001000111101110111011110111111001110110110100000000010110011100100000001101000110111000000101 1110110001111110111010000101010111110010110000000010101001011111110101101001101110110101010000100011010110110001010010100100001000111110110010101110101101101100001101101010100100110010001101001101011011000000011100011100000101010001011000001101000101001000000111110011110010011000011010010011010000010011110011110101101100000101101110000110100011001010011011100111110110101000111001110011010100110000 1110001010101010001011001111000001000111011001011010111000111011000011010010101110001011011101110011100011110110000010011111010001110101010000110111001111011101001000100010001001010010101110000100110110101110001110111011100111010100001001110001101110011111100000010010000010010110000010000000111011100010100101101011100111111110001010111010101011111010111001111010111001000111100011110011111011100110 0010111111001110001011100110001111110010110000011001000010110001111011001110101101111010101111000011001011111001110100000100101011011000000001110110100010101101111000010101100001001000000101011010101011010110110000100101010110110010111110011111010111100101010100010110010100101101011011111001011110101011111011110010000000011110111001111101111110111111110000101100101000000010011101001011011101110101 1110110111001000100011011101000100110010000010010111100001100010110000111101110000101001111100011110000011000001101010010101100001111111111111101000000010101011111001101010100010000001000101110110000100100000110000000101110011111110001001001111011010101110101111011010111000101110011011111001111001011110111011000010101001100101100011011110110101100111101111001000110010101010111101101101000011000000 1101001011110101111011001000111111011000100100011110001010010100101110111100110111001010101001100000000010001110000010011100000001101001100110101111010110011001100100111111110100111011010100100111001001010110101101001111000010000010110111101000000101101111011111001100011100010111000100001111101101011000110011100110001001100100100000101010011101000100110100011111011101011000101101010011011111100101 1100000010011011110101001100011010111110000111010100010011110010011011000100111010101110011111101100111101100100110011001111101011001000000000110101111011000010110000010110110100001011000100100101010110011110100011000110000001001110100101010010000110010000100010110110011010001110101000101011000010011100101011001011100011100100010110011000100111010110011010011111001110101000110100000100110000111111 1011001000111001000011001100101010101011100111011011010110011011011101001110001000011000110010010011111111000010111000111010110110000011110001101001110001111000010011110001111111111011101001101101001001000111111000101110100101000100100111001001101101111000111110010110000101001101011010101001011000001110101100000101111011011111111110010100111000111100010110101001110100110011101100110101001011000111 1010100001100111100110110100000110011111001101001101011100010110100000000101000001100101010011111111101100011110000110101001001010100111110110010101110100110000101110000001100000100100011100001111011001100101001010011000011000000000110010111101110000101110001001111100101100100000100101100101101011010100110110001010010000010110000111100001110001000000110000010111001111001011101100000111110000100000 0100110111100010100001000100010111111000011110001100001001000010110110001110001000001100010101111000101001001001101000001111001001000110100101011001011100101101001001010011000001010110111101101111010000000100111110000011000100110011000000011101001001011101111010100111111000000000010111110010110100111001001101000101010101000111010111000111011000000110100000010011111110001001010001101100101010000111 0001111001100011000010010011100001000000110011100100100100100110010010101000101100111001011110111101010111011111100001010000110001111100001111000010111100110110111001111011011101000000011101000001011111000011110011000001001110101110010101001011110001111111111110000001011111000000000110000010010001000000111111101011110110101110011011110100010100000011111001111000100110001011111100111111110010010100 0000101001100010110101001100001100101010111010111010010100100011111000110111111010111111011010100100110111111011010011100011001111110010010100110001100111100100011010010001000011100100101000011011101111101001100101001011010101010110011101101110000110001001001001100100000101000110011111100101101000100100100100100000101100000011101011011011010011011011111110000110000001111100001101000011110010010010 1000110011100010000101001011000010110011101001111110000100111111100111010010101110111110110001001110011010101001011001100101110001100110101011100001001101000011100110111111110100101110001010110100001000011100000011101101110100111011010100101000100010010001110011111111101110000011010011010001010000110011101100100110111110111111000010000101010110011010110111100000110110101000110001000000000001011011 0111000001111110011010010011110000011011101010010010100000101001101101001111001010100001101001110000101111101100001110011100010100000001010010111010111110010110001001101111010101000000011011000010100111110110100100010001011100110101111111100000110000100011011101001101110110101101111111001010111000110001101110110011011001100110001010100001010110111110101111000100011010000111001111001001100011100100 0001000011111000010010001010110000100010101011010000100101101100101100001110001110000011000100011001100011100011011010000011100011110100011010010001011100010010010101001000101010110100110101110100111001000010010011100000011010111001000110110001100100010011100101011011111001010111101110010000011001100000011101001100000111110110111111111111011010111100010101111011000101001101100111010101011100111111 1101001111011000001100101110001101110110010010001000110100010011010011000100100111111011100101010001111110100101101100010110111011000001010011111010101011111010000100001000001000100000001100001101001011110000111100001000011001100011001000000100101000011001011010111001000111010111011011100110111000001011111011011100100101001101101011001110010101111011010010100101011100011010110010010111110010111110 1101011110110001000010101001101010010010111111010111100101011100000011111010101100101111001010000001000100111101110001111111011000101011011110100101000001101000110011100101000110110110110101100110001110000110000111111000111111100111100011001111111111001010101000111011111111010000111110010101000000000110011000101101101110010010110001101111011011101001011101111001001111000000110000001000000010011100 1011111001111110011100111101101111000101110000011100100000110101011010110101111001100100001111010110111010001100001111000000000001010011110101000110111010100001001011100011100000001011000110000101111010110110100100000011101100010111011110011101010001110000001011110001110111001001001110011110101100010100001110010100100110001101001001100101000011101011001010011010000110011010110011101100011011111111 1111111010011110010101111001110001001011001001110111110100100011111101010011010110011100111001100011100100010011100010100010010101011110111100000100110010111111110111011000111000010110101111111100011100000111011011111100110010011001100001010001001011100110101001100101111110111000111101110000000100100110001101111100011100101010000000001101100100101100101011110111010100001010111010101001010111011011 0111011111100010110110101111101001111001101100110100010111101100010000010110110110010001011101011010111100000010101111111001110011000000011011111011111011111101100011110100011101010110001101011100110110110101101110111110001001101111010111111001101010101110001100010011100101001100001010001011100101100110001000110101110100100001100101111110011100010011011010011000011011100010011110110111111010100011 0000100000110001111000110110010110011010000001000110001111111000110000100101011100100001000111011110000100001100010001011010010101100010001110101101100100001000101111101011000101100001100111011010010010010010011100000100010010001110000000100100000111010011101011101111110011111000000011011101100010010101100101100000001000110100110001100010110100101010011101011001110001011010010000010011100101011001 0011011101001101001001010100100010001101110110001110111001000011100100111010101000011111000011100010100110011010101110111100101010110001100101000011101000011000011101110011110111101000010101100011000101100111111101100011001111101001000011101110000011110011100111011100101000100101011010101101110101001110001011101000011011111110000001000001111111001001000001001010011111101111111110000100100101001010 1100001000100110011111001010100010111001111000001111111100100110100000101111110001110001110100001000110011011011001101010110110101011110110000010001011111111111111111111000101000100010100110001000110100110110000101100101000101011010110100001010110010001010000111001011000001111111110000010111111000010001001111110101001100110110001110100110110001100010110101010100000011010010110110100010010111011000 1110000011101110000011100011110001111110110111111111001100110011101101010000110101001100101010111111001100010000101110000100011011010010001111010101100011101100101000010111010111100111110101110010110011011100001111001101011000000001001100111110111110011110011101010001101010011001011001001100100000000110110110111010010000001011010110010011000011110011011011000101111010000111111011001100001101001011
C#

【C#】値型と参照型

12/30/2020 1/2/2021

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

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

似て非なるコード

まず最初に次の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

© 2026 ajinori